<spanclass="normal"><ahref="#__codelineno-2-72">72</a></span></pre></div></td><tdclass="code"><div><pre><span></span><code><spanid="__span-2-1"><aid="__codelineno-2-1"name="__codelineno-2-1"></a><spanclass="gh"># Build a new application from the Aetos Standards blueprint</span>
<spanclass="normal"><ahref="#__codelineno-2-88">88</a></span></pre></div></td><tdclass="code"><div><pre><span></span><code><spanid="__span-2-1"><aid="__codelineno-2-1"name="__codelineno-2-1"></a><spanclass="gh"># Build a new application from the Aetos Standards blueprint</span>
</span><spanid="__span-2-3"><aid="__codelineno-2-3"name="__codelineno-2-3"></a>You are coding a complete new backend application conforming to the Aetos
</span><spanid="__span-2-4"><aid="__codelineno-2-4"name="__codelineno-2-4"></a>standard app blueprint. Execute every step in order. Only steps 2 and 3 use the
</span><spanid="__span-2-4"><aid="__codelineno-2-4"name="__codelineno-2-4"></a>standard app blueprint. Execute every step in order. Only steps 2–4 use the
</span><spanid="__span-2-5"><aid="__codelineno-2-5"name="__codelineno-2-5"></a>app-specific details provided by the user; everything else is deterministic.
</span><spanid="__span-2-9"><aid="__codelineno-2-9"name="__codelineno-2-9"></a>Connect to the <spanclass="sb">`standards`</span> MCP server and read:
</span><spanid="__span-2-10"><aid="__codelineno-2-10"name="__codelineno-2-10"></a><spanclass="k">-</span><spanclass="w"></span><spanclass="sb">`doc://nav`</span> (the module list)
</span><spanid="__span-2-11"><aid="__codelineno-2-11"name="__codelineno-2-11"></a><spanclass="k">-</span><spanclass="w"></span><spanclass="sb">`doc://modules/genericity_matrix`</span> (Tier A library / Tier B template / Tier C authored)
</span><spanid="__span-2-12"><aid="__codelineno-2-12"name="__codelineno-2-12"></a><spanclass="k">-</span><spanclass="w"></span><spanclass="sb">`doc://modules/layering_rules`</span> (the dependency rules)
</span><spanid="__span-2-10"><aid="__codelineno-2-10"name="__codelineno-2-10"></a><spanclass="k">-</span><spanclass="w"></span><spanclass="sb">`docs://nav`</span> (the module list)
</span><spanid="__span-2-11"><aid="__codelineno-2-11"name="__codelineno-2-11"></a><spanclass="k">-</span><spanclass="w"></span><spanclass="sb">`docs://modules/genericity_matrix`</span> (Tier A library / Tier B template / Tier C authored)
</span><spanid="__span-2-12"><aid="__codelineno-2-12"name="__codelineno-2-12"></a><spanclass="k">-</span><spanclass="w"></span><spanclass="sb">`docs://modules/layering_rules`</span> (the dependency rules)
</span><spanid="__span-2-28"><aid="__codelineno-2-28"name="__codelineno-2-28"></a><spanclass="k">2.</span><spanclass="gs">**Author the spec (app-specific)**</span> — write <spanclass="sb">`openapi.yaml`</span>: resources,
</span><spanid="__span-2-29"><aid="__codelineno-2-29"name="__codelineno-2-29"></a> schemas,<spanclass="sb">`operationId`</span>s, security, and extension metadata. This is the
</span><spanid="__span-2-30"><aid="__codelineno-2-30"name="__codelineno-2-30"></a>contract and drives all routing.
</span><spanid="__span-2-32"><aid="__codelineno-2-32"name="__codelineno-2-32"></a><spanclass="k">3.</span><spanclass="gs">**Write each CRUD slice (app-specific)**</span> — per resource create the four-file
</span><spanid="__span-2-33"><aid="__codelineno-2-33"name="__codelineno-2-33"></a> slice: <spanclass="sb">`models.py`</span>,<spanclass="sb">`ports/db.py`</span>, <spanclass="sb">`ports/service.py`</span>, and optional
</span><spanid="__span-2-34"><aid="__codelineno-2-34"name="__codelineno-2-34"></a><spanclass="sb">`converters.py`</span>. Follow the CRUD template.
</span><spanid="__span-2-36"><aid="__codelineno-2-36"name="__codelineno-2-36"></a><spanclass="k">4.</span><spanclass="gs">**Wire the composition root**</span> — in <spanclass="sb">`init.py`</span>, build leaf repositories, then
</span><spanid="__span-2-37"><aid="__codelineno-2-37"name="__codelineno-2-37"></a> dependent repositories, then services; add infra adapters (db, cache, stores,
</span><spanid="__span-2-41"><aid="__codelineno-2-41"name="__codelineno-2-41"></a>to <spanclass="sb">`operationId`</span>s and re-export them in <spanclass="sb">`interfaces/openapi.py`</span>. Add the cache
</span><spanid="__span-2-42"><aid="__codelineno-2-42"name="__codelineno-2-42"></a>decorator to read endpoints.
</span><spanid="__span-2-44"><aid="__codelineno-2-44"name="__codelineno-2-44"></a><spanclass="k">6.</span><spanclass="gs">**Bootstrap app and worker**</span> — confirm <spanclass="sb">`main.py`</span> runs the OpenAPI-first app
</span><spanid="__span-2-45"><aid="__codelineno-2-45"name="__codelineno-2-45"></a> with its lifespan. If the app has long-running jobs, adapt<spanclass="sb">`worker.py`</span> to poll
</span><spanid="__span-2-46"><aid="__codelineno-2-46"name="__codelineno-2-46"></a>the job collection, run the pipeline, and publish progress.
</span><spanid="__span-2-48"><aid="__codelineno-2-48"name="__codelineno-2-48"></a><spanclass="k">7.</span><spanclass="gs">**Add pipeline families (only if data-driven)**</span> — copy<spanclass="sb">`pipelines/example/`</span>
</span><spanid="__span-2-49"><aid="__codelineno-2-49"name="__codelineno-2-49"></a> to <spanclass="sb">`pipelines/<family>/`</span> with <spanclass="sb">`abc.py`</span>, <spanclass="sb">`impl.py`</span>, <spanclass="sb">`pipeline.yaml`</span>,
</span><spanid="__span-2-50"><aid="__codelineno-2-50"name="__codelineno-2-50"></a><spanclass="sb">`resources/`</span>, and reuse<spanclass="sb">`pipelines/shared/`</span> (loader + registry). Register the
</span><spanid="__span-2-51"><aid="__codelineno-2-51"name="__codelineno-2-51"></a>root. Add fixtures and a parity test.
</span><spanid="__span-2-53"><aid="__codelineno-2-53"name="__codelineno-2-53"></a><spanclass="k">8.</span><spanclass="gs">**Add infrastructure only where needed**</span> — Tier A capability: use the
</span><spanid="__span-2-54"><aid="__codelineno-2-54"name="__codelineno-2-54"></a> library. Tier B capability: copy the template. Never hand-write a Tier A
</span><spanid="__span-2-57"><aid="__codelineno-2-57"name="__codelineno-2-57"></a><spanclass="k">9.</span><spanclass="gs">**Tests**</span> — integration tests with fakes at the HTTP edge; unit tests for
</span><spanid="__span-2-58"><aid="__codelineno-2-58"name="__codelineno-2-58"></a> domain and pipeline logic; a config-consistency test for rule-driven
</span><spanid="__span-2-61"><aid="__codelineno-2-61"name="__codelineno-2-61"></a><spanclass="k">10.</span><spanclass="gs">**Scripts and seeds**</span> — operator scripts under <spanclass="sb">`scripts/`</span> using
</span><spanid="__span-2-62"><aid="__codelineno-2-62"name="__codelineno-2-62"></a><spanclass="sb">`init()`</span> / <spanclass="sb">`get_svc()`</span> / <spanclass="sb">`shutdown()`</span>; run as <spanclass="sb">`python -m scripts.<name>`</span>.
</span><spanid="__span-2-64"><aid="__codelineno-2-64"name="__codelineno-2-64"></a><spanclass="k">11.</span><spanclass="gs">**Docs**</span> — author GSDFC docstrings, generate<spanclass="sb">`.pyi`</span> stubs, mark the package
</span><spanid="__span-2-65"><aid="__codelineno-2-65"name="__codelineno-2-65"></a><spanclass="sb">`py.typed`</span>, and build the docs.
</span><spanid="__span-2-70"><aid="__codelineno-2-70"name="__codelineno-2-70"></a><spanclass="k">-</span><spanclass="w"></span>The app serves every operation in the spec; the worker drains its queue.
</span><spanid="__span-2-71"><aid="__codelineno-2-71"name="__codelineno-2-71"></a><spanclass="k">-</span><spanclass="w"></span>No domain module imports a web framework.
</span><spanid="__span-2-72"><aid="__codelineno-2-72"name="__codelineno-2-72"></a><spanclass="k">-</span><spanclass="w"></span>No Tier A library was reimplemented.
</span><spanid="__span-2-23"><aid="__codelineno-2-23"name="__codelineno-2-23"></a><spanclass="k">1.</span><spanclass="gs">**Scaffold**</span> — copy <spanclass="sb">`standards/src/templates/app/`</span> into <spanclass="sb">`apps/<your-app>/`</span>
</span><spanid="__span-2-24"><aid="__codelineno-2-24"name="__codelineno-2-24"></a>(or pull the same tree via <spanclass="sb">`get_app_template`</span>). Keep the tree: <spanclass="sb">`domain/`</span>,
</span><spanid="__span-2-25"><aid="__codelineno-2-25"name="__codelineno-2-25"></a><spanclass="sb">`infra/`</span>, <spanclass="sb">`interfaces/`</span>, <spanclass="sb">`pipelines/`</span>, <spanclass="sb">`tests/`</span>, <spanclass="sb">`scripts/`</span>, plus
</span><spanid="__span-2-29"><aid="__codelineno-2-29"name="__codelineno-2-29"></a><spanclass="k">2.</span><spanclass="gs">**Author the spec (app-specific)**</span> — write <spanclass="sb">`openapi.yaml`</span>: resources,
</span><spanid="__span-2-30"><aid="__codelineno-2-30"name="__codelineno-2-30"></a>schemas, <spanclass="sb">`operationId`</span>s, security, and extension metadata. This is the
</span><spanid="__span-2-31"><aid="__codelineno-2-31"name="__codelineno-2-31"></a> contract and drives all routing. Every operation MUST have an <spanclass="sb">`operationId`</span>.
</span><spanid="__span-2-33"><aid="__codelineno-2-33"name="__codelineno-2-33"></a><spanclass="k">3.</span><spanclass="gs">**Generate the scaffold (codegen)**</span> — from the spec, generate the wire
</span><spanid="__span-2-34"><aid="__codelineno-2-34"name="__codelineno-2-34"></a>models and the exact handler signatures:
</span><spanid="__span-2-40"><aid="__codelineno-2-40"name="__codelineno-2-40"></a><spanclass="sb">`_gen/models.py`</span>is the <spanclass="gs">**wire contract**</span> (Pydantic, one class per
</span><spanid="__span-2-41"><aid="__codelineno-2-41"name="__codelineno-2-41"></a><spanclass="sb">`components.schemas`</span> entry). <spanclass="sb">`_gen/routes/<resource>/routes.py`</span> lists every
</span><spanid="__span-2-42"><aid="__codelineno-2-42"name="__codelineno-2-42"></a><spanclass="sb">`operationId`</span> with its exact parameter signature. Treat <spanclass="sb">`_gen/`</span> as generated
</span><spanid="__span-2-43"><aid="__codelineno-2-43"name="__codelineno-2-43"></a> (never hand-edit it) — the canonical handlers live in <spanclass="sb">`interfaces/`</span>.
</span><spanid="__span-2-45"><aid="__codelineno-2-45"name="__codelineno-2-45"></a><spanclass="k">4.</span><spanclass="gs">**Write each CRUD slice (app-specific)**</span> — per resource create the four-file
</span><spanid="__span-2-47"><aid="__codelineno-2-47"name="__codelineno-2-47"></a> (<spanclass="sb">`class XDocument(BaseDocument, X)`</span> — id comes from <spanclass="sb">`BaseDocument`</span>),
</span><spanid="__span-2-48"><aid="__codelineno-2-48"name="__codelineno-2-48"></a><spanclass="sb">`ports/service.py`</span>, and optional<spanclass="sb">`converters.py`</span>. Follow the CRUD template.
</span><spanid="__span-2-50"><aid="__codelineno-2-50"name="__codelineno-2-50"></a><spanclass="k">5.</span><spanclass="gs">**Wire the composition root**</span> — in<spanclass="sb">`init.py`</span>, build leaf repositories, then
</span><spanid="__span-2-51"><aid="__codelineno-2-51"name="__codelineno-2-51"></a>dependent repositories, then services; add infra adapters (db, cache, stores,
</span><spanid="__span-2-55"><aid="__codelineno-2-55"name="__codelineno-2-55"></a>names match the <spanclass="sb">`operationId`</span>s (use the signatures from step 3 as your
</span><spanid="__span-2-56"><aid="__codelineno-2-56"name="__codelineno-2-56"></a> checklist) and re-export them in <spanclass="sb">`interfaces/openapi.py`</span>. Add the cache
</span><spanid="__span-2-57"><aid="__codelineno-2-57"name="__codelineno-2-57"></a> decorator to read endpoints.
</span><spanid="__span-2-59"><aid="__codelineno-2-59"name="__codelineno-2-59"></a><spanclass="k">7.</span><spanclass="gs">**Bootstrap app and worker**</span> — confirm <spanclass="sb">`main.py`</span> runs the OpenAPI-first app
</span><spanid="__span-2-60"><aid="__codelineno-2-60"name="__codelineno-2-60"></a> with its lifespan. If the app has long-running jobs, adapt <spanclass="sb">`worker.py`</span> to poll
</span><spanid="__span-2-61"><aid="__codelineno-2-61"name="__codelineno-2-61"></a> the job collection, run the pipeline, and publish progress.
</span><spanid="__span-2-63"><aid="__codelineno-2-63"name="__codelineno-2-63"></a><spanclass="k">8.</span><spanclass="gs">**Add pipeline families (only if data-driven)**</span> — copy <spanclass="sb">`pipelines/example/`</span>
</span><spanid="__span-2-64"><aid="__codelineno-2-64"name="__codelineno-2-64"></a> to <spanclass="sb">`pipelines/<family>/`</span> with<spanclass="sb">`abc.py`</span>,<spanclass="sb">`impl.py`</span>, <spanclass="sb">`pipeline.yaml`</span>,
</span><spanid="__span-2-65"><aid="__codelineno-2-65"name="__codelineno-2-65"></a><spanclass="sb">`resources/`</span>, and reuse <spanclass="sb">`pipelines/shared/`</span> (loader + registry). Register the
</span><spanid="__span-2-66"><aid="__codelineno-2-66"name="__codelineno-2-66"></a> root. Add fixtures and a parity test.
</span><spanid="__span-2-68"><aid="__codelineno-2-68"name="__codelineno-2-68"></a><spanclass="k">9.</span><spanclass="gs">**Add infrastructure only where needed**</span> — Tier A capability: use the
</span><spanid="__span-2-69"><aid="__codelineno-2-69"name="__codelineno-2-69"></a> library. Tier B capability: copy the template. Never hand-write a Tier A
</span><spanid="__span-2-72"><aid="__codelineno-2-72"name="__codelineno-2-72"></a><spanclass="k">10.</span><spanclass="gs">**Tests**</span> — integration tests with fakes at the HTTP edge; unit tests for
</span><spanid="__span-2-73"><aid="__codelineno-2-73"name="__codelineno-2-73"></a> domain and pipeline logic; a config-consistency test for rule-driven
</span><spanid="__span-2-74"><aid="__codelineno-2-74"name="__codelineno-2-74"></a> pipelines. Include <spanclass="sb">`tests/integration/test_openapi_app_builds.py`</span> (imports
</span><spanid="__span-2-75"><aid="__codelineno-2-75"name="__codelineno-2-75"></a> the app, asserts <spanclass="sb">`import main`</span> binds every operation).
</span><spanid="__span-2-77"><aid="__codelineno-2-77"name="__codelineno-2-77"></a><spanclass="k">11.</span><spanclass="gs">**Scripts and seeds**</span> — operator scripts under <spanclass="sb">`scripts/`</span> using
</span><spanid="__span-2-78"><aid="__codelineno-2-78"name="__codelineno-2-78"></a><spanclass="sb">`init()`</span> / <spanclass="sb">`get_svc()`</span> / <spanclass="sb">`shutdown()`</span>; run as <spanclass="sb">`python -m scripts.<name>`</span>.
</span><spanid="__span-2-86"><aid="__codelineno-2-86"name="__codelineno-2-86"></a><spanclass="k">-</span><spanclass="w"></span>The app serves every operation in the spec; the worker drains its queue.
</span><spanid="__span-2-87"><aid="__codelineno-2-87"name="__codelineno-2-87"></a><spanclass="k">-</span><spanclass="w"></span>No domain module imports a web framework.
</span><spanid="__span-2-88"><aid="__codelineno-2-88"name="__codelineno-2-88"></a><spanclass="k">-</span><spanclass="w"></span>No Tier A library was reimplemented.
</span><spanid="__span-2-9"><aid="__codelineno-2-9"name="__codelineno-2-9"></a><spanclass="n">cache</span><spanclass="o">=</span><spanclass="kc">None</span><spanclass="p">,</span><spanclass="c1"># or a CachedBaseRepository config</span>
</span><spanid="__span-2-10"><aid="__codelineno-2-10"name="__codelineno-2-10"></a><spanclass="n">cache</span><spanclass="o">=</span><spanclass="kc">None</span><spanclass="p">,</span><spanclass="c1"># or a CachedBaseRepository config</span>
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.