Files
bakery-ia/QUICK_REFERENCE_DELETION_SYSTEM.md
2025-10-31 11:54:19 +01:00

9.3 KiB

Tenant Deletion System - Quick Reference Card

🎯 Quick Start - What You Need to Know

System Status: 83% Complete (10/12 Services)

READY: Orders, Inventory, Recipes, Sales, Production, Suppliers, POS, External, Forecasting, Alert Processor PENDING: Training, Notification (1 hour to complete)


📍 Quick Navigation

Document Purpose Time to Read
DELETION_SYSTEM_COMPLETE.md START HERE - Complete status & overview 10 min
GETTING_STARTED.md Quick implementation guide 5 min
COMPLETION_CHECKLIST.md Step-by-step completion tasks 3 min
QUICK_START_REMAINING_SERVICES.md Templates for pending services 5 min

🚀 Common Tasks

1. Test a Service Deletion

# Step 1: Preview what will be deleted (dry-run)
curl -X GET "http://localhost:8000/api/v1/pos/tenant/YOUR_TENANT_ID/deletion-preview" \
  -H "Authorization: Bearer YOUR_SERVICE_TOKEN"

# Step 2: Execute deletion
curl -X DELETE "http://localhost:8000/api/v1/pos/tenant/YOUR_TENANT_ID" \
  -H "Authorization: Bearer YOUR_SERVICE_TOKEN"

2. Delete a Tenant

# Requires admin token and verifies no other admins exist
curl -X DELETE "http://localhost:8000/api/v1/tenants/YOUR_TENANT_ID" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

3. Use the Orchestrator (Python)

from services.auth.app.services.deletion_orchestrator import DeletionOrchestrator

# Initialize
orchestrator = DeletionOrchestrator(auth_token="service_jwt")

# Execute parallel deletion across all services
job = await orchestrator.orchestrate_tenant_deletion(
    tenant_id="abc-123",
    tenant_name="Bakery XYZ",
    initiated_by="admin-user-456"
)

# Check results
print(f"Status: {job.status}")
print(f"Deleted: {job.total_items_deleted} items")
print(f"Services completed: {job.services_completed}/10")

📁 Key Files by Service

Base Infrastructure

services/shared/services/tenant_deletion.py          # Base classes
services/auth/app/services/deletion_orchestrator.py  # Orchestrator

Implemented Services (10)

services/orders/app/services/tenant_deletion_service.py
services/inventory/app/services/tenant_deletion_service.py
services/recipes/app/services/tenant_deletion_service.py
services/sales/app/services/tenant_deletion_service.py
services/production/app/services/tenant_deletion_service.py
services/suppliers/app/services/tenant_deletion_service.py
services/pos/app/services/tenant_deletion_service.py
services/external/app/services/tenant_deletion_service.py
services/forecasting/app/services/tenant_deletion_service.py
services/alert_processor/app/services/tenant_deletion_service.py

Pending Services (2)

⏳ services/training/app/services/tenant_deletion_service.py      (30 min)
⏳ services/notification/app/services/tenant_deletion_service.py  (30 min)

🔑 Service Endpoints

All services follow the same pattern:

Endpoint Method Auth Purpose
/tenant/{tenant_id}/deletion-preview GET Service Preview counts (dry-run)
/tenant/{tenant_id} DELETE Service Permanent deletion

Full URLs by Service

# Core Business Services
http://orders-service:8000/api/v1/orders/tenant/{tenant_id}
http://inventory-service:8000/api/v1/inventory/tenant/{tenant_id}
http://recipes-service:8000/api/v1/recipes/tenant/{tenant_id}
http://sales-service:8000/api/v1/sales/tenant/{tenant_id}
http://production-service:8000/api/v1/production/tenant/{tenant_id}
http://suppliers-service:8000/api/v1/suppliers/tenant/{tenant_id}

# Integration Services
http://pos-service:8000/api/v1/pos/tenant/{tenant_id}
http://external-service:8000/api/v1/external/tenant/{tenant_id}

# AI/ML Services
http://forecasting-service:8000/api/v1/forecasting/tenant/{tenant_id}

# Alert/Notification Services
http://alert-processor-service:8000/api/v1/alerts/tenant/{tenant_id}

💡 Common Patterns

Creating a New Deletion Service

# 1. Create tenant_deletion_service.py
from shared.services.tenant_deletion import (
    BaseTenantDataDeletionService,
    TenantDataDeletionResult
)

