Files
bakery-ia/REASONING_I18N_IMPLEMENTATION_SUMMARY.md
Claude 28136cf198 feat: Complete frontend i18n implementation for dashboard components
- Updated TypeScript types to support reasoning_data field
- Integrated useReasoningTranslation hook in all dashboard components:
  * ActionQueueCard: Translates PO reasoning_data and UI text
  * ProductionTimelineCard: Translates batch reasoning_data and UI text
  * OrchestrationSummaryCard: Translates all hardcoded English text
  * HealthStatusCard: Translates all hardcoded English text
- Added missing translation keys to all language files (EN, ES, EU):
  * health_status: never, critical_issues, actions_needed
  * action_queue: total, critical, important
  * orchestration_summary: ready_to_plan, run_info, took, show_more/less
  * production_timeline: Complete rebuild with new keys
- Components now support fallback for deprecated text fields
- Full multilingual support: English, Spanish, Basque

Dashboard is now fully translatable and will display reasoning in user's language.
2025-11-07 18:34:30 +00:00

11 KiB

Reasoning i18n Implementation - Complete Summary

Completed Implementation

1. Backend: Structured Reasoning Data Generation

Created Standard Reasoning Types (shared/schemas/reasoning_types.py)

# Purchase Order Types
- low_stock_detection
- forecast_demand
- safety_stock_replenishment
- supplier_contract
- seasonal_demand
- production_requirement
- manual_request

# Production Batch Types
- forecast_demand
- customer_order
- stock_replenishment
- seasonal_preparation
- promotion_event
- urgent_order
- regular_schedule

Helper Functions

create_po_reasoning_low_stock()
create_po_reasoning_forecast_demand()
create_batch_reasoning_forecast_demand()
create_batch_reasoning_customer_order()

2. Backend: Services Updated

Production Service

File: services/production/app/services/production_service.py:1839-1867

  • Generates reasoning_data when creating production batches
  • Includes: product_name, predicted_demand, current_stock, confidence_score

Example Output:

{
  "type": "forecast_demand",
  "parameters": {
    "product_name": "Croissant",
    "predicted_demand": 500,
    "current_stock": 120,
    "production_needed": 380,
    "confidence_score": 87
  },
  "urgency": {
    "level": "normal",
    "ready_by_time": "08:00"
  },
  "metadata": {
    "trigger_source": "orchestrator_auto",
    "ai_assisted": true
  }
}

Procurement Service

File: services/procurement/app/services/procurement_service.py:874-1040

  • NEW: Implemented actual PO creation (replaced placeholder!)
  • Groups requirements by supplier
  • Intelligently chooses reasoning type based on context
  • Generates comprehensive reasoning_data

Example Output:

{
  "type": "low_stock_detection",
  "parameters": {
    "supplier_name": "Harinas del Norte",
    "product_names": ["Flour Type 55", "Flour Type 45"],
    "current_stock": 45.5,
    "required_stock": 200,
    "days_until_stockout": 3,
    "stock_percentage": 22.8
  },
  "consequence": {
    "type": "stockout_risk",
    "severity": "high",
    "impact_days": 3,
    "affected_products": ["Baguette", "Croissant"],
    "estimated_lost_orders": 15
  },
  "metadata": {
    "trigger_source": "orchestrator_auto",
    "forecast_confidence": 0.85,
    "ai_assisted": true
  }
}

Dashboard Service

File: services/orchestrator/app/services/dashboard_service.py

  • Returns reasoning_data instead of TEXT fields
  • Creates defaults if missing
  • Both PO actions and production timeline use structured data

3. Backend: Database Schema

Models Updated

  • PurchaseOrder: Removed reasoning, consequence TEXT columns
  • ProductionBatch: Removed reasoning TEXT column
  • Both use only reasoning_data (JSONB/JSON)

Unified Schemas Updated

  • services/procurement/migrations/001_unified_initial_schema.py
  • services/production/migrations/001_unified_initial_schema.py
  • No separate migration needed - updated initial schema

