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

403 lines
11 KiB
Markdown

# Reasoning i18n Implementation - Complete Summary
## ✅ Completed Implementation
### 1. **Backend: Structured Reasoning Data Generation**
#### Created Standard Reasoning Types (`shared/schemas/reasoning_types.py`)
```python
# 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
```python
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:**
```json
{
"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:**
```json
{
"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:**
```typescript
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:**
```typescript
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:**
```typescript
// 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:**
```python
reasoning='Lead time or demand std dev is zero or negative'
reasoning='Insufficient historical demand data...'
```
**Needed:**
```python
reasoning_data={
"type": "error",
"code": "LEAD_TIME_INVALID",
"parameters": {}
}
```
#### ❌ Replenishment Planning Service
**File:** `services/procurement/app/services/replenishment_planning_service.py`
**Current:**
```python
reasoning='Insufficient data for safety stock calculation'
```
**Needed:**
```python
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):**
```python
reasoning_text = f"Low stock detected for {supplier.name} items..."
consequence_text = f"Stock-out risk in {days_until_delivery + 2} days..."
```
**Needed:**
```python
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
```typescript
// 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