Skip to content

feat(reporting): add a transactional notification outbox and account activity projection #1168

Description

@bokelley

Summary

The SDK has generated reporting webhook payloads (ReportingDeliveryReadyWebhook, ReportingStatusChangedWebhook, and ReportingLedgerChangedWebhook) and durable generic webhook sender/supervisor primitives, but ReportingProducer/the reporting ledger has no transactional event or outbox seam connecting committed ledger changes to those publishers.

An adopter that sends after commit can lose a notification on process crash. Sending before commit can publish an event for state that never committed. Reimplementing this bridge in every seller defeats the reliability feature.

The same missing integration prevents honest advertisement of supports_webhook_activity: AdCP expects retained, account-scoped delivery attempts to be returned by list_accounts(include_webhook_activity=true), not merely the ability to make an HTTP request.

Desired SDK behavior

  • Persist a reporting notification/outbox record atomically with the ledger transition it describes.
  • Map committed transitions to the generated reporting webhook payloads with stable notification IDs and idempotency keys.
  • Dispatch through the existing hardened sender/supervisor, including tenant-scoped signing resolution.
  • Retain delivery attempts and expose an account-scoped projection/helper suitable for list_accounts webhook activity.
  • Supply capability helpers/boot validation so supports_webhook_activity and reporting webhook support are advertised only when the durable components are configured.

An adopter-owned callback may remain as an escape hatch, but the PostgreSQL happy path should not require a second transaction or custom queue implementation.

Acceptance criteria

  • Revision, adjustment, issue/status, and materialization transitions enqueue the appropriate notification in the same transaction as the ledger mutation.
  • Crash-after-commit and crash-before-commit tests prove no lost or ghost notifications.
  • Worker retries preserve the immutable body and idempotency identity while allowing a fresh valid signature.
  • Duplicate worker turns and unchanged status do not emit duplicate logical notifications.
  • Delivery attempts are retained, account-isolated, paginatable/bounded, and projectable into list_accounts(include_webhook_activity=true).
  • Capability construction fails closed or omits activity support when durable event/attempt storage is absent.
  • In-memory components exist for tests; PostgreSQL components support multi-worker leasing.
  • One end-to-end fixture commits a reporting revision, emits a signed webhook, records a failed/retried/successful attempt, and reads the activity back for only the authorized account.

Adopter impact

This is what lets a buyer-side agent ask “has this publisher sent reporting automatically?” and lets a seller proactively notify/ping the buyer without building an unreliable parallel event system around the SDK ledger.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions