docs: sync todos with g15office and map phases to milestone tasks

Tag the 17 open todos with their g15office task IDs, close 7 todos that
are already done or promoted to Phase 16.3, and record the sync rules
and the phase-to-task map in .planning/G15OFFICE.md.
This commit is contained in:
2026-10-11 02:01:50 +02:00
parent 93a3112fb7
commit 3f9d3b4f11
25 changed files with 114 additions and 0 deletions

49
.planning/G15OFFICE.md Normal file
View File

@@ -0,0 +1,49 @@
# g15office sync
Todos and phases in `.planning/` are mirrored in g15office, project `summercms` (see `g15office.json`). Keep the two in sync.
## Todos
- Every todo in `todos/pending/` has a g15office task, and its frontmatter carries the task ID: `g15office: <id>`.
- Capturing a todo creates its g15office task in the same session (type Bug, Feature, Improvement or Task; the description ends with `Local: .planning/todos/pending/<file>`). Write the ID back into the frontmatter.
- Closing a todo (moving it to `todos/done/`) also moves its task to `Live`, or to `Rejected` if it was dropped, with a one-line comment saying where it was done.
- A todo promoted to a phase closes into that phase's milestone task. For example, `backend-admin-api-tokens` became the Phase 16.3 task.
## Phases
Each roadmap phase has one milestone task titled `[Phase N] <name>`, type Task. Post a short comment on it whenever the phase advances (discussed, planned, a plan executed, verified, UAT, shipped), and keep its status in step:
| Phase state | g15office status |
|---|---|
| Not discussed, or discussed but not planned | To do |
| Planned or executing | In progress |
| Executed, waiting on verification/UAT | Testing |
| Complete | Live |
A new phase, inserted or added, gets its task when it is added to `ROADMAP.md`. A todo that a phase will deliver becomes a subtask of that phase's task.
| Phase | Task | Phase | Task |
|---|---|---|---|
| 1 | 1ar7xvcd | 14.2 | fdlwwsfh |
| 2 | 7uqoumsi | 14.2.1 | bf2wsxhz |
| 3 | 0tszvge7 | 14.3 | utmjarsp |
| 4 | qbwhi5u9 | 15 | qqbp8xtm |
| 5 | 5ahymkhp | 16 | n0nuhzca |
| 6 | altu10qm | 16.1 | y7adhmsm |
| 7 | jzdzafce | 16.2 | gwzqpjyi |
| 8 | 9nwkuxzo | 16.3 | 5lcivllc |
| 9 | hrjqlvb8 | 17 | ejoiuzy4 |
| 10 | vgrmjuwl | 18 | 46vnjevj |
| 10.1 | hwr4istb | 18.1 | 2vriy9pw |
| 10.2 | 6nwcght4 | 19 | 6nojs2go |
| 11 | sz63omvi | 19.1 | uakdpkc8 |
| 11.1 | 9crhrf7k | 19.2 | hgol7otp |
| 11.2 | pvwvnvvi | 19.3 | lpybyjdh |
| 12 | odwb6onw | 19.4 | l7t8dbyl |
| 12.1 | c5wcij0a | 19.5 | onunbz3l |
| 12.2 | hkoccgbx | 19.6 | avoroeb4 |
| 13 | nkbr2ybg | 20 | 0rkcboo0 |
| 14 | cwlaryop | | |
| 14.1 | v0j5lwvq | | |
Backlog phase 999.1 (newsletter) has no task until it is promoted into the roadmap.

View File

@@ -0,0 +1,6 @@
# Todos
- `pending/`: open todos. Each one has a matching g15office task, and its frontmatter carries the task ID as `g15office: <id>`.
- `done/`: closed todos, each ending with a `## Closed <date>` note.
**Keep todos synchronized with g15office** (project `summercms`). Creating, closing or promoting a todo updates its g15office task in the same session. The rules and the phase → task map are in [`../G15OFFICE.md`](../G15OFFICE.md).

View File

