Spaces:
Sleeping
Sleeping
| # Router Prefix Fix - Correcting Double /api/v1 Issue | |
| ## Problem | |
| Four routers were configured with prefix `/api/v1`, which caused double prefixing since the main app already adds `/api/v1`: | |
| ```python | |
| # WRONG - causes /api/v1/api/v1/... | |
| api_router.include_router(ticket_assignments.router, prefix="/api/v1", tags=["..."]) | |
| api_router.include_router(expenses.router, prefix="/api/v1", tags=["..."]) | |
| api_router.include_router(progress_reports.router, prefix="/api/v1", tags=["..."]) | |
| api_router.include_router(incident_reports.router, prefix="/api/v1", tags=["..."]) | |
| ``` | |
| ## URL Construction | |
| FastAPI builds URLs by concatenating: | |
| 1. Main app prefix: `/api/v1` (from main.py) | |
| 2. Router prefix: `/api/v1` (WRONG - duplicates the prefix) | |
| 3. Route path: `/tickets/{id}/self-assign` | |
| Result: `/api/v1/api/v1/tickets/{id}/self-assign` β | |
| ## Solution | |
| Changed router prefixes to be semantic paths without `/api/v1`: | |
| ```python | |
| # CORRECT - results in /api/v1/ticket-assignments/... | |
| api_router.include_router(ticket_assignments.router, prefix="/ticket-assignments", tags=["..."]) | |
| api_router.include_router(expenses.router, prefix="/expenses", tags=["..."]) | |
| api_router.include_router(progress_reports.router, prefix="/progress-reports", tags=["..."]) | |
| api_router.include_router(incident_reports.router, prefix="/incident-reports", tags=["..."]) | |
| ``` | |
| ## Fixed Endpoints | |
| ### 1. Ticket Assignments | |
| **Before:** `/api/v1/api/v1/tickets/{id}/self-assign` β | |
| **After:** `/api/v1/ticket-assignments/tickets/{id}/self-assign` β | |
| **Routes affected:** | |
| - `POST /api/v1/ticket-assignments/tickets/{ticket_id}/self-assign` - Self-assign ticket | |
| - `POST /api/v1/ticket-assignments/tickets/{ticket_id}/assign` - Assign to agent | |
| - `POST /api/v1/ticket-assignments/tickets/{ticket_id}/assign-team` - Assign to team | |
| - `POST /api/v1/ticket-assignments/assignments/{assignment_id}/accept` - Accept assignment | |
| - `POST /api/v1/ticket-assignments/assignments/{assignment_id}/reject` - Reject assignment | |
| - `POST /api/v1/ticket-assignments/assignments/{assignment_id}/start-journey` - Start journey | |
| - `POST /api/v1/ticket-assignments/assignments/{assignment_id}/arrived` - Record arrival | |
| - `POST /api/v1/ticket-assignments/assignments/{assignment_id}/complete` - Complete work | |
| - `POST /api/v1/ticket-assignments/assignments/{assignment_id}/drop` - Drop ticket | |
| - `GET /api/v1/ticket-assignments/tickets/available-for-me` - Get available tickets | |
| - `GET /api/v1/ticket-assignments/assignments/{assignment_id}` - Get assignment details | |
| - `GET /api/v1/ticket-assignments/tickets/{ticket_id}/assignments` - Get ticket assignments | |
| ### 2. Expenses | |
| **Before:** `/api/v1/api/v1/` β | |
| **After:** `/api/v1/expenses/` β | |
| **Routes affected:** | |
| - `POST /api/v1/expenses/` - Create expense | |
| - `GET /api/v1/expenses/` - List expenses | |
| - `GET /api/v1/expenses/{expense_id}` - Get expense | |
| - `PATCH /api/v1/expenses/{expense_id}` - Update expense | |
| - `POST /api/v1/expenses/{expense_id}/approve` - Approve expense | |
| - `POST /api/v1/expenses/{expense_id}/payment-details` - Add payment details | |
| - `POST /api/v1/expenses/{expense_id}/mark-paid` - Mark as paid | |
| - `GET /api/v1/expenses/stats` - Get expense stats | |
| - `DELETE /api/v1/expenses/{expense_id}` - Delete expense | |
| ### 3. Progress Reports | |
| **Before:** `/api/v1/api/v1/` β | |
| **After:** `/api/v1/progress-reports/` β | |
| **Routes affected:** | |
| - `POST /api/v1/progress-reports/` - Create progress report | |
| - `GET /api/v1/progress-reports/` - List progress reports | |
| - `GET /api/v1/progress-reports/stats` - Get stats | |
| - `GET /api/v1/progress-reports/{report_id}` - Get report | |
| - `PATCH /api/v1/progress-reports/{report_id}` - Update report | |
| - `DELETE /api/v1/progress-reports/{report_id}` - Delete report | |
| ### 4. Incident Reports | |
| **Before:** `/api/v1/api/v1/` β | |
| **After:** `/api/v1/incident-reports/` β | |
| **Routes affected:** | |
| - `POST /api/v1/incident-reports/` - Create incident report | |
| - `GET /api/v1/incident-reports/` - List incident reports | |
| - `GET /api/v1/incident-reports/stats` - Get stats | |
| - `GET /api/v1/incident-reports/{report_id}` - Get report | |
| - `PATCH /api/v1/incident-reports/{report_id}` - Update report | |
| - `POST /api/v1/incident-reports/{report_id}/resolve` - Resolve incident | |
| - `DELETE /api/v1/incident-reports/{report_id}` - Delete report | |
| ## Files Modified | |
| - `src/app/api/v1/router.py` - Fixed 4 router prefixes | |
| ## Breaking Changes | |
| **Yes - this is a breaking change for any frontend code calling these endpoints.** | |
| ### Frontend Updates Required | |
| If your frontend is calling any of these endpoints, you need to update the URLs: | |
| **Ticket Assignments:** | |
| ```javascript | |
| // OLD (broken) | |
| POST /api/v1/api/v1/tickets/{id}/self-assign | |
| // NEW (correct) | |
| POST /api/v1/ticket-assignments/tickets/{id}/self-assign | |
| ``` | |
| **Expenses:** | |
| ```javascript | |
| // OLD (broken) | |
| POST /api/v1/api/v1/ | |
| // NEW (correct) | |
| POST /api/v1/expenses/ | |
| ``` | |
| **Progress Reports:** | |
| ```javascript | |
| // OLD (broken) | |
| POST /api/v1/api/v1/ | |
| // NEW (correct) | |
| POST /api/v1/progress-reports/ | |
| ``` | |
| **Incident Reports:** | |
| ```javascript | |
| // OLD (broken) | |
| POST /api/v1/api/v1/ | |
| // NEW (correct) | |
| POST /api/v1/incident-reports/ | |
| ``` | |
| ## Testing | |
| After server restart, verify these endpoints work: | |
| ```bash | |
| # Test ticket assignment | |
| curl -X POST "http://localhost:7860/api/v1/ticket-assignments/tickets/{ticket_id}/self-assign" \ | |
| -H "Authorization: Bearer {token}" | |
| # Test expense creation | |
| curl -X POST "http://localhost:7860/api/v1/expenses/" \ | |
| -H "Authorization: Bearer {token}" | |
| # Test progress report creation | |
| curl -X POST "http://localhost:7860/api/v1/progress-reports/" \ | |
| -H "Authorization: Bearer {token}" | |
| # Test incident report creation | |
| curl -X POST "http://localhost:7860/api/v1/incident-reports/" \ | |
| -H "Authorization: Bearer {token}" | |
| ``` | |
| ## Migration Steps | |
| 1. **Deploy backend changes** - Server restart required | |
| 2. **Update frontend** - Change all API calls to use new URLs | |
| 3. **Test all affected features** - Verify ticket assignments, expenses, reports work | |
| ## Why This Happened | |
| The routers were likely copied from a template or created at different times without consistent prefix conventions. The `/api/v1` prefix should only be added at the main app level, not at individual router levels. | |
| ## Prevention | |
| When creating new routers, use semantic prefixes: | |
| - β `prefix="/users"` | |
| - β `prefix="/tickets"` | |
| - β `prefix="/ticket-assignments"` | |
| - β `prefix="/api/v1"` (never do this) | |
| The `/api/v1` prefix is already added by the main app, so individual routers should only specify their resource path. | |