---
id: TST-PFM-NOT-075
title: dispatch notifications
kind: integration
product_area: platform
module: notifications
revision: 1
status: draft
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
repository: services-platform
files:
  - >-
    modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js
implements:
  - ATS-PFM-NOT-002-01
  - ATS-PFM-NOT-002-03
  - ATS-PFM-NOT-007-03
  - ATS-PFM-NOT-008-01
  - ATS-PFM-NOT-008-02
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 5
isolation: >-
  Suite-owned records in the prepared integration workspaces; seeded workspace
  identities remain shared fixtures.
assertion_bindings:
  - scenario: ATS-PFM-NOT-002-01
    suite: TST-PFM-NOT-075
    assertions:
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#leaves
        nothing to claim when the producer’s transaction rolled back, and one
        row when it committed
  - scenario: ATS-PFM-NOT-002-03
    suite: TST-PFM-NOT-075
    assertions:
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#answers
        a repeated submission as a duplicate and queues it once
  - scenario: ATS-PFM-NOT-007-03
    suite: TST-PFM-NOT-075
    assertions:
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#publishes
        Slack and Teams deliveries to the chat queue and SMS to its own,
        deleting the rows
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#does
        not publish a delivery before its time
  - scenario: ATS-PFM-NOT-008-01
    suite: TST-PFM-NOT-075
    assertions:
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#publishes
        a pointer for a committed row and deletes the row
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#keeps
        a row the queue refused, and offers it again on the next run
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#does
        not offer a row another run holds
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#publishes
        more rows than one batch holds, in rounds
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#drains
        the tenant a nudge names and leaves the other tenant’s rows alone
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#walks
        every tenant on the scheduled run
  - scenario: ATS-PFM-NOT-008-02
    suite: TST-PFM-NOT-075
    assertions:
      - >-
        services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#leaves
        work for the next run when a run died between the publish and the
        delete, and the repeat makes nothing twice
evidence:
  - >-
    services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js
  - The file and referenced assertion titles exist at the pinned commit.
dependency_evidence:
  - >-
    Real: PostgreSQL with row-level security on, the real library insert through
    the producer's capability role, the real claim and
  - >-
    delete. Doubled: the SQS publishers (recorders that can refuse). Never
    doubled: the database or the dispatcher.
---

# dispatch notifications

## Verification Boundary

This suite exercises the local services and prepared PostgreSQL database. API lifecycle cases use signed test contexts through the real route handler; they do not invoke the deployed gateway.

## What This Suite Proves

Its cases exercise tie publication to business commit; deduplicate publication receipts; queue only eligible delivery-work channels; publish acknowledged entries and retain rejected work; recover publication interrupted before deletion.

The registered scenario bindings identify the assertions this executable file contributes. They retain individual test references so that a composite scenario does not become a claim of complete execution by one file.

## What It Does Not Prove

Local outcomes do not prove deployed queues, external provider acceptance, production credentials or complete browser behavior. No fresh execution or conformance result is claimed.

## Real Dependencies and Test Doubles

The notification fixtures use real PostgreSQL and module logic. Queue publication, visibility changes, nudges and installed channel adapters are recorded at their seams when the suite needs them. Signed API contexts replace the authorizer key in API suites.

## Must Not Be Doubled

Database constraints, workspace policy, state guards and the service operation under test must remain real. Recording a provider or queue call must not replace the submission, claim or outcome logic being checked.
