Files
summercms/.planning/phases/15-journal-plugin/15-02-SUMMARY.md
2026-10-06 18:49:08 +02:00

11 KiB

phase, plan, subsystem, tags, requires, provides, affects, actuals, plan_head_before, plugin_repo_head_after, host_repo_head_after, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects actuals plan_head_before plugin_repo_head_after host_repo_head_after tech-stack key-files key-decisions patterns-established requirements-completed coverage duration completed status
15-journal-plugin 02 plugins
journal
cabana
mlmarkdown
goldmark
bonfire
admin
import-export
phase provides
15-01 sm-journal-plugin ID golem15.journal Requires golem15.translate, squashed golem15_journal_* schema, host gitlink + TestBootUserTranslateJournal
Posts/Categories/Tags YAML admin with mltext/mlmarkdown and FormatHTML on save
HasPermissions/HasNavigation/HasSettings; journal-icon.svg embedded in AdminFS
journal:export-posts and journal:import-posts plus Posts toolbar access_import_export
15-03
15-04
16
tokens tasks commits
22500 3 6
8d7979f87e 4ff98f7de85a6404987373ad5630b17fc5542ade d09583ef2825e5fa73b7d5e4cca953834a018c6e
added patterns
github.com/yuin/goldmark v1.8.6 (plugin FormatHTML)
Admin YAML embed file-by-file; NavigationItem has no IconSvg so journal-icon.svg is go:embed in AdminFS
preset is valid only on type: text; post/category mltext slugs omit preset
PHP journal:export-posts/import-posts are JSON-per-slug files, not Winter CSV; toolbar HasAdminActions names are not create/delete
Host gitlink is a nested clone; bump via file:// fetch with protocol.file.allow=always
created modified
../sm-journal-plugin/admin.go
../sm-journal-plugin/admin_permissions.go
../sm-journal-plugin/admin_navigation.go
../sm-journal-plugin/assets/images/journal-icon.svg
../sm-journal-plugin/classes/format_html.go
../sm-journal-plugin/controllers/posts.go
../sm-journal-plugin/controllers/categories.go
../sm-journal-plugin/controllers/tags.go
../sm-journal-plugin/console/export_posts.go
../sm-journal-plugin/console/import_posts.go
../sm-journal-plugin/console/columns.go
../sm-journal-plugin/posts_admin_smoke_test.go
../sm-journal-plugin/plugin.go
../sm-journal-plugin/models/post.go
../sm-journal-plugin/models/post/fields.yaml
../sm-journal-plugin/README.md
../sm-grzybyfunkcjonalne-app/boot_test.go
../sm-grzybyfunkcjonalne-app/plugins/golem15/journal
D-11 is a no-op: post content is mlmarkdown; cabana.RenderMarkdown is not edited; FormatHTML lives in the plugin with goldmark Footnote+Table+WithAttribute plus rejectUnsafe
user_id is WritableForeignKey; FormBeforeCreate stamps it when empty; without access_other_posts List/FormExtendQuery restrict to principal user_id (fail-closed)
publish without access_publish returns ForbiddenError; toolbar import uses the same guard
CLI is JSON files per slug (--path, --dry-run, --force) matching PHP ExportPosts/ImportPosts; PostExport/PostImport column names are the shared field list, not a CSV framework
Toolbar extra buttons exportPosts/importPosts require golem15.journal.access_import_export; names are not create or delete
Compiled journal admin: HasAdminControllers + file-by-file YAML embed + SVG in AdminFS
FilterCategories expands NestedTree children via nest_left/nest_right; switch published uses column: published
HasCommands registers PHP command names; HasAdminActions toolbar reuses console.ExportToDir/ImportFromDir
D-04
D-06
D-08
D-10
D-11
D-13
id description requirement verification human_judgment
D1 Posts admin YAML with mltext/mlmarkdown, FormatHTML on save, nav SVG embed, access_posts and author/publish guards D-04
kind ref status
integration ../sm-journal-plugin#TestPostsFormCompiles pass
kind ref status
integration ../sm-journal-plugin#TestPostsAdminCreateSmoke pass
false
id description requirement verification human_judgment
D2 Categories, Tags, and settings singleton registered; host cabana.Activate sees golem15.journal.posts|categories|tags and settings code journal D-04
kind ref status
integration ../sm-grzybyfunkcjonalne-app#TestBootUserTranslateJournal pass
false
id description requirement verification human_judgment
D3 journal:export-posts and journal:import-posts registered; Posts toolbar exportPosts/importPosts require golem15.journal.access_import_export D-13
kind ref status
unit ../sm-journal-plugin#TestJournalCommands pass
false
id description requirement verification human_judgment
D4 Post content YAML type is mlmarkdown; title/slug/excerpt are mltext; cabana markdown types were not re-added D-10
kind ref status
other ../sm-journal-plugin/models/post/fields.yaml pass
false
id description requirement verification human_judgment
D5 No Winter.Pages menu types and no dashboard widget in plugin.go or admin_navigation.go; README stays application-neutral D-13
kind ref status
other ../sm-journal-plugin/plugin.go pass
false
75min 2026-10-06 complete

