22 KiB
22 KiB
Tenant & User Deletion Architecture
System Overview
┌─────────────────────────────────────────────────────────────────────┐
│ CLIENT APPLICATION │
│ (Frontend / API Consumer) │
└────────────────────────────────┬────────────────────────────────────┘
│
DELETE /auth/users/{user_id}
DELETE /auth/me/account
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ AUTH SERVICE │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ AdminUserDeleteService │ │
│ │ 1. Get user's tenant memberships │ │
│ │ 2. Check owned tenants for other admins │ │
│ │ 3. Transfer ownership OR delete tenant │ │
│ │ 4. Delete user data across services │ │
│ │ 5. Delete user account │ │
│ └───────────────────────────────────────────────────────────────┘ │
└──────┬────────────────┬────────────────┬────────────────┬───────────┘
│ │ │ │
│ Check admins │ Delete tenant │ Delete user │ Delete data
│ │ │ memberships │
▼ ▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────────┐
│ TENANT │ │ TENANT │ │ TENANT │ │ TRAINING │
│ SERVICE │ │ SERVICE │ │ SERVICE │ │ FORECASTING │
│ │ │ │ │ │ │ NOTIFICATION │
│ GET /admins │ │ DELETE │ │ DELETE │ │ Services │
│ │ │ /tenants/ │ │ /user/{id}/ │ │ │
│ │ │ {id} │ │ memberships │ │ DELETE /users/ │
└──────────────┘ └──────┬───────┘ └──────────────┘ └─────────────────┘
│
Triggers tenant.deleted event
│
▼
┌──────────────────────────────────────┐
│ MESSAGE BUS (RabbitMQ) │
│ tenant.deleted event │
└──────────────────────────────────────┘
│
Broadcasts to all services OR
Orchestrator calls services directly
│
┌────────────────┼────────────────┬───────────────┐
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ ORDERS │ │INVENTORY │ │ RECIPES │ │ ... │
│ SERVICE │ │ SERVICE │ │ SERVICE │ │ 8 more │
│ │ │ │ │ │ │ services │
│ DELETE │ │ DELETE │ │ DELETE │ │ │
│ /tenant/ │ │ /tenant/ │ │ /tenant/ │ │ DELETE │
│ {id} │ │ {id} │ │ {id} │ │ /tenant/ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
Detailed Deletion Flow
Phase 1: Owner Deletion (Implemented)
User Deletion Request
│
├─► 1. Validate user exists
│
├─► 2. Get user's tenant memberships
│ │
│ ├─► Call: GET /tenants/user/{user_id}/memberships
│ │
│ └─► Returns: List of {tenant_id, role}
│
├─► 3. For each OWNED tenant:
│ │
│ ├─► Check for other admins
│ │ │
│ │ └─► Call: GET /tenants/{tenant_id}/admins
│ │ Returns: List of admins
│ │
│ ├─► If other admins exist:
│ │ │
│ │ ├─► Transfer ownership
│ │ │ Call: POST /tenants/{tenant_id}/transfer-ownership
│ │ │ Body: {new_owner_id: first_admin_id}
│ │ │
│ │ └─► Remove user membership
│ │ (Will be deleted in step 5)
│ │
│ └─► If NO other admins:
│ │
│ └─► Delete entire tenant
│ Call: DELETE /tenants/{tenant_id}
│ (Cascades to all services)
│
├─► 4. Delete user-specific data
│ │
│ ├─► Delete training models
│ │ Call: DELETE /models/user/{user_id}
│ │
│ ├─► Delete forecasts
│ │ Call: DELETE /forecasts/user/{user_id}
│ │
│ └─► Delete notifications
│ Call: DELETE /notifications/user/{user_id}
│
├─► 5. Delete user memberships (all tenants)
│ │
│ └─► Call: DELETE /tenants/user/{user_id}/memberships
│
└─► 6. Delete user account
│
└─► DELETE from users table
Phase 2: Tenant Deletion (Standardized Pattern)
Tenant Deletion Request
│
├─► TENANT SERVICE
│ │
│ ├─► 1. Verify permissions (owner/admin/service)
│ │
│ ├─► 2. Check for other admins
│ │ (Prevent accidental deletion)
│ │
│ ├─► 3. Cancel subscriptions
│ │
│ ├─► 4. Delete tenant memberships
│ │
│ ├─► 5. Publish tenant.deleted event
│ │
│ └─► 6. Delete tenant record
│
├─► ORCHESTRATOR (Phase 3 - Pending)
│ │
│ ├─► 7. Create deletion job
│ │ (Status tracking)
│ │
│ └─► 8. Call all services in parallel
│ (Or react to tenant.deleted event)
│
└─► EACH SERVICE
│
├─► Orders Service
│ ├─► Delete customers
│ ├─► Delete orders (CASCADE: items, status)
│ └─► Return summary
│
├─► Inventory Service
│ ├─► Delete inventory items
│ ├─► Delete transactions
│ └─► Return summary
│
├─► Recipes Service
│ ├─► Delete recipes (CASCADE: ingredients, steps)
│ └─► Return summary
│
├─► Production Service
│ ├─► Delete production batches
│ ├─► Delete schedules
│ └─► Return summary
│
└─► ... (8 more services)
Data Model Relationships
Tenant Service
┌─────────────────┐
│ Tenant │
│ ───────────── │
│ id (PK) │◄────┬─────────────────────┐
│ owner_id │ │ │
│ name │ │ │
│ is_active │ │ │
└─────────────────┘ │ │
│ │ │
│ CASCADE │ │
│ │ │
┌────┴─────┬────────┴──────┐ │
│ │ │ │
▼ ▼ ▼ │
┌─────────┐ ┌─────────┐ ┌──────────────┐ │
│ Member │ │ Subscr │ │ Settings │ │
│ ship │ │ iption │ │ │ │
└─────────┘ └─────────┘ └──────────────┘ │
│
│
┌─────────────────────────────────────────────┘
│
│ Referenced by all other services:
│
├─► Orders (tenant_id)
├─► Inventory (tenant_id)
├─► Recipes (tenant_id)
├─► Production (tenant_id)
├─► Sales (tenant_id)
├─► Suppliers (tenant_id)
├─► POS (tenant_id)
├─► External (tenant_id)
├─► Forecasting (tenant_id)
├─► Training (tenant_id)
└─► Notifications (tenant_id)
Orders Service Example
┌─────────────────┐
│ Customer │
│ ───────────── │
│ id (PK) │
│ tenant_id (FK) │◄──── tenant_id from Tenant Service
│ name │
└─────────────────┘
│
│ CASCADE
│
▼
┌─────────────────┐
│ CustomerPref │
│ ───────────── │
│ id (PK) │
│ customer_id │
└─────────────────┘
┌─────────────────┐
│ Order │
│ ───────────── │
│ id (PK) │
│ tenant_id (FK) │◄──── tenant_id from Tenant Service
│ customer_id │
│ status │
└─────────────────┘
│
│ CASCADE
│
┌────┴─────┬────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Order │ │ Order │ │ Status │
│ Item │ │ Item │ │ History │
└─────────┘ └─────────┘ └─────────┘
Service Communication Patterns
Pattern 1: Direct Service-to-Service (Current)
Auth Service ──► Tenant Service (GET /admins)
└─► Orders Service (DELETE /tenant/{id})
└─► Inventory Service (DELETE /tenant/{id})
└─► ... (All services)
Pros:
- Simple implementation
- Immediate feedback
- Easy to debug
Cons:
- Tight coupling
- No retry logic
- Partial failure handling needed
Pattern 2: Event-Driven (Alternative)
Tenant Service
│
└─► Publish: tenant.deleted event
│
▼
┌───────────────┐
│ Message Bus │
│ (RabbitMQ) │
└───────────────┘
│
├─► Orders Service (subscriber)
├─► Inventory Service (subscriber)
└─► ... (All services)
Pros:
- Loose coupling
- Easy to add services
- Automatic retry
Cons:
- Eventual consistency
- Harder to track completion
- Requires message bus
Pattern 3: Orchestrated (Recommended - Phase 3)
Auth Service
│
└─► Deletion Orchestrator
│
├─► Create deletion job
│ (Track status)
│
├─► Call services in parallel
│ │
│ ├─► Orders Service
│ │ └─► Returns: {deleted: 100, errors: []}
│ │
│ ├─► Inventory Service
│ │ └─► Returns: {deleted: 50, errors: []}
│ │
│ └─► ... (All services)
│
└─► Aggregate results
│
├─► Update job status
│
└─► Return: Complete summary
Pros:
- Centralized control
- Status tracking
- Rollback capability
- Parallel execution
Cons:
- More complex
- Orchestrator is SPOF
- Requires job storage
Deletion Saga Pattern (Phase 3)
Success Scenario
Step 1: Delete Orders [✓] → Continue
Step 2: Delete Inventory [✓] → Continue
Step 3: Delete Recipes [✓] → Continue
Step 4: Delete Production [✓] → Continue
...
Step N: Delete Tenant [✓] → Complete
Failure with Rollback
Step 1: Delete Orders [✓] → Continue
Step 2: Delete Inventory [✓] → Continue
Step 3: Delete Recipes [✗] → FAILURE
↓
Compensate:
↓
┌─────────────────────┴─────────────────────┐
│ │
Step 3': Restore Recipes (if possible) │
Step 2': Restore Inventory │
Step 1': Restore Orders │
│ │
└─────────────────────┬─────────────────────┘
↓
Mark job as FAILED
Log partial state
Notify admins
Security Layers
┌─────────────────────────────────────────────────────────────┐
│ API GATEWAY │
│ - JWT validation │
│ - Rate limiting │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SERVICE LAYER │
│ - Permission checks (owner/admin/service) │
│ - Tenant access validation │
│ - User role verification │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ BUSINESS LOGIC │
│ - Admin count verification │
│ - Ownership transfer logic │
│ - Data integrity checks │
└──────────────────────────────┬──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ DATA LAYER │
│ - Database transactions │
│ - CASCADE delete enforcement │
│ - Audit logging │
└─────────────────────────────────────────────────────────────┘
Implementation Timeline
Week 1-2: Phase 2 Implementation
├─ Day 1-2: Recipes, Production, Sales services
├─ Day 3-4: Suppliers, POS, External services
├─ Day 5-8: Refactor existing deletion logic (Forecasting, Training, Notification)
└─ Day 9-10: Integration testing
Week 3: Phase 3 Orchestration
├─ Day 1-2: Deletion orchestrator service
├─ Day 3: Service registry
├─ Day 4-5: Saga pattern implementation
Week 4: Phase 4 Enhanced Features
├─ Day 1-2: Soft delete & retention
├─ Day 3-4: Audit logging
└─ Day 5: Testing
Week 5-6: Production Deployment
├─ Week 5: Staging deployment & testing
└─ Week 6: Production rollout with monitoring
Monitoring Dashboard
┌─────────────────────────────────────────────────────────────┐
│ Tenant Deletion Dashboard │
├─────────────────────────────────────────────────────────────┤
│ │
│ Active Deletions: 3 │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Tenant: bakery-123 [████████░░] 80% │ │
│ │ Started: 2025-10-30 10:15 │ │
│ │ Services: 8/10 complete │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ Recent Deletions (24h): 15 │
│ Average Duration: 12.3 seconds │
│ Success Rate: 98.5% │
│ │
│ ┌─────────────────────────┬────────────────────────────┐ │
│ │ Service │ Avg Items Deleted │ │
│ ├─────────────────────────┼────────────────────────────┤ │
│ │ Orders │ 1,234 │ │
│ │ Inventory │ 567 │ │
│ │ Recipes │ 89 │ │
│ │ ... │ ... │ │
│ └─────────────────────────┴────────────────────────────┘ │
│ │
│ Failed Deletions (7d): 2 │
│ ⚠️ Alert: Inventory service timeout (1) │
│ ⚠️ Alert: Orders service connection error (1) │
└─────────────────────────────────────────────────────────────┘
Key Files Reference
Core Implementation:
-
Shared Base Classes
services/shared/services/tenant_deletion.py
-
Tenant Service
services/tenant/app/services/tenant_service.py(Methods: lines 741-1075)services/tenant/app/api/tenants.py(DELETE endpoint: lines 102-153)services/tenant/app/api/tenant_members.py(Membership endpoints: lines 273-425)
-
Orders Service (Example)
services/orders/app/services/tenant_deletion_service.pyservices/orders/app/api/orders.py(Lines 312-404)
-
Documentation
/TENANT_DELETION_IMPLEMENTATION_GUIDE.md/DELETION_REFACTORING_SUMMARY.md/DELETION_ARCHITECTURE_DIAGRAM.md(this file)