Files
bakery-ia/DEMO_IMPLEMENTATION_SUMMARY.md

585 lines
15 KiB
Markdown
Raw Normal View History

2025-10-03 14:09:34 +02:00
# Demo Architecture Implementation Summary
## ✅ Implementation Complete
All components of the production demo system have been implemented. This document provides a summary of what was created and how to use it.
---
## 📁 Files Created
### Demo Session Service (New Microservice)
```
services/demo_session/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI application
│ ├── api/
│ │ ├── __init__.py
│ │ ├── routes.py # API endpoints
│ │ └── schemas.py # Pydantic models
│ ├── core/
│ │ ├── __init__.py
│ │ ├── config.py # Settings
│ │ ├── database.py # Database manager
│ │ └── redis_client.py # Redis client
│ ├── models/
│ │ ├── __init__.py
│ │ └── demo_session.py # Session model
│ └── services/
│ ├── __init__.py
│ ├── session_manager.py # Session lifecycle
│ ├── data_cloner.py # Data cloning
│ └── cleanup_service.py # Cleanup logic
├── migrations/
│ ├── env.py
│ ├── script.py.mako
│ └── versions/
├── requirements.txt
├── Dockerfile
└── alembic.ini
```
### Demo Seeding Scripts
```
scripts/demo/
├── __init__.py
├── seed_demo_users.py # Creates demo users
├── seed_demo_tenants.py # Creates demo tenants
├── seed_demo_inventory.py # Populates Spanish inventory (25 ingredients)
└── clone_demo_tenant.py # Clones data from template (runs as K8s Job)
```
### Gateway Middleware
```
gateway/app/middleware/
└── demo_middleware.py # Demo session handling
```
### Kubernetes Resources
```
infrastructure/kubernetes/base/
├── components/demo-session/
│ ├── deployment.yaml # Service deployment (with CLONE_JOB_IMAGE env)
│ ├── service.yaml # K8s service
│ ├── database.yaml # PostgreSQL DB
│ └── rbac.yaml # RBAC for job creation
├── migrations/
│ └── demo-session-migration-job.yaml # Migration job
├── jobs/
│ ├── demo-seed-users-job.yaml # User seeding
│ ├── demo-seed-tenants-job.yaml # Tenant seeding
│ ├── demo-seed-inventory-job.yaml # Inventory seeding
│ ├── demo-seed-rbac.yaml # RBAC permissions for seed jobs
│ └── demo-clone-job-template.yaml # Reference template for clone jobs
└── cronjobs/
└── demo-cleanup-cronjob.yaml # Hourly cleanup
```
### Documentation
```
DEMO_ARCHITECTURE.md # Complete architecture guide
DEMO_IMPLEMENTATION_SUMMARY.md # This file
```
### Updated Files
```
services/tenant/app/models/tenants.py # Added demo flags
services/demo_session/app/services/k8s_job_cloner.py # K8s Job cloning implementation
gateway/app/main.py # Added demo middleware
gateway/app/middleware/demo_middleware.py # Converted to BaseHTTPMiddleware
Tiltfile # Added demo resources + CLONE_JOB_IMAGE patching
shared/config/base.py # Added demo-related settings
```
---
## 🎯 Key Features Implemented
### 1. Session Isolation ✅
- Each prospect gets isolated virtual tenant
- No data interference between sessions
- Automatic resource cleanup
### 2. Spanish Demo Data ✅
- **Panadería San Pablo** (Individual Bakery)
- Raw ingredients: Harina, Levadura, Mantequilla, etc.
- Local production focus
- Full recipe management
- **Panadería La Espiga** (Central Baker Satellite)
- Pre-baked products from central baker
- Supplier management
- Order tracking
### 3. Redis Caching ✅
- Hot data cached for fast access
- Automatic TTL (30 minutes)
- Session metadata storage
### 4. Gateway Integration ✅
- Demo session detection
- Operation restrictions
- Virtual tenant injection
### 5. Automatic Cleanup ✅
- Hourly CronJob cleanup
- Expired session detection
- Database and Redis cleanup
### 6. K8s Job-based Data Cloning ✅
- Database-level cloning (faster than API calls)
- Environment-based image configuration
- Works in dev (Tilt dynamic tags) and production (stable tags)
- Uses ORM models for safe data copying
- `imagePullPolicy: IfNotPresent` for local images
### 7. AI & Scheduler Restrictions ✅
- Fake AI models in database (no real files)
- Forecast API blocked at gateway for demo accounts
- Procurement scheduler filters out demo tenants
- Manual operations still allowed for realistic testing
---
## 🚀 Quick Start
### Local Development with Tilt
```bash
# Start all services including demo system
tilt up
# Watch demo initialization
tilt logs demo-seed-users
tilt logs demo-seed-tenants
tilt logs demo-seed-inventory
# Check demo service
tilt logs demo-session-service
```
### Test Demo Session Creation
```bash
# Get demo accounts info
curl http://localhost/api/demo/accounts | jq
# Create demo session
curl -X POST http://localhost/api/demo/session/create \
-H "Content-Type: application/json" \
-d '{
"demo_account_type": "individual_bakery",
"ip_address": "127.0.0.1"
}' | jq
# Response:
# {
# "session_id": "demo_abc123...",
# "virtual_tenant_id": "uuid-here",
# "expires_at": "2025-10-02T12:30:00Z",
# "session_token": "eyJ..."
# }
```
### Use Demo Session
```bash
# Make request with demo session
curl http://localhost/api/inventory/ingredients \
-H "X-Demo-Session-Id: demo_abc123..." \
-H "Content-Type: application/json"
# Try restricted operation (should fail)
curl -X DELETE http://localhost/api/inventory/ingredients/uuid \
-H "X-Demo-Session-Id: demo_abc123..."
# Response:
# {
# "error": "demo_restriction",
# "message": "Esta operación no está permitida en cuentas demo..."
# }
```
---
## 📊 Demo Accounts
### Account 1: Individual Bakery
```yaml
Name: Panadería San Pablo - Demo
Email: demo.individual@panaderiasanpablo.com
Password: DemoSanPablo2024!
Business Model: individual_bakery
Location: Madrid, Spain
Features:
- Production Management ✓
- Recipe Management ✓
- Inventory Tracking ✓
- Demand Forecasting ✓
- POS System ✓
- Sales Analytics ✓
Data:
- 20+ raw ingredients
- 5+ finished products
- Multiple stock lots
- Production batches
- Sales history
```
### Account 2: Central Baker Satellite
```yaml
Name: Panadería La Espiga - Demo
Email: demo.central@panaderialaespiga.com
Password: DemoLaEspiga2024!
Business Model: central_baker_satellite
Location: Barcelona, Spain
Features:
- Supplier Management ✓
- Inventory Tracking ✓
- Order Management ✓
- POS System ✓
- Sales Analytics ✓
- Demand Forecasting ✓
Data:
- 15+ par-baked products
- 10+ finished products
- Supplier relationships
- Delivery tracking
- Sales history
```
---
## 🔧 Configuration
### Session Settings
Edit `services/demo_session/app/core/config.py`:
```python
DEMO_SESSION_DURATION_MINUTES = 30 # Session lifetime
DEMO_SESSION_MAX_EXTENSIONS = 3 # Max extensions allowed
REDIS_SESSION_TTL = 1800 # Redis cache TTL (seconds)
```
### Operation Restrictions
Edit `gateway/app/middleware/demo_middleware.py`:
```python
DEMO_ALLOWED_OPERATIONS = {
"GET": ["*"],
"POST": [
"/api/pos/sales", # Allow sales
"/api/orders", # Allow orders
"/api/inventory/adjustments" # Allow adjustments
],
"DELETE": [] # Block all deletes
}
```
### Cleanup Schedule
Edit `infrastructure/kubernetes/base/cronjobs/demo-cleanup-cronjob.yaml`:
```yaml
spec:
schedule: "0 * * * *" # Every hour
# Or:
# schedule: "*/30 * * * *" # Every 30 minutes
# schedule: "0 */3 * * *" # Every 3 hours
```
---
## 📈 Monitoring
### Check Active Sessions
```bash
# Get statistics
curl http://localhost/api/demo/stats | jq
# Get specific session
curl http://localhost/api/demo/session/{session_id} | jq
```
### View Logs
```bash
# Demo session service
kubectl logs -f deployment/demo-session-service -n bakery-ia
# Cleanup job
kubectl logs -l app=demo-cleanup -n bakery-ia --tail=100
# Seed jobs
kubectl logs job/demo-seed-inventory -n bakery-ia
```
### Metrics
```bash
# Database queries
kubectl exec -it deployment/demo-session-service -n bakery-ia -- \
psql $DEMO_SESSION_DATABASE_URL -c \
"SELECT status, COUNT(*) FROM demo_sessions GROUP BY status;"
# Redis memory
kubectl exec -it deployment/redis -n bakery-ia -- \
redis-cli INFO memory
```
---
## 🔄 Maintenance
### Manual Cleanup
```bash
# Trigger cleanup manually
kubectl create job --from=cronjob/demo-session-cleanup \
manual-cleanup-$(date +%s) -n bakery-ia
# Watch cleanup progress
kubectl logs -f job/manual-cleanup-xxxxx -n bakery-ia
```
### Reseed Demo Data
```bash
# Delete and recreate seed jobs
kubectl delete job demo-seed-inventory -n bakery-ia
kubectl apply -f infrastructure/kubernetes/base/jobs/demo-seed-inventory-job.yaml
# Watch progress
kubectl logs -f job/demo-seed-inventory -n bakery-ia
```
### Scale Demo Service
```bash
# Scale up for high load
kubectl scale deployment/demo-session-service --replicas=4 -n bakery-ia
# Scale down for maintenance
kubectl scale deployment/demo-session-service --replicas=1 -n bakery-ia
```
---
## 🛠 Troubleshooting
### Sessions Not Creating
1. **Check demo-session-service health**
```bash
kubectl get pods -l app=demo-session-service -n bakery-ia
kubectl logs deployment/demo-session-service -n bakery-ia --tail=50
```
2. **Verify base tenants exist**
```bash
kubectl exec -it deployment/tenant-service -n bakery-ia -- \
psql $TENANT_DATABASE_URL -c \
"SELECT id, name, is_demo_template FROM tenants WHERE is_demo = true;"
```
3. **Check Redis connection**
```bash
kubectl exec -it deployment/demo-session-service -n bakery-ia -- \
python -c "import redis; r=redis.Redis(host='redis-service'); print(r.ping())"
```
### Sessions Not Cleaning Up
1. **Check CronJob status**
```bash
kubectl get cronjobs -n bakery-ia
kubectl get jobs -l app=demo-cleanup -n bakery-ia
```
2. **Manually trigger cleanup**
```bash
curl -X POST http://localhost/api/demo/cleanup/run
```
3. **Check for stuck sessions**
```bash
kubectl exec -it deployment/demo-session-service -n bakery-ia -- \
psql $DEMO_SESSION_DATABASE_URL -c \
"SELECT session_id, status, expires_at FROM demo_sessions WHERE status = 'active';"
```
### Gateway Not Injecting Virtual Tenant
1. **Check middleware is loaded**
```bash
kubectl logs deployment/gateway -n bakery-ia | grep -i demo
```
2. **Verify session ID in request**
```bash
curl -v http://localhost/api/inventory/ingredients \
-H "X-Demo-Session-Id: your-session-id"
```
3. **Check demo middleware logic**
- Review [demo_middleware.py](gateway/app/middleware/demo_middleware.py)
- Ensure session is active
- Verify operation is allowed
---
## 🎉 Success Criteria
**Demo session creates successfully**
- Session ID returned
- Virtual tenant ID generated
- Expiration time set
**Data is isolated**
- Multiple sessions don't interfere
- Each session has unique tenant ID
**Spanish demo data loads**
- Ingredients in Spanish
- Realistic bakery scenarios
- Both business models represented
**Operations restricted**
- Read operations allowed
- Write operations limited
- Delete operations blocked
**Automatic cleanup works**
- Sessions expire after 30 minutes
- CronJob removes expired sessions
- Redis keys cleaned up
**Gateway integration works**
- Middleware detects sessions
- Virtual tenant injected
- Restrictions enforced
**K8s Job cloning works**
- Dynamic image detection in Tilt (dev)
- Environment variable configuration
- Automatic data cloning per session
- No service-specific clone endpoints needed
**AI & Scheduler protection works**
- Forecast API blocked for demo accounts
- Scheduler filters demo tenants
- Fake models in database only
---
## 📚 Next Steps
### For Frontend Integration
1. Create demo login page showing both accounts
2. Implement session token storage (cookie/localStorage)
3. Add session timer UI component
4. Show "DEMO MODE" badge in header
5. Display session expiration warnings
### For Marketing
1. Publish demo credentials on website
2. Create demo walkthrough videos
3. Add "Probar Demo" CTA buttons
4. Track demo → signup conversion
### For Operations
1. Set up monitoring dashboards
2. Configure alerts for cleanup failures
3. Track session metrics (duration, usage)
4. Optimize Redis cache strategy
---
## 📞 Support
For issues or questions:
- Review [DEMO_ARCHITECTURE.md](DEMO_ARCHITECTURE.md) for detailed documentation
- Check logs: `tilt logs demo-session-service`
- Inspect database: `psql $DEMO_SESSION_DATABASE_URL`
---
## 🔧 Technical Architecture Decisions
### Data Cloning: Why Kubernetes Jobs?
**Problem**: Need to clone demo data from base template tenants to virtual tenants for each session.
**Options Considered**:
1.**Service-based clone endpoints** - Would require `/internal/demo/clone` in every service
2.**PostgreSQL Foreign Data Wrapper** - Complex setup, doesn't work across databases
3.**Kubernetes Jobs** - Selected approach
**Why K8s Jobs Won**:
- Database-level operations (ORM-based, faster than API calls)
- Scalable (one job per session, isolated execution)
- No service coupling (don't need clone endpoints in every service)
- Works in all environments (dev & production)
### Image Configuration: Environment Variables
**Problem**: K8s Jobs need container images, but Tilt uses dynamic tags (e.g., `tilt-abc123`) while production uses stable tags.
**Solution**: Environment variable `CLONE_JOB_IMAGE`
```yaml
# Demo-session deployment has default
env:
- name: CLONE_JOB_IMAGE
value: "bakery/inventory-service:latest"
# Tilt patches it dynamically
# Tiltfile line 231-237
inventory_image_ref = kubectl get deployment inventory-service ...
kubectl set env deployment/demo-session-service CLONE_JOB_IMAGE=$inventory_image_ref
```
**Benefits**:
- ✅ General solution (not tied to specific service)
- ✅ Works in dev (dynamic Tilt tags)
- ✅ Works in production (stable release tags)
- ✅ Easy to change image via env var
### Middleware: BaseHTTPMiddleware Pattern
**Problem**: Initial function-based middleware using `@app.middleware("http")` wasn't executing.
**Solution**: Converted to class-based `BaseHTTPMiddleware`
```python
class DemoMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
# ... middleware logic
```
**Why**: FastAPI's `BaseHTTPMiddleware` provides better lifecycle hooks and guaranteed execution order.
---
**Implementation Date**: 2025-10-02
**Last Updated**: 2025-10-03
**Status**: ✅ Complete - Ready for Production
**Next**: Frontend integration and end-to-end testing