Files
bakery-ia/AI_INSIGHTS_DEMO_SETUP_GUIDE.md
Urtzi Alfaro 9f3b39bd28 Add comprehensive documentation and final improvements
Documentation Added:
- AI_INSIGHTS_DEMO_SETUP_GUIDE.md: Complete setup guide for demo sessions
- AI_INSIGHTS_DATA_FLOW.md: Architecture and data flow diagrams
- AI_INSIGHTS_QUICK_START.md: Quick reference guide
- DEMO_SESSION_ANALYSIS_REPORT.md: Detailed analysis of demo session d67eaae4
- ROOT_CAUSE_ANALYSIS_AND_FIXES.md: Complete analysis of 8 issues (6 fixed, 2 analyzed)
- COMPLETE_FIX_SUMMARY.md: Executive summary of all fixes
- FIX_MISSING_INSIGHTS.md: Forecasting and procurement fix guide
- FINAL_STATUS_SUMMARY.md: Status overview
- verify_fixes.sh: Automated verification script
- enhance_procurement_data.py: Procurement data enhancement script

Service Improvements:
- Demo session cleanup worker: Use proper settings for Redis configuration with TLS/auth
- Procurement service: Add Redis initialization with proper error handling and cleanup
- Production fixture: Remove duplicate worker assignments (cleaned 56 duplicates)
- Orchestrator fixture: Add purchase order metadata for better tracking

Impact:
- Complete documentation for troubleshooting and setup
- Improved Redis connection handling across services
- Clean production data without duplicates
- Better error handling and logging

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 11:32:45 +01:00

18 KiB
Raw Blame History

AI Insights Demo Setup Guide

Overview

This guide explains how to populate demo JSON files to generate AI insights across different services during demo sessions.

Architecture Summary

Demo Session Creation
  ↓
Clone Base Tenant Data (from JSON files)
  ↓
Populate Database with 90 days of history
  ↓
Trigger ML Models in Services
  ↓
Post AI Insights to AI Insights Service
  ↓
Display in Frontend

Key Files to Populate

1. 03-inventory.json - Stock Movements (CRITICAL for AI Insights)

Location: /shared/demo/fixtures/professional/03-inventory.json

What to Add: stock_movements array with 90 days of historical data

{
  "stock_movements": [
    {
      "id": "uuid",
      "tenant_id": "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6",
      "ingredient_id": "10000000-0000-0000-0000-000000000001",
      "stock_id": null,
      "movement_type": "PRODUCTION_USE",  // or "PURCHASE"
      "quantity": 45.23,
      "unit_cost": 0.85,
      "total_cost": 38.45,
      "quantity_before": null,
      "quantity_after": null,  // Set to 0.0 for stockout events!
      "movement_date": "BASE_TS - 7d",
      "reason_code": "production_consumption",
      "notes": "Daily production usage",
      "created_at": "BASE_TS - 7d",
      "created_by": "c1a2b3c4-d5e6-47a8-b9c0-d1e2f3a4b5c6"
    }
  ]
}

Why This Matters:

  • Safety Stock Optimizer needs 90 days of PRODUCTION_USE movements to calculate:
    • Average daily consumption
    • Demand variability
    • Optimal reorder points
    • Cost savings from optimized safety stock levels
  • Stockout events (quantity_after = 0.0) trigger critical insights
  • Purchase patterns help identify supplier reliability

AI Insights Generated:

  • "Safety stock optimization: Reduce Harina T55 from 200kg to 145kg, save €1,200/year"
  • "Detected 3 stockouts in 90 days for Levadura Fresca - increase safety stock by 25%"
  • "Inventory carrying cost opportunity: €850/year savings across 5 ingredients"

2. 06-production.json - Worker Assignments (CRITICAL for Yield Predictions)

Location: /shared/demo/fixtures/professional/06-production.json

What to Add: Worker IDs to batches array + actual duration

