Spaces:
Sleeping
Sleeping
| # Field Agent Project Dashboard API | |
| ## Endpoint | |
| `GET /api/v1/projects/{project_id}/dashboard` | |
| ## Authorization | |
| Field agents can only access projects they're assigned to (via ProjectTeam). | |
| --- | |
| ## Field Agent Response | |
| ```json | |
| { | |
| "project_info": { | |
| "id": "uuid", | |
| "title": "Nairobi Fiber Rollout", | |
| "project_type": "infrastructure", | |
| "status": "active" | |
| }, | |
| "my_stats": { | |
| "tickets": { | |
| "total_assigned": 15, | |
| "pending": 4, | |
| "in_progress": 2, | |
| "completed_this_week": 9 | |
| }, | |
| "expenses": { | |
| "total_amount": 12500.00, | |
| "pending_amount": 4500.00, | |
| "pending_count": 3 | |
| }, | |
| "inventory": { | |
| "items_on_hand": 8 | |
| }, | |
| "notifications": { | |
| "unread": 5, | |
| "total": 20 | |
| } | |
| }, | |
| "work_queue": { | |
| "pending_assignments": [ | |
| { | |
| "assignment_id": "uuid", | |
| "ticket_id": "uuid", | |
| "ticket_title": "Install fiber at Westlands", | |
| "ticket_number": "TKT-2024-001", | |
| "status": "PENDING", | |
| "priority": "high", | |
| "due_date": "2025-11-28T00:00:00Z", | |
| "execution_order": 1, | |
| "assigned_at": "2025-11-27T08:00:00Z" | |
| } | |
| ], | |
| "total_pending": 4, | |
| "high_priority": 1, | |
| "due_today": 2 | |
| }, | |
| "cached_at": "2025-11-27T10:30:00Z", | |
| "cache_expires_in_seconds": 300 | |
| } | |
| ``` | |
| --- | |
| ## Usage | |
| ### Fetch Project Dashboard | |
| ```typescript | |
| const response = await fetch( | |
| `/api/v1/projects/${projectId}/dashboard`, | |
| { headers: { 'Authorization': `Bearer ${token}` } } | |
| ); | |
| const data = await response.json(); | |
| ``` | |
| ### Display Stats Cards | |
| ```typescript | |
| const { my_stats } = data; | |
| <Card title="Pending"> | |
| {my_stats.tickets.pending} | |
| </Card> | |
| <Card title="In Progress"> | |
| {my_stats.tickets.in_progress} | |
| </Card> | |
| <Card title="Completed This Week"> | |
| {my_stats.tickets.completed_this_week} | |
| </Card> | |
| <Card title="Pending Expenses"> | |
| KES {my_stats.expenses.pending_amount.toLocaleString()} | |
| </Card> | |
| ``` | |
| ### Display Work Queue | |
| ```typescript | |
| const { work_queue } = data; | |
| <WorkQueue> | |
| {work_queue.pending_assignments.map(assignment => ( | |
| <WorkItem key={assignment.assignment_id}> | |
| <Badge>{assignment.execution_order || '—'}</Badge> | |
| <Title>{assignment.ticket_title}</Title> | |
| <Priority>{assignment.priority}</Priority> | |
| <Status>{assignment.status}</Status> | |
| </WorkItem> | |
| ))} | |
| </WorkQueue> | |
| ``` | |
| --- | |
| ## Status Values | |
| Assignment status (computed from timeline): | |
| - `PENDING` - Assigned, not responded | |
| - `ACCEPTED` - Responded, not started journey | |
| - `IN_TRANSIT` - Started journey, not arrived | |
| - `ON_SITE` - Arrived at site, working | |
| - `CLOSED` - Work completed | |
| --- | |
| ## Cache | |
| - Cached for 5 minutes | |
| - Use `?refresh=true` to force refresh | |
| - Cache is per-user (field agent sees their own data) | |
| --- | |
| ## Manager Response | |
| Managers get full project stats (different structure): | |
| ```json | |
| { | |
| "project_info": {...}, | |
| "summary_stats": { | |
| "tickets": {...}, | |
| "sales_orders": {...}, | |
| "expenses": {...}, | |
| "team": {...}, | |
| "finances": {...}, | |
| "regions": {...}, | |
| "inventory": {...} | |
| } | |
| } | |
| ``` | |