fix: Align dashboard API calls with actual procurement and production service endpoints

CRITICAL FIX: Dashboard was calling non-existent API endpoints

The Problem:
------------
The orchestrator dashboard service was calling API endpoints that don't exist:
1. Procurement: Expected dict {items: [...]} but API returns array [...]
2. Production: Called /production/production-batches/today - doesn't exist
3. Production: Called /production/production-batches - doesn't exist

Root Cause:
-----------
Created client methods without verifying actual backend API structure.
Made assumptions about response formats that didn't match reality.

The Fix:
--------
**1. Procurement Client (shared/clients/procurement_client.py)**
- Fixed get_pending_purchase_orders return type: Dict → List
- Procurement API returns: List[PurchaseOrderResponse] directly
- Changed: "Dict with {items: [...], total: n}" → "List of purchase order dicts"

**2. Production Client (shared/clients/production_client.py)**
- Fixed get_todays_batches endpoint:
  OLD: "/production/production-batches/today" (doesn't exist)
  NEW: "/production/batches?start_date=today&end_date=today"

- Fixed get_production_batches_by_status endpoint:
  OLD: "/production/production-batches?status=X"
  NEW: "/production/batches?status=X"

- Updated return type docs: {"items": [...]} → {"batches": [...], "total_count": n}
- Response structure: ProductionBatchListResponse (batches, total_count, page, page_size)

**3. Orchestrator Dashboard API (services/orchestrator/app/api/dashboard.py)**
- Fixed all po_data access patterns:
  OLD: po_data.get("items", [])
  NEW: direct list access or po_data if isinstance(po_data, list)

- Fixed production batch access:
  OLD: prod_data.get("items", [])
  NEW: prod_data.get("batches", [])

- Updated 6 locations:
  * Line 206: health-status pending POs count
  * Line 216: health-status production delays count
  * Line 274-281: orchestration-summary PO summaries
  * Line 328-329: action-queue pending POs
  * Line 472-487: insights deliveries calculation
  * Line 499-519: insights savings calculation

Verified Against:
-----------------
Frontend successfully calls these exact APIs:
- /tenants/{id}/procurement/purchase-orders (ProcurementPage.tsx)
- /tenants/{id}/production/batches (production hooks)

Both return arrays/objects as documented in their respective API files:
- services/procurement/app/api/purchase_orders.py: returns List[PurchaseOrderResponse]
- services/production/app/api/production_batches.py: returns ProductionBatchListResponse

Now dashboard calls match actual backend APIs! 
This commit is contained in:
Claude
2025-11-08 06:56:30 +00:00
parent fa0802c9f2
commit 413f652bbc
3 changed files with 22 additions and 23 deletions

View File

@@ -582,7 +582,7 @@ class ProcurementServiceClient(BaseServiceClient):
self,
tenant_id: str,
limit: int = 20
) -> Optional[Dict[str, Any]]:
) -> Optional[List[Dict[str, Any]]]:
"""
Get purchase orders pending approval for dashboard
@@ -591,7 +591,7 @@ class ProcurementServiceClient(BaseServiceClient):
limit: Maximum number of POs to return
Returns:
Dict with {"items": [...], "total": n}
List of purchase order dicts (API returns array directly)
"""
try:
return await self.get(

View File

@@ -460,12 +460,15 @@ class ProductionServiceClient(BaseServiceClient):
tenant_id: Tenant ID
Returns:
Dict with {"batches": [...], "summary": {...}}
Dict with ProductionBatchListResponse: {"batches": [...], "total_count": n, "page": 1, "page_size": n}
"""
try:
from datetime import date
today = date.today()
return await self.get(
"/production/production-batches/today",
tenant_id=tenant_id
"/production/batches",
tenant_id=tenant_id,
params={"start_date": today.isoformat(), "end_date": today.isoformat(), "page_size": 100}
)
except Exception as e:
logger.error("Error fetching today's batches", error=str(e), tenant_id=tenant_id)
@@ -486,13 +489,13 @@ class ProductionServiceClient(BaseServiceClient):
limit: Maximum number of batches to return
Returns:
Dict with {"items": [...], "total": n}
Dict with ProductionBatchListResponse: {"batches": [...], "total_count": n, "page": 1, "page_size": n}
"""
try:
return await self.get(
"/production/production-batches",
"/production/batches",
tenant_id=tenant_id,
params={"status": status, "limit": limit}
params={"status": status, "page_size": limit}
)
except Exception as e:
logger.error("Error fetching production batches", error=str(e),