Phase 15: Journal plugin plan 02 Summary

YAML-driven Posts/Categories/Tags admin with plugin FormatHTML, plus JSON journal:export-posts/import-posts and a permissioned Posts toolbar

Performance

  • Duration: 75 min
  • Started: 2026-10-06T15:30:00Z
  • Completed: 2026-10-06T16:48:34Z
  • Tasks: 3
  • Files modified: 39

Accomplishments

  • Posts, Categories, and Tags admin controllers boot from adapted YAML (mltext/mlmarkdown); nav embeds assets/images/journal-icon.svg
  • classes.FormatHTML regenerates content_html on admin save (goldmark footnote/table/attribute + rejectUnsafe) without editing cabana.RenderMarkdown
  • Without access_other_posts, list/form queries restrict to the backend principal; publish without access_publish returns ForbiddenError
  • journal:export-posts / journal:import-posts match PHP JSON-per-slug CLI flags; Posts toolbar exportPosts/importPosts require golem15.journal.access_import_export
  • Proof host TestBootUserTranslateJournal still activates user+translate+journal after the gitlink bump to 4ff98f7

Task Commits

Each task was committed atomically in the owning repo:

  1. Task 1: Posts admin + mlmarkdown + FormatHTML - dea0934950a290b98feb3dbe66c5b066a5c8b0a9 (feat) sm-journal-plugin
  2. Task 2: Categories, Tags, Settings + query guards
    • afd0a2cafcc62fcfb13359530147ae798349cfa1 (feat) sm-journal-plugin
    • ab0656964103aef4bc91553818447981e9c91b1d (fix) gofmt settings.go
    • 469182d4103343fd1cd6f71b88668e0c658c0dfc (feat) host gitlink + boot_test controller/settings assertions
  3. Task 3: export/import commands + Posts toolbar
    • 4ff98f7de85a6404987373ad5630b17fc5542ade (feat) sm-journal-plugin
    • d09583ef2825e5fa73b7d5e4cca953834a018c6e (chore) host gitlink 4ff98f7

Plan metadata: (this commit)

Files Created/Modified

  • ../sm-journal-plugin/controllers/posts.go - Posts controller, query guards, FormatHTML hook, HasAdminActions
  • ../sm-journal-plugin/classes/format_html.go - plugin markdown HTML (not cabana.RenderMarkdown)
  • ../sm-journal-plugin/models/post/fields.yaml - mltext title/slug/excerpt, mlmarkdown content
  • ../sm-journal-plugin/console/export_posts.go - journal:export-posts
  • ../sm-journal-plugin/console/import_posts.go - journal:import-posts
  • ../sm-journal-plugin/README.md - CLI command names with acme/blog examples
  • ../sm-grzybyfunkcjonalne-app/plugins/golem15/journal - gitlink 4ff98f7

