mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2026-02-05 09:25:18 -05:00
feat: add passkey authentication and enhance user preferences - Add passkey login security event type with fingerprint icon - Include request and site context in email confirmation for backend - Add user_id exact match filter to prevent incorrect user lookups - Enable PATCH method for updating user preferences via API - Add moderation_preferences support to user settings - Optimize ticket queries with select_related and prefetch_related This commit introduces passkey authentication tracking, improves user profile filtering accuracy, and extends the preferences API to support updates. Query optimizations reduce database hits for ticket listings.
477 lines
16 KiB
Python
477 lines
16 KiB
Python
"""
|
|
Rich Choice Objects for Parks Domain
|
|
|
|
This module defines all choice objects for the parks domain, replacing
|
|
the legacy tuple-based choices with rich choice objects.
|
|
"""
|
|
|
|
from apps.core.choices import ChoiceCategory, RichChoice
|
|
from apps.core.choices.registry import register_choices
|
|
|
|
# Park Status Choices
|
|
PARK_STATUSES = [
|
|
RichChoice(
|
|
value="OPERATING",
|
|
label="Operating",
|
|
description="Park is currently open and operating normally",
|
|
metadata={
|
|
"color": "green",
|
|
"icon": "check-circle",
|
|
"css_class": "bg-green-100 text-green-800",
|
|
"sort_order": 1,
|
|
"can_transition_to": [
|
|
"CLOSED_TEMP",
|
|
"CLOSED_PERM",
|
|
],
|
|
"requires_moderator": False,
|
|
"is_final": False,
|
|
"is_initial": True,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="CLOSED_TEMP",
|
|
label="Temporarily Closed",
|
|
description="Park is temporarily closed for maintenance, weather, or seasonal reasons",
|
|
metadata={
|
|
"color": "yellow",
|
|
"icon": "pause-circle",
|
|
"css_class": "bg-yellow-100 text-yellow-800",
|
|
"sort_order": 2,
|
|
"can_transition_to": [
|
|
"CLOSED_PERM",
|
|
],
|
|
"requires_moderator": False,
|
|
"is_final": False,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="CLOSED_PERM",
|
|
label="Permanently Closed",
|
|
description="Park has been permanently closed and will not reopen",
|
|
metadata={
|
|
"color": "red",
|
|
"icon": "x-circle",
|
|
"css_class": "bg-red-100 text-red-800",
|
|
"sort_order": 3,
|
|
"can_transition_to": [
|
|
"DEMOLISHED",
|
|
"RELOCATED",
|
|
],
|
|
"requires_moderator": True,
|
|
"is_final": False,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="UNDER_CONSTRUCTION",
|
|
label="Under Construction",
|
|
description="Park is currently being built or undergoing major renovation",
|
|
metadata={
|
|
"color": "blue",
|
|
"icon": "tool",
|
|
"css_class": "bg-blue-100 text-blue-800",
|
|
"sort_order": 4,
|
|
"can_transition_to": [
|
|
"OPERATING",
|
|
],
|
|
"requires_moderator": False,
|
|
"is_final": False,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="DEMOLISHED",
|
|
label="Demolished",
|
|
description="Park has been completely demolished and removed",
|
|
metadata={
|
|
"color": "gray",
|
|
"icon": "trash",
|
|
"css_class": "bg-gray-100 text-gray-800",
|
|
"sort_order": 5,
|
|
"can_transition_to": [],
|
|
"requires_moderator": True,
|
|
"is_final": True,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="RELOCATED",
|
|
label="Relocated",
|
|
description="Park has been moved to a different location",
|
|
metadata={
|
|
"color": "purple",
|
|
"icon": "arrow-right",
|
|
"css_class": "bg-purple-100 text-purple-800",
|
|
"sort_order": 6,
|
|
"can_transition_to": [],
|
|
"requires_moderator": True,
|
|
"is_final": True,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
]
|
|
|
|
# Park Type Choices
|
|
PARK_TYPES = [
|
|
RichChoice(
|
|
value="THEME_PARK",
|
|
label="Theme Park",
|
|
description="Large-scale amusement park with themed areas and attractions",
|
|
metadata={"color": "red", "icon": "castle", "css_class": "bg-red-100 text-red-800", "sort_order": 1},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="AMUSEMENT_PARK",
|
|
label="Amusement Park",
|
|
description="Traditional amusement park with rides and games",
|
|
metadata={"color": "blue", "icon": "ferris-wheel", "css_class": "bg-blue-100 text-blue-800", "sort_order": 2},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="WATER_PARK",
|
|
label="Water Park",
|
|
description="Park featuring water-based attractions and activities",
|
|
metadata={"color": "cyan", "icon": "water", "css_class": "bg-cyan-100 text-cyan-800", "sort_order": 3},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="FAMILY_ENTERTAINMENT_CENTER",
|
|
label="Family Entertainment Center",
|
|
description="Indoor entertainment facility with games and family attractions",
|
|
metadata={"color": "green", "icon": "family", "css_class": "bg-green-100 text-green-800", "sort_order": 4},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="CARNIVAL",
|
|
label="Carnival",
|
|
description="Traveling amusement show with rides, games, and entertainment",
|
|
metadata={"color": "yellow", "icon": "carnival", "css_class": "bg-yellow-100 text-yellow-800", "sort_order": 5},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="FAIR",
|
|
label="Fair",
|
|
description="Temporary event featuring rides, games, and agricultural exhibits",
|
|
metadata={"color": "orange", "icon": "fair", "css_class": "bg-orange-100 text-orange-800", "sort_order": 6},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="PIER",
|
|
label="Pier",
|
|
description="Seaside entertainment pier with rides and attractions",
|
|
metadata={"color": "teal", "icon": "pier", "css_class": "bg-teal-100 text-teal-800", "sort_order": 7},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="BOARDWALK",
|
|
label="Boardwalk",
|
|
description="Waterfront entertainment area with rides and attractions",
|
|
metadata={
|
|
"color": "indigo",
|
|
"icon": "boardwalk",
|
|
"css_class": "bg-indigo-100 text-indigo-800",
|
|
"sort_order": 8,
|
|
},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="SAFARI_PARK",
|
|
label="Safari Park",
|
|
description="Wildlife park with drive-through animal experiences",
|
|
metadata={
|
|
"color": "emerald",
|
|
"icon": "safari",
|
|
"css_class": "bg-emerald-100 text-emerald-800",
|
|
"sort_order": 9,
|
|
},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="ZOO",
|
|
label="Zoo",
|
|
description="Zoological park with animal exhibits and educational programs",
|
|
metadata={"color": "lime", "icon": "zoo", "css_class": "bg-lime-100 text-lime-800", "sort_order": 10},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="OTHER",
|
|
label="Other",
|
|
description="Park type that doesn't fit into standard categories",
|
|
metadata={"color": "gray", "icon": "other", "css_class": "bg-gray-100 text-gray-800", "sort_order": 11},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
]
|
|
|
|
# Company Role Choices for Parks Domain (OPERATOR and PROPERTY_OWNER only)
|
|
PARKS_COMPANY_ROLES = [
|
|
RichChoice(
|
|
value="OPERATOR",
|
|
label="Park Operator",
|
|
description="Company that operates and manages theme parks and amusement facilities",
|
|
metadata={
|
|
"color": "blue",
|
|
"icon": "building-office",
|
|
"css_class": "bg-blue-100 text-blue-800",
|
|
"sort_order": 1,
|
|
"domain": "parks",
|
|
"permissions": ["manage_parks", "view_operations"],
|
|
"url_pattern": "/parks/operators/{slug}/",
|
|
},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="PROPERTY_OWNER",
|
|
label="Property Owner",
|
|
description="Company that owns the land and property where parks are located",
|
|
metadata={
|
|
"color": "green",
|
|
"icon": "home",
|
|
"css_class": "bg-green-100 text-green-800",
|
|
"sort_order": 2,
|
|
"domain": "parks",
|
|
"permissions": ["manage_property", "view_ownership"],
|
|
"url_pattern": "/parks/owners/{slug}/",
|
|
},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
]
|
|
|
|
# ============================================================================
|
|
# Person/Entity Type Choices (for Company model)
|
|
# ============================================================================
|
|
PERSON_TYPES = [
|
|
RichChoice(
|
|
value="INDIVIDUAL",
|
|
label="Individual",
|
|
description="Single person or sole proprietor",
|
|
metadata={"color": "blue", "icon": "user", "css_class": "bg-blue-100 text-blue-800", "sort_order": 1},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="FIRM",
|
|
label="Firm",
|
|
description="Professional services firm",
|
|
metadata={"color": "indigo", "icon": "briefcase", "css_class": "bg-indigo-100 text-indigo-800", "sort_order": 2},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="ORGANIZATION",
|
|
label="Organization",
|
|
description="Non-profit or member organization",
|
|
metadata={"color": "green", "icon": "users", "css_class": "bg-green-100 text-green-800", "sort_order": 3},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="CORPORATION",
|
|
label="Corporation",
|
|
description="Incorporated business entity",
|
|
metadata={"color": "purple", "icon": "building", "css_class": "bg-purple-100 text-purple-800", "sort_order": 4},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="PARTNERSHIP",
|
|
label="Partnership",
|
|
description="Business partnership",
|
|
metadata={"color": "orange", "icon": "handshake", "css_class": "bg-orange-100 text-orange-800", "sort_order": 5},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="GOVERNMENT",
|
|
label="Government Entity",
|
|
description="Government agency or public entity",
|
|
metadata={"color": "gray", "icon": "landmark", "css_class": "bg-gray-100 text-gray-800", "sort_order": 6},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
]
|
|
|
|
# ============================================================================
|
|
# Company Status Choices
|
|
# ============================================================================
|
|
COMPANY_STATUSES = [
|
|
RichChoice(
|
|
value="ACTIVE",
|
|
label="Active",
|
|
description="Company is currently operating",
|
|
metadata={
|
|
"color": "green",
|
|
"icon": "check-circle",
|
|
"css_class": "bg-green-100 text-green-800",
|
|
"sort_order": 1,
|
|
"is_active": True,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="DEFUNCT",
|
|
label="Defunct",
|
|
description="Company no longer exists",
|
|
metadata={
|
|
"color": "red",
|
|
"icon": "x-circle",
|
|
"css_class": "bg-red-100 text-red-800",
|
|
"sort_order": 2,
|
|
"is_active": False,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="MERGED",
|
|
label="Merged",
|
|
description="Company merged with another entity",
|
|
metadata={
|
|
"color": "purple",
|
|
"icon": "git-merge",
|
|
"css_class": "bg-purple-100 text-purple-800",
|
|
"sort_order": 3,
|
|
"is_active": False,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="ACQUIRED",
|
|
label="Acquired",
|
|
description="Company was acquired by another entity",
|
|
metadata={
|
|
"color": "blue",
|
|
"icon": "arrow-right-circle",
|
|
"css_class": "bg-blue-100 text-blue-800",
|
|
"sort_order": 4,
|
|
"is_active": False,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="RENAMED",
|
|
label="Renamed",
|
|
description="Company changed its name",
|
|
metadata={
|
|
"color": "yellow",
|
|
"icon": "edit",
|
|
"css_class": "bg-yellow-100 text-yellow-800",
|
|
"sort_order": 5,
|
|
"is_active": True,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
RichChoice(
|
|
value="DORMANT",
|
|
label="Dormant",
|
|
description="Company is inactive but not dissolved",
|
|
metadata={
|
|
"color": "gray",
|
|
"icon": "pause-circle",
|
|
"css_class": "bg-gray-100 text-gray-800",
|
|
"sort_order": 6,
|
|
"is_active": False,
|
|
},
|
|
category=ChoiceCategory.STATUS,
|
|
),
|
|
]
|
|
|
|
# ============================================================================
|
|
# Date Precision Choices (for parks domain - founding dates, opening dates, etc.)
|
|
# ============================================================================
|
|
DATE_PRECISION = [
|
|
RichChoice(
|
|
value="exact",
|
|
label="Exact Date",
|
|
description="Date is known exactly",
|
|
metadata={"color": "green", "icon": "calendar", "sort_order": 1, "format": "YYYY-MM-DD"},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="month",
|
|
label="Month and Year",
|
|
description="Only month and year are known",
|
|
metadata={"color": "blue", "icon": "calendar", "sort_order": 2, "format": "YYYY-MM"},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="year",
|
|
label="Year Only",
|
|
description="Only the year is known",
|
|
metadata={"color": "yellow", "icon": "calendar", "sort_order": 3, "format": "YYYY"},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="decade",
|
|
label="Decade",
|
|
description="Only the decade is known",
|
|
metadata={"color": "orange", "icon": "calendar", "sort_order": 4, "format": "YYYYs"},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="century",
|
|
label="Century",
|
|
description="Only the century is known",
|
|
metadata={"color": "gray", "icon": "calendar", "sort_order": 5, "format": "YYc"},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
RichChoice(
|
|
value="approximate",
|
|
label="Approximate",
|
|
description="Date is approximate/estimated",
|
|
metadata={"color": "gray", "icon": "help-circle", "sort_order": 6, "format": "~YYYY"},
|
|
category=ChoiceCategory.CLASSIFICATION,
|
|
),
|
|
]
|
|
|
|
|
|
def register_parks_choices():
|
|
"""Register all parks domain choices with the global registry"""
|
|
|
|
register_choices(
|
|
name="statuses",
|
|
choices=PARK_STATUSES,
|
|
domain="parks",
|
|
description="Park operational status options",
|
|
metadata={"domain": "parks", "type": "status"},
|
|
)
|
|
|
|
register_choices(
|
|
name="types",
|
|
choices=PARK_TYPES,
|
|
domain="parks",
|
|
description="Park type and category classifications",
|
|
metadata={"domain": "parks", "type": "park_type"},
|
|
)
|
|
|
|
register_choices(
|
|
name="company_roles",
|
|
choices=PARKS_COMPANY_ROLES,
|
|
domain="parks",
|
|
description="Company role classifications for parks domain (OPERATOR and PROPERTY_OWNER only)",
|
|
metadata={"domain": "parks", "type": "company_role"},
|
|
)
|
|
|
|
register_choices(
|
|
name="person_types",
|
|
choices=PERSON_TYPES,
|
|
domain="parks",
|
|
description="Person/entity type classifications",
|
|
metadata={"domain": "parks", "type": "person_type"},
|
|
)
|
|
|
|
register_choices(
|
|
name="company_statuses",
|
|
choices=COMPANY_STATUSES,
|
|
domain="parks",
|
|
description="Company operational status options",
|
|
metadata={"domain": "parks", "type": "company_status"},
|
|
)
|
|
|
|
register_choices(
|
|
name="date_precision",
|
|
choices=DATE_PRECISION,
|
|
domain="parks",
|
|
description="Date precision options for parks domain",
|
|
metadata={"domain": "parks", "type": "date_precision"},
|
|
)
|
|
|
|
|
|
# Auto-register choices when module is imported
|
|
register_parks_choices()
|
|
|