Files
pacnpal d631f3183c Based on the git diff provided, here's a concise and descriptive commit message:
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.
2026-01-12 19:13:05 -05:00

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()