From f4c497681f9b88af5faff85a5b744f3f645f0c5c Mon Sep 17 00:00:00 2001 From: Jan Novak Date: Thu, 7 May 2026 22:37:52 +0200 Subject: [PATCH] chore: CHANGELOG and progress tracker for M5.3 Co-Authored-By: Claude Opus 4.7 --- CHANGELOG.md | 5 + ...-05-03-2349-go-backend-rewrite-progress.md | 2 +- ...-2114-go-rewrite-m5-3-python-api-shadow.md | 113 ++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 docs/plans/2026-05-07-2114-go-rewrite-m5-3-python-api-shadow.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f3d2fcf..a3684f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026-05-07 22:37 CEST — feat(py): M5.3 — Python /api/* shadow endpoints + +- `app.py`: four new JSON routes (`/api/version`, `/api/adults`, `/api/juniors`, `/api/payments`) mirroring the Go `/api/*` handlers; `_unwrap_view_model_for_api()` helper expands pre-serialised JSON strings and renames `month_labels_json` → `month_labels`, `raw_payments_json` → `raw_payments` to match Go wire contract. +- `tests/test_app.py`: four new smoke tests asserting top-level key sets and that unwrapped fields are objects (not strings). + ## 2026-05-07 20:13 CEST — feat(go): M5.2 — HTTP handlers for /api/adults, /api/juniors, /api/payments, /api/version - `web/api/handler.go`: `Handler` struct + `ServeAdults`, `ServeJuniors`, `ServePayments`, `ServeVersion` using `membership.Sources`. diff --git a/docs/plans/2026-05-03-2349-go-backend-rewrite-progress.md b/docs/plans/2026-05-03-2349-go-backend-rewrite-progress.md index 883b487..b97f69f 100644 --- a/docs/plans/2026-05-03-2349-go-backend-rewrite-progress.md +++ b/docs/plans/2026-05-03-2349-go-backend-rewrite-progress.md @@ -99,7 +99,7 @@ Goal: byte-equal JSON between Python and Go for every route. This is the parity - [x] **M5.1** Hand-author Go structs for `/api/adults`, `/api/juniors`, `/api/payments`, `/api/version` with explicit `json:` tags matching Python keys; emit JSON Schemas via `github.com/invopop/jsonschema` to `tests/fixtures/api-schema/` — `f253e3f` - [x] **M5.2** Implement Go handlers for `/api/*` routes composing `services/*` results into the JSON structs — `7d48e8f` -- [ ] **M5.3** Add Python `/api/X` shadow endpoints in [app.py](app.py): `jsonify(view_model_dict)` — no transformation +- [x] **M5.3** Add Python `/api/X` shadow endpoints in [app.py](app.py): `jsonify(view_model_dict)` — no transformation — `40e4a9e` - [ ] **M5.4** Build `cmd/parity/main.go`: hits both backends' `/api/X`, normalizes allowlist (`render_time.total`, `build_meta`), prints `cmp.Diff`. Add `make parity` target **Gate:** For each route, `make parity` reports zero non-allowlisted diffs across the M3 fixture corpus. diff --git a/docs/plans/2026-05-07-2114-go-rewrite-m5-3-python-api-shadow.md b/docs/plans/2026-05-07-2114-go-rewrite-m5-3-python-api-shadow.md new file mode 100644 index 0000000..b7d75a7 --- /dev/null +++ b/docs/plans/2026-05-07-2114-go-rewrite-m5-3-python-api-shadow.md @@ -0,0 +1,113 @@ +# M5.3 — Python `/api/X` shadow endpoints + +Companion to: +- [2026-05-03-2349-go-backend-rewrite.md](2026-05-03-2349-go-backend-rewrite.md) (master design) +- [2026-05-03-2349-go-backend-rewrite-progress.md](2026-05-03-2349-go-backend-rewrite-progress.md) (M5.3 row) +- [2026-05-07-1431-m5-json-api-parity.md](2026-05-07-1431-m5-json-api-parity.md) (Python view-model extraction prep) +- [2026-05-07-1650-go-rewrite-m5-1-api-structs-schemas.md](2026-05-07-1650-go-rewrite-m5-1-api-structs-schemas.md) (Go wire types) + +## Context + +M5.1 (Go wire types + JSON Schemas) and M5.2 (Go HTTP handlers for `/api/adults` `/api/juniors` `/api/payments` `/api/version`) have merged. M5.3 mirrors the same four endpoints on the Python Flask side so M5.4's `cmd/parity` tool can hit both backends and diff the JSON. After M5.3, every byte the Go side emits has a Python counterpart to compare against. + +The Python view-model builders ([scripts/views.py](scripts/views.py)) already produce dicts very close to the wire shape — except three template-only fields (`member_data`, `month_labels_json`, `raw_payments_json`) are pre-`json.dumps`'d for inline `