From ed6e43ae51522242dba0a20146de8444ecaa1c3f Mon Sep 17 00:00:00 2001 From: Mischa Date: Fri, 24 Jul 2026 20:55:28 +0200 Subject: [PATCH] docs: trim CLAUDE.md 305->179 lines; extract code descriptions to docs/ CLAUDE.md is loaded into context on every request, so every line has a recurring cost. Applies one rule to decide what earns its place: keep what changes behaviour (rules and gotchas Claude cannot discover before it acts); extract what merely describes code (Claude reads the code anyway, and prose about code silently drifts). The four stale facts fixed in the previous commit were all in the "describes code" class -- active_trip, the Admin2 version, demo-load's scope, the gitignore list. None were rules. That is the argument for moving this material next to what it documents. Extracted (kept as pointers): - entry-map + trip-feed-col parameter contracts (56 lines) -> reference/ architecture.md "Shared partial contracts". CLAUDE.md keeps only the invariants: single map path, must assign window.tripMap/homeMap, keep trip-feed-col single-purpose, initTripStats depends on MapUtils. - Prod override runbook (49 -> 9 lines) -> guides/deploy-cycle.md "The env override tree", incl. the Twig dev/prod table and WEB_HOST. CLAUDE.md keeps the two behavioural rules: never commit prod values, and Admin on the server writes to the env tree (so check both config paths, env wins). - GPX API routes, session auth and the Blob/FormData upload gotcha -> guides/gpx-manager.md "How the manager is wired". - Trip-switch procedure -> guides/trip-switching.md. CLAUDE.md keeps the one rule that matters: never re-add pageconfig.parent to post-form.md. - Also trimmed the dev-command table and custom-plugin table added in the previous commit; both largely restated the Makefile and blueprints. Fixed the guides being pointed into, so the pointers lead to truth: - trip-switching.md instructed editing a pageconfig.parent that no longer exists -- its whole "two files must be updated together" premise was obsolete and would have reintroduced the desync it warned about. - architecture.md: Grav 2.0.4->2.0.7, Admin2 2.0.10->2.0.12, corrected the posting pipeline to show cache-on-save injecting parent before the write, added entry-actions to the custom-plugin list. - japan-korea-2026 -> denmark-2026 across guides/reference (docs/solutions keeps its historical references intact -- those are incident records). Verified: every markdown link resolves, every referenced section heading exists, and each extracted item was confirmed present in its new home. Co-Authored-By: Claude Opus 5 (1M context) --- CLAUDE.md | 160 ++++----------------------------- docs/guides/deploy-cycle.md | 46 ++++++++++ docs/guides/gpx-manager.md | 24 ++++- docs/guides/posting.md | 6 +- docs/guides/trip-switching.md | 41 ++++----- docs/reference/architecture.md | 95 +++++++++++++++----- 6 files changed, 179 insertions(+), 193 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 6f1f7d8..b05935b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,26 +28,13 @@ The Docker dev server runs at **http://localhost:8081** (mapped from container p ### Local dev commands -| Command | What it does | -|---|---| -| `make setup` | One-shot first run: `build` → `start` → `install-plugins` → `fix-perms` | -| `make start` / `make stop` | Bring the compose stack up / down (`start-grav` = Grav service only) | -| `make build` | Rebuild the custom Docker image (after `Dockerfile` changes) | -| `make build-assets` | Rebuild theme JS/CSS bundles in a `node:20-alpine` container | -| `make install-plugins` | GPM-install everything in `plugins.txt`, then re-apply local patches | -| `make fix-perms` | Fix ownership in the container after root-owned writes | +`make setup` for a first run (build → start → install-plugins → fix-perms); `make start` / `make stop` thereafter. Other targets are self-describing in the `Makefile`. -**`make build-assets` is mandatory after editing anything in `user/themes/intotheeast/js/src/`.** Sources live in `js/src/`; esbuild writes the committed bundles — `js/main.js`, `js/map.js`, `js/feed-actions.js`, `js/trip-publish.js`, `js/post/`, and the CSS extracted into `css-compiled/`. **Never hand-edit those.** By contrast `css/style.css` and `css/tokens.css` are hand-authored sources, not build outputs. `build-assets` runs as your host UID (`--user`) so the outputs in the bind-mounted `user/` tree are not root-owned. +**`make build-assets` is mandatory after editing anything in `user/themes/intotheeast/js/src/`** — esbuild writes the *committed* bundles `js/main.js`, `js/map.js`, `js/feed-actions.js`, `js/trip-publish.js`, `js/post/`, and `css-compiled/`. **Never hand-edit those.** By contrast `css/style.css` and `css/tokens.css` are hand-authored sources. ### Custom plugins -Three plugins are site-owned and tracked in the `user/` repo (everything else under `user/plugins/` is GPM-managed and git-ignored): - -| Plugin | Role | -|---|---| -| `cache-on-save` | Clears the page-tree cache on `new-entry` submits, and derives the write target from `site.active_trip` (`onFormValidationProcessed` → `setData('parent', …)`) | -| `story-blocks` | Storytelling shortcode blocks for long-form stories (depends on `shortcode-core`) | -| `entry-actions` | Owner-only, active-trip-scoped journal entry actions (delete) via the Grav API | +Three plugins are site-owned and tracked in the `user/` repo (everything else under `user/plugins/` is GPM-managed and git-ignored): **`cache-on-save`** (clears page-tree cache on `new-entry` submits + injects the write target from `site.active_trip`), **`story-blocks`** (story shortcodes), **`entry-actions`** (owner-only entry delete via the API). ### Local plugin patches @@ -66,96 +53,28 @@ The site is structured around Trip entities. Key facts: - `01.dailies/` and `04.stories/` are `routable:false` **data containers** — visiting `/trips//dailies` or `/stories` directly 404s/redirects; their children (entries/stories) render at their own detail URLs and are aggregated by the trip page - Site nav in `base.html.twig` has Home + Past Trips only — does not link to trip sub-sections - New journal entries are written to the active trip's `dailies` — the write target is derived from `site.active_trip` at submit time by the `cache-on-save` plugin (post-form.md no longer hardcodes `pageconfig.parent`) -- The trip page (`trip.html.twig`) uses a **client-side filter bar** (All content / Journal / Stories). The standalone `/dailies`, `/map`, `/stats`, `/stories` view pages no longer exist — do NOT try to re-create them or link to them. This filter bar + stats chrome is shared with the home active-trip view via the `trip-feed-col` partial (see "Shared trip-feed-col partial" below) +- The trip page (`trip.html.twig`) uses a **client-side filter bar** (All content / Journal / Stories). The standalone `/dailies`, `/map`, `/stats`, `/stories` view pages no longer exist — do NOT try to re-create them or link to them. This filter bar + stats chrome is shared with the home active-trip view via the `trip-feed-col` partial (see "Two shared partials" below) - Stats are shown inline on the trip page via a toggle (the standalone `/stats` view was removed) - GPX route files live as media on the trip page itself, parsed client-side via toGeoJSON (bundled into `js/map.js`) and drawn on the trip/home map -- Manage GPX files (view/upload/delete) at `/gpx-manager` — requires admin login; filenames are auto-slugified on upload -### One map path: `MapUtils.initEntryMap` + the `entry-map` partial +### Two shared partials — the rules -There is a **single** map code path on the site. The engine is `MapUtils.initEntryMap(opts)` in `js/src/maplibre-utils.js` (bundled into `js/map.js` via `make build-assets` — never hand-edit `js/map.js`). It builds the MapLibre map, places markers/popups, fits bounds, draws the GPX journey, and wires the fullscreen toggle. +Trip and home render the same map and feed chrome through **two** shared partials, both included with `{% include … with {…} only %}`. Full parameter contracts: [`docs/reference/architecture.md`](docs/reference/architecture.md) → "Shared partial contracts". The rules that must not be broken: -The map **markup + invocation** is shared via one partial: - -- **Partial:** `user/themes/intotheeast/templates/partials/entry-map.html.twig` -- **Used by:** `trip.html.twig` and the active branch of `home.html.twig` (both via `{% include ... with {...} only %}`) - -It renders the `.home-map-col` column (map div `#{{ map_id }}` + fullscreen button) and, when `entries` is non-empty, a thin `