Build Recipe
Summary
The ordered, deterministic checklist for generating a new application of the standard shape. Every step is fixed; only the resource model (step 2), the codegen pass (step 3), and the pipeline family (step 8) need app-specific work.
This page is served by the standards MCP as docs://modules/build_recipe. The
start_app prompt on that server collects the two axes and hands off here; pull
exact files with get_app_component.
🚀 Bootstrap
From the standards docs checkout:
Install the internal libraries — editable local checkouts (preferred in development) or the private index (CI / fresh machines). Credentials are environment-only; never commit them.
📋 Agent prompt (copyable)
🧭 Where the steps land
The steps map onto the layers as follows:
| Step | Package / file | Depends on |
|---|---|---|
| 1 · Scaffold | whole templates/app/ |
— |
| 2 · Spec | openapi.yaml |
— |
| 3 · Codegen | _gen/ (generated) |
spec, openapi-first |
| 4 · CRUD slices | domain/<resource>/ |
spec, CRUD template |
| 5 · Wiring | init.py |
every slice |
| 6 · Routes | interfaces/<resource>/ |
services, openapi route registry |
| 7 · Bootstrap | main.py, worker.py |
composition root |
| 8 · Pipelines | pipelines/<family>/, shared/ |
library pipeline engine |
| 9 · Infra | infra/ |
domain ports |
| 10 · Tests | tests/ |
app + fixtures |
| 11 · Scripts | scripts/ |
composition root |
| 12 · Docs | docstrings + docs build | code, Doc Forge |
🔧 The codegen fast path, in detail
openapi-first is spec → code only (it never generates a spec). Use it to erase
the two mechanical parts of the build:
| Generated artifact | Replaces | Notes |
|---|---|---|
_gen/models.py |
hand-writing Pydantic wire models | one class per components.schemas entry |
_gen/routes/<resource>/routes.py |
hand-typing handler signatures | names == operationIds; request: Request injected |
Rules of the road:
- Wire models are not domain models.
_gen/models.pyis the HTTP contract;domain/<resource>/models.pyis your business shape. If the spec's schema has a requiredid: str, keep it off the domain model and let the document get its id fromBaseDocument. - Resource names are sanitized.
/fetch-requests→fetch_requests.py. - Multipart bodies expand to
UploadFile = File(...)/Form(...)params. _gen/is disposable. Regenerate on every spec change;git diffshows exactly what moved.
⚠️ Definition of done
python -c "import main"succeeds.pytestpasses.- The app serves the spec's operations; the worker drains its queue.
- No domain module imports a web framework.
- No Tier A library was reimplemented.