- build.py: _TEMPLATE_COMPONENTS rewritten around the vet sample (53 kinds —
per-resource slices, jobs, worked appointment_reminder family, tests);
seed tokens dropped from the manifest ('sample: vet' instead)
- registry.py: get_app_component(kind) no longer renames item/example seeds;
prompts and tool docs updated to 'copy a slice and adapt'
- templates/README.md, 01_build_recipe, 40_ui_admin, wiki/03 updated off the
old seed scheme; repo inventory/config now exclude vet (docs move under
standards; react/vet itself is deleted in a later phase)
- regenerated MCP bundle, vendored templates, and site output
Application Template
A runnable sample of the standardized architecture — the vet veterinary
clinic domain, kept as the standards' reference sample. It demonstrates both
axes of the blueprint (see standards):
- Resource axis — five domain aggregates (parents, pets, treatments,
vets, appointments) plus a jobs queue, each a CRUD slice
(model → document → repo → service → route), all driven from
openapi.yaml. x- extension fields on the spec drive the admin client. - Pipeline axis — a background
worker.pythat polls pending jobs and dispatches byjob.kind;pipelines/appointment_reminder/is the worked family andpipelines/shared/the reusable scaffold.
Copy a slice, replace the domain with your own — the layer structure, wiring patterns and tests stay.
Internal dependencies
The app depends on the internal Aetos libraries (openapi-first, mongo-ops,
hexa, dagpipe, doc-forge). Install them one of two ways.
-
Local checkouts (preferred in development) — install the sibling repos editable:
pip install -e ../aetos/openapi-first -e ../aetos/mongo-ops -e ../aetos/hexa ` -e ../aetos/dagpipe -e ../aetos/doc-forge -
Private index (CI / fresh machines) — the published wheels live on the Aetos index. Pass credentials through the environment only; never commit them:
pip install --extra-index-url ` "https://$PIP_REGISTRY_USERNAME:$PIP_REGISTRY_PASSWORD@pip.aetoskia.com/simple" .The
DockerfilereadsPIP_REGISTRY_USERNAME/PIP_REGISTRY_PASSWORDas build args and setsPIP_EXTRA_INDEX_URLaccordingly.
Instantiate a new app
cp -r src/templates/app apps/<your-app>
cd apps/<your-app>
pyproject.toml— rename the package; keep the internal library pins.config.py— replace/add settings consumed by your domain (keep the worker knobs if you run jobs).openapi.yaml— replace the vet resources with yours; keep the x- extension conventions on schemas and fields.domain/— replace each aggregate slice with your own; copydomain/parents/as the simplest pattern,domain/appointments/when you need FK expansion.interfaces/— oneroutes.pyper resource re-exported fromopenapi.py; keep_common.pyas-is.pipelines/— replace the appointment_reminder family with yours (see below); keeppipelines/shared/as-is.tests/— keeptest_openapi_app_builds.py; adapt the unit tests as patterns for your own.
Install and run:
pip install -e ".[dev]"
uvicorn main:app --reload # API
python worker.py # worker
python -m scripts.seed # operator script
Pipeline families
Copy pipelines/appointment_reminder/ as the family pattern:
pipelines/<family>/
abc.py # port contracts
impl.py # concrete stages + wired root + register(...)
pipeline.yaml # graph spec
resources/
pipeline.yaml # runtime spec
patterns/*.yaml
pipelines/shared/
ports.py loader.py registry.py # reused by every family
The shared loader wires the root through the DI library (hexa.build) and merges
the pattern fragments; the registry resolves a (kind, variant, mode) triple to
a root class. The worker maps job.kind to a handler in its HANDLERS
dispatch table. See standards "50_pipeline_scaffold" and "51_worker_and_progress".
What to keep, what to replace
| Keep | Replace / rename |
|---|---|
config.py shape |
Settings fields |
init.py wiring pattern |
Resource names |
| openapi-first routing | Paths, schemas, operationIds |
| mongo-ops repo factory | Collections, doc models |
| generic CRUD adaptor | Nothing (reuse as-is) |
interfaces/_common.py |
Nothing (reuse as-is) |
pipelines/shared/ |
Nothing (reuse as-is) |
pipelines/appointment_reminder/ |
Family name, stages, patterns |
| worker poll + dispatch loop | Job kinds, payloads, pipeline steps |
scripts/ |
Task bodies |
Where the internal libraries slot in
openapi_first.app.OpenAPIFirstApp— main.py, interfaces/openapi.pymongo_ops— infra/db/setup.py, infra/db/repos/mongo.py, domain/*/ports/db.pyhexa.build— domain/*/ports/service.py, pipelines/shared/loader.pydagpipe— pipelines/ (wrap step chains in a DAG once they branch)docforge— generated.pyistubs and docsomniread/mail-intake— ingestion adapters (add when needed)
Confirm current endpoints and ownership with the standards registry MCP tools:
find_library("pipeline"), find_library("auth"), or
get_app_component("pipeline-abc").