refactor: conform standards docs to doc-forge wiki/lib layout; generic build.py; static kind links
This commit is contained in:
79
standards/src/lib/05_crud_template.md
Normal file
79
standards/src/lib/05_crud_template.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# CRUD Template
|
||||
|
||||
## Summary
|
||||
|
||||
Every resource follows the same four-file slice. Repetition is intentional: it
|
||||
makes the codebase predictable and generatable.
|
||||
|
||||
---
|
||||
|
||||
## The slice
|
||||
|
||||
```
|
||||
domain/<resource>/
|
||||
models.py # pure Pydantic model (no DB fields)
|
||||
ports/
|
||||
db.py # document model + repository factory
|
||||
service.py # service class + factory
|
||||
converters.py # (optional) transforms
|
||||
```
|
||||
|
||||
## models.py
|
||||
|
||||
A framework-free Pydantic model describing the business shape.
|
||||
|
||||
```python
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
quantity: int = 0
|
||||
```
|
||||
|
||||
## ports/db.py
|
||||
|
||||
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/...
|
||||
pass
|
||||
|
||||
def create_item_repo(*, owner_repo=None) -> ItemRepository:
|
||||
return repo_factory(
|
||||
collection="items",
|
||||
document=ItemDocument,
|
||||
populate_rules=[PopulateRule(field="owner", collection="users")],
|
||||
cache=None, # or a CachedBaseRepository config
|
||||
)
|
||||
```
|
||||
|
||||
## ports/service.py
|
||||
|
||||
The service is built through the DI library, injecting the repository. The
|
||||
generic CRUD base provides `create/read/update/patch/delete/search/...`.
|
||||
|
||||
```python
|
||||
class ItemService(CrudsServiceAdaptor[Item, ItemDocument]):
|
||||
model = Item
|
||||
schema = ItemDocument
|
||||
|
||||
def get_item_service(repo) -> ItemService:
|
||||
return build(ItemService, instances={"repo": repo})
|
||||
```
|
||||
|
||||
## Naming conventions
|
||||
|
||||
| Concept | Convention |
|
||||
|---|---|
|
||||
| collection | plural snake case (`items`) |
|
||||
| document | `<Resource>Document` |
|
||||
| repository factory | `create_<resource>_repo` |
|
||||
| service | `<Resource>Service` |
|
||||
| service factory | `get_<resource>_service` |
|
||||
| resource key | `<resource>_svc` |
|
||||
| operationId | `list_items`, `create_item`, ... |
|
||||
|
||||
## Optional files
|
||||
|
||||
- `converters.py` — pure functions mapping between domain types.
|
||||
- `ports/enrichment.py` — adapts a pipeline into an async callable the service
|
||||
can invoke (used when a resource is populated by a pipeline).
|
||||
Reference in New Issue
Block a user