Agent usage guide
This guide covers published @nestarc/outbox 0.3.0. Start with npm ls @nestarc/outbox @nestjs/core @nestjs/schedule @prisma/client in the consuming application. Repository main can contain fixes that are not in the installed package; compare against the 0.3.0 README and tagged source.
Build a working integration
- Use PostgreSQL and the supported Node/Nest/Prisma combination from installation. Prisma 7's PostgreSQL adapter needs
pgeven when notifications are disabled. - Apply the package's complete fresh-install SQL before starting the app. For an upgrade, stop all old pollers and apply
upgrade-to-current.sql; never overlap 0.2 and 0.3 workers. - Register an injectable Prisma provider. Use
forRootAsync()with exporting dependency modules when the transport or tenant provider has injected dependencies. PuttransportandtenantProviderat the top level of the async registration. - Write business data and call
OutboxEmitter.emit(tx, event, options)inside the same Prisma transaction. A call using an independent client does not provide the same atomicity. - Register local decorated handlers as Nest providers, or select
delivery.mode: 'publisher'with anOutboxPublisher. Preserve the event ID, payload, and metadata through the broker; consumers must deduplicate side effects. - Keep periodic polling enabled. Enable
app.enableShutdownHooks()for signal-driven cleanup; the poller waits up to 30 seconds and does not forcibly cancel callbacks. - Verify a committed event reaches
SENT, a rolled-back transaction leaves neither business data nor an event, and a failed callback retries before reachingFAILED.SENTacknowledges local handlers or the publisher, not downstream completion.
Import runtime values and types from @nestarc/outbox. The supported SQL exports are @nestarc/outbox/src/sql/create-outbox-table.sql and @nestarc/outbox/src/sql/upgrade-to-current.sql; do not import internal dist/** paths. For full signatures, use the installed .d.ts files and published API reference.
Published 0.3.0 limitations
| Area | Consumer guidance |
|---|---|
| Wakeups without polling | Startup can succeed if the notification client connects, but notifications do not schedule future retries, exhaust backlog, or replay missed messages. Keep polling.enabled: true. |
| Admin cursor pagination | listPage() loses PostgreSQL sub-millisecond timestamp precision and can skip rows at a page boundary. Do not use it for exhaustive exports; preserve the full database timestamp and ID in an application-owned query. |
| Configuration checks | Validation is not exhaustive at startup. An invalid tenancy.policy can reach emit-time OUTBOX_INVALID_ENVELOPE; use typed options and documented values. |
| Ordering and uniqueness | Delivery is at-least-once and has no global, aggregate, partition, or batch FIFO guarantee. partitionKey controls routing; idempotencyKey is metadata and does not create an outbox uniqueness constraint. |
| Tenant administration | Authenticate and authorize the tenant before calling OutboxTenantAdminService.forTenant(). OutboxOperatorService is privileged and global. |
These are limitations of the published release. Do not assume fixes in repository main exist in an installed 0.3.0 package.
Reference and verification paths
- Installation, SQL, shutdown, and complete provider registration
- Local handlers and callback behavior
- Broker publishers with preserved event identities
- Delivery lifecycle and guarantees
- Version-pinned consumer fixtures
- Fixture runner and database requirements
The tagged fixtures demonstrate the published README and include a notification-only scenario that proves immediate notification delivery, not durable recovery without polling. The fixture harness creates and drops tables in its documented disposable database; follow its setup before running it. Its broker is a recording double, so verify real broker acknowledgements and consumer deduplication in your application as well.