{
  "batches": [
    {
      "id": "40000000-0000-0000-0000-000000000001",
      "product_id": "20000000-0000-0000-0000-000000000001",
      "status": "COMPLETED",
      "yield_percentage": 96.5,
      "staff_assigned": [
        "50000000-0000-0000-0000-000000000001"  // Juan Panadero (expert)
      ],
      "actual_start_time": "BASE_TS - 6d 7h",
      "planned_duration_minutes": 180,
      "actual_duration_minutes": 175.5,
      "completed_at": "BASE_TS - 6d 4h"
    }
  ]
}

Why This Matters:

  • Yield Predictor correlates worker skill levels with yield performance
  • Needs historical batches with:
    • staff_assigned (worker IDs)
    • yield_percentage
    • actual_duration_minutes
  • Worker skill levels defined in generate_ai_insights_data.py:
    • María García (Owner): 0.98 - Expert
    • Juan Panadero (Baker): 0.95 - Very skilled
    • Isabel Producción: 0.90 - Experienced
    • Carlos Almacén: 0.78 - Learning

AI Insights Generated:

  • "Batch #4502 predicted yield: 94.2% (±2.1%) - assign expert worker for 98% yield"
  • "Waste reduction opportunity: Training junior staff could save €2,400/year"
  • "Optimal staffing: Schedule María for croissants (complex), Carlos for baguettes (standard)"

3. 09-sales.json - Sales History (For Demand Forecasting)

Location: /shared/demo/fixtures/professional/09-sales.json

What's Already There: Daily sales records with variability

{
  "sales_data": [
    {
      "id": "SALES-202501-2287",
      "tenant_id": "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6",
      "product_id": "20000000-0000-0000-0000-000000000001",
      "quantity": 51.11,
      "unit_price": 6.92,
      "total_amount": 335.29,
      "sales_date": "BASE_TS - 7d 4h",
      "sales_channel": "online",
      "payment_method": "cash",
      "customer_id": "50000000-0000-0000-0000-000000000001"
    }
  ]
}

AI Insights Generated:

  • "Demand trending up 15% for Croissants - increase next week's production by 12 units"
  • "Weekend sales 40% lower - reduce Saturday production to avoid waste"
  • "Seasonal pattern detected: Baguette demand peaks Mondays (+25%)"

4. 07-procurement.json - Purchase Orders (For Supplier Performance)

Location: /shared/demo/fixtures/professional/07-procurement.json

What's Already There: Purchase orders with delivery tracking

{
  "purchase_orders": [
    {
      "id": "50000000-0000-0000-0000-0000000000c1",
      "po_number": "PO-LATE-0001",
      "supplier_id": "40000000-0000-0000-0000-000000000001",
      "status": "confirmed",
      "required_delivery_date": "BASE_TS - 4h",
      "estimated_delivery_date": "BASE_TS - 4h",
      "notes": "⚠️ EDGE CASE: Delivery should have arrived 4 hours ago",
      "reasoning_data": {
        "type": "low_stock_detection",
        "metadata": {
          "delivery_delayed": true,
          "delay_hours": 4
        }
      }
    }
  ]
}

AI Insights Generated:

  • "Supplier 'Harinas del Norte' late on 3/10 deliveries - consider backup supplier"
  • "Price trend: Mantequilla up 8% in 60 days - consider bulk purchase now"
  • "Procurement optimization: Consolidate 3 orders to Lácteos Gipuzkoa, save €45 shipping"

5. 11-orchestrator.json - Orchestration Metadata

Location: /shared/demo/fixtures/professional/11-orchestrator.json

What's Already There: Last orchestration run results

{
  "orchestration_run": {
    "id": "90000000-0000-0000-0000-000000000001",
    "status": "completed",
    "run_type": "daily",
    "started_at": "BASE_TS - 1d 16h",
    "completed_at": "BASE_TS - 1d 15h45m"
  },
  "orchestration_results": {
    "production_batches_created": 18,
    "purchase_orders_created": 6,
    "ai_insights_posted": 5  // ← Number of AI insights generated
  },
  "ai_insights": {
    "yield_improvement_suggestions": 2,
    "waste_reduction_opportunities": 1,
    "demand_forecasting_updates": 3,
    "procurement_optimization": 2,
    "production_scheduling": 1
  }
}

