Index: 47 open (8 critical, 39 major), 6 resolved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.9 KiB
issue, title, severity, domain, labels, status, resolved, fix, created, source
| issue | title | severity | domain | labels | status | resolved | fix | created | source | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 003 | Route shadowing: POST /api/disputes/:purchaseRequestId/resolve matches dashboard router first and executes wrong handler | critical | Dispute |
|
resolved | 2026-05-29 | Remounted services/dispute router at /api/disputes/pr instead of /api/disputes — eliminates route overlap with dashboard router | 2026-05-29 | Doc vs Code Audit 2026-05-29 |
🔴 Route shadowing: POST /api/disputes/:purchaseRequestId/resolve matches dashboard router first and executes wrong handler
Severity: critical Domain: Dispute Labels: bug, backend, critical, escrow
Description
Both the dashboard disputeRoutes and the releaseHold disputeRoutes are mounted at /api/disputes in app.ts. The dashboard router is mounted first (line 521). A POST /api/disputes/{purchaseRequestId}/resolve with a valid purchaseRequestId will match the dashboard router's POST /:id/resolve (Dispute CRUD resolve) before reaching the releaseHold router's escrow-unblocking resolve. The escrow hold is never cleared.
Current Behavior
The dashboard router intercepts the request and executes Dispute model CRUD resolve only. Escrow hold is not cleared. Outcome is non-deterministic depending on whether the ID matches a Dispute _id.
Expected Behavior
POST /api/disputes/:purchaseRequestId/resolve should reach the releaseHold handler and clear the escrow hold. Route registration order must be corrected or paths made unambiguous.
Reproduction Steps
POST /api/disputes/{validPurchaseRequestId}/resolve with admin token — observe that escrow hold is NOT released, only the Dispute document is updated.
Affected Files
backend/src/app.tsbackend/src/routes/disputeRoutes.ts