Repository navigation
Open
Labels
enhancementNew feature or requestNew feature or requestintermediateRequires working knowledge of the project; scoped but non-trivialRequires working knowledge of the project; scoped but non-trivial
Description
###FILE: 101-dispute-sla-scheduler
Problem
src/modules/dispute-resolution/dispute-resolution.service.ts tracks SLA deadlines and dispute-analytics.service.ts reports on them, but nothing acts on a deadline. There is no scheduler anywhere in the repository — no @Cron, no @Interval, no ScheduleModule.
So SLA breaches are detected only if something happens to query the analytics, rather than being surfaced when they occur.
Why it matters
- Breaches are discovered late. If nobody looks at the analytics today, a dispute that breached its response deadline yesterday looks identical to one on time. The SLA data is collected but not acted upon, which is the worst of both worlds — it looks like monitoring without being monitoring.
- Escalation is manual. Nothing reminds an arbitrator that a dispute is waiting, that a deadline is approaching, or that a case has breached. Disputes go stale because humans have to remember, not because the system tells them.
- Notification listeners already exist (
src/modules/dispute-resolution/listeners/dispute-notification.listener.ts) and respond to discrete events — but "a deadline is now in 24 hours" is a time-based event, and nothing raises it.
Suggested Direction
- Add
@nestjs/scheduleand aDisputeSchedulerin the dispute module, using the same maintenance-module pattern introduced for cleanup jobs. - Run a periodic SLA sweep (every 5–15 minutes) that finds disputes in
IN_ARBITRATIONorEVIDENCE_SUBMITTEDwhose next deadline is approaching or has passed, and emits domain events for each —SLA_APPROACHING,SLA_BREACHED,SLA_ESCALATION_DUE. - Make it idempotent, so a sweep does not re-notify for a deadline already notified. Persist a notified marker per deadline rather than relying on in-memory state.
- Wire the existing notification listener to those events so approaching and breached deadlines actually reach the arbitrator and the parties, using the template system.
- Add configurable thresholds —
SLA_WARNING_HOURS, per-dispute-type — rather than hardcoding them. - Reuse the SLA data already in
DisputeResolutionServicerather than recomputing deadlines; the service already has SLA tracking. - Add an escalation path — after N days breached, escalate to a senior arbitrator or admin, and record it on the timeline so the escalation is auditable.
- Expose sweep health (last run, deadlines evaluated, breaches found) on the existing status endpoint.
Constraints: the sweep must be safe to run on multiple replicas — use a lock (Redis is available) or make every operation idempotent, so two instances do not double-notify. Gate the whole module behind a config flag so tests are not affected.
Acceptance Criteria
-
@nestjs/scheduleis added and aDisputeSchedulerruns a periodic SLA sweep - Approaching and breached deadlines emit domain events
- The notification listener delivers on those events
- Notification is idempotent — a repeated sweep does not re-notify
- Deadlines are persisted with a notified marker, not tracked in memory
- Thresholds are configurable per dispute type
- An escalation path exists and is recorded on the dispute timeline
- The sweep is safe on multiple replicas (lock or idempotency)
- Sweep health is exposed on the status endpoint
- Tests use
jest.useFakeTimers()and cover: approaching, breached, and repeat sweeps -
npm run lint && npx tsc --noEmit && npm testall pass
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestintermediateRequires working knowledge of the project; scoped but non-trivialRequires working knowledge of the project; scoped but non-trivial
Activity
shobhamerabacha-star commentedon Sep 30, 2026
Hey maintainers,
I would love to take this on. My planned approach:
[Feature] Add a scheduler for dispute SLA tracking, deadlines, and escalationfollowingChulilee/InterChangableTrade-Coreconventions.I am ready to start immediately—please feel free to assign this to me!