Purpose: Shows orchestration metadata, NOT the insights themselves (those are in ai_insights service)


How AI Insights Are Generated

Step 1: Demo Session Creation

When a user creates a demo session:

POST /api/demo/sessions
{
  "demo_account_type": "professional"
}

Step 2: Data Cloning (Automatic)

The CloneOrchestrator clones base tenant data from JSON files:

  • Copies inventory products, recipes, suppliers, etc.
  • Crucially: Loads 90 days of stock movements
  • Loads production batches with worker assignments
  • Loads sales history

File: /services/demo_session/app/services/clone_orchestrator.py

Step 3: AI Model Execution (After Data Clone)

Each service runs its ML models:

Inventory Service

# File: /services/inventory/app/ml/safety_stock_insights_orchestrator.py
async def generate_portfolio_summary(tenant_id: str):
    # Analyze 90 days of stock movements
    # Calculate optimal safety stock levels
    # Generate insights with cost impact
    insights = await ai_insights_client.create_insights_bulk(tenant_id, insights_list)

Triggers: After inventory data is cloned Publishes Event: ai_safety_stock_optimization

Production Service

# File: /services/production/app/ml/yield_insights_orchestrator.py
async def generate_yield_predictions(tenant_id: str):
    # Analyze historical batches + worker performance
    # Predict yield for upcoming batches
    # Identify waste reduction opportunities
    insights = await ai_insights_client.create_insights_bulk(tenant_id, insights_list)

Triggers: After production batches are cloned Publishes Event: ai_yield_prediction

Forecasting Service

# File: /services/forecasting/app/ml/demand_insights_orchestrator.py
async def generate_demand_insights(tenant_id: str):
    # Analyze sales history
    # Detect trends, seasonality
    # Recommend production adjustments
    insights = await ai_insights_client.create_insights_bulk(tenant_id, insights_list)

Triggers: After forecasts are generated Publishes Event: ai_demand_forecast

Procurement Service

# File: /services/procurement/app/ml/price_insights_orchestrator.py
async def generate_price_insights(tenant_id: str):
    # Analyze purchase order history
    # Detect price trends
    # Recommend bulk buying opportunities
    insights = await ai_insights_client.create_insights_bulk(tenant_id, insights_list)

Triggers: After purchase orders are cloned Publishes Event: ai_price_forecast

Step 4: AI Insights Storage

All insights are posted to:

POST /api/ai-insights/tenants/{tenant_id}/insights

Stored in ai_insights service database with:

  • Priority (low, medium, high, critical)
  • Confidence score (0-100)
  • Impact metrics (cost savings, waste reduction, etc.)
  • Recommendation actions
  • Expiration (default 7 days)

Step 5: Frontend Display

User sees insights in:

  • AI Insights Page: /app/analytics/ai-insights
  • Dashboard Widget: Summary of actionable insights
  • Service-specific pages: Contextual insights (e.g., production page shows yield predictions)

Running the Generator Script

Run the provided script to populate 03-inventory.json and 06-production.json:

cd /Users/urtzialfaro/Documents/bakery-ia
python shared/demo/fixtures/professional/generate_ai_insights_data.py

What it does:

  1. Generates ~800-900 stock movements (90 days × 10 ingredients):

    • Daily PRODUCTION_USE movements with variability
    • Bi-weekly PURCHASE deliveries
    • 5-8 stockout events (quantity_after = 0.0)
  2. Adds worker assignments to production batches:

    • Assigns workers based on yield performance
    • Adds actual_duration_minutes
    • Correlates high yields with expert workers
  3. Output:

    ✅ AI INSIGHTS DATA GENERATION COMPLETE
    
    📊 DATA ADDED:
       • Stock movements (PRODUCTION_USE): 720 records (90 days)
       • Stock movements (PURCHASE): 60 deliveries
       • Stockout events: 6
       • Worker assignments: 245 batches
    
    🎯 AI INSIGHTS READINESS:
       ✓ Safety Stock Optimizer: READY (90 days demand data)
       ✓ Yield Predictor: READY (worker data added)
       ✓ Sustainability Metrics: READY (existing waste data)
    

