# Overview The blueprint is a **hexagonal (ports & adapters) application** with a **spec-first** web edge and a **single composition root**. It favors explicit wiring over implicit magic and existing internal libraries over hand-written infrastructure. Start here to build the mental model; the enforceable details live in the reference pages. --- ## ๐Ÿ—๏ธ Architecture ```mermaid flowchart LR subgraph EDGE["interfaces/ โ€” HTTP edge"] OAS["openapi.yaml
operationId contract"] RT["/routes.py
thin handlers"] end subgraph CORE["domain/ โ€” business core"] MD["models"] PT["ports (adapter binding seam)"] SV["services"] end subgraph INFRA["infra/ โ€” adapters"] RP["mongo repos (mongo-ops)"] AD["cache ยท stores ยท llm ยท mail"] DB[("MongoDB")] end CR["init.py
composition root"] OAS --> RT RT --> SV SV --> PT SV --> RP PT -. depends on .- RP CR --- RT CR --- SV CR --- RP RP --> DB AD --- CR ``` The rule holds at every edge: code in an outer ring may depend on a ring closer to the core, never the reverse. `domain/` never imports a web framework; only its `ports/` seam reaches into `infra/` to bind adapters. > **Legend** โ€” solid arrows are compile-time calls; dotted arrows are the > port/adapter binding, performed by the composition root at startup. --- ## ๐Ÿ”„ The one-way dependency rule | Ring | May import | Never imports | |-------------|------------------------------------|----------------------------------| | `interfaces/` | `domain`, framework glue (glue only) | business logic, `infra` directly | | `domain/` | its own models + its `ports/` seam (which binds `infra`/libraries) | web frameworks, `interfaces/` | | `infra/` | `domain` ports, drivers, libraries | โ€” | | `init.py` | everything (the wiring point) | โ€” | --- ## ๐Ÿงญ Core principles 1. **One-way dependencies.** `interfaces -> domain -> infra` is allowed; the reverse is forbidden. 2. **Ports in the domain, adapters in infra.** A service depends on a port; the port's factory binds the concrete adapter, and the composition root calls those factories. 3. **One composition root.** Nothing constructs its own dependencies. All wiring lives in one module (`init.py`) exposed as a flat resource registry. 4. **Spec-first.** The HTTP contract is declared in `openapi.yaml`; route handlers are looked up by `operationId`. There are no decorator routers. 5. **Reuse the libraries.** Orchestration, DI, Mongo repositories, ingestion, auth, and docs come from internal libraries โ€” see the [Library Registry](../lib/13_library_registry/). 6. **Explicit state machines.** Long-running work moves through explicit, durable statuses and can pause for human input. --- ## โš™๏ธ Runtime processes A standard app may run as up to three processes that share the same composition root: | Process | Entry point | Responsibility | |---------|------------------------|-------------------------------------------| | API | `main.py` | serve HTTP; start/stop resources via lifespan | | Worker | `worker.py` | poll durable jobs, run pipelines, publish progress | | Scripts | `python -m scripts.` | one-shot operator tasks | --- ## โžก๏ธ Read Next - [02 โ€“ App Components](02_components.md) ยท [03 โ€“ Build Recipe](03_build_recipe.md)