Skip to main content

Task Breakdown: Notifications

Feature ID: notifications Status: Done (Retrospective) Last updated: 2026-05-08


Phase 1 — Schema

  • T1. Add notifications entity + repository (packages/agent/src/entities/notification.entity.ts, packages/agent/src/database/repositories/notification.repository.ts).
  • T2. Add type / category enums (packages/agent/src/entities/notification.types.ts).
  • T3. Indexes: (userId, createdAt desc), (userId, isPersistent), partial unique on (userId, deduplicationKey).

Phase 2 — Service

  • T4. NotificationService.create w/ deduplicationKey short-circuit.
  • T5. Race-condition recovery on Postgres 23505 / MySQL ER_DUP_ENTRY / SQLite SQLITE_CONSTRAINT.
  • T6. List / unread-count / persistent / mark-as-read / dismiss methods.
  • T7. Producer convenience methods: notifyAiCreditsDepleted, notifyAiProviderError, notifyGenerationAccountError, notifySchedulePaused, notifyGitAuthExpired.
  • T8. clearByDeduplicationKey so producers can clear on resolve.
  • T9. cleanup() returning {expired, dismissed, old}.

Phase 3 — API

  • T10. NotificationsController (6 endpoints) behind AuthSessionGuard.
  • T11. Math.min(limit, 100) cap on list endpoint.
  • T12. 400 on dismissing persistent notifications.
  • T13. Cross-user reject via findByIdAndUserId.

Phase 4 — Background Jobs

  • T14. NotificationCleanupService cron worker.
  • T15. DistributedTaskLockService.runExclusive('notifications:cleanup', …) guard.
  • T16. Outer error swallow + log so a failed window does not wedge later runs.

Phase 5 — Web / CLI

  • T17. Web: header bell + panel + persistent banner consume the API.
  • T18. CLI: not in scope — CLI is for work / generator surface.

Phase 6 — Tests

  • T19. NotificationsController unit tests (10) — limit cap, persistent refusal, cross-user reject.
  • T20. NotificationCleanupService unit tests (4) — happy path, locked branch, error swallow.
  • T21. Follow-up: producer / cleanup integration tests in packages/agent (Jest) hitting the real repository against a Postgres test container. Currently only the API-side controller + cleanup worker are covered by unit tests — see #490.

Phase 7 — Docs

  • T22. This Spec Kit folder (spec / plan / tasks).
  • T23. Follow-up: user-facing doc at docs/features/notifications.md describing what shows up in the bell and how to clear it.

Definition of Done

  • Service implemented; all controller endpoints behind auth guard.
  • Race-condition recovery and persistent-dismissal protections in place.
  • Cleanup cron lock-guarded and error-tolerant.
  • Unit tests cover the API surface.
  • Spec / plan / tasks documents authored.

Follow-ups discovered

  • T21: integration tests for producer dedup race against a real DB would catch any drift between in-process check and the partial-unique index. Currently only unit tests cover the dedup-recovery branch.
  • T23: user-facing doc — bell icon, persistent banner behaviour, what categories exist, how to clear them.
  • Notification preferences UI — if user feedback asks for muting by category or quiet hours, this is the spec to amend.