backend-design — backend low-level design
Design the backend for a feature: read enough of the existing code to ground the design
in real conventions, then write a buildable backend LLD. This is a design artifact, not
code — never edit app code, don't implement, and don't design the frontend. Accuracy over
breadth: cite file:line for every constraint you rely on; don't guess. The cross-repo
contract is not written here — you describe the API/events your stack will expose; the
two LLDs are reconciled into the formal contract separately.
Inputs
Your instructions name what to read — the approved HLD — and the artifact path to write.
Standalone? read the HLD and write the LLD to a path you choose (and tell the user where).
Steps
- Ground in the code (read-only). Locate the service(s) this feature touches and read
the layers that matter — routing/controllers → services/domain → persistence; the data
model and migration tool; existing endpoints/events, DTOs, error envelope, auth/roles,
jobs/queues, external integrations, rate-limit/idempotency patterns, logging/metrics,
tests/fixtures, and the dominant conventions. Capture only what constrains the design,
with
file:line evidence. (No separate map is produced — this understanding feeds the LLD.)
- Component & sequence design — the modules/objects, their responsibilities, and the
call/sequence for each critical path (happy + main error paths); where new code slots in.
- Data model & migration plan — entities, relations, indexes; a concrete
expand → migrate → contract plan with rollback and any backfill of existing rows.
- API/events to EXPOSE — the operations this backend will offer (your side of the
contract): method/path or event/topic, request/response DTOs, status codes, error
envelope, auth + the exact permission per operation, per-field validation, pagination &
limits, rate limits (429 + retry-after), idempotency keys, concurrency/versioning,
backward-compatibility. The formal contract is derived from this separately.
- Threat-model the change (authz per operation, data exposure, abuse); design
observability (logs/metrics/traces for new paths), timeouts/retries/degradation, and
performance considerations.
- Test plan — unit + integration coverage, including the contract's negative paths.
- Write the backend LLD; flag every breaking change in plain language.
- Emit the task DAG — write a
tasks.json (see section below), reusing the code you
already read. No re-reading.
What the backend LLD must cover (write all)
Context & constraints (grounded in the code, cited) · component/sequence design · data model
- migration plan · API/events exposed (the backend's side of the contract) · error handling ·
security & privacy (authz, tenancy, PII, secrets handling) · observability · performance ·
reliability (timeouts, retries, idempotency, partial-failure) · test plan · rollout/backout.
Edge cases the design must define (not leave to the implementer)
- Empty / missing / null inputs; maximum-size and oversized payloads; duplicate submissions.
- Concurrent updates to the same entity; lost-update prevention.
- Partial failure across services; retries and idempotency; timeouts and their fallbacks.
- Pagination boundaries (first/last/empty page, unstable ordering).
- Authz denied, expired token, insufficient scope, cross-tenant access attempts.
- Rate-limit exhaustion; downstream dependency down or slow.
- Migration failure mid-way; backfill of large existing datasets; rollback safety.
- Monorepo vs multi-repo; generated code; vendored/legacy areas; areas with no tests.
External skill (provision — research)
If a suitable deep-research skill is installed you may delegate to it to research unfamiliar
libraries, protocols, or compliance — it must return sourced findings you can cite in the
LLD. Otherwise design from the code + HLD.
Emit tasks.json (the parallel task DAG)
Write a tasks.json (to the path your instructions specify) conforming to
engine/schemas/tasks.schema.json. It is the plan the backend impl phase fans out over —
build it from the LLD you just wrote, reusing the files you already read (do not re-read the
codebase).
Author it in one shot, then refine once. Compose the entire tasks.json — manifest, every
tasks[] entry, and slices[] — in a single Write. Do not stub the file and grow it with
successive Edits; assemble the whole structure in memory first and emit it once. After the
one Write, run the validator (below): if it prints OK you are done; if it fails, make one
corrective Edit (or a single rewriting Write) and re-validate. If that still fails, fix and
re-validate as needed — but never build the file up incrementally.
Fields:
context_manifest.read_once = the code files the tasks edit against; reference = this LLD
path, the (pending) contract path, and CLAUDE.md/AGENTS.md.
- One
tasks[] entry per ≤1-commit slice, each with id, group_id, title, depends_on
(intra-group only), reads (files needed beyond the manifest), writes (exact files),
test (the failing test to write first), standards, needs_human_gate (true for DB
migration, auth/permission, payment, prod config, or dependency changes).
- Grouping into independent slices: two tasks share a
group_id iff one depends on
the other OR they write a common file; otherwise put them in different groups. Then fill
slices[] — one entry per group, task_ids in dependency order.
- Validate before returning: run
python3 engine/validate_tasks.py <tasks.json path> — it must print OK.
Fix any FAIL (cross-group edge, shared write, mis-ordered slice) before finishing.
Output contract
Write your LLD to the given artifact path, with the sections above, each constraint citing
file:line. Return lld_path, tasks_path, and
contract_notes — a short summary of the decisions/constraints that shape the contract
(e.g. "auth is centralized in X — new endpoints must use it"; "exposes GET /searches with
cursor pagination"). The API/events section feeds the contract step.
Definition of done
Every section present; API surface concrete enough to formalize; migration reversible; edge
cases specified (not "TBD"); breaking changes flagged. Do not implement — this is a design
artifact only.
1---2name: backend-design3description: Author the backend low-level design (LLD) for a feature — read the relevant backend code to ground the design, then design how the feature slots in — component/sequence design, data model + migration plan, the API/events the backend will expose, error handling, security, observability, and test plan. Writes the LLD doc; never edits app code. Front door for /backend-design.4---56# backend-design — backend low-level design78Design the **backend** for a feature: read enough of the existing code to ground the design9in real conventions, then write a **buildable backend LLD**. This is a design artifact, not10code — never edit app code, don't implement, and don't design the frontend. Accuracy over11breadth: cite `file:line` for every constraint you rely on; don't guess. The **cross-repo12contract** is not written here — you describe the API/events your stack will **expose**; the13two LLDs are reconciled into the formal contract separately.1415## Inputs16Your instructions name what to read — the approved HLD — and the artifact path to write.17Standalone? read the HLD and write the LLD to a path you choose (and tell the user where).1819## Steps201. **Ground in the code (read-only).** Locate the service(s) this feature touches and read21 the layers that matter — routing/controllers → services/domain → persistence; the data22 model and migration tool; existing endpoints/events, DTOs, error envelope, auth/roles,23 jobs/queues, external integrations, rate-limit/idempotency patterns, logging/metrics,24 tests/fixtures, and the dominant conventions. Capture only what constrains the design,25 with `file:line` evidence. (No separate map is produced — this understanding feeds the LLD.)262. **Component & sequence design** — the modules/objects, their responsibilities, and the27 call/sequence for each critical path (happy + main error paths); where new code slots in.283. **Data model & migration plan** — entities, relations, indexes; a concrete29 **expand → migrate → contract** plan with rollback and any backfill of existing rows.304. **API/events to EXPOSE** — the operations this backend will offer (your side of the31 contract): method/path or event/topic, request/response DTOs, status codes, error32 envelope, auth + the exact permission per operation, per-field validation, pagination &33 limits, rate limits (429 + retry-after), idempotency keys, concurrency/versioning,34 backward-compatibility. The formal contract is derived from this separately.355. **Threat-model** the change (authz per operation, data exposure, abuse); design36 **observability** (logs/metrics/traces for new paths), timeouts/retries/degradation, and37 **performance** considerations.386. **Test plan** — unit + integration coverage, including the contract's negative paths.397. **Write** the backend LLD; flag every breaking change in plain language.408. **Emit the task DAG** — write a `tasks.json` (see section below), reusing the code you41 already read. No re-reading.4243## What the backend LLD must cover (write all)44Context & constraints (grounded in the code, cited) · component/sequence design · data model45+ migration plan · API/events exposed (the backend's side of the contract) · error handling ·46security & privacy (authz, tenancy, PII, secrets handling) · observability · performance ·47reliability (timeouts, retries, idempotency, partial-failure) · test plan · rollout/backout.4849## Edge cases the design must define (not leave to the implementer)50- Empty / missing / null inputs; maximum-size and oversized payloads; duplicate submissions.51- Concurrent updates to the same entity; lost-update prevention.52- Partial failure across services; retries and idempotency; timeouts and their fallbacks.53- Pagination boundaries (first/last/empty page, unstable ordering).54- Authz denied, expired token, insufficient scope, cross-tenant access attempts.55- Rate-limit exhaustion; downstream dependency down or slow.56- Migration failure mid-way; backfill of large existing datasets; rollback safety.57- Monorepo vs multi-repo; generated code; vendored/legacy areas; areas with **no tests**.5859## External skill (provision — research)60If a suitable deep-research skill is installed you may delegate to it to research unfamiliar61libraries, protocols, or compliance — it must return sourced findings you can cite in the62LLD. Otherwise design from the code + HLD.6364## Emit tasks.json (the parallel task DAG)65Write a `tasks.json` (to the path your instructions specify) conforming to66`engine/schemas/tasks.schema.json`. It is the plan the backend impl phase fans out over —67build it from the LLD you just wrote, reusing the files you already read (do not re-read the68codebase).6970**Author it in one shot, then refine once.** Compose the entire tasks.json — manifest, every71`tasks[]` entry, and `slices[]` — in a single `Write`. Do **not** stub the file and grow it with72successive `Edit`s; assemble the whole structure in memory first and emit it once. After the73one `Write`, run the validator (below): if it prints `OK` you are done; if it fails, make **one**74corrective `Edit` (or a single rewriting `Write`) and re-validate. If that still fails, fix and75re-validate as needed — but never build the file up incrementally.7677Fields:78- `context_manifest.read_once` = the code files the tasks edit against; `reference` = this LLD79 path, the (pending) contract path, and `CLAUDE.md`/`AGENTS.md`.80- One `tasks[]` entry per ≤1-commit slice, each with `id`, `group_id`, `title`, `depends_on`81 (**intra-group only**), `reads` (files needed beyond the manifest), `writes` (exact files),82 `test` (the failing test to write first), `standards`, `needs_human_gate` (true for DB83 migration, auth/permission, payment, prod config, or dependency changes).84- **Grouping into independent slices:** two tasks share a `group_id` **iff** one depends on85 the other OR they write a common file; otherwise put them in different groups. Then fill86 `slices[]` — one entry per group, `task_ids` in dependency order.87- **Validate before returning:** run88 `python3 engine/validate_tasks.py <tasks.json path>` — it must print `OK`.89 Fix any `FAIL` (cross-group edge, shared write, mis-ordered slice) before finishing.9091## Output contract92Write your LLD to the given artifact path, with the sections above, each constraint citing93`file:line`. Return `lld_path`, `tasks_path`, and94`contract_notes` — a short summary of the **decisions/constraints that shape the contract**95(e.g. "auth is centralized in X — new endpoints must use it"; "exposes `GET /searches` with96cursor pagination"). The API/events section feeds the contract step.9798## Definition of done99Every section present; API surface concrete enough to formalize; migration reversible; edge100cases specified (not "TBD"); breaking changes flagged. Do not implement — this is a design101artifact only.