mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-24 01:31:11 -05:00
chore: fix pghistory migration deps and improve htmx utilities
- Update pghistory dependency from 0007 to 0006 in account migrations - Add docstrings and remove unused imports in htmx_forms.py - Add DJANGO_SETTINGS_MODULE bash commands to Claude settings - Add state transition definitions for ride statuses
This commit is contained in:
@@ -7,3 +7,11 @@ class ParksConfig(AppConfig):
|
||||
|
||||
def ready(self):
|
||||
import apps.parks.signals # noqa: F401 - Register signals
|
||||
import apps.parks.choices # noqa: F401 - Register choices
|
||||
from apps.core.state_machine import apply_state_machine
|
||||
from apps.parks.models import Park
|
||||
|
||||
# Register FSM transitions for Park
|
||||
apply_state_machine(
|
||||
Park, field_name="status", choice_group="statuses", domain="parks"
|
||||
)
|
||||
|
||||
@@ -19,7 +19,14 @@ PARK_STATUSES = [
|
||||
'color': 'green',
|
||||
'icon': 'check-circle',
|
||||
'css_class': 'bg-green-100 text-green-800',
|
||||
'sort_order': 1
|
||||
'sort_order': 1,
|
||||
'can_transition_to': [
|
||||
'CLOSED_TEMP',
|
||||
'CLOSED_PERM',
|
||||
],
|
||||
'requires_moderator': False,
|
||||
'is_final': False,
|
||||
'is_initial': True,
|
||||
},
|
||||
category=ChoiceCategory.STATUS
|
||||
),
|
||||
@@ -31,7 +38,12 @@ PARK_STATUSES = [
|
||||
'color': 'yellow',
|
||||
'icon': 'pause-circle',
|
||||
'css_class': 'bg-yellow-100 text-yellow-800',
|
||||
'sort_order': 2
|
||||
'sort_order': 2,
|
||||
'can_transition_to': [
|
||||
'CLOSED_PERM',
|
||||
],
|
||||
'requires_moderator': False,
|
||||
'is_final': False,
|
||||
},
|
||||
category=ChoiceCategory.STATUS
|
||||
),
|
||||
@@ -43,7 +55,13 @@ PARK_STATUSES = [
|
||||
'color': 'red',
|
||||
'icon': 'x-circle',
|
||||
'css_class': 'bg-red-100 text-red-800',
|
||||
'sort_order': 3
|
||||
'sort_order': 3,
|
||||
'can_transition_to': [
|
||||
'DEMOLISHED',
|
||||
'RELOCATED',
|
||||
],
|
||||
'requires_moderator': True,
|
||||
'is_final': False,
|
||||
},
|
||||
category=ChoiceCategory.STATUS
|
||||
),
|
||||
@@ -55,7 +73,12 @@ PARK_STATUSES = [
|
||||
'color': 'blue',
|
||||
'icon': 'tool',
|
||||
'css_class': 'bg-blue-100 text-blue-800',
|
||||
'sort_order': 4
|
||||
'sort_order': 4,
|
||||
'can_transition_to': [
|
||||
'OPERATING',
|
||||
],
|
||||
'requires_moderator': False,
|
||||
'is_final': False,
|
||||
},
|
||||
category=ChoiceCategory.STATUS
|
||||
),
|
||||
@@ -67,7 +90,10 @@ PARK_STATUSES = [
|
||||
'color': 'gray',
|
||||
'icon': 'trash',
|
||||
'css_class': 'bg-gray-100 text-gray-800',
|
||||
'sort_order': 5
|
||||
'sort_order': 5,
|
||||
'can_transition_to': [],
|
||||
'requires_moderator': True,
|
||||
'is_final': True,
|
||||
},
|
||||
category=ChoiceCategory.STATUS
|
||||
),
|
||||
@@ -79,7 +105,10 @@ PARK_STATUSES = [
|
||||
'color': 'purple',
|
||||
'icon': 'arrow-right',
|
||||
'css_class': 'bg-purple-100 text-purple-800',
|
||||
'sort_order': 6
|
||||
'sort_order': 6,
|
||||
'can_transition_to': [],
|
||||
'requires_moderator': True,
|
||||
'is_final': True,
|
||||
},
|
||||
category=ChoiceCategory.STATUS
|
||||
),
|
||||
|
||||
@@ -14,7 +14,7 @@ class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
("pghistory", "0007_auto_20250421_0444"),
|
||||
("pghistory", "0006_delete_aggregateevent"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.db import migrations, models
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("parks", "0003_add_business_constraints"),
|
||||
("pghistory", "0007_auto_20250421_0444"),
|
||||
("pghistory", "0006_delete_aggregateevent"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.db import migrations, models
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("parks", "0006_remove_company_insert_insert_and_more"),
|
||||
("pghistory", "0007_auto_20250421_0444"),
|
||||
("pghistory", "0006_delete_aggregateevent"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
||||
@@ -11,7 +11,7 @@ from django.db import migrations, models
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("parks", "0007_companyheadquartersevent_parklocationevent_and_more"),
|
||||
("pghistory", "0007_auto_20250421_0444"),
|
||||
("pghistory", "0006_delete_aggregateevent"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
|
||||
@@ -7,15 +7,17 @@ from typing import Optional, Any, TYPE_CHECKING, List
|
||||
import pghistory
|
||||
from apps.core.history import TrackedModel
|
||||
from apps.core.choices import RichChoiceField
|
||||
from apps.core.state_machine import RichFSMField, StateMachineMixin
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from apps.rides.models import Ride
|
||||
from . import ParkArea
|
||||
from django.contrib.auth.models import AbstractBaseUser
|
||||
|
||||
|
||||
@pghistory.track()
|
||||
class Park(TrackedModel):
|
||||
class Park(StateMachineMixin, TrackedModel):
|
||||
# Import managers
|
||||
from ..managers import ParkManager
|
||||
|
||||
@@ -25,7 +27,9 @@ class Park(TrackedModel):
|
||||
name = models.CharField(max_length=255)
|
||||
slug = models.SlugField(max_length=255, unique=True)
|
||||
description = models.TextField(blank=True)
|
||||
status = RichChoiceField(
|
||||
state_field_name = "status"
|
||||
|
||||
status = RichFSMField(
|
||||
choice_group="statuses",
|
||||
domain="parks",
|
||||
max_length=20,
|
||||
@@ -175,6 +179,41 @@ class Park(TrackedModel):
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
# FSM Transition Wrapper Methods
|
||||
def reopen(self, *, user: Optional["AbstractBaseUser"] = None) -> None:
|
||||
"""Transition park to OPERATING status."""
|
||||
self.transition_to_operating(user=user)
|
||||
self.save()
|
||||
|
||||
def close_temporarily(self, *, user: Optional["AbstractBaseUser"] = None) -> None:
|
||||
"""Transition park to CLOSED_TEMP status."""
|
||||
self.transition_to_closed_temp(user=user)
|
||||
self.save()
|
||||
|
||||
def start_construction(self, *, user: Optional["AbstractBaseUser"] = None) -> None:
|
||||
"""Transition park to UNDER_CONSTRUCTION status."""
|
||||
self.transition_to_under_construction(user=user)
|
||||
self.save()
|
||||
|
||||
def close_permanently(
|
||||
self, *, closing_date=None, user: Optional["AbstractBaseUser"] = None
|
||||
) -> None:
|
||||
"""Transition park to CLOSED_PERM status."""
|
||||
self.transition_to_closed_perm(user=user)
|
||||
if closing_date:
|
||||
self.closing_date = closing_date
|
||||
self.save()
|
||||
|
||||
def demolish(self, *, user: Optional["AbstractBaseUser"] = None) -> None:
|
||||
"""Transition park to DEMOLISHED status."""
|
||||
self.transition_to_demolished(user=user)
|
||||
self.save()
|
||||
|
||||
def relocate(self, *, user: Optional["AbstractBaseUser"] = None) -> None:
|
||||
"""Transition park to RELOCATED status."""
|
||||
self.transition_to_relocated(user=user)
|
||||
self.save()
|
||||
|
||||
def save(self, *args: Any, **kwargs: Any) -> None:
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from apps.core.history import HistoricalSlug
|
||||
@@ -264,21 +303,6 @@ class Park(TrackedModel):
|
||||
def get_absolute_url(self) -> str:
|
||||
return reverse("parks:park_detail", kwargs={"slug": self.slug})
|
||||
|
||||
def get_status_color(self) -> str:
|
||||
"""Get Tailwind color classes for park status"""
|
||||
status_colors = {
|
||||
"OPERATING": "bg-green-100 text-green-800",
|
||||
"CLOSED_TEMP": "bg-yellow-100 text-yellow-800",
|
||||
"CLOSED_PERM": "bg-red-100 text-red-800",
|
||||
"UNDER_CONSTRUCTION": "bg-blue-100 text-blue-800",
|
||||
"DEMOLISHED": "bg-gray-100 text-gray-800",
|
||||
"RELOCATED": "bg-purple-100 text-purple-800",
|
||||
}
|
||||
if self.status in status_colors:
|
||||
return status_colors[self.status]
|
||||
else:
|
||||
raise ValueError(f"Unknown park status: {self.status}")
|
||||
|
||||
@property
|
||||
def formatted_location(self) -> str:
|
||||
"""Get formatted address from ParkLocation if it exists"""
|
||||
|
||||
@@ -146,11 +146,7 @@ class ParkService:
|
||||
"""
|
||||
with transaction.atomic():
|
||||
park = Park.objects.select_for_update().get(id=park_id)
|
||||
park.status = "DEMOLISHED"
|
||||
|
||||
# CRITICAL STYLEGUIDE FIX: Call full_clean before save
|
||||
park.full_clean()
|
||||
park.save()
|
||||
park.demolish(user=deleted_by)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user