fix: repair cp1252-mangled em-dashes and ellipsis in the reference-app wiki
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
All four 06_reference_app pages round-tripped U+2014 (em-dash) and U+2026 (ellipsis) through cp1252 during earlier PowerShell edits; restored the characters and regenerated the wiki HTML + MCP modules.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Reference App — Overview
|
||||
# Reference App — Overview
|
||||
|
||||
The standards ship a **runnable sample** of the whole blueprint: the **vet**
|
||||
veterinary-clinic application. It exists to be copied — it is the reference
|
||||
veterinary-clinic application. It exists to be copied — it is the reference
|
||||
for how a real domain sits on the architecture, and the code an agent pulls
|
||||
through the MCP tools (`get_app_template`, `get_app_component`).
|
||||
|
||||
@@ -17,12 +17,12 @@ through the MCP tools (`get_app_template`, `get_app_component`).
|
||||
|
||||
| Aggregate | What it demonstrates |
|
||||
|---------------|---------------------------------------------------------------|
|
||||
| **parents** | The simplest CRUD slice (no foreign keys) — copy this first |
|
||||
| **parents** | The simplest CRUD slice (no foreign keys) — copy this first |
|
||||
| **pets** | Embedded list-of-refs (`parents[]`), file upload, enum fields |
|
||||
| **treatments**| Plain resource with pricing fields |
|
||||
| **vets** | Plain resource; target of prefetch FKs |
|
||||
| **appointments** | Single FKs (`pet`, `vet`, `treatment`) expanded on read, filtered list |
|
||||
| **jobs** | The worker's queue — durable status machine |
|
||||
| **jobs** | The worker's queue — durable status machine |
|
||||
|
||||
The pipeline axis ships one worked family, **`appointment_reminder`**, plus the
|
||||
reusable `pipelines/shared/` scaffold and a `worker.py` that dispatches jobs by
|
||||
@@ -41,7 +41,7 @@ python -m scripts.seed # optional: seed demo data (mongo backend)
|
||||
```
|
||||
|
||||
The default `REPO_BACKEND=memory` means the API boots with **no external
|
||||
services** — repositories are process-local dictionaries. Switch to
|
||||
services** — repositories are process-local dictionaries. Switch to
|
||||
`REPO_BACKEND=mongo` for persistence (see `.env.example`).
|
||||
|
||||
The client pairs with it:
|
||||
@@ -60,11 +60,11 @@ npm run dev # Vite dev server
|
||||
(`{AUTH_SERVER}` introspection). Without a reachable auth-server the API
|
||||
answers `401` on resource routes; `/health` stays public. For a local
|
||||
no-auth demo, remove the `security` block from `openapi.yaml` and the
|
||||
global security entry — see
|
||||
global security entry — see
|
||||
[Auth Integration](../lib/22_auth_integration/).
|
||||
|
||||
## Next
|
||||
|
||||
- [Domain & API](02_domain_and_api.md) — walking the resource axis
|
||||
- [Pipelines & Worker](03_pipelines_and_worker.md) — the pipeline axis
|
||||
- [Client Admin](04_client_admin.md) — the spec-driven frontend
|
||||
- [Domain & API](02_domain_and_api.md) — walking the resource axis
|
||||
- [Pipelines & Worker](03_pipelines_and_worker.md) — the pipeline axis
|
||||
- [Client Admin](04_client_admin.md) — the spec-driven frontend
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Domain & API — the resource axis
|
||||
# Domain & API — the resource axis
|
||||
|
||||
Every aggregate follows the same four-file slice
|
||||
([CRUD Template](../lib/21_crud_template/)); walk `parents` first, then
|
||||
@@ -13,10 +13,10 @@ domain/parents/
|
||||
db.py # ParentDocument(Parent, BaseDocument) + create_parent_repo()
|
||||
service.py # ParentCrudsService(CrudsServiceAdaptor[...]) + get_parent_service()
|
||||
interfaces/parents/
|
||||
routes.py # list/create/get/update/delete — names == operationIds
|
||||
routes.py # list/create/get/update/delete — names == operationIds
|
||||
```
|
||||
|
||||
Wiring happens in exactly one place — the composition root
|
||||
Wiring happens in exactly one place — the composition root
|
||||
`init.py`:
|
||||
|
||||
```python
|
||||
@@ -41,7 +41,7 @@ single source of truth: `main.py` builds an `OpenAPIFirstApp` that binds each
|
||||
re-export of every routes module). There are no decorator routers.
|
||||
|
||||
The x- extension fields on schemas and properties are what make the admin
|
||||
client render itself — see [Auto-Rendered Admin](../lib/40_ui_admin/) and
|
||||
client render itself — see [Auto-Rendered Admin](../lib/40_ui_admin/) and
|
||||
the worked `Job` schema (enum selects, hidden fields, filterable columns).
|
||||
|
||||
## Foreign keys (appointments)
|
||||
@@ -54,7 +54,7 @@ fully expanded objects:
|
||||
pet = await expand_ref(svc(request, "pet"), body.get("pet"), "pet")
|
||||
```
|
||||
|
||||
The list endpoint additionally filters by date prefix and embedded fk ids —
|
||||
The list endpoint additionally filters by date prefix and embedded fk ids —
|
||||
client-side over the repository result, the pattern for small reference data.
|
||||
|
||||
## Ids on the wire
|
||||
@@ -67,7 +67,7 @@ Mongo persistence layer consistent.
|
||||
|
||||
## Tests
|
||||
|
||||
- `tests/integration/test_openapi_app_builds.py` — generic gate: every
|
||||
- `tests/integration/test_openapi_app_builds.py` — generic gate: every
|
||||
`operationId` resolves and the app builds. Copy it verbatim.
|
||||
- `tests/unit/test_jobs_routes.py` — the pattern for route unit tests with a
|
||||
- `tests/unit/test_jobs_routes.py` — the pattern for route unit tests with a
|
||||
service double (no HTTP client needed).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Pipelines & Worker — the pipeline axis
|
||||
# Pipelines & Worker — the pipeline axis
|
||||
|
||||
The sample proves the full loop: **API creates a job document → worker polls →
|
||||
pipeline family runs → job reaches a terminal status.**
|
||||
@@ -46,7 +46,7 @@ reminder = await pipeline.run(appointment_id)
|
||||
```
|
||||
|
||||
To add a family: copy `appointment_reminder/`, replace the stages, call
|
||||
`register(kind, variant, root_cls)` — see
|
||||
`register(kind, variant, root_cls)` — see
|
||||
[Pipeline Scaffold](../lib/50_pipeline_scaffold/).
|
||||
|
||||
## The worker
|
||||
@@ -56,7 +56,7 @@ documents into execution:
|
||||
|
||||
1. poll `job_svc.search({"status": "pending"})` on `WORKER_POLL_SECONDS`
|
||||
2. claim a job: `status → processing`
|
||||
3. dispatch through the `HANDLERS` table — `HANDLERS[job.kind](job, resources)`
|
||||
3. dispatch through the `HANDLERS` table — `HANDLERS[job.kind](job, resources)`
|
||||
4. on success `status → done`; on exception `status → failed`,
|
||||
`retry_count += 1`, `error_message` captured; jobs at
|
||||
`WORKER_MAX_RETRIES` are skipped
|
||||
@@ -69,17 +69,17 @@ HANDLERS: dict[str, Callable] = {
|
||||
```
|
||||
|
||||
The worker shares the composition root: `from init import init` gives it the
|
||||
same wired services the API uses — one place to add a dependency.
|
||||
same wired services the API uses — one place to add a dependency.
|
||||
|
||||
!!! note "Same process model in production"
|
||||
API and worker are separate processes (see `docker-compose.yaml`: `api`,
|
||||
`worker`, `mongo`). Any in-memory progress bus is per-process; to surface
|
||||
live progress through the API, swap the bus adaptor for a broker-backed
|
||||
one — see [Worker & Progress](../lib/51_worker_and_progress/).
|
||||
one — see [Worker & Progress](../lib/51_worker_and_progress/).
|
||||
|
||||
## Tests
|
||||
|
||||
- `tests/unit/test_appointment_reminder_pipeline.py` — stage units + the wired
|
||||
- `tests/unit/test_appointment_reminder_pipeline.py` — stage units + the wired
|
||||
root against a fake service.
|
||||
- `tests/unit/test_worker.py` — dispatch, done/failed transitions, retry
|
||||
- `tests/unit/test_worker.py` — dispatch, done/failed transitions, retry
|
||||
exhaustion, using an in-memory job service double and a cancelled poll task.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Client Admin — the spec-driven frontend
|
||||
# Client Admin — the spec-driven frontend
|
||||
|
||||
The client sample (`standards/src/templates/client/`) renders a full admin —
|
||||
auth pages, resource lists, forms, detail views — **from the server's
|
||||
The client sample (`standards/src/templates/client/`) renders a full admin —
|
||||
auth pages, resource lists, forms, detail views — **from the server's
|
||||
`openapi.yaml`**, driven entirely by the x- extension fields. There are no
|
||||
hand-written screens per resource.
|
||||
|
||||
@@ -9,10 +9,10 @@ hand-written screens per resource.
|
||||
|
||||
A Vite + React + MUI app wiring the two Aetos packages:
|
||||
|
||||
- **`@aetoskia/react-openapi`** — fetches `${VITE_API_BASE_URL}/openapi.json`,
|
||||
- **`@aetoskia/react-openapi`** — fetches `${VITE_API_BASE_URL}/openapi.json`,
|
||||
builds the router and the resource admin from the spec's schemas and x-
|
||||
fields (list columns, autocomplete, fk pickers, enum selects, hidden fields…)
|
||||
- **`@aetoskia/react-auth`** — login/register/logout against the auth-server
|
||||
fields (list columns, autocomplete, fk pickers, enum selects, hidden fields…)
|
||||
- **`@aetoskia/react-auth`** — login/register/logout against the auth-server
|
||||
paths declared in the spec's `securitySchemes.bearerAuth`, and attaches the
|
||||
JWT to every API call
|
||||
- a shared MUI theme (`src/shared-theme/`) and the shell
|
||||
@@ -40,7 +40,7 @@ npm run dev
|
||||
|
||||
Open the dev-server URL; the admin lists Parents, Pets, Treatments, Vets,
|
||||
Appointments and Jobs straight from the vet spec. Edit `openapi.yaml` on the
|
||||
server and the client follows on reload — the spec is the contract on both
|
||||
server and the client follows on reload — the spec is the contract on both
|
||||
sides.
|
||||
|
||||
## Where the x- extensions come from
|
||||
|
||||
Reference in New Issue
Block a user