Add secret management guide, client-side performance monitoring, and search accessibility enhancements

- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols.
- Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage.
- Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
This commit is contained in:
pacnpal
2025-12-23 16:41:42 -05:00
parent ae31e889d7
commit edcd8f2076
155 changed files with 22046 additions and 4645 deletions

View File

@@ -0,0 +1,186 @@
# ADR-003: State Machine Pattern
## Status
Accepted
## Context
Parks and rides in ThrillWiki go through various operational states:
- Parks: Operating, Closed Temporarily, Closed Permanently, Under Construction
- Rides: Operating, Closed, Under Construction, Removed, Relocated
Managing these state transitions requires:
- Valid state transition enforcement
- Audit trail of state changes
- Business logic tied to state changes (notifications, cache invalidation)
## Decision
We implemented a **Finite State Machine (FSM) pattern** for managing entity states, using django-fsm with custom enhancements.
### State Model
```python
from django_fsm import FSMField, transition
class Park(models.Model):
status = FSMField(default='OPERATING')
@transition(
field=status,
source=['OPERATING', 'CLOSED_TEMP'],
target='CLOSED_PERM'
)
def close_permanently(self, reason=None):
"""Close the park permanently."""
self.closure_reason = reason
self.closure_date = timezone.now()
@transition(
field=status,
source='CLOSED_TEMP',
target='OPERATING'
)
def reopen(self):
"""Reopen a temporarily closed park."""
self.closure_reason = None
```
### State Diagram
```
Park States:
┌──────────────┐
│ PLANNED │
└──────┬───────┘
┌──────────────────────────────────────┐
│ UNDER_CONSTRUCTION │
└──────────────────┬───────────────────┘
┌──────────────────────────────────────┐
│ OPERATING │◄────┐
└──────────────────┬───────────────────┘ │
│ │
┌───────────┼───────────┐ │
│ │ │ │
▼ ▼ ▼ │
┌────────────┐ ┌────────┐ ┌────────────┐ │
│CLOSED_TEMP │ │SEASONAL│ │CLOSED_PERM │ │
└─────┬──────┘ └────────┘ └────────────┘ │
│ │
└───────────────────────────────────────┘
```
### Transition Validation
```python
class ParkStateTransition(models.Model):
"""Audit log for park state transitions."""
park = models.ForeignKey(Park, on_delete=models.CASCADE)
from_state = models.CharField(max_length=20)
to_state = models.CharField(max_length=20)
transition_date = models.DateTimeField(auto_now_add=True)
transitioned_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
reason = models.TextField(blank=True)
```
## Consequences
### Benefits
1. **Valid Transitions Only**: Invalid state changes are rejected at the model level
2. **Audit Trail**: All transitions are logged with timestamps and users
3. **Business Logic Encapsulation**: Transition methods contain related logic
4. **Testability**: State machines are easy to unit test
5. **Documentation**: State diagrams document valid workflows
### Trade-offs
1. **Learning Curve**: Developers need to understand FSM concepts
2. **Migration Complexity**: Adding new states requires careful migration
3. **Flexibility**: Rigid state transitions can be limiting for edge cases
### State Change Hooks
```python
from django.db.models.signals import pre_save
from django.dispatch import receiver
@receiver(pre_save, sender=Park)
def park_state_change(sender, instance, **kwargs):
if instance.pk:
old_instance = Park.objects.get(pk=instance.pk)
if old_instance.status != instance.status:
# Log transition
ParkStateTransition.objects.create(
park=instance,
from_state=old_instance.status,
to_state=instance.status,
)
# Invalidate caches
invalidate_park_caches(instance)
# Send notifications
notify_state_change(instance, old_instance.status)
```
## Alternatives Considered
### Simple Status Field
**Rejected because:**
- No validation of state transitions
- Business logic scattered across codebase
- No built-in audit trail
### Event Sourcing
**Rejected because:**
- Overkill for current requirements
- Significant complexity increase
- Steeper learning curve
### Workflow Engine
**Rejected because:**
- External dependency overhead
- More complex than needed
- FSM sufficient for current use cases
## Implementation Details
### Ride Status States
```python
class RideStatus(models.TextChoices):
OPERATING = 'OPERATING', 'Operating'
CLOSED_TEMP = 'CLOSED_TEMP', 'Temporarily Closed'
CLOSED_PERM = 'CLOSED_PERM', 'Permanently Closed'
UNDER_CONSTRUCTION = 'UNDER_CONSTRUCTION', 'Under Construction'
REMOVED = 'REMOVED', 'Removed'
RELOCATED = 'RELOCATED', 'Relocated'
```
### Testing State Transitions
```python
class ParkStateTransitionTest(TestCase):
def test_cannot_reopen_permanently_closed_park(self):
park = ParkFactory(status='CLOSED_PERM')
with self.assertRaises(TransitionNotAllowed):
park.reopen()
def test_can_close_operating_park_temporarily(self):
park = ParkFactory(status='OPERATING')
park.close_temporarily(reason='Maintenance')
self.assertEqual(park.status, 'CLOSED_TEMP')
```
## References
- [django-fsm Documentation](https://github.com/viewflow/django-fsm)
- [State Machine Diagrams](../state_machines/diagrams.md)
- [Finite State Machine Wikipedia](https://en.wikipedia.org/wiki/Finite-state_machine)