7.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
SummerCMS in Go: a content management framework modelled on WinterCMS/OctoberCMS, for the Golem15 stack. An application built on it compiles into one binary: framework modules, the application's plugins, the embedded admin SPA and console commands. Read README.md first (module table, quick start, development commands), then .planning/PROJECT.md and .planning/notes/ for decisions.
The core value: a WinterCMS-shaped app is ported plugin by plugin to a single Go binary without its frontend noticing. When porting endpoints, the existing frontend's requests (Nuxt app, MCP server) define the contract; response shapes are not "improved" during a port.
References: the WinterCMS starter at ../examples/golem15-wintercms-starter, the first port target Płytarium at /media/nvme/dev/golem15/fonoteka.
Commands
go vet ./...
go test -short ./... # fast loop, no Docker
go test ./... # also the testcontainers Postgres/Mailpit tests (needs Docker)
go test -short ./modules/cabana -run TestName # one test
cd examples/hello && go test ./... # separate workspace module, not covered by the root ./...
go install ./cmd/summer # the CLI
go test ./cmd/summer -run TestDocsTree # docs checker
summer docs:build --check # docs checker (identifiers, links, anchors, src= snippets, command names)
summer docs:sync # refresh src= code copies in docs/ after changing their source
npm --prefix admin ci
npm --prefix admin run test | typecheck | build | dev
scripts/check-admin-openapi.sh [--check] # swag annotations in cabana -> admin/openapi/admin.json -> admin/src/api/schema.d.ts
scripts/check-admin-dist.sh # committed modules/boardwalk/dist must match a fresh admin build
scripts/check-phaseN.sh # per-phase verification gates
Docker-backed tests skip themselves under testing.Short(). Keep go vet and go test ./... green at every commit.
Architecture
- One Go module,
git.golem15.com/golem15/summercms; each package is imported as.../modules/<name>. Module names follow a beach theme, and each README carries a**Name:**mnemonic; a new module gets a fitting beach name, a README in the standard structure and a row in the rootREADME.mdtable. - Compiled plugins. A plugin implements capability interfaces from
pact(routes, config, migrations, middleware, commands, admin screens, translations, mail, jobs).summer buildreads the application'ssummer.yaml, generatesplugins.gen.goandmain.go(internal/build) and builds the binary.partyorders plugins byRequires()and runsRegister(app)thenBoot(app);backpack.Appis the per-instance container (config, typed service registry viaapp.Lookup[T](), event bus, activated plugins). No runtime plugin loading (stdlibplugin, yaegi) without a decision note. - Request path.
surfassembles plugin routes and named middleware onto a stdlibnet/httpServeMux;bouncerauthenticates (JWT, and personal API tokens resolved via cabana);towelcarries actor/locale throughcontext.Context;wirekeeps JSON byte-compatible with the PHP (Laravel) backend. - Admin. Plugins describe lists, forms, filters and relations in WinterCMS-style YAML (
columns.yaml,fields.yaml).cabanacompiles them at boot and serves a JSON admin API (swag-annotated, seeadmin_openapi.go);boardwalkembeds the Vue 3 SPA fromadmin/, whose build output is committed inmodules/boardwalk/dist. Before tagging a release that changesadmin/, rebuild, commit the dist and passcheck-admin-dist.sh(.planning/notes/2026-10-07-embedded-admin-release-gate.md). - Data.
lagoon: GORM on Postgres only, per-plugin gormigrate migrations, model helpers, attachments (lagoon/attach).conga: River jobs on the same pool plus thesummer_jobsrecord. YAML is parsed withgoccy/go-yaml, nevergopkg.in/yaml.v3(archived). - Dependencies. Standard library first. A new dependency needs a research doc or a phase/decision note naming it (
.planning/research/STACK.mdhas the decided set and versions).
Sibling repositories
The meta repo (..) holds the framework and its consumers side by side. Consumers require a tagged framework version (vX.Y.Z tags on master) and replace it with ../summercms.go during development:
fonoteka.go: Płytarium application (go.work workspace; app-specific plugins stay in-repo).sm-*-app: other applications (sm-grzybyfunkcjonalne-app,sm-summercmsio-app,sm-bm-app).sm-*-plugin: shared core plugins in their own repos, module path = repo path, mounted in apps as git submodules atplugins/<vendor>/<name>(.planning/notes/core-plugins-own-repos.md). Commit and push the plugin first, then the pointer bump in the app as a separate commit.vue-journal-layer: public Nuxt layer consumed by site apps as a pnpm git dependency pinned by tag.
Framework code never names a consuming application (READMEs, docs, examples use neutral names like blog or acme).
Documentation rules
- A change to a module's exported API, config keys, CLI commands or dependencies updates that module's
README.mdand the affecteddocs/pages in the same commit. - Module README structure: H1 name, one-sentence summary, import line,
**Name:**mnemonic, then Overview, Features, Usage, API reference, optional Configuration and CLI commands, Dependencies, Testing. The root table's purpose text reuses the summary sentence. - Every identifier in a README or docs page must exist in the package (the docs checker enforces it). Config keys are not checked automatically; review them by hand.
MSD workflow
Work goes through MSD (/msd-* commands; the older GSD tooling is retired): /msd-quick for small tasks (.planning/quick/), /msd-fast for trivial edits, /msd-debug, and /msd-discuss-phase → /msd-plan-phase → /msd-execute-phase for roadmap phases (.planning/ROADMAP.md, .planning/phases/). Urgent work is inserted as decimal phases (/msd-phase --insert). Don't edit the repo outside an MSD workflow unless the user says so.
Project rules that override MSD defaults:
- Lean planning. Few, large plans per phase. Before writing PLAN.md files, present the suggested plan count with a one-line scope each and wait for confirmation.
- Unit tests are the last plan of every phase. Earlier plans may carry smoke tests but are not blocked on coverage.
- State through handlers. Update
.planning/STATE.mdwithmsd_run query state.*handlers, not raw edits. - g15office sync. Todos and phase milestone tasks are mirrored in g15office (
.planning/G15OFFICE.md); post a short comment when a phase advances.
Commits and concurrency
- No co-author tags. One logical change per commit; planning docs and code in separate commits.
- Several Claude sessions often work in this repo at once (different phases, quick tasks). Stage files explicitly by path (never
git add -A), leave other sessions' uncommitted edits (oftenSTATE.md,state.json) alone, and check for in-flight edits before touching shared files such as cabana. - Don't push, tag or deploy without the user's go-ahead; deploys are documented per application (for example
../sm-grzybyfunkcjonalne-app/DEPLOY.md).