4. Frontend: i18n Translation System

Translation Files Created

Languages: English (EN), Spanish (ES), Basque/Euskara (EU)

Files:

  • frontend/src/locales/en/reasoning.json
  • frontend/src/locales/es/reasoning.json
  • frontend/src/locales/eu/reasoning.json

Translation Coverage:

  • All purchase order reasoning types
  • All production batch reasoning types
  • All consequence types
  • Severity levels
  • Error codes
  • Complete JTBD dashboard UI text

Example Translations:

Language Translation
🇬🇧 EN "Low stock for {{supplier_name}}. Stock runs out in {{days_until_stockout}} days."
🇪🇸 ES "Stock bajo para {{supplier_name}}. Se agota en {{days_until_stockout}} días."
🇪🇺 EU "{{supplier_name}}-rentzat stock baxua. {{days_until_stockout}} egunetan amaituko da."

Translation Hook Created

File: frontend/src/hooks/useReasoningTranslation.ts

Functions:

translatePOReasonng(reasoningData)      // Purchase orders
translateBatchReasoning(reasoningData)   // Production batches
translateConsequence(consequenceData)    // Consequences
translateSeverity(severity)              // Severity levels
translateTrigger(trigger)                // Trigger sources
translateError(errorCode)                // Error codes

// High-level formatters
formatPOAction(reasoningData)            // Complete PO formatting
formatBatchAction(reasoningData)         // Complete batch formatting

Usage Example:

import { useReasoningFormatter } from '@/hooks/useReasoningTranslation';

function ActionQueueCard({ action }) {
  const { formatPOAction } = useReasoningFormatter();

  const { reasoning, consequence, severity } = formatPOAction(action.reasoning_data);

  return (
    <div>
      <p>{reasoning}</p>  {/* Translated! */}
      <p>{consequence}</p> {/* Translated! */}
    </div>
  );
}

🔄 Remaining Work

1. Frontend Components Need Updates

ActionQueueCard.tsx

Current: Expects reasoning and consequence TEXT fields Needed: Use useReasoningFormatter() to translate reasoning_data

Change Required:

// BEFORE
<p>{action.reasoning}</p>
<p>{action.consequence}</p>

// AFTER
import { useReasoningFormatter } from '@/hooks/useReasoningTranslation';

const { formatPOAction } = useReasoningFormatter();
const { reasoning, consequence } = formatPOAction(action.reasoning_data);

<p>{reasoning}</p>
<p>{consequence}</p>

ProductionTimelineCard.tsx

Needed: Use formatBatchAction() to translate batch reasoning

OrchestrationSummaryCard.tsx

Needed: Replace hardcoded English text with i18n keys:

  • "Last Night I Planned Your Day" → t('reasoning:jtbd.orchestration_summary.title')
  • "All caught up!" → t('reasoning:jtbd.action_queue.all_caught_up')
  • etc.

HealthStatusCard.tsx

Needed: Replace hardcoded text with i18n

2. Backend Services Need Error Code Updates

Safety Stock Calculator

File: services/procurement/app/services/safety_stock_calculator.py

Current:

reasoning='Lead time or demand std dev is zero or negative'
reasoning='Insufficient historical demand data...'

Needed:

reasoning_data={
    "type": "error",
    "code": "LEAD_TIME_INVALID",
    "parameters": {}
}

Replenishment Planning Service

File: services/procurement/app/services/replenishment_planning_service.py

Current:

reasoning='Insufficient data for safety stock calculation'

Needed:

reasoning_data={
    "type": "error",
    "code": "INSUFFICIENT_DATA",
    "parameters": {}
}

3. Demo Seed Scripts Need Updates

Purchase Orders Seed

File: services/procurement/scripts/demo/seed_demo_purchase_orders.py

Current (lines 126-127):

reasoning_text = f"Low stock detected for {supplier.name} items..."
consequence_text = f"Stock-out risk in {days_until_delivery + 2} days..."

Needed:

