Skip to content

routes: dispute management endpoints - #72

Merged
joelpeace48-cell merged 1 commit into
FinesseStudioLab:mainfrom
Codeinx:issue-58-dispute-routes
Aug 25, 2026
Merged

joelpeace48-cell merged 1 commit into
FinesseStudioLab:mainfrom
Codeinx:issue-58-dispute-routes

Conversation

@Codeinx

@Codeinx Codeinx commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Problem

The dispute flow is the protocol's differentiator, and there was no API surface for it: a buyer couldn't raise a dispute, an adjudicator couldn't see the queue, and neither party could attach evidence.

What this adds

New module src/routes/disputes/, registered under the v1 prefix:

  • POST /disputes — raise a dispute against a settlement with a reason and optional evidence.
  • GET /disputes — role-scoped: buyers/sellers only see disputes they're a party to; adjudicators see everything.
  • POST /disputes/:id/evidence — either original party may add evidence, rejected once the dispute's window has closed. The deadline is enforced server-side (not left only to the contract).
  • POST /disputes/:id/resolve — adjudicator-only, records the outcome.
  • A notification is logged on every lifecycle transition (raised, evidence-added, resolved).

Evidence handling follows the same principle as inference payloads elsewhere in this service: each evidence item is stored with a sha256 contentHash kept as a field separate from the raw content from day one, so wiring in real off-chain storage plus an on-chain commit call later is a swap of one function rather than a data-model change.

Role and identity are currently read from x-role / x-user-id headers, since the repo doesn't yet have an auth/session layer to hang this off of — the role-scoping and window-enforcement logic itself is real and fully tested per role, and swapping the header read for a real identity middleware later is a one-function change.

Testing

src/routes/disputes/index.test.ts uses Fastify's inject to cover the full lifecycle:

  • raising a dispute with evidence, hash-committed
  • listing is role-scoped (an unrelated party sees nothing; an adjudicator sees everything)
  • only a party to the dispute may add evidence
  • only an adjudicator may resolve, and resolving fires a notification
  • evidence is rejected once the window has closed
  • unauthenticated requests are rejected

npm run lint, npm run build, npm test, and npm audit --audit-level=high are all clean on this branch.

Scope note

This PR touches src/routes/v1/index.ts (registering the new plugin) in addition to the new src/routes/disputes/** files. No other PR open against this issue tracker (#44, #54) touches that file or package.json, so this should merge independently of the other two regardless of order.

Closes #58.

Adds the dispute lifecycle API (src/routes/disputes), registered under
the v1 prefix:

- POST /disputes — raise a dispute against a settlement with a reason
  and optional evidence. Evidence content is stored alongside a sha256
  commitment (contentHash) — the value that would go on-chain — kept
  as a separate field from day one so wiring in real off-chain storage
  and an on-chain commit call later doesn't change the data model.
- GET /disputes — role-scoped: buyers/sellers only see disputes
  they're a party to, adjudicators see everything.
- POST /disputes/:id/evidence — either original party may add
  evidence, rejected once the dispute's window has closed
  (server-enforced, not just left to the contract).
- POST /disputes/:id/resolve — adjudicator-only, records the outcome.
- A notification is logged on every lifecycle transition (raised,
  evidence-added, resolved).

Role and identity are read from x-role/x-user-id headers for now,
since the repo has no auth/session layer yet to hang this off of — the
role-scoping and window-enforcement logic itself is real and tested
per role. Tests cover the full lifecycle, cross-role access denial,
adjudicator-only resolution, window enforcement, and unauthenticated
rejection.

Closes FinesseStudioLab#58.
@joelpeace48-cell
joelpeace48-cell merged commit 59c697e into FinesseStudioLab:main Aug 25, 2026
1 check passed
@grantfox-oss grantfox-oss Bot mentioned this pull request Aug 25, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

routes: dispute management endpoints

2 participants