docs(15-01): complete journal plugin clone and schema plan
Tasks completed: 3/3 - Clone plugin, translatable Post tracer, three-plugin host boot - Categories, tags, pivots, settings, author slug - en/pl phrasebooks, README, host CORS SUMMARY: .planning/phases/15-journal-plugin/15-01-SUMMARY.md Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
232
.planning/phases/15-journal-plugin/15-01-SUMMARY.md
Normal file
232
.planning/phases/15-journal-plugin/15-01-SUMMARY.md
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
---
|
||||||
|
phase: 15-journal-plugin
|
||||||
|
plan: 01
|
||||||
|
subsystem: plugins
|
||||||
|
tags: [journal, gormigrate, translate, translatable, postgres, gitlink, cors]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 14.2.1
|
||||||
|
provides: "sm-translate-plugin Translatable/SetTranslated/MorphName, sm-grzybyfunkcjonalne-app user+translate mount"
|
||||||
|
provides:
|
||||||
|
- "sm-journal-plugin clone at D-23 with ID golem15.journal and Requires golem15.translate"
|
||||||
|
- "squashed golem15_journal_* tables plus backend_users.golem15_bloghub_author_slug"
|
||||||
|
- "Post/Category Translatable MorphName PHP class strings and TestPostTranslatableSmoke"
|
||||||
|
- "proof-host three-plugin boot TestBootUserTranslateJournal and CORS _journal/api/*"
|
||||||
|
affects: [15-02, 15-03, 15-04, 16]
|
||||||
|
|
||||||
|
actuals:
|
||||||
|
tokens: 10000
|
||||||
|
tasks: 3
|
||||||
|
commits: 6
|
||||||
|
plan_head_before: a28bb1e4ece6040850793b90eb543474d2dd2e8a
|
||||||
|
plugin_repo_head_after: bb903a68509159e90dac6a77a0124d2b2dd14843
|
||||||
|
host_repo_head_after: 41c9b9212dbe11c3b1da5d0a87323b2245d32f6a
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Sibling plugin go.mod replaces only summercms => ../summercms.go; other plugin replaces live in go.work"
|
||||||
|
- "models tests call Plugin.Migrations() instead of importing updates (models leaf check)"
|
||||||
|
- "Proof host gitlink at plugins/golem15/journal with go.work use and go.mod replace"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- ../sm-journal-plugin/go.mod
|
||||||
|
- ../sm-journal-plugin/plugin.go
|
||||||
|
- ../sm-journal-plugin/README.md
|
||||||
|
- ../sm-journal-plugin/models/post.go
|
||||||
|
- ../sm-journal-plugin/models/category.go
|
||||||
|
- ../sm-journal-plugin/models/tag.go
|
||||||
|
- ../sm-journal-plugin/models/settings.go
|
||||||
|
- ../sm-journal-plugin/models/post_translatable_smoke_test.go
|
||||||
|
- ../sm-journal-plugin/updates/202610060001_create_golem15_journal_posts.go
|
||||||
|
- ../sm-journal-plugin/updates/202610060002_create_golem15_journal_categories.go
|
||||||
|
- ../sm-journal-plugin/updates/202610060003_create_golem15_journal_tags.go
|
||||||
|
- ../sm-journal-plugin/updates/202610060004_create_golem15_journal_posts_categories.go
|
||||||
|
- ../sm-journal-plugin/updates/202610060005_create_golem15_journal_posts_tags.go
|
||||||
|
- ../sm-journal-plugin/updates/202610060006_create_golem15_journal_settings.go
|
||||||
|
- ../sm-journal-plugin/updates/202610060007_add_author_slug_to_backend_users.go
|
||||||
|
- ../sm-journal-plugin/lang/en/lang.yaml
|
||||||
|
- ../sm-journal-plugin/lang/pl/lang.yaml
|
||||||
|
modified:
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/summer.yaml
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/go.work
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/go.mod
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/.gitmodules
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/boot_test.go
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/plugins.gen.go
|
||||||
|
- ../sm-grzybyfunkcjonalne-app/config/http.yaml
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Go schema is squashed to golem15_journal_* from PHP pin 02110eb1; rainlab-era names are not created"
|
||||||
|
- "translate replace stays in journal go.work, not go.mod, so the host workspace module path does not conflict"
|
||||||
|
- "Uncategorized is seeded (A4 PHP seed_all_tables still inserts it); first post is not seeded"
|
||||||
|
- "slug is in Translatable() as well as TranslatableIndexes() because SetTranslated requires a declared translatable field"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Compiled journal plugin: party.Register, HasMigrations/HasModels/HasLang, Requires exactly golem15.translate"
|
||||||
|
- "Host mounts user, translate, journal as gitlinks; TestBootUserTranslateJournal asserts three IDs"
|
||||||
|
- "Plugin README stays application-neutral (the application / blog / acme)"
|
||||||
|
|
||||||
|
requirements-completed: [D-01, D-02, D-03, D-04, D-06, D-07, D-09, D-10, D-17, D-18, D-19, D-20, D-21, D-22, D-23]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: "sm-journal-plugin exists at D-23 with module git.golem15.com/golem15/sm-journal-plugin, ID golem15.journal, Requires exactly golem15.translate"
|
||||||
|
requirement: D-09
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "../sm-journal-plugin#TestPostTranslatableSmoke"
|
||||||
|
status: pass
|
||||||
|
- kind: other
|
||||||
|
ref: "git ls-remote git@git.golem15.com:golem15/sm-journal-plugin.git"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: "Migration 202610060001 creates golem15_journal_posts; English lives on the host row and Polish title/slug in golem15_translate_attributes"
|
||||||
|
requirement: D-10
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin/models#TestPostTranslatableSmoke"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: "Proof host Activate returns user, translate, and journal; gitlink plugins/golem15/journal; plugins.gen.go blank-imports sm-journal-plugin"
|
||||||
|
requirement: D-18
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "../sm-grzybyfunkcjonalne-app#TestBootUserTranslateJournal"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D4
|
||||||
|
description: "After migrate, six golem15_journal_* tables exist, backend_users.golem15_bloghub_author_slug exists, settings.search_use_typesense defaults false"
|
||||||
|
requirement: D-04
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: "../sm-journal-plugin/updates#TestJournalTables"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D5
|
||||||
|
description: "en/pl phrasebooks exist, plugin README is application-neutral, host CORS includes _journal/api/* with supports_credentials false"
|
||||||
|
requirement: D-06
|
||||||
|
verification:
|
||||||
|
- kind: other
|
||||||
|
ref: "go test ./... -short; python README forbidden-name scan; grep _journal/api/* config/http.yaml"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D6
|
||||||
|
description: "PHP journal tree at SHA 02110eb1c0c3861370b0b9b47b209a0702ac5d88 is unmodified"
|
||||||
|
requirement: D-07
|
||||||
|
verification:
|
||||||
|
- kind: other
|
||||||
|
ref: "git -C /media/nvme/dev/golem15/fonoteka/plugins/golem15/journal rev-parse HEAD && git diff empty"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
|
||||||
|
duration: 11min
|
||||||
|
completed: 2026-10-06
|
||||||
|
status: complete
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 15 Plan 01: Clone journal plugin, squash schema, boot three plugins Summary
|
||||||
|
|
||||||
|
**Compiled sm-journal-plugin persists one en/pl Post through translate, mounts in sm-grzybyfunkcjonalne-app with user+translate, and ships squashed golem15_journal_* plus CORS**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 11 min
|
||||||
|
- **Started:** 2026-10-06T16:19:00Z
|
||||||
|
- **Completed:** 2026-10-06T16:29:41Z
|
||||||
|
- **Tasks:** 3
|
||||||
|
- **Files modified:** 31
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
- Cloned `sm-journal-plugin` with ID `golem15.journal`, `Requires` exactly `golem15.translate`, and squashed posts DDL
|
||||||
|
- `TestPostTranslatableSmoke` stores English on the host row and Polish in `golem15_translate_attributes` under MorphName `Golem15\Journal\Models\Post`
|
||||||
|
- Proof host Activate returns three plugins including `golem15.journal`; `summer build` regenerates `plugins.gen.go`
|
||||||
|
- Categories, tags, pivots, settings singleton ID=1, and `backend_users.golem15_bloghub_author_slug` migrate; Uncategorized is seeded, posts are not
|
||||||
|
- en/pl UI catalogs, application-neutral README, host CORS `_journal/api/*` with `supports_credentials: false`
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically in the owning repo:
|
||||||
|
|
||||||
|
1. **Task 1: Clone the plugin, persist one en/pl Post title, and boot the host with three plugins**
|
||||||
|
- `54322128fb6d4fb9d73e3b74e5575c86e9798c68` (feat) sm-journal-plugin tracer
|
||||||
|
- `445022ef711274cb4ea1973a5b10ee7afc047a53` (fix) models leaf + go.mod translate replace
|
||||||
|
- `d77f945c05f372b2ca221c5a0acb21137d46e330` (feat) sm-grzybyfunkcjonalne-app mount
|
||||||
|
2. **Task 2: Add categories, tags, pivots, settings singleton, and author_slug** - `9ae4b9141eaec1bb8efb367f8d8f525f15f23dc8` (feat) sm-journal-plugin
|
||||||
|
3. **Task 3: Add en/pl phrasebook, neutral README, and host CORS**
|
||||||
|
- `bb903a68509159e90dac6a77a0124d2b2dd14843` (feat) sm-journal-plugin lang/README
|
||||||
|
- `41c9b9212dbe11c3b1da5d0a87323b2245d32f6a` (feat) host CORS + gitlink `bb903a6`
|
||||||
|
|
||||||
|
**Plan metadata:** (this commit)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
- `../sm-journal-plugin/plugin.go` - compiled registration, Requires translate, HasMigrations/HasModels/HasLang
|
||||||
|
- `../sm-journal-plugin/models/post.go` - TableName, MorphName, Translatable, AttachRelations, belongsTo BackendUser
|
||||||
|
- `../sm-journal-plugin/updates/202610060001` through `007` - squashed journal DDL and author slug
|
||||||
|
- `../sm-journal-plugin/README.md` - application-neutral plugin docs
|
||||||
|
- `../sm-grzybyfunkcjonalne-app/summer.yaml`, `go.work`, `go.mod`, `.gitmodules`, `boot_test.go`, `plugins.gen.go`, `config/http.yaml` - three-plugin host + CORS
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
- Squash to `golem15_journal_*` only; do not emit rainlab-era table names
|
||||||
|
- Keep `sm-translate-plugin` replace in journal `go.work`, not `go.mod`, matching the host workspace `use` of translate
|
||||||
|
- Seed Uncategorized because PHP `seed_all_tables.php` at this pin still inserts it (A4); do not seed the first post
|
||||||
|
- Declare `slug` on `Translatable()` so `SetTranslated` accepts the indexed slug
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 3 - Blocking] models cannot import updates**
|
||||||
|
- **Found during:** Task 1 (`summer build`)
|
||||||
|
- **Issue:** `checkModelsLeaf` rejects `models/post_translatable_smoke_test.go` importing `.../updates`
|
||||||
|
- **Fix:** Smoke test calls `(&journal.Plugin{}).Migrations()` and `(&translate.Plugin{}).Migrations()`
|
||||||
|
- **Files modified:** `../sm-journal-plugin/models/post_translatable_smoke_test.go`
|
||||||
|
- **Verification:** `summer build` in the host; `TestPostTranslatableSmoke` PASS
|
||||||
|
- **Committed in:** `445022e` (Task 1 fix)
|
||||||
|
|
||||||
|
**2. [Rule 3 - Blocking] go.mod translate replace collides with host workspace**
|
||||||
|
- **Found during:** Task 1 (host `go vet`)
|
||||||
|
- **Issue:** `replace => ../sm-translate-plugin` from `plugins/golem15/journal` points at a second path next to `use ./plugins/golem15/translate`
|
||||||
|
- **Fix:** Drop the translate replace from plugin `go.mod`; keep it in plugin `go.work`
|
||||||
|
- **Files modified:** `../sm-journal-plugin/go.mod`
|
||||||
|
- **Verification:** host `go vet` and `TestBootUserTranslateJournal` PASS
|
||||||
|
- **Committed in:** `445022e` (Task 1 fix)
|
||||||
|
|
||||||
|
**3. [Rule 2 - Missing Critical] slug must be translatable for SetTranslated**
|
||||||
|
- **Found during:** Task 1 (`TestPostTranslatableSmoke`)
|
||||||
|
- **Issue:** PHP `$translatable` includes `['slug','index'=>true]`; indexes-only made `SetTranslated(..., "slug", "pl", ...)` fail
|
||||||
|
- **Fix:** Add `slug` to `Post.Translatable()` (and Category)
|
||||||
|
- **Files modified:** `../sm-journal-plugin/models/post.go`, `models/category.go`
|
||||||
|
- **Verification:** `TestPostTranslatableSmoke` PASS
|
||||||
|
- **Committed in:** `5432212` / Task 2 Category
|
||||||
|
|
||||||
|
**4. [A4] Seed Uncategorized despite RESEARCH grep skip**
|
||||||
|
- **Found during:** Task 2 (execute-time read of PHP `seed_all_tables.php`)
|
||||||
|
- **Issue:** Plan said RESEARCH grep found no seeder — skip; A4 said verify at execute. The pin seeder still inserts Uncategorized and a first post
|
||||||
|
- **Fix:** Seed Uncategorized only; do not seed posts
|
||||||
|
- **Files modified:** `../sm-journal-plugin/updates/202610060002_create_golem15_journal_categories.go`
|
||||||
|
- **Verification:** `TestJournalTables` asserts one `uncategorized` row and zero posts
|
||||||
|
- **Committed in:** `9ae4b91` (Task 2)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 4 auto-fixed (3 blocking/correctness, 1 A4 seeder)
|
||||||
|
**Impact on plan:** Required for host mount, translate writes, and PHP pin fidelity. No scope creep.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
- `git submodule add` from a local path needed `protocol.file.allow=always`; `.gitmodules` URL was then set to `git@git.golem15.com:golem15/sm-journal-plugin.git`
|
||||||
|
- Journal remote still has no refs; gitlink records local SHA `bb903a6`. Do not push unless asked
|
||||||
|
- Host submodule is a separate checkout from the sibling; Task 2/3 SHAs were fetched from the sibling with file protocol
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
Ready for 15-02 (admin YAML, FormatHTML, permissions/nav, import/export). Public `/_journal/api/v1` handlers are not in this plan; CORS path is in place. Plugin remote is empty until a later push.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 15-journal-plugin*
|
||||||
|
*Completed: 2026-10-06*
|
||||||
Reference in New Issue
Block a user