Spaces:
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:
# 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:
- Main app prefix:
/api/v1(from main.py) - Router prefix:
/api/v1(WRONG - duplicates the prefix) - 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:
# 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 ticketPOST /api/v1/ticket-assignments/tickets/{ticket_id}/assign- Assign to agentPOST /api/v1/ticket-assignments/tickets/{ticket_id}/assign-team- Assign to teamPOST /api/v1/ticket-assignments/assignments/{assignment_id}/accept- Accept assignmentPOST /api/v1/ticket-assignments/assignments/{assignment_id}/reject- Reject assignmentPOST /api/v1/ticket-assignments/assignments/{assignment_id}/start-journey- Start journeyPOST /api/v1/ticket-assignments/assignments/{assignment_id}/arrived- Record arrivalPOST /api/v1/ticket-assignments/assignments/{assignment_id}/complete- Complete workPOST /api/v1/ticket-assignments/assignments/{assignment_id}/drop- Drop ticketGET /api/v1/ticket-assignments/tickets/available-for-me- Get available ticketsGET /api/v1/ticket-assignments/assignments/{assignment_id}- Get assignment detailsGET /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 expenseGET /api/v1/expenses/- List expensesGET /api/v1/expenses/{expense_id}- Get expensePATCH /api/v1/expenses/{expense_id}- Update expensePOST /api/v1/expenses/{expense_id}/approve- Approve expensePOST /api/v1/expenses/{expense_id}/payment-details- Add payment detailsPOST /api/v1/expenses/{expense_id}/mark-paid- Mark as paidGET /api/v1/expenses/stats- Get expense statsDELETE /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 reportGET /api/v1/progress-reports/- List progress reportsGET /api/v1/progress-reports/stats- Get statsGET /api/v1/progress-reports/{report_id}- Get reportPATCH /api/v1/progress-reports/{report_id}- Update reportDELETE /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 reportGET /api/v1/incident-reports/- List incident reportsGET /api/v1/incident-reports/stats- Get statsGET /api/v1/incident-reports/{report_id}- Get reportPATCH /api/v1/incident-reports/{report_id}- Update reportPOST /api/v1/incident-reports/{report_id}/resolve- Resolve incidentDELETE /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:
// OLD (broken)
POST /api/v1/api/v1/tickets/{id}/self-assign
// NEW (correct)
POST /api/v1/ticket-assignments/tickets/{id}/self-assign
Expenses:
// OLD (broken)
POST /api/v1/api/v1/
// NEW (correct)
POST /api/v1/expenses/
Progress Reports:
// OLD (broken)
POST /api/v1/api/v1/
// NEW (correct)
POST /api/v1/progress-reports/
Incident Reports:
// OLD (broken)
POST /api/v1/api/v1/
// NEW (correct)
POST /api/v1/incident-reports/
Testing
After server restart, verify these endpoints work:
# 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
- Deploy backend changes - Server restart required
- Update frontend - Change all API calls to use new URLs
- 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.