feat(standards): codify codegen, ship generic Tier-B infra, add get_app_template + prompts; fix docs:// regressions
P0: fix doc:// -> docs:// across standards src/server/registry and regenerate stale mongo-ops bundle. P1: build recipe + spec-first routing now document the openapi-first codegen fast path (models/routes with --inject-request/--package). P4: CRUD template documents the model-vs-document id rule (BaseDocument owns id). P5: authless guidance (omit security keys). P6: template gains generic infra (http_cache, keyed SSE bus, KV port+in-memory+Redis), interfaces/openapi.py + .dockerignore + generic build test registered as components, and a get_app_template tool; genericity matrix marks LLM pool + human-in-loop as reference-app patterns. P7: intake/build/start_app/trial prompts. P8: template ships tests/integration/test_openapi_app_builds.py. Rebuilt standards + openapi-first bundles and re-collected.
This commit is contained in:
@@ -18,9 +18,36 @@ domain/<resource>/
|
||||
converters.py # (optional) transforms
|
||||
```
|
||||
|
||||
## The id rule (model vs. document)
|
||||
|
||||
Two different objects, two different jobs:
|
||||
|
||||
| Object | Lives in | Has `id`? | Purpose |
|
||||
|---|---|---|---|
|
||||
| **Domain model** | `domain/<resource>/models.py` | **No** | business shape, framework-free |
|
||||
| **Document** | `domain/<resource>/ports/db.py` | **Yes** (from `BaseDocument`) | Mongo persistence shape |
|
||||
|
||||
`BaseDocument` (mongo-ops) supplies `id: Optional[PyObjectId]` (aliased to
|
||||
`_id`) plus `created_at` / `updated_at`. The domain model must **not** declare
|
||||
`id`; Mongo owns it.
|
||||
|
||||
> **Trap — generated wire models.** `openapi-first models` produces the HTTP
|
||||
> *contract* (see the [Build Recipe](01_build_recipe.md), step 3). Response
|
||||
> schemas frequently declare a required `id: str`, so a generated class is
|
||||
> **not** a domain model. If you write
|
||||
> `class ItemDocument(Item, BaseDocument)` and `Item` re-exports a required
|
||||
> `id: str`, that field shadows `BaseDocument.id` and no Mongo `_id` can ever be
|
||||
> set. Fix it one of three ways:
|
||||
>
|
||||
> 1. **Preferred:** keep the domain model id-free (hand-author it from the CRUD
|
||||
> template), and keep the required `id` only on the wire model.
|
||||
> 2. Order the bases so the document wins:
|
||||
> `class ItemDocument(BaseDocument, Item)`.
|
||||
> 3. Keep a separate document type and translate with `ports/converters.py`.
|
||||
|
||||
## models.py
|
||||
|
||||
A framework-free Pydantic model describing the business shape.
|
||||
A framework-free Pydantic model describing the business shape (no `id`).
|
||||
|
||||
```python
|
||||
class Item(BaseModel):
|
||||
@@ -34,7 +61,8 @@ The persistence model extends the business model and adds database concerns.
|
||||
The repository factory selects the right repository flavour.
|
||||
|
||||
```python
|
||||
class ItemDocument(Item, BaseDocument): # BaseDocument adds id/created_at/...
|
||||
# Item is id-free; BaseDocument adds id/created_at/updated_at.
|
||||
class ItemDocument(Item, BaseDocument):
|
||||
pass
|
||||
|
||||
def create_item_repo(*, owner_repo=None) -> ItemRepository:
|
||||
|
||||
Reference in New Issue
Block a user