From 6ee8c055ee7b1ea11a8befa63b888ea83369c208 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Nov 2025 18:05:45 +0000 Subject: [PATCH] fix: Handle null values in dashboard API to prevent React error #306 Fixed critical React error #306 by adding proper null handling for reasoning and consequence fields in the dashboard service. Issue: When database columns (reasoning, consequence) contain NULL values, Python's .get() method returns None, which becomes undefined in JavaScript, causing React to throw error #306 when trying to render. Solution: Changed from `.get("field", "default")` to `.get("field") or "default"` to properly handle None values throughout the dashboard service. Changes: - Purchase order actions: Added null coalescing for reasoning/consequence - Production timeline: Added null coalescing for reasoning field - Alert actions: Added null coalescing for description and source - Onboarding actions: Added null coalescing for title and consequence This ensures all text fields always have valid string values before being sent to the frontend, preventing undefined rendering errors. --- .../app/services/dashboard_service.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/services/orchestrator/app/services/dashboard_service.py b/services/orchestrator/app/services/dashboard_service.py index 1b8e0632..b7fbade6 100644 --- a/services/orchestrator/app/services/dashboard_service.py +++ b/services/orchestrator/app/services/dashboard_service.py @@ -352,8 +352,8 @@ class DashboardService: "type": ActionType.RESOLVE_ALERT, "urgency": ActionUrgency.CRITICAL, "title": alert["title"], - "subtitle": alert.get("source", "System Alert"), - "reasoning": alert.get("description", ""), + "subtitle": alert.get("source") or "System Alert", + "reasoning": alert.get("description") or "System alert requires attention", "consequence": "Immediate action required to prevent production issues", "actions": [ {"label": "View Details", "type": "primary", "action": "view_alert"}, @@ -373,8 +373,8 @@ class DashboardService: "urgency": urgency, "title": f"Purchase Order {po.get('po_number', 'N/A')}", "subtitle": f"Supplier: {po.get('supplier_name', 'Unknown')}", - "reasoning": po.get("reasoning", "Low stock levels detected"), - "consequence": po.get("consequence", "Order needed to maintain inventory levels"), + "reasoning": po.get("reasoning") or "Low stock levels detected", + "consequence": po.get("consequence") or "Order needed to maintain inventory levels", "amount": po.get("total_amount", 0), "currency": po.get("currency", "EUR"), "actions": [ @@ -393,14 +393,14 @@ class DashboardService: "id": f"onboarding_{step['id']}", "type": ActionType.COMPLETE_ONBOARDING, "urgency": ActionUrgency.IMPORTANT, - "title": step["title"], + "title": step.get("title") or "Complete onboarding step", "subtitle": "Setup incomplete", "reasoning": "Required to unlock full automation", - "consequence": step.get("consequence", "Some features are limited"), + "consequence": step.get("consequence") or "Some features are limited", "actions": [ {"label": "Complete Setup", "type": "primary", "action": "complete_onboarding"} ], - "estimatedTimeMinutes": step.get("estimated_minutes", 10) + "estimatedTimeMinutes": step.get("estimated_minutes") or 10 }) # Sort by urgency priority @@ -505,7 +505,7 @@ class DashboardService: "progress": progress, "readyBy": planned_end.isoformat() if planned_end else None, "priority": batch.get("priority", "MEDIUM"), - "reasoning": batch.get("reasoning", "Based on demand forecast") + "reasoning": batch.get("reasoning") or "Based on demand forecast" }) # Sort by planned start time