Issue: Ensure dispute-driven Agreement changes trigger notifications & activity logs
Depends on: —
Task Description
Improve the reliability and consistency of Agreement data by making sure that every Agreement state change produces the same side effects, regardless of where it originates. Today, dispute-related state changes silently skip the notifications and activity logs that normal Agreement updates generate — so users are not notified and the audit trail is incomplete when a dispute changes an Agreement. This issue closes that gap so disputes behave like a first-class Agreement event.
This is a consistency and observability improvement, not a rewrite: existing endpoints and behaviors are preserved; we are adding the missing side effects and unifying how they fire.
Background / Current State
DisputesService writes Agreement state changes directly to the agreements table in several places.
- Those direct writes bypass the central Agreement update path, so they do not emit the activity logs and notifications that the normal flow emits (
dispute_opened, dispute_resolved, and related status changes).
- Result: when a dispute changes an Agreement's status, participants receive no notification and the activity history has gaps — a real data-consistency and user-experience problem.
logActivity() currently exists in multiple copies across services, which makes it easy for a code path to log inconsistently or not at all.
Goals
- Every dispute-driven Agreement change emits the correct notification(s) and activity log entry, matching the normal update flow.
- A single, shared way to record Agreement activity so no code path can silently skip it.
- No user-facing behavior is lost; disputes keep working exactly as before, but now with complete notifications and audit history.
Non-Goals
- No new public endpoints.
- No changes to authorization or who can perform dispute actions.
- No change to the on-chain / Trustless Work dispute logic.
Deliverable
- Dispute-driven Agreement state changes route through the same side-effect path (notifications + activity logging) as normal Agreement updates.
- A single shared
logActivity() used by all services (the duplicate copies are consolidated into one).
Requirements
- Dispute status changes (e.g. dispute opened, dispute resolved) produce the corresponding notification events, consistent with existing event types.
- Dispute-driven Agreement status changes produce activity log entries identical in shape to the normal flow.
- All services use one shared
logActivity() implementation.
GET /agreements/by-wallet must be preserved, not rewritten — this endpoint already exists with its own scoping/authorization; keep its behavior and access rules exactly as-is. Any interaction with it here is read-only reuse.
Validation System
- Open a dispute that changes an Agreement's status → confirm the participants receive the expected notification AND an activity log entry is created.
- Resolve a dispute → confirm the resolution notification and activity log entry are created.
- Compare a dispute-driven status change against an equivalent normal status change → confirm the activity log entries and notifications match in shape and coverage.
- Confirm
GET /agreements/by-wallet returns the same results and respects the same scope as before this change.
Technical Requirements
- Reuse the existing notification event types and activity-log schema — do not invent new formats.
- Consolidate
logActivity() into a single shared utility/service and update all call sites (remove usage before removing the now-dead copies).
- Keep the dispute flow's existing inputs/outputs stable so no caller breaks.
Additional Notes
Framed as an improvement: the value is complete, consistent notifications and audit history for disputes, plus a single logging path that prevents this class of gap from recurring. Keep the scope tight — this should be a low-risk change that makes an existing feature more trustworthy, not a structural overhaul.
Testing (required)
Proof of Completion (required)
Issue: Ensure dispute-driven Agreement changes trigger notifications & activity logs
Depends on: —
Task Description
Improve the reliability and consistency of Agreement data by making sure that every Agreement state change produces the same side effects, regardless of where it originates. Today, dispute-related state changes silently skip the notifications and activity logs that normal Agreement updates generate — so users are not notified and the audit trail is incomplete when a dispute changes an Agreement. This issue closes that gap so disputes behave like a first-class Agreement event.
This is a consistency and observability improvement, not a rewrite: existing endpoints and behaviors are preserved; we are adding the missing side effects and unifying how they fire.
Background / Current State
DisputesServicewrites Agreement state changes directly to theagreementstable in several places.dispute_opened,dispute_resolved, and related status changes).logActivity()currently exists in multiple copies across services, which makes it easy for a code path to log inconsistently or not at all.Goals
Non-Goals
Deliverable
logActivity()used by all services (the duplicate copies are consolidated into one).Requirements
logActivity()implementation.GET /agreements/by-walletmust be preserved, not rewritten — this endpoint already exists with its own scoping/authorization; keep its behavior and access rules exactly as-is. Any interaction with it here is read-only reuse.Validation System
GET /agreements/by-walletreturns the same results and respects the same scope as before this change.Technical Requirements
logActivity()into a single shared utility/service and update all call sites (remove usage before removing the now-dead copies).Additional Notes
Framed as an improvement: the value is complete, consistent notifications and audit history for disputes, plus a single logging path that prevents this class of gap from recurring. Keep the scope tight — this should be a low-risk change that makes an existing feature more trustworthy, not a structural overhaul.
Testing (required)
GET /agreements/by-walletbehavior and scoping are unchanged.Proof of Completion (required)
GET /agreements/by-walletreturns identical, correctly-scoped results before and after the change.