from shared.schemas.reasoning_types import create_po_reasoning_low_stock

reasoning_data = create_po_reasoning_low_stock(
    supplier_name=supplier.name,
    product_names=[...],
    current_stock=...,
    required_stock=...,
    days_until_stockout=days_until_delivery + 2
)

Production Batches Seed

File: services/production/scripts/demo/seed_demo_batches.py Needed: Similar update using create_batch_reasoning_*() functions


📋 Quick Implementation Checklist

High Priority (Breaks Current Functionality)

  • Update ActionQueueCard.tsx to use reasoning translation
  • Update ProductionTimelineCard.tsx to use reasoning translation
  • Update demo seed scripts to use structured reasoning_data

Medium Priority (Improves UX)

  • Update OrchestrationSummaryCard.tsx with i18n
  • Update HealthStatusCard.tsx with i18n
  • Update InsightsGrid.tsx with i18n (if needed)

Low Priority (Code Quality)

  • Update safety stock calculator with error codes
  • Update replenishment service with error codes
  • Audit ML services for hardcoded text

🎯 Example Implementation for ActionQueueCard

// frontend/src/components/dashboard/ActionQueueCard.tsx

import { useReasoningFormatter } from '@/hooks/useReasoningTranslation';
import { useTranslation } from 'react-i18next';

function ActionItemCard({ action, onApprove, onViewDetails, onModify }: ...) {
  const { formatPOAction } = useReasoningFormatter();
  const { t } = useTranslation('reasoning');

  // Translate reasoning_data
  const { reasoning, consequence, severity } = formatPOAction(action.reasoning_data);

  return (
    <div className={`...`}>
      {/* Reasoning (always visible) */}
      <div className="bg-white rounded-md p-3 mb-3">
        <p className="text-sm font-medium text-gray-700 mb-1">
          {t('jtbd.action_queue.why_needed')}
        </p>
        <p className="text-sm text-gray-600">{reasoning}</p>
      </div>

      {/* Consequence (expandable) */}
      <button onClick={() => setExpanded(!expanded)} className="...">
        {t('jtbd.action_queue.what_if_not')}
      </button>

      {expanded && (
        <div className="bg-amber-50 border border-amber-200 rounded-md p-3 mb-3">
          <p className="text-sm text-amber-900">{consequence}</p>
          {severity && (
            <span className="text-xs font-semibold">{severity}</span>
          )}
        </div>
      )}
    </div>
  );
}

🚀 Benefits Achieved

  1. Multilingual Support

    • Dashboard works in EN, ES, and EU
    • Easy to add more languages (CA, FR, etc.)
  2. Maintainability

    • Backend: One place to define reasoning logic
    • Frontend: Translations in organized JSON files
    • No hardcoded text scattered across code
  3. Consistency

    • Same reasoning type always translates the same way
    • Centralized terminology
  4. Flexibility

    • Can change wording without touching code
    • Can A/B test different phrasings
    • Translators can work independently
  5. Type Safety

    • TypeScript interfaces for reasoning_data
    • Compile-time checks for translation keys

📚 Documentation

  • Reasoning Types: shared/schemas/reasoning_types.py
  • Translation Hook: frontend/src/hooks/useReasoningTranslation.ts
  • Translation Files: frontend/src/locales/{en,es,eu}/reasoning.json
  • Audit Report: REASONING_I18N_AUDIT.md

Next Steps

  1. Update frontend components (30-60 min)

    • Replace TEXT field usage with reasoning_data translation
    • Use useReasoningFormatter() hook
    • Replace hardcoded strings with t() calls
  2. Update demo seed scripts (15-30 min)

    • Replace hardcoded text with helper functions
    • Test demo data generation
  3. Update backend services (15-30 min)

    • Replace hardcoded error messages with error codes
    • Frontend will translate error codes
  4. Test (30 min)

    • Switch between EN, ES, EU
    • Verify all reasoning types display correctly
    • Check mobile responsiveness

Total Estimated Time: 2-3 hours for complete implementation