Spaces:
Sleeping
Sleeping
| # Project Overview Endpoint | |
| ## Purpose | |
| Single endpoint that replaces 4 separate calls to get complete project structure. Returns project details, regions, roles, subcontractors, and team info based on user permissions. | |
| **Replaces:** | |
| - `GET /projects/{id}` | |
| - `GET /projects/{id}/regions` | |
| - `GET /projects/{id}/project-roles` | |
| - `GET /projects/{id}/subcontractors` | |
| ## Endpoint | |
| ``` | |
| GET /api/v1/projects/{project_id}/overview | |
| ``` | |
| **Query Params:** | |
| - `refresh` (optional): `true` to force cache refresh | |
| **Cache:** 12 hours | |
| ## Response Structure | |
| ### For Managers/Admins | |
| ```json | |
| { | |
| "project": { | |
| "id": "uuid", | |
| "title": "Project Name", | |
| "project_type": "customer_service", | |
| "status": "active", | |
| "client_id": "uuid", | |
| "client_name": "Client Name", | |
| "contractor_id": "uuid", | |
| "contractor_name": "Contractor Name", | |
| "primary_manager_id": "uuid", | |
| "primary_manager_name": "Manager Name", | |
| "service_type": "ftth", | |
| "planned_start_date": "2025-01-01", | |
| "planned_end_date": "2025-12-31", | |
| "activation_requirements": [...], | |
| "photo_requirements": [...], | |
| "budget": {...}, | |
| "is_closed": false, | |
| "created_at": "2025-01-01T00:00:00Z" | |
| }, | |
| "regions": [ | |
| { | |
| "id": "uuid", | |
| "region_name": "Nairobi West", | |
| "region_code": "NRB-W", | |
| "manager_id": "uuid", | |
| "manager_name": "Regional Manager", | |
| "is_active": true, | |
| "city": "Nairobi", | |
| "latitude": -1.2921, | |
| "longitude": 36.8219 | |
| } | |
| ], | |
| "roles": [ | |
| { | |
| "id": "uuid", | |
| "role_name": "Technician", | |
| "compensation_type": "commission", | |
| "commission_percentage": 15.0, | |
| "base_amount": 500.0, | |
| "is_active": true | |
| } | |
| ], | |
| "subcontractors": [ | |
| { | |
| "id": "uuid", | |
| "subcontractor_id": "uuid", | |
| "subcontractor_name": "SubCo Ltd", | |
| "scope_description": "Installation work", | |
| "project_region_id": "uuid", | |
| "region_name": "Nairobi West", | |
| "contract_value": 50000.0, | |
| "is_active": true | |
| } | |
| ], | |
| "team_summary": { | |
| "total_members": 25, | |
| "by_role": { | |
| "field_agent": 15, | |
| "dispatcher": 3, | |
| "sales_agent": 5, | |
| "project_manager": 2 | |
| }, | |
| "by_region": { | |
| "Nairobi West": 10, | |
| "Mombasa": 8, | |
| "Project-wide": 7 | |
| } | |
| }, | |
| "my_involvement": null, | |
| "cached_at": "2025-12-02T10:00:00Z", | |
| "cache_expires_in_seconds": 43200 | |
| } | |
| ``` | |
| ### For Field Agents/Sales Agents | |
| ```json | |
| { | |
| "project": { | |
| "id": "uuid", | |
| "title": "Project Name", | |
| "project_type": "customer_service", | |
| "status": "active", | |
| "client_name": "Client Name", | |
| "contractor_name": "Contractor Name", | |
| "service_type": "ftth", | |
| "activation_requirements": [...], | |
| "photo_requirements": [...] | |
| }, | |
| "regions": [ | |
| { | |
| "id": "uuid", | |
| "region_name": "Nairobi West", | |
| "is_active": true, | |
| "city": "Nairobi" | |
| } | |
| ], | |
| "roles": null, | |
| "subcontractors": null, | |
| "team_summary": null, | |
| "my_involvement": { | |
| "user_id": "uuid", | |
| "user_name": "John Doe", | |
| "user_email": "john@example.com", | |
| "user_role": "field_agent", | |
| "team_role": "technician", | |
| "project_role_id": "uuid", | |
| "project_role_name": "Senior Technician", | |
| "assigned_region_id": "uuid", | |
| "assigned_region_name": "Nairobi West", | |
| "is_lead": false, | |
| "assigned_at": "2025-01-15T08:00:00Z", | |
| "subcontractor_id": null, | |
| "subcontractor_name": null | |
| }, | |
| "cached_at": "2025-12-02T10:00:00Z", | |
| "cache_expires_in_seconds": 43200 | |
| } | |
| ``` | |
| ## Frontend Usage | |
| ### Display Project Overview Page | |
| ```typescript | |
| // Fetch overview | |
| const response = await fetch(`/api/v1/projects/${projectId}/overview`); | |
| const data = await response.json(); | |
| // Show project header | |
| showProjectHeader({ | |
| title: data.project.title, | |
| status: data.project.status, | |
| client: data.project.client_name, | |
| contractor: data.project.contractor_name | |
| }); | |
| // Show regions (all users see all regions) | |
| data.regions.forEach(region => { | |
| const isMyRegion = data.my_involvement?.assigned_region_id === region.id; | |
| renderRegionCard(region, isMyRegion); // Highlight user's region | |
| }); | |
| // Role-specific rendering | |
| if (data.my_involvement) { | |
| // Field agent/sales agent view | |
| showMyInvolvement({ | |
| role: data.my_involvement.team_role, | |
| region: data.my_involvement.assigned_region_name, | |
| projectRole: data.my_involvement.project_role_name | |
| }); | |
| } else { | |
| // Manager/admin view | |
| showRoles(data.roles); | |
| showSubcontractors(data.subcontractors); | |
| showTeamSummary(data.team_summary); | |
| } | |
| ``` | |
| ### Check User's Region Assignment | |
| ```typescript | |
| // Highlight user's assigned region in UI | |
| const myRegionId = data.my_involvement?.assigned_region_id; | |
| data.regions.forEach(region => { | |
| const card = createRegionCard(region); | |
| if (region.id === myRegionId) { | |
| card.classList.add('my-region', 'highlighted'); | |
| } | |
| }); | |
| ``` | |
| ### Display Requirements (Field Agents) | |
| ```typescript | |
| // Show what photos are required | |
| data.project.photo_requirements.forEach(req => { | |
| console.log(`${req.type}: ${req.min_photos}-${req.max_photos} photos`); | |
| }); | |
| // Show activation form fields | |
| data.project.activation_requirements.forEach(field => { | |
| renderFormField({ | |
| name: field.field, | |
| label: field.label, | |
| type: field.type, | |
| required: field.required, | |
| options: field.options | |
| }); | |
| }); | |
| ``` | |
| ## Key Points | |
| 1. **Single call** - Replaces 4 separate API calls | |
| 2. **Role-based** - Response adapts to user permissions automatically | |
| 3. **Long cache** - 12 hours (structure rarely changes) | |
| 4. **All see regions** - Everyone sees all regions, UI highlights user's assigned region | |
| 5. **Field agents** - See their involvement only, not other team members | |
| 6. **Managers** - See complete project structure and team composition | |
| ## Error Responses | |
| - `404` - Project not found | |
| - `403` - User not authorized to access project | |
| - `500` - Server error | |