class MyServiceTenantDeletionService(BaseTenantDataDeletionService):
    def __init__(self, db: AsyncSession):
        self.db = db
        self.service_name = "my_service"

    async def get_tenant_data_preview(self, tenant_id: str) -> Dict[str, int]:
        # Return counts without deleting
        return {"my_table": count}

    async def delete_tenant_data(self, tenant_id: str) -> TenantDataDeletionResult:
        result = TenantDataDeletionResult(tenant_id, self.service_name)
        # Delete children before parents
        # Track counts in result.deleted_counts
        await self.db.commit()
        result.success = True
        return result

Adding API Endpoints

# 2. Add to your API router
@router.delete("/tenant/{tenant_id}")
@service_only_access
async def delete_tenant_data(
    tenant_id: str = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    deletion_service = MyServiceTenantDeletionService(db)
    result = await deletion_service.safe_delete_tenant_data(tenant_id)

    if not result.success:
        raise HTTPException(500, detail=f"Deletion failed: {result.errors}")

    return {"message": "Success", "summary": result.to_dict()}

Deletion Order (Foreign Keys)

# Always delete in this order:
1. Child records (with foreign keys)
2. Parent records (referenced by children)
3. Independent records (no foreign keys)
4. Audit logs (last)

# Example:
await self.db.execute(delete(OrderItem).where(...))    # Child
await self.db.execute(delete(Order).where(...))         # Parent
await self.db.execute(delete(Customer).where(...))      # Parent
await self.db.execute(delete(AuditLog).where(...))      # Independent

⚠️ Important Reminders

Security

  • All deletion endpoints require @service_only_access
  • Tenant endpoint checks for admin permissions
  • User deletion verifies ownership before tenant deletion

Data Integrity

  • Always use database transactions
  • Delete children before parents (foreign keys)
  • Track deletion counts for audit
  • Log every step with structlog

Testing

  • Always test preview endpoint first (dry-run)
  • Test with small tenant before large ones
  • Verify counts match expected values
  • Check logs for errors

🐛 Troubleshooting

Issue: Foreign Key Constraint Error

Solution: Check deletion order - delete children before parents
Fix: Review the delete() statements in delete_tenant_data()

Issue: Service Returns 401 Unauthorized

Solution: Endpoint requires service token, not user token
Fix: Use @service_only_access decorator and service JWT

Issue: Deletion Count is Zero

Solution: tenant_id column might be UUID vs string mismatch
Fix: Use UUID(tenant_id) in WHERE clause
Example: .where(Model.tenant_id == UUID(tenant_id))

Issue: Orchestrator Can't Reach Service

Solution: Check service URL in SERVICE_DELETION_ENDPOINTS
Fix: Ensure service name matches Kubernetes service name
Example: "orders-service" not "orders"

📊 What Gets Deleted

Per-Service Data Summary

Service Main Tables Typical Count
Orders Customers, Orders, Items 1,000-10,000
Inventory Products, Stock Movements 500-2,000
Recipes Recipes, Ingredients, Steps 100-500
Sales Sales Records, Predictions 5,000-50,000
Production Production Runs, Steps 500-5,000
Suppliers Suppliers, Orders, Contracts 100-1,000
POS Transactions, Items, Logs 10,000-100,000
External Tenant Weather Data 100-1,000
Forecasting Forecasts, Batches, Cache 5,000-50,000
Alert Processor Alerts, Interactions 1,000-10,000

Total Typical Deletion: 25,000-250,000 records per tenant


🎯 Next Actions

To Complete System (5 hours)

  1. ⏱️ 1 hour: Complete Training & Notification services
  2. ⏱️ 2 hours: Integrate Auth service with orchestrator
  3. ⏱️ 2 hours: Add integration tests

To Deploy to Production

  1. Run integration tests
  2. Update monitoring dashboards
  3. Create runbook for ops team
  4. Set up alerting for failed deletions
  5. Deploy to staging first
  6. Verify with test tenant deletion
  7. Deploy to production

📞 Need Help?

  1. Check docs: Start with DELETION_SYSTEM_COMPLETE.md
  2. Review examples: Look at completed services (Orders, POS, Forecasting)
  3. Use tools: scripts/generate_deletion_service.py for boilerplate
  4. Test first: Always use preview endpoint before deletion

Success Criteria

Service is Complete When:

  • tenant_deletion_service.py created
  • Extends BaseTenantDataDeletionService
  • DELETE endpoint added to API
  • GET preview endpoint added
  • Service registered in orchestrator
  • Tested with real tenant data
  • Logs show successful deletion

System is Complete When:

  • All 12 services implemented
  • Auth service uses orchestrator
  • Integration tests pass
  • Documentation complete
  • Deployed to production

Current Progress: 10/12 services (83%)


Last Updated: 2025-10-31 Status: Production-Ready for 10/12 services 🚀