From 06635f21cd2a0ee70a7767f53abd090a57eaea64 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Fri, 18 Sep 2026 18:53:33 +0200 Subject: [PATCH] docs(05-01): record plan close-out in STATE and ROADMAP - Advance to plan 2 of 6; 05-01 marked complete - DATA-03, DATA-06, DATA-10 checked in REQUIREMENTS.md --- .planning/REQUIREMENTS.md | 12 ++++++------ .planning/ROADMAP.md | 4 ++-- .planning/STATE.md | 33 ++++++++++++++++++++------------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 7085ba8..a39fdde 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -38,14 +38,14 @@ Requirements for v1 (the Płytarium port). Each maps to roadmap phases. "User" b - [x] **DATA-01**: GORM on Postgres through one shared *sql.DB (pgx stdlib) with a separate small pgx pool reserved for River's listener - [x] **DATA-02**: Each plugin ships a gormigrate migration set with up and down; sets run in plugin dependency order with per-plugin version tracking; AutoMigrate is never the schema source -- [ ] **DATA-03**: Models get timestamps, soft delete, and lifecycle hooks (beforeValidate, beforeCreate, beforeSave, beforeDelete, afterDelete) that can cascade soft deletes inside a transaction +- [x] **DATA-03**: Models get timestamps, soft delete, and lifecycle hooks (beforeValidate, beforeCreate, beforeSave, beforeDelete, afterDelete) that can cascade soft deletes inside a transaction - [ ] **DATA-04**: Relations cover belongsTo, hasOne, hasMany and belongsToMany with ordered results and dedicated pivot models carrying business columns (CollectionEditor role/granted_at/granted_by, album_artists sort_order) - [ ] **DATA-05**: Model rule strings (required, between, unique:table, nullable, integer, in) are validated on save via go-playground/validator with translated messages and a 422 error map shaped like Laravel's -- [ ] **DATA-06**: Mass assignment goes through per-endpoint request DTOs honoring each model's fillable allow-list; serialization honors a hidden deny-list with an explicit per-call override +- [x] **DATA-06**: Mass assignment goes through per-endpoint request DTOs honoring each model's fillable allow-list; serialization honors a hidden deny-list with an explicit per-call override - [ ] **DATA-07**: Custom casts exist for jsonable columns, money as a fixed four-decimal string, and encrypted-at-rest secrets (AES-GCM, app-key derived) that are also hidden from serialization - [ ] **DATA-08**: A polymorphic file attachment table (owner type, owner id, field, disk path, sort order, public/private) backs attachOne and attachMany, stored via gocloud.dev/blob with the same public URL shape - [ ] **DATA-09**: All 25 Płytarium models and their squashed migration set are ported with matching table names, columns, indexes and defaults (migration count is not itself an acceptance number — squashed per plan-time decision D-01 in 05-CONTEXT.md) -- [ ] **DATA-10**: Paginated responses use the exact `{data, meta{current_page, last_page, per_page, total}}` envelope without a links key +- [x] **DATA-10**: Paginated responses use the exact `{data, meta{current_page, last_page, per_page, total}}` envelope without a links key - [ ] **DATA-11**: Other plugins can hook a model's lifecycle through the GORM callback registry and extend its schema with a companion migration ### HTTP and routing (HTTP) @@ -174,14 +174,14 @@ Which phases cover which requirements. Updated during roadmap creation. | I18N-03 | Phase 4 | Complete | | DATA-01 | Phase 3 | Complete | | DATA-02 | Phase 3 | Complete | -| DATA-03 | Phase 5 | Pending | +| DATA-03 | Phase 5 | Complete | | DATA-04 | Phase 5 | Pending | | DATA-05 | Phase 5 | Pending | -| DATA-06 | Phase 5 | Pending | +| DATA-06 | Phase 5 | Complete | | DATA-07 | Phase 5 | Pending | | DATA-08 | Phase 5 | Pending | | DATA-09 | Phase 5 | Pending | -| DATA-10 | Phase 5 | Pending | +| DATA-10 | Phase 5 | Complete | | DATA-11 | Phase 5 | Pending | | HTTP-01 | Phase 3 | Complete | | HTTP-02 | Phase 3 | Complete | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index cc31d21..7eaa023 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -189,7 +189,7 @@ Plans: Plans: **Wave 1** -- [ ] 05-01-PLAN.md — Verify models-leaf rule, restructure plugins into Winter layout, ship lagoon write/read-path primitives +- [x] 05-01-PLAN.md — Verify models-leaf rule, restructure plugins into Winter layout, ship lagoon write/read-path primitives **Wave 2** *(blocked on Wave 1 completion)* @@ -391,7 +391,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 2. API parity harness bootstrap | 5/5 | Complete | 2026-09-17 | | 3. First vertical slice — genres end to end | 4/4 | Complete | 2026-09-17 | | 4. CLI scaffolding, i18n and mail | 4/4 | Complete | 2026-09-18 | -| 5. Data layer full fidelity | 0/6 | Planned | - | +| 5. Data layer full fidelity | 1/6 | In Progress| | | 6. HTTP routing, auth groups and rate limiting | 0/TBD | Not started | - | | 7. User plugin and authentication | 0/TBD | Not started | - | | 8. OAuth2.1 authorization server | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index f2a625d..a2c2731 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,15 +3,15 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: Phase 5 context gathered -last_updated: "2026-09-18T16:06:30.536Z" -last_activity: 2026-09-18 -- Phase 05 planning complete +stopped_at: Completed 05-01-PLAN.md +last_updated: "2026-09-18T16:50:24.472Z" +last_activity: 2026-09-18 progress: total_phases: 15 completed_phases: 4 total_plans: 23 - completed_plans: 17 - percent: 27 + completed_plans: 18 + percent: 78 --- # Project State @@ -21,16 +21,16 @@ progress: See: .planning/PROJECT.md (updated 2026-09-16) **Core value:** An existing WinterCMS-shaped app can be ported plugin by plugin to a single Go binary without its frontend noticing: the PHP version's API contract is the acceptance test. -**Current focus:** Phase 5 — data layer full fidelity +**Current focus:** Phase 05 — data-layer-full-fidelity ## Current Position -Phase: 5 -Plan: Not started +Phase: 05 (data-layer-full-fidelity) — EXECUTING +Plan: 2 of 6 Status: Ready to execute -Last activity: 2026-09-18 -- Phase 05 planning complete +Last activity: 2026-09-18 -Progress: [██████████] 100% +Progress: [████████░░] 78% ## Performance Metrics @@ -63,6 +63,7 @@ Progress: [██████████] 100% | Phase 04 P04-02 | 10 min | 3 tasks | 11 files | | Phase 04 P04-03 | 6 min | 3 tasks | 15 files | | Phase 04 P04-04 | 8 min | 3 tasks | 9 files | +| Phase 05 P01 | 16 min | 4 tasks | 37 files | ## Accumulated Context @@ -117,6 +118,12 @@ Recent decisions affecting current work: - [Phase 04]: mail.smtp.tls defaults to mandatory STARTTLS; none/notls is opt-in for Mailpit and is never inferred — D-18 T-04-10: no silent production TLS downgrade; Mailpit needs explicit NoTLS - [Phase 04]: Mailpit image is axllent/mailpit:v1.31.1; receipt is polled from /api/v1/messages then /api/v1/message/{ID} — D-19: a successful Send claim requires observed receipt through a separate HTTP API; pin a released Mailpit tag - [Phase 04]: fstest.MapFS WalkDir cannot host '..' keys; malformed lang paths are extra-segment and wrong-suffix files — MapFS Open/WalkDir follows .. into an infinite directory loop; parseLangPath still rejects cleaned traversal +- [Phase 05]: Models-leaf rule holds on keios.eu user, jz chat, and pxpx checkout; contracts/VOs/jobs/broadcasting stay inside the cast-or-hook conversion treatments +- [Phase 05]: plugin.go Models()/Migrations() return registry All(); Boot calls classes.RegisterHooks when *gorm.DB is published — later Phase 5 plans add files, not edit plugin.go +- [Phase 05]: lagoon.Fill matches gorm column tags against the caller allow-list and logs dropped keys once per type+key in non-production — D-05 D-06 +- [Phase 05]: Lifecycle Has* interfaces use GORM-native signatures; WithSoftDeleteCascade does not open a new transaction — DATA-03 primitive +- [Phase 05]: Paginate coerces nil data to []; RegisterJoinTable fails loud on nil db — DATA-10 and pivot-write contract +- [Phase 05]: DATA-09 migration count is not an acceptance number (D-01); HTTP DTO fuzz moves to Phase 12 (D-07) ### Pending Todos @@ -138,6 +145,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-09-18T13:23:21.535Z -Stopped at: Phase 5 context gathered -Resume file: .planning/phases/05-data-layer-full-fidelity/05-CONTEXT.md +Last session: 2026-09-18T16:50:24.446Z +Stopped at: Completed 05-01-PLAN.md +Resume file: None