From 5db65fb2686bb50c0a98b194f06fb507a013bb8d Mon Sep 17 00:00:00 2001 From: carsten Date: Mon, 28 Sep 2026 22:11:55 +0200 Subject: [PATCH] Update CLAUDE.md for task 8a, add standing update-after-each-task note Order/OrderLine now have a real write path (the public order API), so their "model exists, no API yet" notes are replaced with what's actually there. Participant's entry documents the ad-hoc-create/ always-update-on-order behavior. Mail-events #2 marked implemented with the same detail level as #1. Fase 1 task 8 split into 8a (done)/ 8b (pending, own stack decision) matching the 7a/7b/7c precedent. Added a short process note at the top, per explicit user request: this file should be updated after each (sub)task, not just on request. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 3ed4374..888577e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,10 @@ # Fælles Vinindkøb — Projektplan +> **Proces:** Når en opgave (eller delopgave, fx 7a/8a) er +> gennemført, skal denne fil opdateres til at afspejle det faktisk +> byggede — datamodel, endpoints, og status i Fase 1-listen. Filen er +> den løbende sandhed om projektet, ikke kun den oprindelige plan. + ## Formål Erstatte manuel administration (regneark til betalingstracking, direkte databaseredigering for nye runder/deltagere/vine) med en rigtig @@ -54,6 +59,11 @@ vinbonden Horcher-familiens egne ruter i Frankrig/Belgien), selvom kun - Soft-delete via `is_active` er den normale vej (bevarer historik for deltagere der forlader og kommer tilbage); en rigtig `DELETE` findes også, kun til GDPR-sletningsanmodninger + - Oprettes/opdateres også ad-hoc via den offentlige bestillings-API + (opgave 8a) — matcher emailen en eksisterende deltager på ruten, + **overskrives** `name`/`phone`/`is_active` fra formularen ved hver + bestilling (ingen login = bestillingsformularen er selve vejen man + holder sine oplysninger opdateret); ny email = ny deltager-række - **PurchaseRound** — tilhører en Route - `name` (frit, fx "Forår 2026" — intet sæson/år-felt, da det ikke @@ -74,10 +84,11 @@ vinbonden Horcher-familiens egne ruter i Frankrig/Belgien), selvom kun - **Order** — deltager + runde - `payment_status` (`unpaid`/`paid`), `paid_at`, `created_at` - - *Model findes, men ingen CRUD/API endnu — kommer med opgave 8/9* + - Oprettes via den offentlige bestillings-API (opgave 8a, ingen + login); admin-ordreoversigt + "markér betalt" er stadig opgave 9 - **OrderLine** — ordre + wine_offering + antal - - *Model findes, men ingen CRUD/API endnu — kommer med opgave 8/9* + - Samme som Order — skrives af opgave 8a's bestillings-endpoint - **MailTemplate** — tilhører Route, én pr. `(route, event_type)` - `event_type`: `round_announced` / `order_confirmed` / @@ -102,21 +113,26 @@ vinbonden Horcher-familiens egne ruter i Frankrig/Belgien), selvom kun `POST /purchase-rounds/{id}/announce`, logges i `MailLog`, statusopdateres løbende via Postal-webhook (`POST /webhooks/postal`, RSA-SHA256-signatur verificeret mod DKIM-nøglen fra DNS). -2. Ordre afgivet → kvittering til deltager + notifikation til admin - (findes allerede i den gamle offentlige bestillingsside — flyttes i - opgave 8) +2. Ordre afgivet → kvittering til deltager. **Implementeret** (opgave + 8a): `POST /public/routes/{route_id}/orders` (ingen login) genbruger + 7b's render/send/log-mønster for én deltager. Manglende skabelon + blokerer bevidst **ikke** bestillingen (kun `/announce`'s admin-flow + fejler hårdt på det) — en konfigurationsfejl må aldrig stoppe en + rigtig kundes ordre. Kvitteringen genskaber bevidst det gamle + systems fulde vinkatalog-layout (efterligner den fysiske + bestillingsseddel ved vinbonden). *Notifikation til admin ved ny + ordre findes ikke endnu.* 3. **Nyt:** Admin markerer ordre "betalt" → automatisk kvitteringsmail - til deltager (opgave 9) + til deltager (opgave 9 — bygger videre på samme mønster) -Event #2 og #3 er modelleret i `MailEventType` -(`order_confirmed`/`payment_confirmed`) og kan allerede have skabeloner -oprettet via 7a's CRUD, men selve udløsningen (fra ordre-flowet i -opgave 8/9) er ikke bygget endnu — 7b's afsendelses-/logmønster -(rendering, `send_mail`, `MailLog`) er genbrugbart når det sker. +Event #3 er modelleret i `MailEventType` (`payment_confirmed`) og kan +allerede have en skabelon oprettet via 7a's CRUD, men selve +udløsningen (fra "markér betalt"-handlingen i opgave 9) er ikke bygget +endnu. ## Fase 1 — nuværende scope -**Færdige opgaver (1-7):** +**Færdige opgaver (1-7, 8a):** 1. ✅ FastAPI + SQLModel + PostgreSQL + Alembic scaffolding 2. ✅ Datamodellerne (Organization/Route-hierarki) 3. ✅ Deltager-migrering fra MongoDB (308 deltagere importeret, @@ -132,9 +148,15 @@ opgave 8/9) er ikke bygget endnu — 7b's afsendelses-/logmønster - **7b**: Afsendelse via Postal + `MailLog` (`POST /purchase-rounds/{id}/announce`, `GET /mail-logs`) - **7c**: Postal-webhook til leveringsstatus (`POST /webhooks/postal`) +8. "Flyt offentlig bestillingsformular til nyt API" — delt i to: + - **8a**: ✅ Backend-API (`GET /public/routes/{id}/current-round`, + `POST /public/routes/{id}/orders`), ad-hoc deltageroprettelse, + kvitteringsmail + - **8b**: Selve den nye offentlige frontend — brugeren har ikke + adgang til den gamle frontends kode (hårdt koblet til det gamle + API), så en ny bygges. Egen stack-beslutning, ikke taget endnu. **Resterende opgaver:** -8. Flyt offentlig bestillingsformular til nyt API (fortsat uden login) 9. Admin-ordreoversigt pr. runde med "markér betalt" → trigger mail #3 10. Genskab afhentningsliste (HTML-udtræk til print) mod ny datamodel 11. Simpelt React admin-UI til pkt. 5, 6, 7, 9