FastAPI to Django REST Framework - Complete Conversion Plan
Date: November 30, 2025 Objective: 100% Django REST Framework conversion - Zero FastAPI references before build Scope: All remaining documentation files (14 files, 19+ FastAPI references) Current Status: 4/18 workflow files converted (22% complete)
Executive Summary
What's Done:
- ✅ 4 critical workflow files converted (Phase 7B + 7E)
- ✅ 300+ lines of production-ready Django code examples
- ✅ Consistent Django patterns established
What Remains:
- ⏸️ 1 workflow file (zombie-session-cleanup.md) - 3 FastAPI references
- ⏸️ 1 architecture file (c3-security-components.md) - 8 FastAPI references
- ⏸️ 8 sequence diagrams - 8 FastAPI references
- ⏸️ 4 sequence diagrams - 0 FastAPI (already clean)
Total Work: ~5.5 hours for 100% conversion
Conversion Strategy Overview
Three-Tier Priority System
Tier 1: Critical Workflow Documents (HIGH PRIORITY)
- zombie-session-cleanup.md - Background cleanup mechanism
- Why critical: Implements automatic seat reclamation (core MVP feature)
- Risk: Medium - Background worker pattern different from API endpoints
- Time: 40 minutes
Tier 2: Architecture Reference (MEDIUM PRIORITY)
- c3-security-components.md - Security architecture documentation
- Why important: Referenced during implementation, sets patterns
- Risk: Low - Documentation only, not implementation spec
- Time: 45 minutes
Tier 3: Sequence Diagrams (LOW PRIORITY)
- 8 files with FastAPI references (examples/duplicates)
- Why defer-able: Many duplicate already-converted workflows
- Risk: Very low - Example flows, not primary specs
- Time: 4 hours total (batch conversion)
Detailed Conversion Plan by Tier
Tier 1: Critical Workflow Document
Task 1.1: Convert zombie-session-cleanup.md
File: docs/diagrams/workflows/zombie-session-cleanup.md
FastAPI References: 3 decorators
Lines to Convert: ~40 lines
Estimated Time: 40 minutes
FastAPI Code to Convert
Current FastAPI patterns (lines 257, 269, 349):
@app.on_event("startup")
async def startup_event():
asyncio.create_task(subscribe_to_expired_sessions())
@app.on_event("shutdown")
async def shutdown_event():
cleanup_worker.stop()
@router.put("/heartbeat")
async def heartbeat(session_id: str, request: Request):
# Heartbeat logic
Django Conversion Strategy
Pattern 1: Startup/Shutdown Events → Django Signals
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from django.core.signals import request_finished
import threading
class LicenseConfig(AppConfig):
name = 'license'
def ready(self):
"""Startup: Initialize cleanup worker"""
from .workers import CleanupWorker
# Start Redis keyspace notification listener
self.cleanup_worker = CleanupWorker()
self.cleanup_thread = threading.Thread(
target=self.cleanup_worker.start,
daemon=True
)
self.cleanup_thread.start()
Pattern 2: Heartbeat Endpoint → Django REST Framework APIView
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from django.core.cache import cache
from django.utils import timezone
@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def heartbeat(request):
"""Extend session TTL to prevent zombie cleanup"""
session_id = request.data.get('session_id')
if not session_id:
return Response(
{"detail": "session_id required"},
status=status.HTTP_400_BAD_REQUEST
)
# Extend Redis TTL
redis_client = cache.client.get_client()
session_key = f"session:{session_id}"
# Check if session exists
if not redis_client.exists(session_key):
return Response(
{"detail": "Session not found or expired"},
status=status.HTTP_404_NOT_FOUND
)
# Extend TTL to 6 minutes
redis_client.expire(session_key, 360)
return Response(
{
"status": "heartbeat_acknowledged",
"session_id": session_id,
"ttl_extended_to": 360,
"next_heartbeat_due": timezone.now() + timezone.timedelta(minutes=5)
},
status=status.HTTP_200_OK
)
Pattern 3: Redis Keyspace Notification Worker (Django-compatible)
# workers/cleanup_worker.py
import redis
import logging
from django.conf import settings
from django.core.cache import cache
logger = logging.getLogger(__name__)
class CleanupWorker:
"""Background worker for Redis keyspace notifications"""
def __init__(self):
self.redis_client = cache.client.get_client()
self.pubsub = self.redis_client.pubsub()
self.running = False
def start(self):
"""Subscribe to expired events and process"""
self.running = True
self.pubsub.psubscribe('__keyevent@0__:expired')
logger.info("Cleanup worker started - listening for expired sessions")
for message in self.pubsub.listen():
if not self.running:
break
if message['type'] == 'pmessage':
expired_key = message['data'].decode('utf-8')
if expired_key.startswith('session:'):
self.handle_session_expiry(expired_key)
def handle_session_expiry(self, session_key):
"""Process expired session - reclaim seat"""
session_id = session_key.replace('session:', '')
try:
# Get session metadata from PostgreSQL
from .models import LicenseSession
session = LicenseSession.objects.get(session_id=session_id)
# Remove from active sessions set
active_sessions_key = f"tenant:{session.tenant_id}:active_sessions"
self.redis_client.srem(active_sessions_key, session_key)
# Decrement seat count
seat_count_key = f"tenant:{session.tenant_id}:seat_count"
new_count = self.redis_client.decr(seat_count_key)
# Audit log
from .models import AuditLog
AuditLog.objects.create(
action='SESSION_EXPIRED',
session_id=session_id,
tenant_id=session.tenant_id,
details=f"Zombie session cleaned - seat reclaimed (new count: {new_count})"
)
logger.info(f"Zombie session cleaned: {session_id} (tenant: {session.tenant_id}, new seat count: {new_count})")
except Exception as e:
logger.error(f"Failed to clean expired session {session_id}: {e}")
def stop(self):
"""Graceful shutdown"""
self.running = False
self.pubsub.unsubscribe()
logger.info("Cleanup worker stopped")
Conversion Checklist
- Lines 257-268: Convert
@app.on_event("startup")to Django AppConfig.ready() - Lines 269-271: Convert
@app.on_event("shutdown")to worker.stop() signal - Lines 349-370: Convert
@router.put("/heartbeat")to@api_view(['PUT']) - Lines 100-150: Update Python worker code to Django-compatible imports
- Lines 200-250: Update Redis subscription pattern for Django
- Verify: No
from fastapi importstatements remain - Verify: No
@app.or@router.decorators remain - Test: Code examples compile with Django imports
- Commit:
git commit -m "docs: Convert ZOMBIE-SESSION-CLEANUP to Django REST Framework"
Acceptance Criteria:
- ✅ All 3 FastAPI decorators converted to Django equivalents
- ✅ Background worker pattern uses Django signals and threading
- ✅ Heartbeat endpoint follows Django REST Framework conventions
- ✅ Redis keyspace notification logic Django-compatible
- ✅ No FastAPI imports or decorators remain
Tier 2: Architecture Reference Document
Task 2.1: Convert c3-security-components.md
File: docs/diagrams/architecture/c3-security-components.md
FastAPI References: 8 decorators
Lines to Convert: ~60 lines
Estimated Time: 45 minutes
FastAPI Code to Convert
Current FastAPI patterns (lines 210, 221, 469, 627, 726, 1014, 1028):
@app.get("/auth/login/google")
@app.get("/auth/callback")
@app.get("/api/v1/public-key")
@app.post("/api/v1/licenses/acquire")
@app.delete("/api/v1/gdpr/delete")
Django Conversion Strategy
Pattern: All HTTP Method Decorators → Django REST Framework
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework import status
@api_view(['GET'])
@permission_classes([AllowAny])
def google_login(request):
"""Initiate OAuth2 flow with Google"""
# OAuth2 redirect logic
pass
@api_view(['GET'])
@permission_classes([AllowAny])
def auth_callback(request):
"""Handle OAuth2 callback"""
# Token exchange logic
pass
@api_view(['GET'])
@permission_classes([AllowAny])
def public_key(request):
"""Return RSA public key for offline license verification"""
# Cloud KMS public key retrieval
pass
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def acquire_license(request):
"""Acquire floating license seat"""
# License acquisition logic
pass
@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def gdpr_delete(request):
"""GDPR right to deletion"""
# Account deletion logic
pass
Conversion Checklist
- Line 210: Convert
@app.get("/auth/login/google")to@api_view(['GET']) - Line 221: Convert
@app.get("/auth/callback")to@api_view(['GET']) - Line 469: Convert
@app.get("/api/v1/public-key")to@api_view(['GET']) - Line 627: Convert
@app.post("/api/v1/licenses/acquire")to@api_view(['POST']) - Line 726: Convert duplicate
@app.postto@api_view(['POST']) - Line 1014: Convert
@app.get("/api/v1/gdpr/export")to@api_view(['GET']) - Line 1028: Convert
@app.delete("/api/v1/gdpr/delete")to@api_view(['DELETE']) - Update imports: Replace
from fastapi importwithfrom rest_framework - Verify: Security examples use Django permissions (
@permission_classes) - Test: Code examples align with ADR-001 (Django REST Framework)
- Commit:
git commit -m "docs: Convert c3-security-components to Django REST Framework"
Acceptance Criteria:
- ✅ All 8 FastAPI decorators converted
- ✅ OAuth2 examples use Django REST Framework patterns
- ✅ GDPR endpoints follow Django conventions
- ✅ Security architecture doc consistent with implementation choice
Tier 3: Sequence Diagrams (Batch Conversion)
Batch 1: Phase 1 Core Flows (Already Converted - Duplicates)
Files with FastAPI references:
02-seat-acquisition-flow.md(1 reference) - Duplicates license-acquisition-workflow.md03-heartbeat-renewal-flow.md(1 reference) - Duplicates heartbeat-mechanism.md04-seat-release-flow.md(1 reference) - Duplicates graceful-license-release.md
Strategy: Copy Django code from converted workflow documents Estimated Time: 30 minutes (simple copy-paste + verification)
Conversion Checklist (Batch 1)
- 02-seat-acquisition-flow.md: Copy Django code from license-acquisition-workflow.md
- 03-heartbeat-renewal-flow.md: Copy Django code from heartbeat-mechanism.md
- 04-seat-release-flow.md: Copy Django code from graceful-license-release.md
- Verify: Code examples match source workflow documents exactly
- Commit:
git commit -m "docs: Sync Phase 1 sequence diagrams with Django workflow docs"
Batch 2: Phase 2 Security Flows
Files with FastAPI references:
4. 14-cloud-kms-license-signing-flow.md (2 references) - Cloud KMS signing
Strategy: Convert Cloud KMS integration to Django Estimated Time: 45 minutes
FastAPI Code to Convert
@app.post("/api/v1/licenses/sign")
async def sign_license(license_data: dict):
# Cloud KMS signing
pass
@app.get("/api/v1/public-key")
async def get_public_key():
# Public key retrieval
pass
Django Conversion
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework import status
from google.cloud import kms
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def sign_license(request):
"""Sign license token with Cloud KMS RSA-4096 key"""
license_data = request.data
# Validate license data
# ... validation logic ...
# Sign with Cloud KMS
kms_client = kms.KeyManagementServiceClient()
key_name = settings.CLOUD_KMS_KEY_NAME
digest = hashlib.sha256(json.dumps(license_data).encode()).digest()
sign_response = kms_client.asymmetric_sign(
request={"name": key_name, "digest": {"sha256": digest}}
)
return Response(
{
"signed_license": base64.b64encode(sign_response.signature).decode(),
"license_data": license_data
},
status=status.HTTP_200_OK
)
@api_view(['GET'])
@permission_classes([AllowAny])
def get_public_key(request):
"""Return RSA public key for offline verification"""
kms_client = kms.KeyManagementServiceClient()
key_name = settings.CLOUD_KMS_KEY_NAME
public_key = kms_client.get_public_key(request={"name": key_name})
return Response(
{
"public_key": public_key.pem,
"algorithm": "RSA_SIGN_PKCS1_4096_SHA256"
},
status=status.HTTP_200_OK
)
Conversion Checklist (Batch 2)
- 14-cloud-kms-license-signing-flow.md: Convert Cloud KMS endpoints to Django
- Update imports: Google Cloud KMS library imports
- Add settings: Document
settings.CLOUD_KMS_KEY_NAMEconfiguration - Verify: Signature verification examples use Django patterns
- Test: Code examples compile with
google-cloud-kmspackage - Commit:
git commit -m "docs: Convert Cloud KMS signing flow to Django REST Framework"
Batch 3: Phase 3+ Billing Flows (Future Features)
Files with FastAPI references:
5. 06-stripe-checkout-flow.md (2 references) - Stripe integration
6. 07-trial-license-activation-flow.md (1 reference) - Trial licenses
7. 09-subscription-cancellation-flow.md (1 reference) - Subscription management
8. 10-usage-based-metering-flow.md (1 reference) - Usage metering
Strategy: Batch convert all Stripe/billing flows together Estimated Time: 2 hours
FastAPI Patterns to Convert
@app.post("/api/v1/checkout/create-session")
@app.get("/api/v1/licenses/trial/activate")
@app.post("/api/v1/subscriptions/cancel")
@app.post("/api/v1/usage/record")
Django Conversion Template
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
import stripe
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_checkout_session(request):
"""Create Stripe checkout session"""
stripe.api_key = settings.STRIPE_SECRET_KEY
session = stripe.checkout.Session.create(
# Stripe session params
)
return Response(
{"checkout_url": session.url},
status=status.HTTP_200_OK
)
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def activate_trial(request):
"""Activate trial license"""
# Trial activation logic
pass
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def cancel_subscription(request):
"""Cancel active subscription"""
# Stripe subscription cancellation
pass
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def record_usage(request):
"""Record usage for metering"""
# Usage metering logic
pass
Conversion Checklist (Batch 3)
- 06-stripe-checkout-flow.md: Convert Stripe checkout to Django
- 07-trial-license-activation-flow.md: Convert trial activation to Django
- 09-subscription-cancellation-flow.md: Convert subscription endpoints to Django
- 10-usage-based-metering-flow.md: Convert metering endpoints to Django
- Update imports: Stripe SDK, Django REST Framework
- Add settings: Document Stripe API key configuration
- Verify: Webhook handling uses Django patterns
- Test: Code examples compile with
stripepackage - Commit:
git commit -m "docs: Convert billing/metering flows to Django REST Framework"
Batch 4: Deployment Flow (Infrastructure)
Files with FastAPI references:
11. 11-gke-deployment-flow.md (2 references) - GKE deployment
Strategy: Update deployment examples to Django ASGI/WSGI Estimated Time: 45 minutes
FastAPI Code to Convert
# Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.11
# Kubernetes health check
@app.get("/health")
async def health():
return {"status": "healthy"}
Django Conversion
# Dockerfile
FROM python:3.11-slim
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY . /app
WORKDIR /app
# Run with Gunicorn (WSGI) or Daphne (ASGI)
CMD ["gunicorn", "license_server.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
# Health check endpoint
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(['GET'])
def health(request):
return Response({"status": "healthy"})
Conversion Checklist (Batch 4)
- 11-gke-deployment-flow.md: Convert Dockerfile from FastAPI to Django
- Update server: Change uvicorn/gunicorn-fastapi to gunicorn/daphne
- Update health checks: Convert to Django REST Framework endpoint
- Update K8s manifests: Use Django-compatible probes
- Verify: Deployment examples use correct Python WSGI/ASGI server
- Test: Dockerfile builds successfully
- Commit:
git commit -m "docs: Convert GKE deployment to Django REST Framework"
Validation Strategy
Phase 1: Per-File Validation (During Conversion)
After converting each file:
# 1. Check for remaining FastAPI references
grep -i "from fastapi import\|@app\.\|@router\." FILE.md
# Expected: No results (0 matches)
# 2. Verify Django REST Framework imports
grep "from rest_framework" FILE.md
# Expected: Multiple results (5+ imports)
# 3. Verify Django decorators
grep "@api_view\|@permission_classes" FILE.md
# Expected: Multiple results (API endpoints converted)
Checklist per file:
- ❌ FastAPI imports present
- ✅ Django REST Framework imports present
- ✅ Django decorators used
- ✅ Django patterns (Response, status codes) consistent
Phase 2: Comprehensive Validation (After All Conversions)
Run full repository audit:
# Navigate to repository root
cd /Users/halcasteel/PROJECTS/coditect-rollout-master/submodules/cloud/coditect-cloud-infra
# 1. Find ALL FastAPI references (should be ZERO in application docs)
grep -r "from fastapi import" docs/ | grep -v "BACKUP\|ARCHIVE"
# Expected: 0 results (only backup files should match)
# 2. Count Django REST Framework usage
grep -r "from rest_framework" docs/diagrams/ | wc -l
# Expected: 50+ results (all workflows + sequences converted)
# 3. Verify no FastAPI decorators
grep -r "@app\.\|@router\.\|@websocket\." docs/diagrams/ | wc -l
# Expected: 0 results
# 4. Check for mixed patterns (bad sign)
grep -r "from rest_framework" docs/diagrams/ | xargs grep -l "from fastapi import"
# Expected: 0 results (no files mixing frameworks)
Comprehensive Checklist:
- ❌ Zero FastAPI imports in
docs/diagrams/workflows/ - ❌ Zero FastAPI imports in
docs/diagrams/sequences/ - ❌ Zero FastAPI imports in
docs/diagrams/architecture/ - ✅ 50+ Django REST Framework imports across all diagrams
- ✅ Consistent Django patterns (decorators, Response, status)
- ✅ No mixed framework files
Phase 3: Quality Gates (Before Build)
Verify Django patterns are correct:
# 1. Extract all Django code examples to temporary directory
mkdir -p /tmp/django-validation
find docs/ -name "*.md" -exec grep -Pzo '```python\n.*?```' {} \; > /tmp/django-validation/all_examples.txt
# 2. Create test Django project
django-admin startproject test_validation /tmp/django-validation/test_project
# 3. Extract code blocks and attempt import validation
python3 << 'EOF'
import re
import sys
# Read all code examples
with open('/tmp/django-validation/all_examples.txt', 'r') as f:
content = f.read()
# Extract Python code blocks
code_blocks = re.findall(r'```python\n(.*?)```', content, re.DOTALL)
# Check for Django imports
django_imports = [
'from rest_framework',
'from django',
'@api_view',
'@permission_classes'
]
errors = []
for i, block in enumerate(code_blocks):
has_django = any(imp in block for imp in django_imports)
has_fastapi = 'from fastapi' in block or '@app.' in block or '@router.' in block
if has_fastapi:
errors.append(f"Block {i+1}: Contains FastAPI code!")
if errors:
print("❌ VALIDATION FAILED:")
for error in errors:
print(f" {error}")
sys.exit(1)
else:
print("✅ All code blocks use Django REST Framework")
EOF
Quality Gate Checklist:
- ✅ All Python code blocks use Django imports
- ❌ No Python code blocks use FastAPI imports
- ✅ All API decorators use
@api_view - ✅ All permissions use
@permission_classes - ✅ All responses use
Response(status=status.HTTP_*) - ✅ Consistent Django patterns across all files
Documentation Updates Needed
Task D1: Update Conversion Status Documents
Files to update:
-
phase-7e-fastapi-verification-report.md
- Update "Additional Files with FastAPI" section
- Change all ⏸️ to ✅ after conversion
- Update "Build Readiness" to 100% complete
-
phase-7e-fastapi-audit-report.md
- Update audit results
- Confirm zero FastAPI references
- Document conversion date for each file
-
tasklist-with-checkboxes.md
- Mark Phase 7F tasks complete
- Add verification task checkboxes
Update Checklist
- Update phase-7e-fastapi-verification-report.md with 100% conversion status
- Update phase-7e-fastapi-audit-report.md with final audit results
- Update tasklist-with-checkboxes.md Phase 7F section
- Create Phase 7F completion report (summary document)
- Commit:
git commit -m "docs: Update conversion status to 100% Django REST Framework"
Task D2: Create Cross-Reference Index
Purpose: Enable developers to quickly find Django code examples for each feature
Structure:
# Django REST Framework Code Example Index
## License Acquisition
- Workflow: [license-acquisition-workflow.md](docs/diagrams/workflows/license-acquisition-workflow.md#django-implementation)
- Sequence: [02-seat-acquisition-flow.md](docs/diagrams/sequences/02-seat-acquisition-flow.md#code-example)
- Lua Script: [license-acquisition-workflow.md](docs/diagrams/workflows/license-acquisition-workflow.md#redis-lua-script)
## Session Heartbeat
- Workflow: [heartbeat-mechanism.md](docs/diagrams/workflows/heartbeat-mechanism.md#django-implementation)
- Sequence: [03-heartbeat-renewal-flow.md](docs/diagrams/sequences/03-heartbeat-renewal-flow.md#code-example)
- Background Worker: [zombie-session-cleanup.md](docs/diagrams/workflows/zombie-session-cleanup.md#cleanup-worker)
## License Release
- Workflow: [graceful-license-release.md](docs/diagrams/workflows/graceful-license-release.md#django-implementation)
- Sequence: [04-seat-release-flow.md](docs/diagrams/sequences/04-seat-release-flow.md#code-example)
## Cloud KMS Signing
- Workflow: [docs/diagrams/sequences/14-cloud-kms-license-signing-flow.md](docs/diagrams/sequences/14-cloud-kms-license-signing-flow.md#django-implementation)
- Architecture: [c3-security-components.md](docs/diagrams/architecture/c3-security-components.md#cloud-kms-integration)
## Billing & Subscriptions
- Stripe Checkout: [06-stripe-checkout-flow.md](docs/diagrams/sequences/06-stripe-checkout-flow.md#code-example)
- Trial Activation: [07-trial-license-activation-flow.md](docs/diagrams/sequences/07-trial-license-activation-flow.md#code-example)
- Subscription Management: [09-subscription-cancellation-flow.md](docs/diagrams/sequences/09-subscription-cancellation-flow.md#code-example)
- Usage Metering: [10-usage-based-metering-flow.md](docs/diagrams/sequences/10-usage-based-metering-flow.md#code-example)
## Deployment
- GKE Deployment: [11-gke-deployment-flow.md](docs/diagrams/sequences/11-gke-deployment-flow.md#dockerfile)
- Health Checks: [11-gke-deployment-flow.md](docs/diagrams/sequences/11-gke-deployment-flow.md#health-endpoint)
Location: docs/reference/DJANGO-CODE-EXAMPLE-INDEX.md
Cross-Reference Checklist
- Create DJANGO-CODE-EXAMPLE-INDEX.md
- Add links to all 18 converted files
- Group by feature (license, billing, deployment, security)
- Include anchor links to specific code sections
- Add "Quick Start" section with most common examples
- Commit:
git commit -m "docs: Add Django REST Framework code example index"
Time Estimates by Phase
Detailed Time Breakdown
| Phase | Task | Files | Time | Running Total |
|---|---|---|---|---|
| Tier 1 | zombie-session-cleanup.md | 1 | 40 min | 40 min |
| Tier 2 | c3-security-components.md | 1 | 45 min | 1h 25min |
| Tier 3 - Batch 1 | Phase 1 duplicates (copy-paste) | 3 | 30 min | 1h 55min |
| Tier 3 - Batch 2 | Cloud KMS signing | 1 | 45 min | 2h 40min |
| Tier 3 - Batch 3 | Billing/metering flows | 4 | 2h | 4h 40min |
| Tier 3 - Batch 4 | GKE deployment | 1 | 45 min | 5h 25min |
| Validation | Comprehensive validation suite | - | 30 min | 5h 55min |
| Documentation | Status updates + cross-reference | - | 30 min | 6h 25min |
Total Estimated Time: 6.5 hours for 100% conversion
Batch Conversion Strategy (Optimize for Speed)
Parallel Work Approach
Sequential Steps:
- Hour 1: Tier 1 (40 min) + Tier 2 (45 min) = Critical files done
- Hour 2: Batch 1 (30 min) + Batch 2 (45 min) = Phase 1-2 complete
- Hours 3-4: Batch 3 (2 hours) = Billing flows complete
- Hour 5: Batch 4 (45 min) + Validation (30 min) = All conversions validated
- Hour 6: Documentation updates (30 min) = 100% complete
Daily Work Schedule (8-hour day):
- Day 1 (Morning): Hours 1-3 (Tier 1, Tier 2, Batch 1-2, Batch 3 partial)
- Day 1 (Afternoon): Hours 4-6 (Batch 3 complete, Batch 4, Validation, Docs)
- Result: 100% conversion complete in 1 day
Risk Mitigation
Risk 1: Background Worker Pattern Complexity
Risk: ZOMBIE-SESSION-CLEANUP uses Redis keyspace notifications (unfamiliar pattern) Impact: HIGH (critical for automatic seat reclamation) Likelihood: MEDIUM
Mitigation:
- Use Django signals (
AppConfig.ready()) for initialization - Use threading module (built-in, stable) for background worker
- Test Redis keyspace notifications in development environment before documenting
- Document graceful shutdown pattern clearly
Contingency: If background worker pattern too complex, defer to Phase 2 implementation and document as "implementation detail TBD"
Risk 2: Cloud KMS Integration Specifics
Risk: Cloud KMS signing examples may have GCP SDK edge cases Impact: MEDIUM (Phase 2 feature, not MVP blocker) Likelihood: LOW
Mitigation:
- Use official Google Cloud KMS Python SDK documentation as reference
- Test basic sign/verify flow locally before documenting
- Document error handling for common KMS failures
Contingency: If KMS integration complex, keep examples high-level (pseudocode) and defer detailed implementation to Phase 2
Risk 3: Stripe Webhook Handling
Risk: Stripe webhooks use different patterns in Django vs FastAPI Impact: LOW (Phase 3+ feature) Likelihood: MEDIUM
Mitigation:
- Use Django REST Framework for webhook endpoints (same as other endpoints)
- Document signature verification using
stripe.Webhook.construct_event() - Reference Stripe's official Django examples
Contingency: If webhook pattern unclear, document as "see Stripe Django docs" with link
Success Criteria
Definition of Done
File-Level Success:
- ❌ Zero FastAPI imports in file
- ✅ Django REST Framework imports present
- ✅ Correct Django decorators used (
@api_view,@permission_classes) - ✅ Django Response objects with status codes
- ✅ Code examples compile (no syntax errors)
- ✅ Patterns consistent with ADR-001 (Django REST Framework decision)
Repository-Level Success:
- ❌ Zero FastAPI references in
docs/diagrams/workflows/ - ❌ Zero FastAPI references in
docs/diagrams/sequences/ - ❌ Zero FastAPI references in
docs/diagrams/architecture/ - ✅ 50+ Django REST Framework code examples across all docs
- ✅ Comprehensive validation suite passes (no FastAPI detected)
- ✅ Quality gates pass (all code uses Django patterns)
- ✅ Cross-reference index created
- ✅ Status documents updated to reflect 100% conversion
Build Readiness:
- ✅ All Phase 2 implementation specs use Django REST Framework
- ✅ No confusion about which framework to use (100% Django)
- ✅ Code examples can be copied directly into implementation
- ✅ Documentation provides single source of truth (Django only)
Post-Conversion Actions
Immediate (Same Day as Completion)
-
Run final validation suite
cd /Users/halcasteel/PROJECTS/coditect-rollout-master/submodules/cloud/coditect-cloud-infra
./scripts/validate-django-conversion.sh # Create this script -
Update tasklist-with-checkboxes.md
- Mark Phase 7F tasks complete
- Update overall Phase 7 completion percentage
-
Create Phase 7F completion report
- Document total conversions (18 files)
- Summarize time spent vs estimated
- List all converted files with verification status
-
Git commit and push
git add docs/
git commit -m "docs: Complete FastAPI to Django REST Framework conversion (Phase 7F)
Converted 14 remaining files to 100% Django REST Framework:
- zombie-session-cleanup.md (background worker)
- c3-security-components.md (security architecture)
- 8 sequence diagrams (billing, deployment, security)
Repository now 100% Django REST Framework - zero FastAPI references.
All documentation consistent with ADR-001 framework decision.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>"
Next Steps (Phase 2 Backend Implementation)
-
Use converted docs as implementation specs
- license-acquisition-workflow.md → license acquisition API
- heartbeat-mechanism.md → heartbeat API
- graceful-license-release.md → license release API
- zombie-session-cleanup.md → background cleanup worker
-
Create Django project structure
django-admin startproject license_server
python manage.py startapp licenses -
Copy code examples from docs to implementation
- Django views from workflow docs
- Redis Lua scripts from workflow docs
- Model definitions from architecture docs
-
Implement comprehensive tests (80%+ coverage)
- Unit tests for each endpoint
- Integration tests for Redis Lua scripts
- E2E tests for complete license flow
Appendix A: Quick Reference Commands
Validation Commands
# Check for FastAPI in specific file
grep -i "from fastapi import\|@app\.\|@router\." FILE.md
# Check for Django in specific file
grep "from rest_framework" FILE.md
# Full repository scan for FastAPI
grep -r "from fastapi import" docs/ | grep -v "BACKUP"
# Full repository scan for Django
grep -r "from rest_framework" docs/diagrams/ | wc -l
# Find files mixing frameworks (bad)
grep -r "from rest_framework" docs/ | xargs grep -l "from fastapi import"
Conversion Tracking
# Create conversion log
cat > /tmp/conversion-log.txt << 'EOF'
FASTAPI TO DJANGO CONVERSION LOG
=================================
File: zombie-session-cleanup.md
Date: 2025-11-30
Time: 40 minutes
FastAPI References Removed: 3
Django Patterns Added: 5
Status: ✅ COMPLETE
File: c3-security-components.md
Date: 2025-11-30
Time: 45 minutes
FastAPI References Removed: 8
Django Patterns Added: 8
Status: ✅ COMPLETE
# ... continue for each file
EOF
# Track progress
echo "Conversion Progress: $(grep -c '✅ COMPLETE' /tmp/conversion-log.txt)/14 files"
Appendix B: Code Pattern Reference
FastAPI → Django Conversion Patterns
| FastAPI Pattern | Django REST Framework Pattern |
|---|---|
from fastapi import FastAPI, Request, HTTPException | from rest_framework.decorators import api_view |
from fastapi import APIRouter | from rest_framework import routers (or function views) |
@app.get("/endpoint") | @api_view(['GET']) |
@app.post("/endpoint") | @api_view(['POST']) |
@router.put("/endpoint") | @api_view(['PUT']) |
@app.delete("/endpoint") | @api_view(['DELETE']) |
async def endpoint(param: str) | def endpoint(request) |
request.json() | request.data |
return {"key": "value"} | return Response({"key": "value"}) |
HTTPException(status_code=404) | return Response(..., status=status.HTTP_404_NOT_FOUND) |
Depends(get_current_user) | @permission_classes([IsAuthenticated]) |
@app.on_event("startup") | AppConfig.ready() (Django signals) |
@app.on_event("shutdown") | Signal handler or cleanup in AppConfig |
Summary
What This Plan Delivers:
- ✅ 100% Django REST Framework conversion
- ✅ Zero FastAPI references in documentation
- ✅ Consistent patterns across all 18 workflow/sequence files
- ✅ Production-ready code examples developers can copy
- ✅ Cross-reference index for quick code lookup
- ✅ Comprehensive validation suite
- ✅ Quality gates to prevent regression
Estimated Effort: 6.5 hours (1 business day)
Completion Milestone: Phase 7F complete, ready for Phase 2 backend build
Success Metric: grep -r "from fastapi import" docs/ | wc -l returns 0
Recommended Execution Order:
- Tier 1 (zombie-session-cleanup.md) - 40 min
- Tier 2 (c3-security-components.md) - 45 min
- Batch 1-2 (Phase 1-2 sequences) - 1h 15min
- Batch 3-4 (Billing + deployment) - 2h 45min
- Validation + Documentation - 1h
After Completion:
- Documentation 100% aligned with ADR-001 (Django REST Framework)
- Phase 2 backend implementation can begin with clear, consistent specs
- Zero confusion about framework choice
- All code examples production-ready
Plan Created: November 30, 2025 Plan Version: 1.0 Next Action: Begin Tier 1 conversion (zombie-session-cleanup.md)