Skip to content

[PBI] Notification dispatcher (creation and fan-out) #435

@cjlapao

Description

@cjlapao

Description

Implement the internal NotificationDispatcher service that accepts a notification emit request, resolves the target user set (fan-out for system events, explicit list for targeted events), and creates a per-user Notification record in the database for each resolved recipient.

User Story

As a backend engineer building a feature that needs to alert users, I want a single, well-defined dispatcher interface I can call to raise a notification, so that I don't need to know about user resolution, persistence, or delivery details — I just emit the event and the system handles the rest.

Acceptance Criteria

  • Dispatcher interface: A Dispatcher interface (or equivalent idiomatic Go construct) exposes at minimum: Emit(ctx, NotificationRequest) error.
  • NotificationRequest struct: Defines the input contract: type, title, message, host_id (optional), record_id (optional), correlation_id (optional), actions (optional), meta (optional), and either target_users []string (explicit) or a fan_out bool flag (system-wide).
  • Fan-out resolution: When fan_out is true and no target_users are provided, the dispatcher resolves the full set of users who should receive the notification (e.g. all active users, or users with access to the relevant host). The resolution strategy is configurable/injectable for testability.
  • Explicit targeting: When target_users is provided, the dispatcher creates exactly one Notification row per user ID in the list, ignoring fan-out logic.
  • Per-user rows: A separate Notification row is created for each target user. Rows are identical except for user_id and id.
  • Correlation ID passthrough: If correlation_id is set in the request it is stored verbatim. No server-side validation of whether the ID refers to a real record.
  • Error handling: Partial failures (one user's row fails to write) are logged but do not abort the entire dispatch. The dispatcher returns a composite error if any rows fail.
  • Unit tests: Tests cover fan-out resolution, explicit targeting, per-user row creation, partial failure handling, and correlation ID passthrough.

Definition of Done

  • Code implemented following best practices.
  • Unit tests written and passing.
  • Code reviewed and approved.
  • Merged into the main branch.
  • Documentation updated (if applicable).
  • Deployed to staging/production environment.

Assumptions and Constraints

No response

Dependencies

  • Assumption: Fan-out user resolution can be implemented as a simple "all active users" strategy initially, with the resolution logic designed to be swappable in future.
  • Constraint: The dispatcher must not block the calling goroutine waiting for WebSocket delivery. Persistence is synchronous; WS push is fire-and-forget via a channel or callback.

Additional Notes

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    pbiProduct Backlog ItemtriageSelected for triage

    Type

    No fields configured for Task.

    Projects

    Status

    📋 Awaiting Triage

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions