This skill creates a backend design brief through structured conversation. It is the server-side counterpart to design-brief. Skip any question the codebase already answers — read first, then ask only what is unresolved.
Example prompts
- "Write a backend brief for the notifications service"
- "Plan the backend for the checkout flow"
- "I need to think through the data model and auth before building this API"
- "Backend brief: a job queue that processes uploaded videos"
Process
Ask the user for a one-paragraph description of what they want to build, who/what calls it, and any constraints they already have in mind (latency, region, compliance, expected scale).
Explore the existing codebase to learn what is already decided. Scan specifically for:
Fastify-specific (check first, since this is the primary stack)
fastify in package.json and the server entry (often server.ts, app.ts, src/server.ts)
- Plugin tree: every
fastify.register(...) call and any files using fastify-plugin (fp(...)) — these define the encapsulation boundaries
- Route definitions:
fastify.get/post/put/delete, fastify.route({...}), route schemas (schema: { body, querystring, params, response })
- Schema strategy: raw JSON Schema,
@sinclair/typebox, fastify-type-provider-zod, or @fastify/type-provider-typebox
- Hooks in use:
onRequest, preParsing, preValidation, preHandler, preSerialization, onSend, onResponse, onError
- Decorators:
fastify.decorate(...), fastify.decorateRequest(...), fastify.decorateReply(...) — these reveal cross-cutting concerns (auth context, db handle, current user)
- Common ecosystem plugins already wired up:
@fastify/cors, @fastify/helmet, @fastify/rate-limit, @fastify/jwt, @fastify/cookie, @fastify/session, @fastify/multipart, @fastify/static, @fastify/swagger, @fastify/under-pressure, @fastify/auth, @fastify/oauth2, @fastify/websocket
- Logger config: Pino is the default — check
logger: { ... } options, transport, redaction config, log level per environment
- Error handling:
setErrorHandler, setNotFoundHandler, custom error classes
- Server lifecycle:
fastify.ready(), fastify.listen(...), graceful shutdown (closeWithGrace, @fastify/graceful-shutdown)
Other backends (scan if Fastify isn't present, or to identify hybrid setups)
- Express, NestJS, Koa, Hapi, FastAPI, Django, Rails, Go (chi/gin/echo), tRPC routers, GraphQL servers (Apollo, Mercurius — note Mercurius is Fastify-native)
ORM / schema
- Prisma (
schema.prisma), Drizzle (schema.ts, drizzle.config.ts), Kysely, TypeORM, MikroORM, raw SQL with postgres/pg
- Migrations directory and how migrations are run (Prisma Migrate, Drizzle Kit, custom)
Datastores
- Postgres (most common with Fastify), MySQL, SQLite, MongoDB, Redis (
@fastify/redis or ioredis directly), DynamoDB
- Connection pool config — Fastify benefits a lot from sized pools tied to plugin lifetime
Async / jobs
- BullMQ (often paired with Fastify via Redis), Inngest, Trigger.dev, Temporal, raw cron, webhook receivers
Caching
- Redis, in-memory (
@fastify/caching, lru-cache), HTTP cache headers, edge cache
Deployment / runtime
Dockerfile, docker-compose.yml, fly.toml, railway.toml, render.yaml, Kubernetes manifests
- Serverless adapters:
@fastify/aws-lambda, @fastify/serverless — note Fastify is happier as a long-running process than as a per-request lambda
Observability
- Pino transports (
pino-pretty in dev, pino-loki/pino-datadog in prod), @fastify/under-pressure for load shedding, OpenTelemetry instrumentation (@opentelemetry/instrumentation-fastify), Sentry (@sentry/node with Fastify integration), healthcheck routes
Config / secrets
@fastify/env with JSON Schema validation, dotenv, secret managers, feature flag clients
- If a frontend brief or IA exists at
.design/<slug>/DESIGN_BRIEF.md or INFORMATION_ARCHITECTURE.md, read it. The data model and routes must serve those flows.
- Treat what exists as the starting vocabulary. Extend, don't replace.
Interview the user on each unresolved area below. Ask one question at a time. For each, propose a recommended answer and explain the tradeoff so the user can push back. Skip any area the codebase scan answered definitively.
Data model
- What are the core entities and how do they relate?
- Which fields are required vs. optional? Which are derived?
- What are the natural unique constraints and indexes?
- What is the expected row count per entity in 1 month, 1 year?
- Soft delete vs. hard delete? Audit trail needed?
Auth model
- Who calls this? (end users, internal services, third-party integrations)
- Authentication: sessions, JWT, API keys, OAuth, mTLS?
- Authorization: role-based, attribute-based, resource-scoped, multi-tenant isolation?
- What is the blast radius if a credential leaks?
Fastify shape (skip if not Fastify)
- Plugin boundaries: which concerns are isolated plugins (auth, db, business domain) vs. flat in the root scope?
- Schema strategy: raw JSON Schema, TypeBox, or Zod via
fastify-type-provider-zod? Pick one and stick to it — mixing is painful.
- Where does validation happen: route schema (preferred — Fastify compiles it),
preValidation hook, or downstream service?
- Decorators planned for cross-cutting state:
request.user, request.tenantId, fastify.db, fastify.cache?
- Error handling: one global
setErrorHandler mapping to RFC 7807 problem details, or per-plugin error handlers?
- Logger: keep Pino default, or wire a transport (loki, datadog, otel)? What gets redacted?
Scale & latency targets
- p50 / p95 / p99 latency budget for the hot path?
- Requests per second at launch, in 6 months, at the ceiling we'd celebrate?
- Read-heavy, write-heavy, or balanced?
- Geographic distribution of callers?
Consistency requirements
- Strong consistency, read-your-writes, or eventual consistency acceptable?
- Where are transactions required? Where can we tolerate retries / idempotency keys instead?
- Any operations that must be exactly-once vs. at-least-once?
Deployment target
- Serverless, long-running container, edge runtime, or VM?
- One region or multi-region? Cold-start tolerance?
- How are migrations applied? Zero-downtime requirements?
- Blue/green, canary, or rolling deploys?
Observability
- What signals tell us this is healthy? (latency, error rate, queue depth, business metrics)
- What gets logged at info vs. error? Any PII redaction needed?
- Tracing across services? Sampling rate?
- Alerts: who gets paged, on what threshold?
Once you have a complete picture, write the brief using the template below.
File Output
Save the brief to .design/<feature-slug>/BACKEND_DESIGN.md, using the same <feature-slug> as any existing frontend brief in .design/. If no .design/ folder exists yet, create one and pick a slug derived from the feature name (e.g., notifications-service, checkout-api, video-processor).
If a DESIGN_BRIEF.md already exists in the chosen subfolder, cross-reference it: the data model and API should serve the flows and components named there.
Example:
.design/
└── checkout-api/
├── DESIGN_BRIEF.md (if frontend brief exists)
└── BACKEND_DESIGN.md ← this skill produces this
Brief Template
# Backend Design: [Service / Feature Name]
## Problem
What this backend exists to do, framed by the calling context (which frontends, jobs, or external systems depend on it and why). Not implementation detail — purpose.
## Solution Sketch
The shape of the solution in plain terms: what kind of system this is (CRUD API, event processor, job runner, gateway), and the one or two architectural choices that define it.
## Callers & Consumers
| Caller | Pattern | Auth method | Notes |
| ----------------- | -------------------- | ----------- | ----- |
| [frontend / svc] | [request/response, webhook, subscribe] | [session, JWT, API key] | [rate, criticality] |
## Data Model
### Entities
For each entity: fields, types, required/optional, indexes, relationships.
EntityName
├── id [pk, type]
├── field_a [type, required, indexed]
├── field_b [type, optional]
└── relations [foreign keys / joins]
### Invariants
Business rules the schema must enforce (uniqueness, referential integrity, state machines, allowed transitions). Note which are enforced at the DB layer vs. application layer and why.
### Growth & Retention
Expected size per entity at 1 month, 1 year. Retention policy (keep forever, archive after N, hard delete after N).
## API Surface
| Method | Path | Purpose | Auth | Idempotent? |
| ------ | ---- | ------- | ---- | ----------- |
| GET | /... | ... | ... | yes |
| POST | /... | ... | ... | no (use idempotency key) |
For non-trivial endpoints, sketch request/response shape inline.
## Fastify Architecture (if applicable)
- **Plugin tree**: how the app is decomposed into plugins and which use `fastify-plugin` to escape encapsulation.
- **Schema/validation**: chosen strategy (JSON Schema / TypeBox / Zod) and where it lives.
- **Decorators**: cross-cutting state attached to `fastify`, `request`, `reply`.
- **Hooks**: which lifecycle hooks are used and for what (auth in `preHandler`, audit in `onResponse`, etc.).
- **Error handling**: shape of the error response, where `setErrorHandler` lives.
- **Logger**: Pino config, transports per environment, redaction list.
## Auth Model
- **Authentication**: [mechanism — sessions/JWT/API keys/OAuth/mTLS, where credentials live, rotation policy]
- **Authorization**: [model — RBAC/ABAC/resource-scoped, who can do what]
- **Tenancy**: [single-tenant, multi-tenant with row-level isolation, multi-tenant with separate DBs]
- **Threat model notes**: [what we worry about — credential leak, replay, IDOR, enumeration]
## Scale & Latency Targets
| Metric | Target | Notes |
| ---------------- | ----------------- | ----- |
| p50 latency | [ms] | [hot path / cold path] |
| p95 latency | [ms] | |
| p99 latency | [ms] | |
| RPS at launch | [n] | |
| RPS ceiling | [n] | |
| Read:write ratio | [e.g. 90:10] | |
## Consistency Model
What guarantees we promise and where. Call out:
- Operations that need ACID transactions
- Operations safe under eventual consistency
- Idempotency strategy for retried writes (idempotency keys, dedup tables, natural keys)
- Exactly-once vs. at-least-once expectations for async work
## Deployment
- **Runtime**: [serverless / long-running container / edge / VM]
- **Region(s)**: [one / multi, primary, failover]
- **Migrations**: [tool, when applied, zero-downtime requirements, backfill strategy]
- **Rollout**: [blue/green, canary %, rolling, manual]
- **Rollback**: [how, how fast]
## Observability
- **Logs**: [what gets logged, levels, format, PII handling]
- **Metrics**: [the handful that matter — latency, error rate, queue depth, business KPIs]
- **Traces**: [tooling, sampling rate, propagation across services]
- **Alerts**: [signal → threshold → who gets paged]
- **Healthcheck**: [endpoint, what it actually checks]
## Failure Modes
The top 3-5 ways this can go wrong and the chosen response: retry, fail loud, degrade gracefully, queue for later.
| Failure | Response |
| ------------------------ | ------------------------------- |
| [downstream times out] | [retry with backoff, then ...] |
| [DB unavailable] | [...] |
## Out of Scope
Explicit non-goals. Things this brief does not cover so the build stays bounded.
## Open Questions
Anything still unresolved that needs a decision before or during the build.
1---2name: backend-design3description: Create a backend design brief through an interactive interview, codebase exploration, and decisions about data model, auth, scale, consistency, deployment, and observability. Biased toward Fastify (Node) but works for any backend stack. Saved as a markdown file in the project. Use when user wants to plan a backend, design an API, define a data model, mention "backend brief", or pair with a frontend design brief.4---56This skill creates a backend design brief through structured conversation. It is the server-side counterpart to `design-brief`. Skip any question the codebase already answers — read first, then ask only what is unresolved.78## Example prompts910- "Write a backend brief for the notifications service"11- "Plan the backend for the checkout flow"12- "I need to think through the data model and auth before building this API"13- "Backend brief: a job queue that processes uploaded videos"1415## Process16171. Ask the user for a one-paragraph description of what they want to build, who/what calls it, and any constraints they already have in mind (latency, region, compliance, expected scale).18192. Explore the existing codebase to learn what is already decided. Scan specifically for:2021 **Fastify-specific (check first, since this is the primary stack)**22 - `fastify` in `package.json` and the server entry (often `server.ts`, `app.ts`, `src/server.ts`)23 - Plugin tree: every `fastify.register(...)` call and any files using `fastify-plugin` (`fp(...)`) — these define the encapsulation boundaries24 - Route definitions: `fastify.get/post/put/delete`, `fastify.route({...})`, route schemas (`schema: { body, querystring, params, response }`)25 - Schema strategy: raw JSON Schema, `@sinclair/typebox`, `fastify-type-provider-zod`, or `@fastify/type-provider-typebox`26 - Hooks in use: `onRequest`, `preParsing`, `preValidation`, `preHandler`, `preSerialization`, `onSend`, `onResponse`, `onError`27 - Decorators: `fastify.decorate(...)`, `fastify.decorateRequest(...)`, `fastify.decorateReply(...)` — these reveal cross-cutting concerns (auth context, db handle, current user)28 - Common ecosystem plugins already wired up: `@fastify/cors`, `@fastify/helmet`, `@fastify/rate-limit`, `@fastify/jwt`, `@fastify/cookie`, `@fastify/session`, `@fastify/multipart`, `@fastify/static`, `@fastify/swagger`, `@fastify/under-pressure`, `@fastify/auth`, `@fastify/oauth2`, `@fastify/websocket`29 - Logger config: Pino is the default — check `logger: { ... }` options, `transport`, redaction config, log level per environment30 - Error handling: `setErrorHandler`, `setNotFoundHandler`, custom error classes31 - Server lifecycle: `fastify.ready()`, `fastify.listen(...)`, graceful shutdown (`closeWithGrace`, `@fastify/graceful-shutdown`)3233 **Other backends (scan if Fastify isn't present, or to identify hybrid setups)**34 - Express, NestJS, Koa, Hapi, FastAPI, Django, Rails, Go (chi/gin/echo), tRPC routers, GraphQL servers (Apollo, Mercurius — note Mercurius is Fastify-native)3536 **ORM / schema**37 - Prisma (`schema.prisma`), Drizzle (`schema.ts`, `drizzle.config.ts`), Kysely, TypeORM, MikroORM, raw SQL with `postgres`/`pg`38 - Migrations directory and how migrations are run (Prisma Migrate, Drizzle Kit, custom)3940 **Datastores**41 - Postgres (most common with Fastify), MySQL, SQLite, MongoDB, Redis (`@fastify/redis` or ioredis directly), DynamoDB42 - Connection pool config — Fastify benefits a lot from sized pools tied to plugin lifetime4344 **Async / jobs**45 - BullMQ (often paired with Fastify via Redis), Inngest, Trigger.dev, Temporal, raw cron, webhook receivers4647 **Caching**48 - Redis, in-memory (`@fastify/caching`, `lru-cache`), HTTP cache headers, edge cache4950 **Deployment / runtime**51 - `Dockerfile`, `docker-compose.yml`, `fly.toml`, `railway.toml`, `render.yaml`, Kubernetes manifests52 - Serverless adapters: `@fastify/aws-lambda`, `@fastify/serverless` — note Fastify is happier as a long-running process than as a per-request lambda5354 **Observability**55 - Pino transports (`pino-pretty` in dev, `pino-loki`/`pino-datadog` in prod), `@fastify/under-pressure` for load shedding, OpenTelemetry instrumentation (`@opentelemetry/instrumentation-fastify`), Sentry (`@sentry/node` with Fastify integration), healthcheck routes5657 **Config / secrets**58 - `@fastify/env` with JSON Schema validation, `dotenv`, secret managers, feature flag clients59 - If a frontend brief or IA exists at `.design/<slug>/DESIGN_BRIEF.md` or `INFORMATION_ARCHITECTURE.md`, read it. The data model and routes must serve those flows.60 - Treat what exists as the starting vocabulary. Extend, don't replace.61623. Interview the user on each unresolved area below. Ask one question at a time. For each, propose a recommended answer and explain the tradeoff so the user can push back. Skip any area the codebase scan answered definitively.6364 **Data model**65 - What are the core entities and how do they relate?66 - Which fields are required vs. optional? Which are derived?67 - What are the natural unique constraints and indexes?68 - What is the expected row count per entity in 1 month, 1 year?69 - Soft delete vs. hard delete? Audit trail needed?7071 **Auth model**72 - Who calls this? (end users, internal services, third-party integrations)73 - Authentication: sessions, JWT, API keys, OAuth, mTLS?74 - Authorization: role-based, attribute-based, resource-scoped, multi-tenant isolation?75 - What is the blast radius if a credential leaks?7677 **Fastify shape (skip if not Fastify)**78 - Plugin boundaries: which concerns are isolated plugins (auth, db, business domain) vs. flat in the root scope?79 - Schema strategy: raw JSON Schema, TypeBox, or Zod via `fastify-type-provider-zod`? Pick one and stick to it — mixing is painful.80 - Where does validation happen: route schema (preferred — Fastify compiles it), `preValidation` hook, or downstream service?81 - Decorators planned for cross-cutting state: `request.user`, `request.tenantId`, `fastify.db`, `fastify.cache`?82 - Error handling: one global `setErrorHandler` mapping to RFC 7807 problem details, or per-plugin error handlers?83 - Logger: keep Pino default, or wire a transport (loki, datadog, otel)? What gets redacted?8485 **Scale & latency targets**86 - p50 / p95 / p99 latency budget for the hot path?87 - Requests per second at launch, in 6 months, at the ceiling we'd celebrate?88 - Read-heavy, write-heavy, or balanced?89 - Geographic distribution of callers?9091 **Consistency requirements**92 - Strong consistency, read-your-writes, or eventual consistency acceptable?93 - Where are transactions required? Where can we tolerate retries / idempotency keys instead?94 - Any operations that must be exactly-once vs. at-least-once?9596 **Deployment target**97 - Serverless, long-running container, edge runtime, or VM?98 - One region or multi-region? Cold-start tolerance?99 - How are migrations applied? Zero-downtime requirements?100 - Blue/green, canary, or rolling deploys?101102 **Observability**103 - What signals tell us this is healthy? (latency, error rate, queue depth, business metrics)104 - What gets logged at info vs. error? Any PII redaction needed?105 - Tracing across services? Sampling rate?106 - Alerts: who gets paged, on what threshold?1071084. Once you have a complete picture, write the brief using the template below.109110## File Output111112Save the brief to `.design/<feature-slug>/BACKEND_DESIGN.md`, using the same `<feature-slug>` as any existing frontend brief in `.design/`. If no `.design/` folder exists yet, create one and pick a slug derived from the feature name (e.g., `notifications-service`, `checkout-api`, `video-processor`).113114If a `DESIGN_BRIEF.md` already exists in the chosen subfolder, cross-reference it: the data model and API should serve the flows and components named there.115116Example:117118```119.design/120└── checkout-api/121 ├── DESIGN_BRIEF.md (if frontend brief exists)122 └── BACKEND_DESIGN.md ← this skill produces this123```124125## Brief Template126127```markdown128# Backend Design: [Service / Feature Name]129130## Problem131132What this backend exists to do, framed by the calling context (which frontends, jobs, or external systems depend on it and why). Not implementation detail — purpose.133134## Solution Sketch135136The shape of the solution in plain terms: what kind of system this is (CRUD API, event processor, job runner, gateway), and the one or two architectural choices that define it.137138## Callers & Consumers139140| Caller | Pattern | Auth method | Notes |141| ----------------- | -------------------- | ----------- | ----- |142| [frontend / svc] | [request/response, webhook, subscribe] | [session, JWT, API key] | [rate, criticality] |143144## Data Model145146### Entities147148For each entity: fields, types, required/optional, indexes, relationships.149150```151EntityName152├── id [pk, type]153├── field_a [type, required, indexed]154├── field_b [type, optional]155└── relations [foreign keys / joins]156```157158### Invariants159160Business rules the schema must enforce (uniqueness, referential integrity, state machines, allowed transitions). Note which are enforced at the DB layer vs. application layer and why.161162### Growth & Retention163164Expected size per entity at 1 month, 1 year. Retention policy (keep forever, archive after N, hard delete after N).165166## API Surface167168| Method | Path | Purpose | Auth | Idempotent? |169| ------ | ---- | ------- | ---- | ----------- |170| GET | /... | ... | ... | yes |171| POST | /... | ... | ... | no (use idempotency key) |172173For non-trivial endpoints, sketch request/response shape inline.174175## Fastify Architecture (if applicable)176177- **Plugin tree**: how the app is decomposed into plugins and which use `fastify-plugin` to escape encapsulation.178- **Schema/validation**: chosen strategy (JSON Schema / TypeBox / Zod) and where it lives.179- **Decorators**: cross-cutting state attached to `fastify`, `request`, `reply`.180- **Hooks**: which lifecycle hooks are used and for what (auth in `preHandler`, audit in `onResponse`, etc.).181- **Error handling**: shape of the error response, where `setErrorHandler` lives.182- **Logger**: Pino config, transports per environment, redaction list.183184## Auth Model185186- **Authentication**: [mechanism — sessions/JWT/API keys/OAuth/mTLS, where credentials live, rotation policy]187- **Authorization**: [model — RBAC/ABAC/resource-scoped, who can do what]188- **Tenancy**: [single-tenant, multi-tenant with row-level isolation, multi-tenant with separate DBs]189- **Threat model notes**: [what we worry about — credential leak, replay, IDOR, enumeration]190191## Scale & Latency Targets192193| Metric | Target | Notes |194| ---------------- | ----------------- | ----- |195| p50 latency | [ms] | [hot path / cold path] |196| p95 latency | [ms] | |197| p99 latency | [ms] | |198| RPS at launch | [n] | |199| RPS ceiling | [n] | |200| Read:write ratio | [e.g. 90:10] | |201202## Consistency Model203204What guarantees we promise and where. Call out:205- Operations that need ACID transactions206- Operations safe under eventual consistency207- Idempotency strategy for retried writes (idempotency keys, dedup tables, natural keys)208- Exactly-once vs. at-least-once expectations for async work209210## Deployment211212- **Runtime**: [serverless / long-running container / edge / VM]213- **Region(s)**: [one / multi, primary, failover]214- **Migrations**: [tool, when applied, zero-downtime requirements, backfill strategy]215- **Rollout**: [blue/green, canary %, rolling, manual]216- **Rollback**: [how, how fast]217218## Observability219220- **Logs**: [what gets logged, levels, format, PII handling]221- **Metrics**: [the handful that matter — latency, error rate, queue depth, business KPIs]222- **Traces**: [tooling, sampling rate, propagation across services]223- **Alerts**: [signal → threshold → who gets paged]224- **Healthcheck**: [endpoint, what it actually checks]225226## Failure Modes227228The top 3-5 ways this can go wrong and the chosen response: retry, fail loud, degrade gracefully, queue for later.229230| Failure | Response |231| ------------------------ | ------------------------------- |232| [downstream times out] | [retry with backoff, then ...] |233| [DB unavailable] | [...] |234235## Out of Scope236237Explicit non-goals. Things this brief does not cover so the build stays bounded.238239## Open Questions240241Anything still unresolved that needs a decision before or during the build.242```