# Docs - [The field guide](/docs): Aviary is a habitat of plug-n-play, fully-configurable libraries for NestJS, published under @dudousxd. - Agent: A governed AI agent for NestJS — chat + tools + RBAC + quota + HITL, each turn an optionally-durable workflow. - [Agent](/docs/agent): A governed AI agent for NestJS — chat, tool-calling, per-tool RBAC, token quota, cost tracking, and human-in-the-loop approval, with each turn optionally a replay-safe durable workflow and wired into the ecosystem's durable, telescope, and diagnostics glue. - [Getting Started](/docs/agent/getting-started): Stand up a governed AI agent in a NestJS app — install, declare a tool, register the module, and stream your first turn. - Concepts - [Architecture](/docs/agent/concepts/architecture): The library is mechanism — the loop, tool registry, RBAC, quota, cost, audit, HITL, streaming; your domain is policy you supply through a fixed set of SPIs. - [The agent loop](/docs/agent/concepts/the-agent-loop): One turn is model → tools → model, bounded by maxSteps, with a usage row appended every time the model is called. - [Runners](/docs/agent/concepts/runners): One AgentRunner SPI, two implementations — inline runs in-process by default, durable is an opt-in that checkpoints every step and turns HITL approval into a real suspend. - [Governance](/docs/agent/concepts/governance): Four layers stack on every turn — who's calling and what they may do, how many tokens they've spent today, what it cost, and an audit trail of everything that happened. - Guides - [Tools](/docs/agent/guides/tools): Declaring agent tools with @AiTool — the decorator surface, read vs action, the ToolHandler interface, and the per-invocation context. - [Identity & Authorization](/docs/agent/guides/identity-and-authorization): How the agent learns who is calling (ActorResolver, with no insecure default) and decides — per tool, server-side — whether they may run it (roles vs abilities). - [Human-in-the-loop & Durability](/docs/agent/guides/human-in-the-loop-and-durability): Action tools pause for a human decision — and under the durable runner that pause is a real durable signal, so the run suspends in the state store and resumes on approval, surviving restarts. - [Multi-agent](/docs/agent/guides/multi-agent): Declare named agents as @Agent classes, let an orchestrator hand off to sub-agents via handoff, and run each delegation as a durable child run. - [RAG](/docs/agent/guides/rag): Ground the agent in your documents — agentic retrieval as a tool (default) or always-on prompt injection, with citations flowing through the tool-call mechanism. - [Cost & Governance](/docs/agent/guides/cost-and-governance): The usage ledger and read-model — spend per model and actor, a gateway's reported cost preferred over a cache-aware estimate, daily quota, and the console that surfaces it all. - [Persistence](/docs/agent/guides/persistence): The AgentStore SPI — threads, messages, tool calls, and a token-usage ledger — behind one ORM-portable interface, wired on MikroORM or Drizzle. - [Frontend](/docs/agent/guides/frontend): Wire a React chat UI to the agent with useAgentChat — the AI SDK v7 transport, threads, quota, cancel, HITL approve/reject, and styling-agnostic components. - [Bring your own UI](/docs/agent/guides/bring-your-own-ui): The package ships no components by design — build a chat entirely on useAgentChat, AgentChatTransport, and the stored-history mappers, owning every pixel yourself. - [Governed SQL](/docs/agent/guides/governed-sql): Give the model read-only SQL access without handing it the database — AST-validated single SELECTs, a fail-closed table allowlist, per-tenant rewriting, and a row cap, all before your runner touches the DB. - Packages - [Packages](/docs/agent/packages): The full nestjs-agent package set — core, the NestJS module, the model adapter, stores, the React frontend, governed SQL, the dashboard, and the ecosystem glue points. - [@dudousxd/nestjs-agent-core](/docs/agent/packages/core): The framework-agnostic agent loop, tool registry, and every SPI a provider, store, or dashboard implements against. - [@dudousxd/nestjs-agent](/docs/agent/packages/nestjs): The umbrella NestJS module — AgentModule, @AiTool discovery, provideAgentTool, the inline runner, HeaderActorResolver, and the /durable subpath. - [@dudousxd/nestjs-agent-ai-sdk](/docs/agent/packages/ai-sdk): aiSdkModel adapts any Vercel AI SDK v7 LanguageModel to the ModelProvider SPI — streaming, tool-call translation, cache-aware usage, and gateway cost, with zero provider code. - [@dudousxd/nestjs-agent-react](/docs/agent/packages/react): useAgentChat, the AgentChatTransport and AgentClient, styling-agnostic chat components, dictation, and the markdown subpath. - [@dudousxd/nestjs-agent-data](/docs/agent/packages/data): createExecuteSqlTool — governed, read-only SQL as a prebuilt tool. AST-validated single SELECTs, a fail-closed table allowlist, tenant scoping, and a row cap. - [@dudousxd/nestjs-agent-rag](/docs/agent/packages/rag): Retrieval-Augmented Generation — chunking, ingestion, an embedding-backed Retriever, and in-memory + pgvector stores. Framework-agnostic, core-only dep. - [@dudousxd/nestjs-agent-rag-media](/docs/agent/packages/rag-media): Auto-ingest nestjs-media uploads into agent RAG — extract, chunk, embed, index, owner-scoped, delete-synced. Couples via the diagnostics channel, no hard media dependency. - [@dudousxd/nestjs-agent-dashboard](/docs/agent/packages/dashboard): A standalone AI-gateway governance console — bundled React SPA + JSON/SSE API mounted at its own route, no Telescope required — plus a dependency-free client subpath. - [@dudousxd/nestjs-agent-store-mikro-orm](/docs/agent/packages/store-mikro-orm): MikroORM AgentStore adapter — threads, messages, tool calls, usage, and run reliability — with safe auto-schema. - [@dudousxd/nestjs-agent-store-drizzle](/docs/agent/packages/store-drizzle): Drizzle AgentStore adapter — threads, messages, tool calls, usage, and run reliability — over an app-owned SQLite-dialect handle. - [@dudousxd/nestjs-agent-transport-redis](/docs/agent/packages/transport-redis): RedisTokenStreamSink — a TokenStreamSink over Redis for multi-replica deployments, so a token stream started on one pod is subscribable and resumable from any other. - [@dudousxd/nestjs-agent-telescope](/docs/agent/packages/telescope): Telescope extension that adds an "Agent" tab — live runs + tool calls off diagnostics, historical spend off the governance read-model. - [@dudousxd/nestjs-agent-authz](/docs/agent/packages/authz): Adapts a @dudousxd/nestjs-authz Gate to the agent's RolesPolicy SPI, so ability-gated tools run through your app's real authz policies. - [@dudousxd/nestjs-agent-codegen](/docs/agent/packages/codegen): A @dudousxd/nestjs-codegen extension that injects a typed api.agent.* client for the agent's JSON REST routes into your generated api.ts. - [@dudousxd/nestjs-agent-testing](/docs/agent/packages/testing): In-memory store, governance queries, quota, token sink, and a deterministic fake model — the whole agent loop, offline. - Recipes - [Recipes](/docs/agent/recipes): Copy-pasteable cookbook for @dudousxd/nestjs-agent — a hand-rolled ModelProvider, flipping the inline runner to durable, DI-powered functional tools, a billing export off the governance read-model, and exercising the whole loop offline. - [Custom ModelProvider](/docs/agent/recipes/custom-model-provider): Implement the ModelProvider SPI by hand for a gateway or client aiSdkModel doesn't cover — stream text deltas to the sink, translate the endpoint's tool-call events, and never execute a tool yourself. - [Inline → durable](/docs/agent/recipes/inline-to-durable): Durable is the production default — dispatchedSteps routes every model/tool call as a checkpointed, worker-served step the moment durable is true. This recipe covers getting to durable: true, and the dispatchedSteps: false escape hatch for a simple in-process case. - [Functional tools with DI](/docs/agent/recipes/functional-tools-with-di): Register a tool that needs constructor-injected dependencies without a class — provideAgentTool(factory, inject) resolves it through Nest's container and returns { spec, handler }, auto-discovered at boot exactly like an @AiTool class. - [Billing export](/docs/agent/recipes/billing-export): Inject AGENT_GOVERNANCE_QUERIES and build your own CSV/JSON spend export off the same read-model the standalone dashboard and Telescope tab consume — the interface and the diagnostics channel are both public. - [Offline testing](/docs/agent/recipes/offline-testing): Exercise the whole agent loop — chat, tool calling, HITL approval — with @dudousxd/nestjs-agent-testing's in-memory doubles. No API key, no Redis, fully deterministic. - Reference - [Configuration](/docs/agent/reference/configuration): The full AgentModule.forRoot() options reference, forRootAsync, and how @Agent-decorated classes register into the AgentRegistry. - [Endpoints](/docs/agent/reference/endpoints): The REST + SSE surface mounted by AgentModule (default /agent) and the dashboard JSON API mounted by AgentDashboardModule (default /ai-gateway/api). - [Diagnostics events](/docs/agent/reference/diagnostics-events): The aviary:agent:* diagnostics_channel events published by @dudousxd/nestjs-agent-core, with exact payload shapes. - [DI tokens](/docs/agent/reference/di-tokens): The Symbol.for(...) injection tokens exported by @dudousxd/nestjs-agent-core, what they resolve to, and who binds them. - Authz: Laravel-style Gates & Policies for NestJS — a zero-dependency authorization core. - [Authz](/docs/authz): Laravel-style Gates & Policies for NestJS — a zero-dependency authorization core. - [Getting Started](/docs/authz/getting-started): Install @dudousxd/nestjs-authz, register the module, write your first policy, guard a route, and check abilities programmatically. - [Policies](/docs/authz/policies): Resource policy classes — ability methods, the before bypass hook, class-level abilities, registration, and the PolicyRegistry. - [Gates](/docs/authz/gates): Ad-hoc, model-less abilities — define, allows, authorize, forUser, and the BoundGate API. - [Enforcement](/docs/authz/enforcement): Declarative authorization with @Can and the CanGuard, role checks with @Roles and the RolesGuard, and the optional can-endpoint controller. - [Current user](/docs/authz/current-user): How the gate resolves the current user — the context accessor, the UserRef hydration caveat, resolveUser, forUser, and anonymous handling. - [Resource resolution](/docs/authz/resource-resolution): How @Can loads the instance it passes to your policy — the default IdParamResourceResolver, the RESOURCE_RESOLVER token, and writing a custom ORM-backed resolver. - [RBAC (roles & permissions)](/docs/authz/rbac): The opt-in, persisted roles-and-permissions layer — coarse @Roles checks in the core, and database-backed providers via the typeorm / mikro-orm / prisma adapters. - [Ecosystem & integrations](/docs/authz/ecosystem): The glue packages that make authz disappear into your stack — context, Inertia, codegen, React, Telescope, and the filter integration. - Codegen: Typed client artifacts with pluggable validators (zod/valibot/arktype). - [Codegen](/docs/codegen): A typed-client codegen for NestJS — routes, API client, and validation schemas, generated from your controllers. - [Getting Started](/docs/codegen/getting-started): Wire the module into your NestJS app and generate a typed client. - [Configuration](/docs/codegen/configuration): Every option in nestjs-codegen.config.ts. - [CLI](/docs/codegen/cli): The codegen, init, and doctor commands. - [OpenAPI Export](/docs/codegen/openapi): Emit a valid OpenAPI 3.1 openapi.json from your discovered routes + validation IR. - [Mock Handlers (MSW)](/docs/codegen/mocks): Emit deterministic Mock Service Worker handlers shaped to your response schemas — no faker dependency. - Validation - [Pluggable Validation](/docs/codegen/validation): zod, valibot, or arktype from one neutral schema IR. - [Forms](/docs/codegen/validation/forms): forms.ts — a validation schema per validated endpoint. - Client - [API Client](/docs/codegen/client/api-client): The createApi(fetcher) factory and how to use it. - [Fetcher & Transports](/docs/codegen/client/fetcher): createFetcher, custom transports (axios), and serializers (superjson). - [Receiving array query params](/docs/codegen/client/array-query-params): Why ParseArrayPipe 400s the single-value case, and the safe string | string[] pattern (with @QueryList). - [TanStack Query](/docs/codegen/client/tanstack-query): queryOptions / mutationOptions from your framework adapter. - [Routes](/docs/codegen/client/routes): routes.ts — typed route names, params, and a route() helper. - Integrations - [Extensions](/docs/codegen/integrations/extensions): Register integrations via extensions, and write your own. - [nestjs-inertia](/docs/codegen/integrations/inertia): Pages, shared props, and Inertia router navigation. - [nestjs-filter](/docs/codegen/integrations/filters): Typed query filters from @FilterFor / @ApplyFilter. - Reference - [Programmatic API](/docs/codegen/reference): Generate from a build script without the CLI. - Context: Shared AsyncLocalStorage context for NestJS — user, tenant and traceId across the request. - [Introduction](/docs/context): A shared AsyncLocalStorage context for NestJS that carries user, tenant and traceId across the whole request — and across the ecosystem. - [Getting Started](/docs/context/getting-started): Install nestjs-context, register the global module, read the traceId anywhere, and populate the user and tenant from your auth guard. - [The Store](/docs/context/the-store): The ContextStore shape, why it carries a UserRef instead of the full user, the always-present traceId invariant, and how to add your own typed fields. - [Customization](/docs/context/customization): The five levels of customizing nestjs-context — custom fields, populating values, non-HTTP entrypoints, the cross-process carrier, and swapping the accessor. - [Cross-Process](/docs/context/cross-process): Carry the context across queue and durable boundaries with serialize() and deserialize() — the hard part that justifies the library. - [Testing](/docs/context/testing): Run unit tests inside a fake context store with runWithContext and enterContext from the nestjs-context-testing package. - Diagnostics: A vendor-neutral diagnostics channel for the NestJS ecosystem — emit once, observe anywhere. - [Introduction](/docs/diagnostics): A vendor-neutral diagnostics channel for the NestJS ecosystem — emit once, observe anywhere. - [Getting Started](/docs/diagnostics/getting-started): Install the package, emit diagnostic events, and correlate them with a trace id. - [Consumers](/docs/diagnostics/consumers): Observe diagnostic events from anywhere — Telescope, OpenTelemetry, an APM, a logger, or your own subscriber. - Durable: Durable, resumable cross-app workflows for NestJS. - [Durable](/docs/durable): Durable workflows for NestJS — write a workflow as plain code; every step is checkpointed, so it survives crashes and deploys. Steps can run across apps and languages, with a built-in control plane. - [Getting Started](/docs/durable/getting-started): Run your first durable workflow in an existing NestJS app — install the module, write a workflow, register it, and start a run. Zero infrastructure with the event-emitter transport. - [Comparison](/docs/durable/comparison): How nestjs-durable compares to Temporal, Inngest, and BullMQ — what the suspend-model library approach buys you, and when a dedicated orchestration cluster or a managed platform is the better call. - Concepts - [Concepts](/docs/durable/concepts): The mental model behind the engine — why replay is the durability mechanism, what a workflow and a step actually are, how a run waits for hours without holding a process, and whose runs a pool executes. - [Durability & replay](/docs/durable/concepts/durability): How checkpoint-and-replay makes a workflow survive crashes — and the one rule it imposes. The workflow body must be deterministic; all side effects live in steps. - [Workflows & steps](/docs/durable/concepts/workflows-and-steps): Declaring workflows with @Workflow, the one dispatched ctx.step primitive and its @Step handlers, retries and backoff, fan-out, ctx.continueAsNew for long-running loops, fatal errors, sub-process events, step interceptors, tags, and search attributes. - [Sleep & signals](/docs/durable/concepts/sleep-and-signals): Pause a workflow durably — ctx.sleep for time-based waits (minutes to months, no compute) and ctx.waitForSignal for human approvals and webhooks, both surviving restarts. - [Tenancy](/docs/durable/concepts/tenancy): What namespace and partition actually partition, how a store-less tenant borrows the control plane's store over the transport, and the boundary that keeps each tenant to its own runs. - Authoring - [Authoring](/docs/durable/authoring): Everything you compose a real workflow out of — child workflows, durable entities, events, queries and updates, webhooks and external tasks, versioning, and scheduling. - [Child workflows](/docs/durable/authoring/child-workflows): Compose workflows by calling other workflows — await a child's result with ctx.child, kick one off fire-and-forget with ctx.startChild, or fan out N children of the same workflow and wait for all with ctx.all. Pass the workflow class for a typed input and result, or a name string for a cross-runtime child. - [Durable entities](/docs/durable/authoring/entities): Keyed, long-lived virtual objects — @Entity + @On declare per-key state and its operations; ctx.callEntity/signalEntity or EntityService drive them, serialized per key, exactly once. - [Event-driven workflows](/docs/durable/authoring/events): publishEvent(name, payload) starts every @Workflow({ onEvent }) subscriber and resumes any run parked on ctx.waitForEvent — with optional debounce/batch coalescing for bursty sources. - [Queries & updates](/docs/durable/authoring/queries-and-updates): Reading a live run's state with ctx.setEvent + engine.getEvent (side-effect-free queries), and steering it with ctx.onUpdate + engine.registerUpdateValidator + engine.update (validated, Temporal-style updates that can be rejected before they touch the run). - [Durable webhooks](/docs/durable/authoring/webhooks): ctx.webhook() mints a durable callback handle with a deterministic token and a public url; hand the url to a third party inside a step, then await handle.wait() to suspend with zero compute until the callback arrives as engine.signal(token, body). ctx.task() is the general form for external work you deliver and complete yourself, with no callback URL. - [Versioning & determinism](/docs/durable/authoring/versioning): Keeping in-flight runs replay-safe across code changes — workflow versions for breaking changes, the NonDeterminismError guard, the deterministic now/random/uuid sources, and ctx.patched for guarding an in-place change without a new version. - [Scheduling](/docs/durable/authoring/scheduling): Recurring workflows with ScheduledWorkflow — fixed intervals via everyMs or DST-aware cron via cron + timezone — fired each tick by the NestJS module's schedules option, started exactly once per window by an idempotent time-bucket run id. - Reliability - [Reliability](/docs/durable/reliability): How nestjs-durable keeps long-running work correct in the face of transient failures, crashes and overload — step retries, saga compensation, durable flow-control queues and the dead-letter queue. - [Retries & backoff](/docs/durable/reliability/retries): Durable step retries with fixed/exponential backoff and jitter (a failed step re-dispatches on a persisted wakeAt), FatalError and worker-side retryable:false to opt out, and the in-memory timeoutMs + heartbeat liveness path for presumed-dead workers. - [Sagas & compensation](/docs/durable/reliability/sagas): Undo a dispatched step's side effects with a compensate ref/name that receives a StepUndo envelope, retried per the undo's own @Step config and checkpointed at negative seqs for crash-safe resume — plus the ctx.localStep closure form, compensationRetries, compensate: visibility, and compensating cancellation via engine.cancel(runId, { compensate: true }). - [Flow control](/docs/durable/reliability/flow-control): Every knob that throttles or prioritizes dispatched steps: durable queues (concurrency caps + fixed-window rate limits) via engine.registerQueue, per-call priority + fairnessKey on ctx.step, worker/transport concurrency (fixed or adaptive), and RedisAdmissionBackend for a fleet-wide global cap. - [Singleton workflows](/docs/durable/reliability/singleton): @Workflow({ singleton }) serializes runs that share a key — a durable, FIFO mutex: at most limit run concurrently per key, the rest wait (suspended) and admit in creation order as slots free, with an optional maxQueueDepth back-pressure cap that rejects a start with SingletonQueueFullError instead of letting the same-key backlog grow forever. - [Dead-letter queue](/docs/durable/reliability/dead-letter): Cap crash-recovery with maxRecoveryAttempts so a poison-pill run moves to the terminal dead status instead of crash-looping forever, then route dead runs with engine.onDead or a DLQ workflow — an inline @DeadLetter() method, a per-workflow deadLetterWorkflow reference, or the module-level default — to alert, compensate, or queue for review. - [Run retention & pruning](/docs/durable/reliability/retention): The module's retention option hard-prunes terminal run history (completed/failed/cancelled/dead) on an interval via StateStore.pruneTerminalRuns, per disjoint RetentionPolicy rules (maxAge and/or maxCount) — without it, run history is kept forever by default and the durable tables grow unbounded. - Transports - [Overview](/docs/durable/transports): How steps travel to workers. From an in-process event-emitter for zero-infra single-process handlers, to BullMQ/Redis, SQS, and a broker-less SQL transport for cross-process and cross-language steps. - [BullMQ / Redis](/docs/durable/transports/bullmq): The queue-backed transport for cross-process and cross-language steps. Each step name gets its own tasks queue; results return on a shared results queue. Run one instance engine-side, one per worker. - [AWS SQS](/docs/durable/transports/sqs): The queue-backed transport on AWS SQS. Same RemoteTask/StepResult contract as BullMQ — tasks go to a per-group queue, results return on a shared queue — so Node and Python workers interoperate. - [SQL (database)](/docs/durable/transports/db): A broker-less, DBOS-style transport — dispatched steps are rows in the database you already run. Workers claim tasks with SELECT … FOR UPDATE SKIP LOCKED. The table + claim contract is documented so Node and Python workers share it. - State stores - [Overview](/docs/durable/stores): Where durable state lives. A StateStore interface with MikroORM, TypeORM, Prisma and Drizzle adapters that run on Postgres, MySQL, SQLite or libSQL, an in-memory store for tests, and auto-schema on boot (opt-out, with a migration helper). - [MikroORM](/docs/durable/stores/mikro-orm): The reference StateStore adapter. Register the durable entities with your MikroORM config, pass the ORM to MikroOrmStateStore, and run on Postgres, MySQL or SQLite — with auto-schema on boot or an ensure* helper for your own migration. - [TypeORM](/docs/durable/stores/typeorm): The TypeORM StateStore adapter. Register the durable entities on your DataSource, pass it to TypeOrmStateStore, and run on Postgres, MySQL/MariaDB or SQLite — with auto-schema on boot or an ensureTypeOrmDurableSchema helper for your own migration. - [Prisma](/docs/durable/stores/prisma): The Prisma StateStore adapter. Add the durable models to your schema.prisma, prisma generate, and pass your PrismaClient to PrismaStateStore. Schema is owned by Prisma Migrate — there is no auto-schema. - [Drizzle](/docs/durable/stores/drizzle): The Drizzle StateStore adapter for SQLite / libSQL (Turso, edge). Build your drizzle db with the package's schema and pass it to DrizzleStateStore. Schema is owned by drizzle-kit — no auto-schema. - Observability - [Observability](/docs/durable/observability): Seeing what your workflows are doing — the embedded control-plane dashboard, OpenTelemetry spans, dependency-free metrics, the Telescope watcher, and the raw diagnostics bus underneath them. - [Control plane](/docs/durable/observability/dashboard): The embedded dashboard — a React SPA served by NestJS that lists runs and renders each one as a graph across local and remote steps, with retry and cancel. - [OpenTelemetry](/docs/durable/observability/otel): One span per step, one root span per run's first turn. Bridge the engine's lifecycle events to OpenTelemetry and see workflows in Jaeger, Grafana or Datadog. - [Metrics](/docs/durable/observability/metrics): Dependency-free run/step counters and duration percentiles — feed a /metrics route or a Prometheus scrape endpoint, with nothing but the engine's own lifecycle events. - [Telescope](/docs/durable/observability/telescope): Surface workflow runs and steps inside nestjs-telescope, alongside your app's requests, queries and jobs. - [Diagnostics channel](/docs/durable/observability/diagnostics): Bridge every durable engine lifecycle event onto the node diagnostics-channel bus, so any @OnDiagnostic subscriber sees runs and steps alongside your app's other channels — additive to OTel and Telescope. - **Cluster** - Cluster: Split the API from the engine, run store-less thin workers, route per tenant, and share one control plane across languages. - [Topologies](/docs/durable/cluster): Run durable in one process, split the control plane from the workers, or spread store-less thin workers per tenant — the same engine over the same wire, selected by which options a process is given. - [Roles & config](/docs/durable/cluster/roles-and-config): The topology preset on DurableModule.forRoot, the RunGateway surface every shape shares, and layered tenant authentication for a store-less fleet. - [Node worker](/docs/durable/cluster/js-worker): Author and run a store-less Node worker with @dudousxd/durable-worker — the JS counterpart to the Python client. Register @Step/@Workflow bodies on a DurableWorkerRuntime and drive them with runRedisWorker, with fixed or adaptive concurrency. - [Handshake & negotiation](/docs/durable/cluster/handshake): How a mixed fleet stays version-safe — workers advertise a capability descriptor, the control plane negotiates compatibility, and work routes only to workers that can run it. Runs park blocked instead of hanging. - [Cross-ecosystem interop](/docs/durable/cluster/interop): Run NestJS, Adonis, and Python workers on one durable control plane. The BullMQ transport is the shared wire, so a step dispatched by a NestJS engine can execute on a Python or Adonis worker and flow back. - **Guides** - [Patterns](/docs/durable/patterns): A cookbook of common durable-workflow shapes — human approval, webhook confirmation, batch fan-out, cron digests, booking sagas, rate-limited APIs, and long-lived pollers — each a short, self-contained recipe with a link to the full page. - [Running in production](/docs/durable/production): The operational checklist for taking nestjs-durable from a single dev process to a real deployment — durable store and transport, multi-replica crash recovery, the dead-letter cap, graceful shutdown, replay-safe deploys, flow control, tenancy isolation, retention, observability, and schema management. - [Troubleshooting](/docs/durable/troubleshooting): Symptom-first answers to the errors and stuck states you'll actually hit — NonDeterminismError, a caught suspend that corrupts a run via a missing isWorkflowControlFlowSignal guard, a run wedged in pending or suspended, SignalTimeoutError, dead-lettered runs, MySQL collation clashes, and an empty dashboard. - **Cross-language** - [Python](/docs/durable/python): Python is a first-class durable runtime. Implement steps a TypeScript workflow calls, OR author whole workflows in Python that the engine drives — both over the same Redis wire, with the engine owning durable state. - **Tooling** - Tooling - [Overview](/docs/durable/tooling): The two build-time tools — a lint rule set that catches non-determinism inside a workflow body before it ever runs, and a codegen extension that emits a typed client for the dashboard's REST API. - [Linting for non-determinism](/docs/durable/tooling/linting): Catch Date.now(), Math.random(), new Date() and crypto.randomUUID() inside a @Workflow run at author time with @dudousxd/nestjs-durable-eslint-plugin — shipped for both ESLint (flat config) and Biome (GritQL plugin). - [Typed dashboard client](/docs/durable/tooling/codegen): Generate a fully-typed client (and TanStack hooks) for the durable dashboard's REST API — list/inspect runs, retry, cancel, deliver webhooks — with the nestjsDurableCodegen extension for @dudousxd/nestjs-codegen. - [Testing](/docs/durable/testing): Unit-test workflows with an in-memory engine harness, crash/flaky-step injection, and replay assertions — no Postgres, no Redis, no real time. - [CLI](/docs/durable/cli): Inspect and cancel workflow runs from the terminal with `durable inspect` and `durable cancel`. - **Reference** - [API reference](/docs/durable/api-reference): Every public member of WorkflowCtx, the authoring decorators, WorkflowService, the WorkflowEngine's selected surface, DurableModuleOptions, the thrown error classes, and the run/checkpoint status enums — one line each, distilled from source. - Filter: A query filter language with ORM adapters and a typed client. - [Filter](/docs/filter): Declarative, ORM-agnostic filter classes for NestJS — turn query strings into safe, validated database queries. - [Getting Started](/docs/filter/getting-started): Add declarative filtering to a NestJS project in minutes — install, define a filter, register the module, and go. - Guides - [Filter Classes](/docs/filter/guides/filter-classes): Writing filter classes — validated mode, lean mode, setup(), $query, $input, $context, and advanced features. - [Computed fields](/docs/filter/guides/computed): Virtual/derived columns backed by a SQL expression — @Computed methods, correlated subqueries, SELECT projection with project true, and codegen typing. - [Controller Integration](/docs/filter/guides/controllers): Using @ApplyFilter in controllers — method-aware source resolution, custom sources, dynamic filter selection, and error handling. - [Using Filters in Services](/docs/filter/guides/repositories): How to apply filters programmatically in services using @ApplyFilter (controller) and FilterRunner.apply() (service). - [Cursor Pagination](/docs/filter/guides/cursor-pagination): Stable keyset (seek) pagination with FilterRunner.findPage() — opaque before/after cursors, multi-column sort with a primary-key tiebreaker. - [Relation Filtering](/docs/filter/guides/relations): Cross-entity filtering with @Relations — delegate input keys to related entity filters via ORM joins. - [Full-Text Search](/docs/filter/guides/full-text-search): Global search — ILIKE across string columns, or a Postgres tsvector column via websearch_to_tsquery with optional ts_rank relevance ordering. - [Group-by-count](/docs/filter/guides/group-by-count): A terminal aggregation mode over a primary-entity column — SELECT col, COUNT(*) GROUP BY col, with an optional parameterized numeric bucket — the typed way to feed charts and histograms. - [Multi-Tenancy](/docs/filter/guides/multi-tenancy): Automatic tenant scoping with @TenantScoped(field) — WHERE tenantId = current-tenant, wired through the @dudousxd/nestjs-context accessor. - [Input Validation](/docs/filter/guides/validation): class-validator integration, filter-as-DTO pattern, ValidationMode, FilterExceptionFilter, and FilterInput type helper. - [Spatie / JSON:API Input](/docs/filter/guides/spatie-input): Opt into spatie-laravel-query-builder / JSON:API query strings — filter[field][op]=, sort=-a,b, include=, fields[type]=, page[after]= — parsed into the native model. - [Async Configuration](/docs/filter/guides/async-configuration): Configure FilterModule with FilterModule.forRootAsync — useFactory, useClass, and useExisting to derive options from ConfigService or other providers. - [Testing](/docs/filter/guides/testing): FilterTestingModule, makeMockQueryBuilder, unit testing filters, integration testing with real databases, and Docker Compose setup. - [Generic Operators](/docs/filter/guides/operators): Operator-based filtering with ColumnFilter, 22 operators, query string bracket notation, body format, AND/OR composition, and security. - [Typed Client (nestjs-codegen)](/docs/filter/guides/codegen): Generate a type-safe filterQuery() builder for your filter endpoints with the @dudousxd/nestjs-filter-codegen extension for nestjs-codegen. - [React](/docs/filter/guides/react): useFilterTable, useFilterQuery, and useFilterQueryUrl — the React adapter for the filter-query builder, with nuqs URL sync and TanStack Query/Table interop. - Inertia: TypeScript-first Inertia.js adapter — multi-app, Vite-native. - [Inertia](/docs/inertia): A TypeScript-first Inertia.js adapter for NestJS — multi-app, Vite-native, with a Tuyau-style typed client. - [Getting Started](/docs/inertia/getting-started): Add Inertia.js to an existing NestJS project in minutes -- install the packages, run nestjs-inertia init, and you're done. - Guides - [Installation](/docs/inertia/guides/installation): Install nestjs-inertia packages with pnpm, npm, or yarn, and understand peer dependencies. - [Codegen](/docs/inertia/guides/codegen): Static analysis of your NestJS controllers that emits typed pages, routes, and a full API client surface. Zero runtime cost. - [Typed Client](/docs/inertia/guides/typed-client): Auto-generated type-safe API client with queryOptions, mutationOptions, and queryKey for every controller endpoint. Zero configuration. - [Typed Link](/docs/inertia/guides/typed-link): Type-safe Link components for React, Vue 3, and Svelte with route-name autocomplete and conditional routeParams. - [Forms & Validation](/docs/inertia/guides/forms): The full round-trip — the typed useForm hook on the client, class-validator DTOs on the server, and the InertiaValidationFilter that flashes a field-keyed error bag back into form.errors, byte-for-byte aligned with your field names. - [Multi-App (forFeature)](/docs/inertia/guides/multi-app): Run multiple independent Inertia apps inside the same NestJS process using forFeature. - [Testing](/docs/inertia/guides/testing): Use expectInertia, InertiaTestingModule, and assertInertia to test NestJS Inertia controllers. - Recipes - [Auth Redirect Guard](/docs/inertia/recipes/auth-redirect): A production-ready NestJS guard that sends 302 for plain browser requests and 409 X-Inertia-Location for Inertia XHR — the two-response pattern required by the Inertia protocol. - [File Upload](/docs/inertia/recipes/file-upload): Upload files via FormData using the codegen fetcher — the right pattern when @UploadedFile() makes mutationOptions() impractical. - [Using with setGlobalPrefix](/docs/inertia/recipes/global-prefix): How to serve Inertia pages alongside an existing API that uses NestJS setGlobalPrefix — the middleware gap and how to fix it. - [nestjs-filter Integration](/docs/inertia/recipes/nestjs-filter): Type-safe filter queries with operators, sort, pagination, and search when using @ApplyFilter from nestjs-filter. - [Not Found Filter](/docs/inertia/recipes/not-found): A production-ready NestJS exception filter that renders an Inertia component on 404 for page requests and returns structured JSON for API routes. - Packages - [@dudousxd/nestjs-inertia (core)](/docs/inertia/packages/core): Core NestJS module, @Inertia decorator, InertiaService, and version negotiation. - [@dudousxd/nestjs-inertia-vite](/docs/inertia/packages/vite): Vite plugin and dev-server middleware bridge for NestJS. - [@dudousxd/nestjs-inertia-codegen-extension](/docs/inertia/packages/codegen): The Inertia extension for @dudousxd/nestjs-codegen — adds a typed navigate() helper to the generated api.ts. - [@dudousxd/nestjs-inertia-client](/docs/inertia/packages/client): Typed HTTP client, route naming, components, and SSR hydration. - [@dudousxd/nestjs-inertia-testing](/docs/inertia/packages/testing): expectInertia, InertiaTestingModule, and assertion helpers for testing NestJS Inertia controllers. - Reference - [Architecture](/docs/inertia/reference/architecture): Package responsibilities, dependency graph, and request lifecycle for nestjs-inertia. - [Changelog](/docs/inertia/reference/changelog): Links to per-package changelogs and the monorepo CHANGELOG. - Media: Filesystem + media-library in one package — disks, resumable uploads, attachments, conversions. - [Media](/docs/media): Filesystem and media-library for NestJS in one package — the Laravel/spatie feel for files. Disk-agnostic storage, resumable uploads, entity attachments, and image conversions, all wired into the ecosystem's diagnostics, codegen, and React glue points. - [Getting Started](/docs/media/getting-started): Install nestjs-media, wire MediaModule with a disk + store, attach your first file, and serve it back — in about five minutes. - Concepts - [The two layers](/docs/media/concepts/two-layers): Storage (layer 1) is a disk-agnostic filesystem; media-library (layer 2) attaches files to entities on top of it. How they relate, and why they're split. - [Uploads & multipart](/docs/media/concepts/uploads): Resumable proxy uploads (tus) vs direct presigned uploads, the uploadMode that picks between them, and the engine underneath. - [Conversions](/docs/media/concepts/conversions): Image conversions generated lazily on first access or eagerly on upload, via a pluggable processor (sharp by default). - [Folders & prefix navigation](/docs/media/concepts/folders): Object stores have no real folders — only keys. How media fakes them — the delimiter rollup that turns a flat key space into a navigable tree (ListResult.folders / ListOptions.delimiter), and the dashboard folder feature (create, delete, move, copy) built on top of it. - [Persistence](/docs/media/concepts/persistence): The MediaStore contract, how the media table is shaped, and the non-destructive auto-schema convention shared across ORM adapters. - [Attachments (column model)](/docs/media/concepts/attachments): The adonis-attachment-style persistence model — a file stored as a JSON value object on your own entity's column, instead of in a separate media table. When to reach for it, the Attachment value object, the AttachmentManager API, and how each ORM serializes it. - [Diagnostics & the glue points](/docs/media/concepts/diagnostics): Media emits to nestjs:media:* diagnostics channels with zero coupling; Telescope, Codegen, and React plug in from there. - Packages - [Overview](/docs/media/packages): The full nestjs-media package set — core, the NestJS module, the browser client, disks, ORM stores, the image engine, and the ecosystem glue points. - [@dudousxd/nestjs-media-core](/docs/media/packages/core): The framework-agnostic heart — SPIs, the storage facade, the media-library, the upload engine, and diagnostics. No NestJS dependency. - [@dudousxd/nestjs-media](/docs/media/packages/nestjs): The umbrella package — MediaModule, MediaService, the tus controller, and the /storage subpath. - [@dudousxd/nestjs-media-client](/docs/media/packages/client): The framework-agnostic browser client — one implementation of the resumable tus upload, plus a URL helper. - [@dudousxd/nestjs-media-disk-local](/docs/media/packages/disk-local): The local filesystem driver, with a path-traversal guard. - [@dudousxd/nestjs-media-disk-s3](/docs/media/packages/disk-s3): The S3 driver — presigned URLs + native multipart, works with any S3-compatible endpoint. - [@dudousxd/nestjs-media-image-sharp](/docs/media/packages/image-sharp): The default ImageProcessor, backed by sharp. - [@dudousxd/nestjs-media-database-typeorm](/docs/media/packages/database-typeorm): TypeORM media store with non-destructive auto-schema. - [@dudousxd/nestjs-media-database-mikro-orm](/docs/media/packages/database-mikro-orm): MikroORM media store with safe auto-schema. - [@dudousxd/nestjs-media-database-drizzle](/docs/media/packages/database-drizzle): Drizzle media store (sqlite), migration-first. - [@dudousxd/nestjs-media-database-prisma](/docs/media/packages/database-prisma): Prisma media store — consumer-managed schema, structural client typing. - [@dudousxd/nestjs-media-telescope](/docs/media/packages/telescope): Telescope watcher that surfaces media events in the observability console. - [@dudousxd/nestjs-media-codegen](/docs/media/packages/codegen): Codegen extension that emits a typed media client next to your generated api.ts. - [@dudousxd/nestjs-media-react](/docs/media/packages/react): React hook + uploader component for resumable uploads. - [@dudousxd/nestjs-media-upload-redis](/docs/media/packages/upload-redis): A Redis-backed UploadSessionStore — share resumable (tus/proxy) upload sessions across instances. - [@dudousxd/nestjs-media-testing](/docs/media/packages/testing): In-memory driver/store/session + reusable conformance suites. - [@dudousxd/nestjs-media-dashboard](/docs/media/packages/dashboard): Standalone /media console — disks, live uploads, and the media library, with your choice of auth. - Recipes - [Overview](/docs/media/recipes): Task-shaped walkthroughs — the common media jobs (avatars, galleries, browser uploads, serving, multi-disk) and the extension points (custom driver, custom store, testing). - [Single-file avatar](/docs/media/recipes/avatar): A single-file collection that replaces the previous image on each upload, with MIME validation. - [Gallery with thumbnails](/docs/media/recipes/gallery): A multi-file collection with lazy + eager image conversions, ordering, and a clean render shape. - [Resumable uploads from the browser](/docs/media/recipes/direct-s3-upload): Wire the tus server and upload large files directly from React with progress and resume. - [Serving files](/docs/media/recipes/serving-files): Public URLs, signed temporary URLs, and streaming files through a controller. - [Multiple disks](/docs/media/recipes/multi-disk): Register several disks and route collections (or individual uploads) to the right one. - [Writing a custom disk driver](/docs/media/recipes/custom-driver): Implement the StorageDriver contract for any backend, and verify it with the shared conformance suite. - [Writing a custom store](/docs/media/recipes/custom-store): Implement the MediaStore contract for any persistence backend, verified by the shared conformance suite. - [Consuming storage from another library](/docs/media/recipes/mail-attachments): How a sibling library (mail attachments, durable steps) uses the filesystem layer through the /storage subpath. - [Testing your media code](/docs/media/recipes/testing): Unit-test services that use MediaService with in-memory doubles — no filesystem, DB, or containers. - [Raw storage (no entities)](/docs/media/recipes/raw-storage): Use the filesystem layer alone — for generated files, caches, or other libraries. - Reference - [Configuration](/docs/media/reference/configuration): Every MediaModule option, the MediaService surface, and the injection tokens — in one place. - [Changelog](/docs/media/reference/changelog): Release history for the nestjs-media packages. - Notifications: Laravel-style notifications — one notification, many channels. - [Notifications](/docs/notifications): Laravel-style notifications for NestJS — define a notification once and deliver it across many channels (mail, database, Slack) and real-time transports (SSE, WebSocket), synchronously or queued. - [Getting Started](/docs/notifications/getting-started): Send your first notification in an existing NestJS app — install the core and a channel, write a notification class, and call send(). Synchronous by default; add a queue when you're ready. - Concepts - [Overview](/docs/notifications/concepts): The model in nine pieces — what a notifiable and a notification are, the channel/dispatcher split, and the behaviours layered on top — async delivery, tenancy, attribution, guards, fallbacks and locales. - [Notifiables](/docs/notifications/concepts/notifiables): A notifiable is anything that can receive a notification. Declare per-channel addresses with @RouteFor decorators and mark the id with @NotifiableId — no routeNotificationFor switch, no manual toNotifiableRef. - [Notifications](/docs/notifications/concepts/notifications): A notification is a plain class. Annotate each payload method with the channel handle — @Mail(), @Database() — and via() is inferred automatically. No magic strings; add the channel interface for compile-time type safety when you want it. - [Channels & Dispatchers](/docs/notifications/concepts/channels-and-dispatchers): The two pluggable abstractions at the heart of the library. Channels decide how a notification leaves; dispatchers decide where and when it is processed. They are independent. - [Async dispatch](/docs/notifications/concepts/async-dispatch): How a notification and its recipient survive the trip to a worker — notifications serialize to { name, data }, notifiables to a { type, id } reference rebuilt by resolveNotifiable. - [Multi-tenancy](/docs/notifications/concepts/multi-tenancy): The same user lives in many workspaces, each with its own feed. Scope any send to one tenant or fan out to many with forTenant — tenant flows into storage, the read API, and per-tenant channel config. - [Context capture (causer attribution)](/docs/notifications/concepts/context-capture): Capture who triggered a notification — the causer, tenant, and trace id — at send() time and thread it through lifecycle events, the async carrier, and the database row. Integrates @dudousxd/nestjs-context; degrades to a no-op when it's absent. - [Dispatch guards](/docs/notifications/concepts/dispatch-guards): Dedup (idempotency) and throttle (rate-limit) a notification before any channel runs. Opt in per notification with idempotencyKey() and throttle(); back them with an in-memory or Redis store. - [Fallback chains](/docs/notifications/concepts/fallback-chains): Deliver a notification down an ordered chain of channels — push first, escalate to SMS, then email — stopping at the first that reaches the recipient. Opt in per notification with fallback(). - [Localization (i18n)](/docs/notifications/concepts/localization): Translate each notification per recipient. Resolve a locale off the notifiable, look strings up in a catalog (or your own translator), and render channel payloads in the recipient's language with localization.t(). - Channels - [Channels](/docs/notifications/channels): A channel is a transport — mail, database, Slack, and the real-time SSE / WebSocket channels. Import a channel's module and it registers itself; the notification's to() method shapes the payload. - [Mail](/docs/notifications/channels/mail): Send email notifications. A fluent MailMessage builder, an HTML + text renderer, and a swappable transport — nodemailer SMTP out of the box. - [Database](/docs/notifications/channels/database): Persist notifications so you can show an in-app feed. A NotificationStore interface, a bundled in-memory store, and TypeORM / MikroORM / Prisma adapters. - [Broadcast](/docs/notifications/channels/broadcast): Push notifications to the browser in real time over socket.io. Each notifiable gets its own room; pair it with the database channel for a live in-app feed. - [Slack](/docs/notifications/channels/slack): Post notifications to Slack via an incoming webhook or the Web API. A fluent SlackMessage builder with text, Block Kit blocks, and attachments. - [Discord](/docs/notifications/channels/discord): Post notifications to Discord via an incoming webhook. A fluent DiscordMessage builder with plain content and rich embeds, routed per notifiable. - [Telegram](/docs/notifications/channels/telegram): Send notifications through the Telegram Bot API. Return a plain string or a fluent TelegramMessage with a parse mode, routed to a chat id per notifiable. - [Microsoft Teams](/docs/notifications/channels/teams): Post notifications to Microsoft Teams via an incoming webhook. A fluent TeamsMessage builder for MessageCards, or post a custom Adaptive Card, routed per notifiable. - [Server-Sent Events](/docs/notifications/channels/sse): Push notifications to the browser over native NestJS Server-Sent Events. This channel feeds an SseHub; you mount the stream with Nest's own @Sse() decorator — tenant-aware. - [Webhook](/docs/notifications/channels/webhook): Deliver notifications as an HTTP request to any endpoint. Return a plain object for a JSON POST, or a fluent WebhookMessage for full control over url, method, and headers. - [SMS](/docs/notifications/channels/sms): Text a notification through a pluggable SMS transport. Ships with a Twilio transport; return a plain string or a fluent SmsMessage, and route the recipient per notifiable. - [Push](/docs/notifications/channels/push): Send push notifications through Web Push, Firebase Cloud Messaging, or Expo. Pick one transport, build a PushMessage, and route to one device token or many. - Dispatchers - [Dispatchers](/docs/notifications/dispatchers): A dispatcher decides where and when a notification is processed — inline now, or on a worker later. The default is synchronous; opt into async per notification with shouldQueue and swap the driver in forRoot. - [Event emitter](/docs/notifications/dispatchers/event-emitter): In-process, fire-and-forget async on a later tick. No queue, no serialization, no resolveNotifiable — the simplest way to move delivery off the request without any infrastructure. - [BullMQ](/docs/notifications/dispatchers/bullmq): Out-of-process delivery on a BullMQ worker, reusing your app's existing @nestjs/bullmq and Redis connection. Jobs serialize, enqueue with retry and backoff, and rehydrate on the worker. - [Redis](/docs/notifications/dispatchers/redis): A dedicated notification worker without BullMQ. The dispatcher pushes serialized jobs onto a Redis list; a long-running worker drains it with a blocking BRPOP loop and isolates per-job failures. - Recipes - [Recipes](/docs/notifications/recipes): Task-focused guides for the things you actually reach for — on-demand sends, queueing end-to-end, writing your own channel, and wiring up Telescope. - [On-demand notifications](/docs/notifications/recipes/on-demand): Send to a raw address — an email, a Slack webhook, a phone number — without a Notifiable entity. Use notifications.route(channel, value).notify(notification) for one-off and ops alerts. - [Queued notifications](/docs/notifications/recipes/queued-notifications): Move delivery off the request, end to end — set shouldQueue, register the notification and resolveNotifiable, and pick a dispatcher. The call site never changes. - [Real-time & in-app](/docs/notifications/recipes/realtime-in-app): nestjs-notifications is also your real-time delivery layer. Persist with the database channel, push live with SSE or WebSocket, and consume in React — the whole in-app notification loop, and how to pick SSE vs WebSocket. - [In-app notifications](/docs/notifications/recipes/in-app-notifications): Build an in-app feed from persisted notifications. Inject NotificationsQueryService to list, count, and mark read — or mount the optional REST controller in one call. - [React inbox widget](/docs/notifications/recipes/react-inbox): Drop a notification inbox into a React app with one component. The @dudousxd/nestjs-notifications-react package ships , a NotificationsProvider, and the useNotifications / useUnreadCount hooks — all consuming the read API and SSE stream you already expose. - [Headless SDK & TanStack Query](/docs/notifications/recipes/headless-sdk): A framework-neutral client for the inbox API + SSE — fetch functions, a live subscribe(), and TanStack Query option factories that work in React and Vue. For frontends separate from the backend. - [Live unread badge](/docs/notifications/recipes/live-badge): A notification bell whose unread count updates the instant a notification arrives — SSE pushes the change, no polling. Combine the SSE channel with the unread count from the database channel. - [Live / progress notifications](/docs/notifications/recipes/progress-notifications): Some notifications evolve — an export going 0% → 100%, a job that flips from "running" to "done". Update a single notification row in place across sends with a stable databaseKey, instead of spamming a new row each time. - [Delivery tracking](/docs/notifications/recipes/delivery-tracking): Persist the real per-channel delivery status — sent, failed, delivered, bounced — not just the in-memory SendResult. The delivery-tracking package records every send and updates it from Twilio / SES status webhooks. - [Typed client with codegen](/docs/notifications/recipes/codegen): Generate a fully typed HTTP client for the inbox API from your NestJS controllers using nestjs-codegen — no hand-written fetch calls, no drift between server and client. - [Channel preferences](/docs/notifications/recipes/preferences): Let users mute channels they don't want. Register PreferencesModule, mute/unmute per user (and per tenant), and muted channels are auto-skipped because the package binds the core PreferenceGate. - [Digests & quiet hours](/docs/notifications/recipes/digests-and-quiet-hours): Batch notifications into a daily or weekly summary, and defer delivery during a recipient's quiet hours. Collect suppressed notifications in a pending-digest store and flush them on a schedule. - [Pruning old notifications](/docs/notifications/recipes/pruning): Keep the notifications table from growing forever — schedule automatic deletion of old (or old-and-read) notifications with the database channel's built-in pruner. - [Adopting in an existing app](/docs/notifications/recipes/adopting-existing-app): Already have a notifications table and endpoints? Adopt nestjs-notifications gradually — wrap your table with a custom NotificationStore, route writes through the library, and keep your current API working the whole time. - [Injecting services](/docs/notifications/recipes/injecting-services): Pull a provider into a notification with NestJS's own @Inject. The notification stays new-able with plain data, and the library fills the service from the Nest container at delivery time — sync and queued. - [Writing a custom channel](/docs/notifications/recipes/custom-channel): Implement a ChannelDriver and the library discovers it automatically. Build an SMS channel end to end — the driver, a type-safe notification interface, and a global module. - [Telescope integration](/docs/notifications/recipes/telescope): Record every notification delivery in the nestjs-telescope dashboard with one watcher. It listens to the events the core already emits — no monkey-patching, no call-site changes. - [Diagnostics integration](/docs/notifications/recipes/diagnostics): Put every notification on the Aviary diagnostics bus with one import. React to send/sent/failed across the ecosystem via @OnDiagnostic or getChannel — typed, no call-site changes. - Reference - [Overview](/docs/notifications/reference): The full API surface — every module option, the lifecycle events and error policy, and the fake plus assertions you test against. - [Configuration](/docs/notifications/reference/configuration): Every NotificationsModule.forRoot and forRootAsync option, the three lifecycle events, the error policy, and the error classes — the full reference for wiring the core. - [Testing](/docs/notifications/reference/testing): Assert what your code would send without delivering anything. The @dudousxd/nestjs-notifications-testing package gives you a NotificationFake with Laravel-style assertions and a RecordingChannel for end-to-end tests. - Resilience: Composable timeout, retry, circuit-breaker and failover policies — with a pluggable, distributed breaker store. - [Resilience](/docs/resilience): Composable resilience policies for NestJS — timeout, retry, circuit breaker and failover, with a pluggable distributed circuit-breaker store. - [Getting Started](/docs/resilience/getting-started): Install nestjs-resilience, wrap a flaky call with a composed policy, then register the module and use it through dependency injection. - [Policies](/docs/resilience/policies): The policy engine — timeout, retry with backoff, circuit breaker, wrap composition, and the list-oriented failover primitive, plus the typed errors they throw. - [Decorators & Module](/docs/resilience/nest): Wrap provider methods with @Timeout / @Retry / @CircuitBreaker, register named policies through ResilienceModule, and run them via ResilienceService. - [Stores](/docs/resilience/stores): Share circuit-breaker state across instances with a pluggable ResilienceStore — in-memory by default, or Redis / Postgres / SQLite adapters that coordinate the half-open probe atomically. - [Integrations](/docs/resilience/integrations): Emit state transitions over nestjs-diagnostics, mirror them onto @nestjs/event-emitter, and make breaker keys tenant-aware through nestjs-context — all soft-detected and optional. - [Telescope dashboard](/docs/resilience/telescope): Add @dudousxd/nestjs-resilience-telescope for a first-class Resilience dashboard in Telescope — open circuits, recent failovers, most-tripped keys, and a live table of transitions — recorded straight off the diagnostics channels. - [Testing](/docs/resilience/testing): Drive time deterministically with FakeClock so timeouts, backoff and cooldowns are instant and reproducible — and validate a custom store against the shared contract suite. - Telescope: Telescope-style observability console with watchers + dashboard. - [Telescope](/docs/telescope): Laravel Telescope, redesigned for NestJS — a headless observability console that correlates every request, query, job, mail, cache hit, and exception under one batch, with a pluggable store and an optional dashboard. - [Getting Started](/docs/telescope/getting-started): Mount the Telescope dashboard in an existing NestJS app — install core + ui, import two modules, and open /telescope. Zero-config SQLite by default; swap the storage adapter when you're ready. - Concepts - [Capture & correlation](/docs/telescope/concepts/capture): How watchers, batches, and AsyncLocalStorage turn scattered events into one navigable flow — the request and everything it caused, in capture order. - [Storage](/docs/telescope/concepts/storage): The StorageProvider SPI, the zero-config SQLite default, self-healing schema, and the adapter table — your DB, your store, the same contract everywhere. - [Performance](/docs/telescope/concepts/performance): Why capture doesn't slow your app — request capture off the response path, ~microsecond query capture, rollup-backed reads, and the /health endpoint that surfaces Telescope's own cost. - [CPU profiling](/docs/telescope/concepts/profiling): On-demand V8 CPU flamegraphs — strictly opt-in, off by default, with a headless "profile the next N requests" API and a uniform sampled mode, aggregated into a bounded flame tree the dashboard renders. - [MCP server](/docs/telescope/concepts/mcp): An optional Model Context Protocol server at /telescope/api/mcp — stateless JSON-RPC over streamable HTTP so coding agents (Claude Code, Cursor, …) can debug straight from the captured data. - [Extensions](/docs/telescope/concepts/extensions): A declarative SPI for packaging watchers, a navigable entry type, dashboard pages, and server-side data providers into one installable unit — the fixed UI renders the spec, the extension ships no React. - Dashboard - [Dashboard tour](/docs/telescope/dashboard): The optional dashboard — overview and pulse health, entries per type, traces, the Horizon-style live queue console with default-deny mutations, and schedules. - [Dashboard auth](/docs/telescope/dashboard/auth): Gate the Telescope dashboard so only your logged-in admins see it — all the way to prod, no infra required. Two modes, one signed-cookie mechanism, both copy-pasteable. - Packages - [Packages](/docs/telescope/packages): The full suite — core, the dashboard, watchers, storage adapters, queue managers, the OpenTelemetry bridge, the AI exception diagnoser, and test utilities. Install only what your stack needs. - [@dudousxd/nestjs-telescope (core)](/docs/telescope/packages/core): The core module — request + exception watchers, the recorder, ALS correlation, the zero-config SQLite store, the headless API, the gate, and the pruner. - [@dudousxd/nestjs-telescope-ui (dashboard)](/docs/telescope/packages/ui): The bundled dashboard SPA served by a NestJS module — plus the composable React components, hooks, and typed client to build your own admin. - [Watchers](/docs/telescope/packages/watchers): Query watchers (MikroORM, TypeORM, Prisma) and behavioral watchers (mail, cache, schedule, events, logs, redis, model) — each a small package you add to the watchers array. - [Storage adapters](/docs/telescope/packages/storages): Persist Telescope entries in your own database (MikroORM — MySQL/SQLite) or share one store across replicas (Redis). Same StorageProvider contract everywhere. - [Queue managers](/docs/telescope/packages/queue-managers): Horizon-style live queue consoles — BullMQ (browse + retry/remove/promote/retry-all) and SQS (depth + DLQ inspection + redrive), all behind a default-deny mutation gate. - [@dudousxd/nestjs-telescope-otel](/docs/telescope/packages/otel): OpenTelemetry trace-context provider — stamp every captured entry with the active traceId/spanId so a Telescope batch maps 1:1 to a trace. - [@dudousxd/nestjs-telescope-observe](/docs/telescope/packages/observe): Forward Telescope entries to NestJS Observe — requests as snapshots, everything they caused as child spans, jobs and logs alongside. - [@dudousxd/nestjs-telescope-ai](/docs/telescope/packages/ai): AI-powered exception diagnosis — turn a captured exception into a markdown triage report (probable cause, where to look, suggested fix, confidence) using the Vercel AI SDK with any provider. - [@dudousxd/nestjs-telescope-testing](/docs/telescope/packages/testing): Test utilities — a deterministic FakeClock, a no-NestJS watcher harness, and the in-memory storage provider re-exported for tests. - Recipes - [Recipes](/docs/telescope/recipes): Copy-pasteable cookbook for extending Telescope — a custom storage adapter, custom watchers, dashboard login, custom tags and redaction, request-context capture, archiving to S3 before prune, reporting frontend errors, and AI exception diagnosis. - [Custom storage adapter](/docs/telescope/recipes/custom-storage): Persist Telescope entries in a store no shipped adapter covers — implement the StorageProvider SPI end to end, with the keyset-pagination contract and the optional RollupStore add-on. - [Custom watcher](/docs/telescope/recipes/custom-watcher): Capture a source Telescope doesn't ship a watcher for — a tiny WebSocket-events watcher built on ctx.record(), and the real instrument(emit, ctx) escape hatch for a bespoke cache, both correlated to the request that caused them. - [Building an extension](/docs/telescope/recipes/building-an-extension): Package a watcher, a navigable entry type, a server-side data provider, and a declarative dashboard page into one installable Telescope extension — step by step, using the durable workflows surface as the worked example. - [Capture @nestjs/axios traffic](/docs/telescope/recipes/capturing-axios): HttpClientWatcher patches global fetch out of the box, but @nestjs/axios calls bypass it. Wire the axios source to capture HttpService and plain axios instances too — no monkey-patching. - [Dashboard login & sessions](/docs/telescope/recipes/dashboard-auth): Practical dashboardAuth — login mode validating against your own user table with bcrypt, session mode bridging an existing JWT, and role-gating queue mutations via request.telescopeSession. - [Custom tags & redaction](/docs/telescope/recipes/tags-and-redaction): Tag entries by tenant from a captured header, mask extra fields with redact.keys/paths and a custom mask, drop noisy entries with filter, and sample high-volume types. - [Request context for your routes](/docs/telescope/recipes/request-context): Capture the authenticated user on each request with resolveUser, keep capture working under setGlobalPrefix via telescopeRequestCapture, and drop ad-hoc debug dumps with telescopeDump. - [Archiving exceptions to S3](/docs/telescope/recipes/archiving-exceptions-to-s3): Export exception entries to Amazon S3 before the pruner deletes them, using the archive.sink hook and @aws-sdk/client-s3 — host-side code; Telescope itself stays dependency-free. - [Reporting frontend errors](/docs/telescope/recipes/reporting-frontend-errors): Turn Telescope into your frontend error reporter — a public ingestion endpoint browsers POST to, recorded as client_exception entries that compose with new-exception alerts, prune, archive and the dashboard. Endpoint config, security knobs, a fetch/sendBeacon snippet, and a react-error-boundary integration. - [AI exception diagnosis](/docs/telescope/recipes/ai-exception-diagnosis): Add an AI "probable cause" to every exception — a Diagnose with AI button in the dashboard, plus optional auto-mode that enriches new-exception alerts. Works with Bedrock, OpenAI, Anthropic, or any Vercel AI SDK model. - Reference - [Configuration](/docs/telescope/reference/configuration): The full TelescopeModule.forRoot() options reference — capture, storage, the gate, retention, alerts, AI, CPU profiling, the MCP server, and overload protection. - [Changelog](/docs/telescope/reference/changelog): Per-package changelogs and the release process — versioned with Changesets, published from CI. - [Telescope vs NestJS Observe](/docs/telescope/reference/vs-nestjs-observe): An honest side-by-side with the official @nestjs/observe SDK and its hosted dashboard — what each one captures, where each one wins, and how to send Telescope entries to Observe.