feat: Implement structured reasoning_data generation for i18n support

Implemented proper reasoning data generation for purchase orders and
production batches to enable multilingual dashboard support.

Backend Strategy:
- Generate structured JSON with type codes and parameters
- Store only reasoning_data (JSONB), not hardcoded text
- Frontend will translate using i18n libraries

Changes:
1. Created shared/schemas/reasoning_types.py
   - Defined reasoning types for POs and batches
   - Created helper functions for common reasoning patterns
   - Supports multiple reasoning types (low_stock, forecast_demand, etc.)

2. Production Service (services/production/app/services/production_service.py)
   - Generate reasoning_data when creating batches from forecast
   - Include parameters: product_name, predicted_demand, current_stock, etc.
   - Structure supports frontend i18n interpolation

3. Procurement Service (services/procurement/app/services/procurement_service.py)
   - Implemented actual PO creation (was placeholder before!)
   - Groups requirements by supplier
   - Generates reasoning_data based on context (low_stock vs forecast)
   - Creates PO items automatically

Example reasoning_data:
{
  "type": "low_stock_detection",
  "parameters": {
    "supplier_name": "Harinas del Norte",
    "product_names": ["Flour Type 55", "Flour Type 45"],
    "days_until_stockout": 3,
    "current_stock": 45.5,
    "required_stock": 200
  },
  "consequence": {
    "type": "stockout_risk",
    "severity": "high",
    "impact_days": 3
  }
}

Frontend will translate:
- EN: "Low stock detected for Harinas del Norte. Stock runs out in 3 days."
- ES: "Stock bajo detectado para Harinas del Norte. Se agota en 3 días."
- CA: "Estoc baix detectat per Harinas del Norte. S'esgota en 3 dies."

Next steps:
- Remove TEXT fields (reasoning, consequence) from models
- Update dashboard service to use reasoning_data
- Create frontend i18n translation keys
- Update dashboard components to translate dynamically
This commit is contained in:
Claude
2025-11-07 18:16:44 +00:00
parent 6ee8c055ee
commit ddc4928d78
3 changed files with 446 additions and 2 deletions

View File

@@ -1836,6 +1836,18 @@ class ProductionService:
# Note: In a real scenario, we'd fetch recipe_id from product/inventory
# For now, we assume recipe_id = product_id or fetch from a mapping
# Generate reasoning data for JTBD dashboard
from shared.schemas.reasoning_types import create_batch_reasoning_forecast_demand
reasoning_data = create_batch_reasoning_forecast_demand(
product_name=f"Product {product_id}", # TODO: Get actual product name from inventory
predicted_demand=predicted_demand,
current_stock=current_stock,
production_needed=production_needed,
target_date=target_date.isoformat(),
confidence_score=forecast.get('confidence_score', 0.85)
)
# Create production batch
batch_data = {
'tenant_id': tenant_id,
@@ -1847,6 +1859,7 @@ class ProductionService:
'planned_start_time': datetime.combine(target_date, datetime.min.time()),
'planned_end_time': datetime.combine(target_date, datetime.max.time()),
'planned_quantity': production_needed,
'reasoning_data': reasoning_data, # NEW: Structured reasoning for i18n
'created_at': datetime.now(timezone.utc),
'updated_at': datetime.now(timezone.utc),
}