- 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.
403 lines
11 KiB
Markdown
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
|