Manual Data Population (Alternative)

If you need custom data, manually add to JSON files:

For Safety Stock Insights

Add to 03-inventory.json:

{
  "stock_movements": [
    // 90 days of daily consumption for each ingredient
    {
      "movement_type": "PRODUCTION_USE",
      "ingredient_id": "10000000-0000-0000-0000-000000000001",
      "quantity": 45.0,  // Average daily usage
      "movement_date": "BASE_TS - 1d"
    },
    {
      "movement_type": "PRODUCTION_USE",
      "ingredient_id": "10000000-0000-0000-0000-000000000001",
      "quantity": 52.3,  // Variability is key!
      "movement_date": "BASE_TS - 2d"
    },
    // ... repeat for 90 days

    // Add stockout events (triggers critical insights)
    {
      "movement_type": "PRODUCTION_USE",
      "ingredient_id": "10000000-0000-0000-0000-000000000001",
      "quantity": 48.0,
      "quantity_before": 45.0,
      "quantity_after": 0.0,  // STOCKOUT!
      "movement_date": "BASE_TS - 15d",
      "notes": "STOCKOUT - Ran out during production"
    }
  ]
}

For Yield Prediction Insights

Add to 06-production.json:

{
  "batches": [
    {
      "id": "batch-uuid",
      "product_id": "20000000-0000-0000-0000-000000000001",
      "status": "COMPLETED",
      "yield_percentage": 96.5,  // High yield
      "staff_assigned": [
        "50000000-0000-0000-0000-000000000001"  // Expert worker (Juan)
      ],
      "actual_duration_minutes": 175.5,
      "planned_duration_minutes": 180
    },
    {
      "id": "batch-uuid-2",
      "product_id": "20000000-0000-0000-0000-000000000001",
      "status": "COMPLETED",
      "yield_percentage": 88.2,  // Lower yield
      "staff_assigned": [
        "50000000-0000-0000-0000-000000000005"  // Junior worker (Carlos)
      ],
      "actual_duration_minutes": 195.0,
      "planned_duration_minutes": 180
    }
  ]
}

Verifying AI Insights Generation

1. Check Demo Session Logs

After creating a demo session, check service logs:

# Inventory service (safety stock insights)
docker logs bakery-inventory-service | grep "ai_safety_stock"

# Production service (yield insights)
docker logs bakery-production-service | grep "ai_yield"

# Forecasting service (demand insights)
docker logs bakery-forecasting-service | grep "ai_demand"

# Procurement service (price insights)
docker logs bakery-procurement-service | grep "ai_price"

2. Query AI Insights API

curl -X GET "http://localhost:8000/api/ai-insights/tenants/{tenant_id}/insights" \
  -H "Authorization: Bearer {token}"

Expected Response:

{
  "items": [
    {
      "id": "insight-uuid",
      "type": "optimization",
      "category": "inventory",
      "priority": "medium",
      "confidence": 88.5,
      "title": "Safety stock optimization opportunity for Harina T55",
      "description": "Reduce safety stock from 200kg to 145kg based on 90-day demand analysis",
      "impact_type": "cost_savings",
      "impact_value": 1200.0,
      "impact_unit": "EUR/year",
      "is_actionable": true,
      "recommendation_actions": [
        "Update reorder point to 145kg",
        "Adjust automatic procurement rules"
      ],
      "status": "new",
      "detected_at": "2025-01-16T10:30:00Z"
    }
  ],
  "total": 5,
  "page": 1
}

3. Check Frontend

Navigate to: http://localhost:3000/app/analytics/ai-insights

Should see:

  • Statistics: Total insights, actionable count, average confidence
  • Insight Cards: Categorized by type (inventory, production, procurement, forecasting)
  • Action Buttons: Apply, Dismiss, Acknowledge

Troubleshooting

No Insights Generated

