Files
thrillwiki_django_no_react/source_docs/AGENT_RULES.md
pacnpal 1adba1b804 lol
2026-01-02 07:58:58 -05:00

3.5 KiB

Agent Rules

These rules are MANDATORY and MUST be followed without exception by all agents working on this codebase.


1. Entity Versioning MUST Be Automatic

Caution

NON-NEGOTIABLE REQUIREMENT

All versioned entities (Parks, Rides, Companies, etc.) MUST have their version history created automatically via Django signals—NEVER manually in views, serializers, or management commands.

Why This Rule Exists

Manual version creation is fragile and error-prone. If any code path modifies a versioned entity without explicitly calling "create version," history is lost forever. Signal-based versioning guarantees that every single modification is captured, regardless of where the change originates.

Required Implementation Pattern

# apps/{entity}/signals.py - REQUIRED for all versioned entities

from django.db.models.signals import pre_save
from django.dispatch import receiver
from .models import Park, ParkVersion
from .serializers import ParkSerializer

@receiver(pre_save, sender=Park)
def auto_create_park_version(sender, instance, **kwargs):
    """
    Automatically snapshot the entity BEFORE any modification.
    This signal fires for ALL save operations, ensuring no history is ever lost.
    """
    if not instance.pk:
        return  # Skip for initial creation
    
    try:
        old_instance = sender.objects.get(pk=instance.pk)
        ParkVersion.objects.create(
            park=instance,
            data=ParkSerializer(old_instance).data,
            changed_by=getattr(instance, '_changed_by', None),
            change_summary=getattr(instance, '_change_summary', 'Auto-versioned')
        )
    except sender.DoesNotExist:
        pass  # Edge case: concurrent deletion

Passing Context to Signals

When updating entities, attach metadata to the instance before saving:

# In views/serializers - attach context, DON'T create versions manually
park._changed_by = request.user
park._change_summary = submission_note or "Updated via API"
park.save()  # Signal handles versioning automatically

What Is FORBIDDEN

The following patterns are strictly prohibited and will be flagged as non-compliant:

# ❌ FORBIDDEN: Manual version creation in views
def update(self, request, slug=None):
    park = self.get_object()
    # ... update logic ...
    ParkVersion.objects.create(park=park, ...)  # VIOLATION!
    park.save()

# ❌ FORBIDDEN: Manual version creation in serializers
def update(self, instance, validated_data):
    ParkVersion.objects.create(park=instance, ...)  # VIOLATION!
    return super().update(instance, validated_data)

# ❌ FORBIDDEN: Manual version creation in management commands
def handle(self, *args, **options):
    for park in Park.objects.all():
        ParkVersion.objects.create(park=park, ...)  # VIOLATION!
        park.status = 'updated'
        park.save()

Compliance Checklist

For every versioned entity, verify:

  • A pre_save signal receiver exists in signals.py
  • The signal is connected in apps.py via ready() method
  • No manual {Entity}Version.objects.create() calls exist in views
  • No manual {Entity}Version.objects.create() calls exist in serializers
  • No manual {Entity}Version.objects.create() calls exist in management commands

Document Authority

This document has the same authority as all other source_docs/ files. Per the /comply workflow, these specifications are immutable law and must be enforced immediately upon detection of any violation.