Decisions Made

  • D-11 no-op: keep existing cabana mlmarkdown; FormatHTML is plugin-local goldmark with footnote/table/attribute plus the same rejectUnsafe gate
  • preset omitted on mltext slugs (cabana allows preset only on type: text); tag slug stays type: text with preset
  • PHP CLI is JSON files, not Winter CSV; shared column sets are ExportColumns/ImportColumns; --force is included because PHP ImportPosts has it
  • Toolbar import refuses published writes without access_publish (CLI has no principal)
  • Navigation SVG is go:embed; NavigationItem has no IconSvg field

Deviations from Plan

Auto-fixed Issues

1. [Rule 3 - Blocking] preset on mltext fails schema compile

  • Found during: Task 1 (YAML compile)
  • Issue: cabana accepts preset only on type: text; PHP post/category slugs are mltext
  • Fix: Drop preset on post and category slugs; keep it on tag slug (type: text)
  • Files modified: ../sm-journal-plugin/models/post/fields.yaml, models/category/fields.yaml
  • Verification: TestPostsFormCompiles PASS
  • Committed in: dea0934 (Task 1)

2. [Rule 3 - Blocking] nav cannot name unknown controllers

  • Found during: Task 1 (cabana.Activate)
  • Issue: Task 1 nav listing categories/tags fails boot until those controllers exist
  • Fix: Defer categories/tags side-menu entries to Task 2
  • Files modified: ../sm-journal-plugin/admin_navigation.go
  • Verification: Task 1 smoke PASS; Task 2 TestBootUserTranslateJournal PASS
  • Committed in: dea0934 / afd0a2c

3. [Rule 3 - Blocking] goldmark must be a direct plugin require

  • Found during: Task 1 (go get / FormatHTML import)
  • Issue: FormatHTML imports goldmark; tidy via HTTPS could not resolve sm-translate-plugin without go.work
  • Fix: Direct-require goldmark v1.8.6 (and gocloud.dev already used by admin smokes); run vet/test with GOWORK=plugin/go.work
  • Files modified: ../sm-journal-plugin/go.mod
  • Verification: go vet ./... PASS
  • Committed in: dea0934 (Task 1)

4. [gofmt] settings.go left unstaged after Task 2 commit

  • Found during: Task 2 (post-commit git status)
  • Issue: gofmt rewrote models/settings.go after the feat commit; amend is disallowed
  • Fix: Separate fix commit
  • Files modified: ../sm-journal-plugin/models/settings.go
  • Verification: gofmt clean
  • Committed in: ab06569 (Task 2 fix)

Total deviations: 4 auto-fixed (3 blocking compile/boot, 1 gofmt follow-up) Impact on plan: Required for cabana schema boot and FormatHTML. No scope creep. CLI is JSON (PHP) rather than inventing CSV.

Issues Encountered

  • Plan verify go test ./... -run '^(TestJournalCommands)$' (and Task 1 TestPosts*) prints [no tests to run] / [no test files] for models, updates, classes, console, controllers. Named tests still --- PASS. Same leaf-package shape as 15-01; stubs were not added.
  • Host go test must run with GOWORK unset so it does not inherit the plugin workspace
  • Nested host gitlink is a separate clone from sibling sm-journal-plugin; bump with git -c protocol.file.allow=always fetch file://…
  • Journal remote still has no refs; gitlink records local SHA 4ff98f7. Do not push unless asked

User Setup Required

None - no external service configuration required.

Next Phase Readiness

Ready for 15-03 (/_journal/api/v1, buckets, backend Bearer writes, media, Typesense gate off). Admin screens and import/export CLI are in. Pages menu types and dashboard widgets remain absent by design.


Phase: 15-journal-plugin Completed: 2026-10-06