Problem: AI Insights page shows 0 insights after demo session creation

Solutions:

  1. Check stock movements count:

    # Should have ~800+ movements
    cat shared/demo/fixtures/professional/03-inventory.json | jq '.stock_movements | length'
    

    If < 100, run generate_ai_insights_data.py

  2. Check worker assignments:

    # Should have ~200+ batches with staff_assigned
    cat shared/demo/fixtures/professional/06-production.json | jq '[.batches[] | select(.staff_assigned != null)] | length'
    

    If 0, run generate_ai_insights_data.py

  3. Check service logs for errors:

    docker logs bakery-ai-insights-service --tail 100
    
  4. Verify ML models are enabled: Check .env files for:

    AI_INSIGHTS_ENABLED=true
    ML_MODELS_ENABLED=true
    

Insights Not Showing in Frontend

Problem: API returns insights but frontend shows empty

Solutions:

  1. Check tenant_id mismatch:

    • Frontend uses virtual_tenant_id from demo session
    • Insights should be created with same virtual_tenant_id
  2. Check filters:

    • Frontend may filter by status, priority, category
    • Try "Show All" filter
  3. Check browser console:

    // In browser dev tools
    localStorage.getItem('demo_session')
    // Should show virtual_tenant_id
    

Low Confidence Scores

Problem: Insights generated but confidence < 50%

Causes:

  • Insufficient historical data (< 60 days)
  • High variability in data (inconsistent patterns)
  • Missing worker assignments for yield predictions

Solutions:

  • Ensure 90 days of stock movements
  • Add more consistent patterns (reduce random variability)
  • Verify all batches have staff_assigned and yield_percentage

Summary Checklist

Before creating a demo session, verify:

  • 03-inventory.json has 800+ stock movements (90 days)
  • Stock movements include PRODUCTION_USE and PURCHASE types
  • 5-8 stockout events present (quantity_after = 0.0)
  • 06-production.json batches have staff_assigned arrays
  • Batches have yield_percentage and actual_duration_minutes
  • 09-sales.json has daily sales for 30+ days
  • 07-procurement.json has purchase orders with delivery dates
  • All JSON files are valid (no syntax errors)

Quick Validation:

cd /Users/urtzialfaro/Documents/bakery-ia
python -c "
import json
with open('shared/demo/fixtures/professional/03-inventory.json') as f:
    data = json.load(f)
    movements = len(data.get('stock_movements', []))
    stockouts = sum(1 for m in data['stock_movements'] if m.get('quantity_after') == 0.0)
    print(f'✓ Stock movements: {movements}')
    print(f'✓ Stockout events: {stockouts}')

with open('shared/demo/fixtures/professional/06-production.json') as f:
    data = json.load(f)
    batches_with_workers = sum(1 for b in data['batches'] if b.get('staff_assigned'))
    print(f'✓ Batches with workers: {batches_with_workers}')
"

Expected Output:

✓ Stock movements: 842
✓ Stockout events: 6
✓ Batches with workers: 247

Next Steps

  1. Run generator script (if not already done):

    python shared/demo/fixtures/professional/generate_ai_insights_data.py
    
  2. Create demo session:

    curl -X POST http://localhost:8000/api/demo/sessions \
      -H "Content-Type: application/json" \
      -d '{"demo_account_type": "professional"}'
    
  3. Wait for cloning (~40 seconds)

  4. Navigate to AI Insights: http://localhost:3000/app/analytics/ai-insights

  5. Verify insights (should see 5-10 insights across categories)

  6. Test actions:

    • Click "Apply" on an insight
    • Check if recommendation is executed
    • Provide feedback on outcome

Additional Resources

  • AI Insights Service: /services/ai_insights/README.md
  • ML Models Documentation: /services/*/app/ml/README.md
  • Demo Session Flow: /services/demo_session/README.md
  • Frontend Integration: /frontend/src/pages/app/analytics/ai-insights/README.md

For questions or issues, check service logs:

docker-compose logs -f ai-insights-service inventory-service production-service forecasting-service procurement-service