@@ -3,6 +3,9 @@ title: Backend admin personal API tokens (Phase 16.3)
date: 2026-09-28
priority: high
area: summercms.go admin auth
g15office: 5lcivllc
status: done
closed: 2026-10-11
---
Apparatus provides personal API tokens for backend admins (`PersonalApiToken` model, `TokenAuthenticate` + `ForceJsonResponse` middleware, token create/revoke on the backend user form). Nothing in Płytarium calls it, so it is deferred past v1. The Phase 9 `backend` guard already accepts `Authorization: Bearer` for CLI and tests.
@@ -10,3 +13,7 @@ Apparatus provides personal API tokens for backend admins (`PersonalApiToken` mo
Revisit when a Golem15 project needs scripted access to the admin API. See `.planning/notes/apparatus-dissolved-into-framework.md`.
**2026-10-10:** Promoted to Phase 16.3 (scoped tokens, Journal agent use case). No migration of Apparatus tokens.
## Closed 2026-10-11
Promoted to Phase 16.3 on 2026-10-10. The g15office task is now the Phase 16.3 milestone task.

View File

@@ -9,6 +9,8 @@ files:
- modules/cabana/extension.go
- modules/pact
- admin/src/components/form/registry.ts
status: done
closed: 2026-10-11
---
## Problem
@@ -30,3 +32,7 @@ Add a capability interface in `pact` (for example `HasFormFieldTypes`) through w
- Update the cabana README and `docs/`, the admin OpenAPI and the generated types, and commit `dist/`, all in the same change.
Decide in a framework phase (or a decimal phase before the first plugin that needs it). Phase 18's `money` field stays a core cabana type (18-CONTEXT); this todo covers the plugins that follow.
## Closed 2026-10-11
Done in Phase 16.2: `pact.FormFieldType` plus cabana's field-type registry (`modules/cabana/field_type.go`).

View File

@@ -6,6 +6,8 @@ severity: minor
files:
- modules/cabana/form_schema.go
- ../sm-journal-plugin/models/category/fields.yaml
status: done
closed: 2026-10-11
---
## Problem
@@ -15,3 +17,7 @@ D-21 asks for a rich content field on Journal categories. cabana has no WYSIWYG
## Solution
Add a `richeditor` field type (and an `mlricheditor` variant if a translatable rich field is needed) to the cabana form schema (`modules/cabana/form_schema.go`) and to the admin SPA. Keep the server-side gate on save: the Journal plugin's `classes.CheckHTML` runs in the Categories controller's `FormBeforeCreate` and `FormBeforeUpdate`, and the new field type must not bypass it. Then switch the Journal category `content` field in `models/category/fields.yaml` from `textarea` to `richeditor`.
## Closed 2026-10-11
Done in Phase 16.2: the Journal `blogeditor`/`mlblogeditor` plugin field type edits category and post HTML content.

View File

@@ -3,6 +3,8 @@ title: Keep imported HTML post bodies intact when a Journal post is re-saved in
date: 2026-10-09
priority: high
area: sm-journal-plugin
status: done
closed: 2026-10-11
---
Phase 16 RESEARCH Pitfall 2. The PHP journal export carries the pl post `content` as **HTML** (61 of 63 published posts on grzybyfunkcjonalne.pl). `journal:import-posts` stores it as is and the pl `content_html` is correct, so imported posts render fine. But an admin save of such a post runs `FormatHTML(content)`: goldmark without `html.WithUnsafe()` replaces raw HTML with `<!-- raw HTML omitted -->`, so the post body is wiped (probe in 16-RESEARCH.md: `pl HTML content -> out="<!-- raw HTML omitted -->\n"`).
@@ -16,3 +18,7 @@ Fix in `sm-journal-plugin`, one of:
- add a content format flag on the post so HTML-sourced posts are edited as HTML.
Whatever the fix, it must keep the XSS gate (`classes.CheckHTML`) on every write path and keep the PHP API contract of `content`/`content_html` unchanged. Add a test that re-saves an imported HTML post and asserts `content_html` is unchanged.
## Closed 2026-10-11
Done in Phase 16.2 (D-03): `FormatHTML` passes raw HTML through (`html.WithUnsafe()`), covered by `TestFormatHTMLKeepsRawHTML` and the posts admin smoke test.

View File

@@ -3,6 +3,8 @@ title: Nest framework packages under modules/ — same beach names
date: 2026-09-28
priority: high
area: summercms.go
status: done
closed: 2026-10-11
---
Mechanical layout change only. Do not rename packages.
@@ -18,3 +20,7 @@ Import paths become `git.golem15.com/golem15/summercms/modules/<name>`. Rewrite
Do this before Phase 11 adds more root packages. Do not remap onto Winter `system` / `backend` / `cms`.
After the move is green, run the sibling todo that writes a short `README.md` per module.
## Closed 2026-10-11
Done in Phase 10.2: every framework package lives under `modules/<name>/`.

View File

@@ -3,6 +3,8 @@ title: Short README.md per modules/* after the nest
date: 2026-09-28
priority: medium
area: summercms.go/modules
status: done
closed: 2026-10-11
---
Blocked on `.planning/todos/pending/nest-framework-packages-under-modules.md`.
@@ -12,3 +14,7 @@ After the packages live under `modules/`, spawn a GSD explore / researcher pass
Each file: one paragraph on what the package is for, who imports it, and one example entry point (`Package.Type` or file). No architecture essays. No copy-paste of planning docs.
The top-level `summercms.go/README.md` should then link the directory instead of explaining every beach name inline.
## Closed 2026-10-11
Done: all 24 `modules/*` packages ship a README (Phase 10.2, later the Role and mnemonic passes).

View File

@@ -3,6 +3,8 @@ title: Rewrite summercms.go README — onboard, recreate login, honest cutover
date: 2026-09-28
priority: high
area: summercms.go/README.md
status: done
closed: 2026-10-11
---
Replace `README.md`. It currently says pre-alpha / nothing runs. That is false.
@@ -16,3 +18,7 @@ The long story lives here, not in `fonoteka.go`. Include:
- After the `modules/` nest lands, point at `modules/<name>/README.md` instead of listing beach-named packages at the repo root.
Do not invent a production runbook. Operator procedure stays in the PHP `docs/deploy/plytarium.com.md` until Phase 15.
## Closed 2026-10-11
Done: the root README now covers key concepts, requirements, quick start and links to every module README.

View File

@@ -5,6 +5,7 @@ area: docs
severity: minor
files:
- docs/architecture/performance-and-scaling.md
g15office: gy0u2z5c
---
## Problem

View File

@@ -7,6 +7,7 @@ files:
- ../sm-translate-plugin/admin_settings.go
- modules/pact/capabilities.go (SettingsItem.Controller)
- ../examples/golem15-wintercms-starter/plugins/golem15/translate/Plugin.php (registerSettings: messages)
g15office: ewlzc7we
---
## Problem

View File

@@ -7,6 +7,7 @@ files:
- modules/boardwalk/boardwalk.go:110-133
- admin/src/app/fieldTypes.ts
- admin/src/components/form/registry.ts
g15office: ltcvqext
---
## Problem

View File

@@ -3,6 +3,7 @@ title: Reject duplicate console command names in bonfire.NewRoot
date: 2026-09-30
priority: low
area: summercms.go bonfire
g15office: u4rtpcl1
---
`bonfire.NewRoot` validates each command name's form (`namespace:verb`, or one of the bare framework names) but does not check for duplicates. The generated application `main` appends plugin commands after the framework's runtime commands, so a plugin that declares a command with the same name as a framework command, or as another plugin's command, builds and starts without an error, and which one runs is decided by Cobra.

View File

@@ -3,6 +3,7 @@ title: Port the FAQ plugin as sm-faq-plugin so FAQs become editable
date: 2026-10-07
priority: medium
area: sm-faq-plugin
g15office: ylgfanlk
---
Phase 16 ships the grzybyfunkcjonalne.pl FAQ (`g15_faq` slug `what-mushrooms-can-give-you`) as static i18n/markdown content in the Nuxt app. Later blogs need editors to manage FAQs, so port `Golem15.Faq` 1:1 as its own `sm-faq-plugin` repo (see `.planning/notes/core-plugins-own-repos.md`): models, admin screens and a public read API by slug.

View File

@@ -6,6 +6,7 @@ severity: minor
files:
- ../sm-journal-plugin/controllers/api/authors.go
- modules/lagoon/backend_admin_migrations.go
g15office: esrp4qtx
---
## Problem

View File

@@ -3,6 +3,7 @@ title: lagoon README registers an after-commit GORM callback that can sort after
date: 2026-09-30
priority: high
area: summercms.go lagoon
g15office: fqfoclxq
---
The `lagoon.OnDatabase` example in `modules/lagoon/README.md` registers its create callback with `After("gorm:after_create")` and calls `lagoon.AfterCommit` from it. GORM sorts that callback after `lagoon:after_commit` (itself `After("gorm:commit_or_rollback_transaction")`), so the work is buffered after the buffer was flushed and never runs, with no error or log. A docs test reproduced it: the same callback registered with `After("gorm:create").Before("gorm:commit_or_rollback_transaction")` runs as expected.

View File

@@ -3,6 +3,7 @@ title: Port MailBlocker and the block-mail checkbox with the mailing work
date: 2026-10-04
priority: medium
area: sm-user-plugin mail
g15office: 9cxuwfzy
---
The PHP user form has a "block all mail to this user" checkbox (`block_mail`, update context) backed by `Golem15\User\Models\MailBlocker`. Phase 12.1 left it out (12.1-CONTEXT D-21): it needs its own table and a check in every mail send path, which is a mail feature rather than an admin screen.

View File

@@ -3,6 +3,7 @@ title: Port the menu plugin as sm-menu-plugin so blog menus become editable
date: 2026-10-07
priority: medium
area: sm-menu-plugin
g15office: rfd6l4u4
---
Phase 16 hardcodes the grzybyfunkcjonalne.pl main menu as typed config in the Nuxt app, replacing the `g15_menu` component. Later blogs need editors to manage menus again, so port `Golem15.Menu` 1:1 as its own `sm-menu-plugin` repo (see `.planning/notes/core-plugins-own-repos.md`): models, admin screens and a public read API that the shared `vue-journal-layer` (or a sibling layer) can consume.

View File

@@ -3,6 +3,7 @@ title: Convert module README Go code blocks to compiled src= references
date: 2026-09-30
priority: medium
area: summercms.go/modules/*/README.md, internal/docsite
g15office: gplauwlb
---
Phase 11.1 (D-18) publishes every module README as an `api/<name>` docs page, but its Go code blocks (about 41 across 22 READMEs) are only identifier-checked, not compiled. Move each to an `Example*` or region in the module's `example_test.go` and reference it with `src=`, then drop the README exemption in `internal/docsite` `check_policy.go` so ROADMAP 11.1 SC4 can be widened back to "every Go example in the docs".

View File

@@ -3,6 +3,7 @@ title: Refresh fonoteka.go README — short status plus migrate/serve/login
date: 2026-09-28
priority: high
area: ../fonoteka.go/README.md
g15office: is8whvje
---
Keep this file a short run card. Do not duplicate the framework story.

View File

@@ -3,6 +3,7 @@ title: make:admin-controller output does not boot and names the model after the
date: 2026-09-30
priority: medium
area: summercms.go internal/build
g15office: evdzmic4
---
`summer make:admin-controller acme.blog Posts` writes a controller and YAML that compile but are not a working admin screen:

View File

@@ -3,6 +3,7 @@ title: Scaffolded files carry a DO NOT EDIT header, and make:command cannot reac
date: 2026-09-30
priority: medium
area: summercms.go internal/build
g15office: hqyet7qh
---
Two scaffolder conventions that the porting walkthrough had to work around:

View File

@@ -3,6 +3,7 @@ title: make:model and make:migration in the same second produce migrations that
date: 2026-09-30
priority: high
area: summercms.go internal/build
g15office: xp2bt2rl
---
`nextMigrationFile` in `internal/build/artifact.go` names a migration `<UTC second>_<slug>` and only moves to the next second when a file with the same full name already exists. Two migrations with different slugs created in the same second share one timestamp, and `refreshRegistry` sorts them by file name. Running `summer make:model acme.news Item` and `summer make:migration acme.news AddFlag` back to back (a probe in a copy of examples/hello, 2026-09-30) wrote `20260930213644_add_flag.go` and `20260930213644_create_acme_news_items.go`, and `registry.gen.go` listed `AddFlag` before `CreateItems`. gormigrate runs the set in slice order, so the ALTER TABLE migration would run before the CREATE TABLE one and fail.

View File

@@ -3,6 +3,7 @@ title: Port the sitemap plugin 1:1 as sm-sitemap-plugin for the next blog projec
date: 2026-10-03
priority: medium
area: sm-sitemap-plugin
g15office: krx9geua
---
Phase 14 dropped sitemap for Płytarium, because Nuxt builds its own sitemap with `@nuxtjs/seo` and fonoteka registers no menu item types. The next port after Płytarium is a blog project (grzybyfunkcjonalne.pl or golem15.com), and it needs `Golem15.Sitemap` 1:1.

View File

@@ -3,6 +3,7 @@ title: Neutral default resource URL in wristband.DefaultOptions
date: 2026-09-30
priority: medium
area: summercms.go wristband
g15office: iarcg5dk
---
`wristband.DefaultOptions()` ships a `Resource` default (the RFC 8707 resource indicator) whose URL names a consuming application, and the comments around it name that application too: the `Resource` field comment and the default in `modules/wristband/server.go`, the package comment at the top of `server.go`, and comments in `stores.go` and `client_issue.go`.