Five weeks of undocumented evolution left the docs describing a site that
partly no longer exists, with nothing marking which documents were historical.
The code is treated as the source of truth throughout; every claim below was
verified against code, config or the Makefile rather than inferred.
Two mechanisms, following patterns the repo already used:
- docs/reference/superseded-decisions.md (new) — one authoritative table of all
14 reversals: what was planned, where, what is true now, when, and why. Plus
a short list of decisions that were NOT reversed, since their planning docs
are old enough to look suspect.
- Inline "> **Superseded ...**" notes at each stale claim, so a claim can never
be read un-corrected. This mirrors the existing "> History:" notes in
architecture.md and "> **Changed 2026-07:**" in trip-switching.md.
Scope split by tense: present-tense docs (CLAUDE.md, reference/, guides/,
README.md, CONCEPTS.md) are corrected; past-tense records (plans/, specs/,
milestones/, summary.md, pm-analysis.md) are annotated only, never rewritten —
their staleness is what makes them records.
Present-tense corrections:
- CLAUDE.md asserted css-compiled/ is generated from css/style.css and
css/tokens.css. That source relationship does not exist: css/ is hand-authored
and served directly via assets.addCss in partials/base.html.twig, while
css-compiled/ is esbuild output from the CSS imports inside js/src/*.js.
Highest-severity finding — an always-loaded file inviting a hand-edit of a
generated bundle.
- README.md documented every remote-* target without the -test/-prod suffix
guard-env requires, so its entire server runbook was unrunnable, and listed
7 of ~20 targets while CLAUDE.md designates it authoritative for the full
list. Rewritten with all targets, grouped, and the suffix rule stated.
- README.md told readers to "git clone" into user/, which is a submodule.
- architecture.md: nav is Home + Trips + (authenticated) New Post, not
"Home + Past Trips only"; template tree omitted trips.html.twig,
post-form.html.twig and forms/, and placed base.html.twig at templates/ root
rather than in partials/; entry-actions has three API routes, not just delete;
added the undocumented css-compiled/maplibre-gl.css output and a section on
the /post pin editor as the one sanctioned non-entry-map map.
- design-system.md: documented 13 colour tokens against 19 in tokens.css
(missing --color-error, --color-draft-accent and four glass overlays); claimed
"all 3 map templates"; and described --color-canvas as "white".
- design-system-light.md documented a light palette in present tense. No light
mode exists — tokens.css has a single :root block, no prefers-color-scheme or
data-theme switch, and no light hex appears in css/. Banner added.
- posting.md said photos were optional; they are required, 1-6. It documented
hero_image, which was removed for entries (stories keep it). It had no mention
of the frontend edit flow or photo editor, both shipped 2026-07-08. Photo
files are photo-01..NN, zero-padded.
- working/README.md advertised summary.md as the project's "current state" while
summary.md describes Leaflet, /tracker, /map and /stats. Most misleading line
in the tree.
- CLAUDE.md: recorded js/src/location-map.js as the one sanctioned exception to
the single-map-path rule, and documented that make start/setup fail on a clean
checkout because docker-compose.yml still builds a travel-memories service
whose source moved out in a80b0a9.
Also: 2026-07-23-post-form-location-override.md read "Not started" while merged
in user/ as dd19995; status corrected.
Findings that are not documentation problems — the compose breakage, a
repeatable drift check, the unused shortcode-gallery-plusplus, and demo fixtures
for retired views — are collected in
docs/working/2026-07-25-doc-drift-recommendations.md and deliberately not acted
on. Design and verification method: docs/working/specs/2026-07-25-docs-reconciliation-design.md
The submodule gitlink is deliberately not bumped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
171 lines
8.4 KiB
Markdown
171 lines
8.4 KiB
Markdown
# PM Analysis — What to Build (and What to Skip)
|
||
|
||
*Role: Senior Product Manager. Audience: one solo traveler (Mischa), platform: Grav CMS flat-file PHP, no native app.*
|
||
|
||
> **Historical — written 2026-06-21. The verdicts still hold; some delivery mechanisms do not.**
|
||
>
|
||
> The **SKIP** column is still the standing decision and has not been revisited — background GPS,
|
||
> followers, comments, social discovery, reactions, reels, 3D flyover, print, and AI itineraries
|
||
> remain deliberately out of scope. What changed is *how* some **BUILD** items shipped: the map and
|
||
> stats render inline on the trip page rather than as `/map` and `/stats`, MapLibre replaced Leaflet,
|
||
> galleries use PhotoSwipe rather than `shortcode-gallery-plusplus`, and `hero_image` was dropped for
|
||
> entries. See [`../reference/superseded-decisions.md`](../reference/superseded-decisions.md).
|
||
|
||
---
|
||
|
||
## Starting position
|
||
|
||
Polarsteps and FindPenguins are native mobile apps built around:
|
||
1. Background GPS tracking (requires OS-level access)
|
||
2. Social networks (followers, discovery, comments)
|
||
3. App-side video/reel processing
|
||
|
||
**None of these three pillars are reproducible in a web CMS.** Any plan that tries to replicate them wholesale is delusional. What we can do is cherry-pick the *outputs* — the things those apps display to readers — and build them into the blog in ways that add real value to both Mischa (the poster) and readers (friends/family following along).
|
||
|
||
---
|
||
|
||
## Feature-by-Feature Audit
|
||
|
||
| Feature | Makes sense solo? | Buildable in Grav+JS? | Value to readers? | Worth the cost? | Decision |
|
||
|---|---|---|---|---|---|
|
||
| Auto background GPS tracking | No — posting manually anyway | No — requires native app | — | — | **SKIP** |
|
||
| Interactive map of visited locations | Yes | Yes — Leaflet.js + frontmatter lat/lng | High | High | **BUILD** |
|
||
| Route line on map between entries | Yes | Yes — connect entry coords in order | High | Medium | **BUILD** |
|
||
| Entry location name (city, country) | Yes | Yes — manual input on form | High | Low | **BUILD** |
|
||
| Weather metadata per entry | Yes | Yes — Open-Meteo free API, no key needed | Medium | Medium | **BUILD** |
|
||
| Photo gallery per entry | Yes | Yes — shortcode-gallery-plusplus installed | High | Low | **BUILD** (already partial) |
|
||
| Hero image on feed cards | Yes | Yes — already in frontmatter | High | Low | **BUILD** |
|
||
| Trip statistics page | Yes | Yes — compute from frontmatter | Medium | Low | **BUILD** |
|
||
| Countries visited world map | Yes | Yes — highlight SVG or Leaflet layers | Medium | Medium | **BUILD** |
|
||
| Follower system | No — solo blog | Would need auth + DB | None | — | **SKIP** |
|
||
| Comments on entries | No — spam risk, no community | Would need plugin + moderation | Minimal | — | **SKIP** |
|
||
| Social discovery / explore | No — not a platform | Would need indexing infrastructure | None | — | **SKIP** |
|
||
| Group trip / travel buddies | No — solo trip | — | — | — | **SKIP** |
|
||
| Reactions / likes | No | — | — | — | **SKIP** |
|
||
| 3D flyover video | No — proprietary pipeline | No | Nice | — | **SKIP** |
|
||
| Trip reels / short video | No — app-side processing | No | Nice | — | **SKIP** |
|
||
| Travel book / print | No — out of scope | No | — | — | **SKIP** |
|
||
| AI itinerary builder | No — trip already started | No | — | — | **SKIP** |
|
||
| Flight detection | No — requires native app sensors | No | — | — | **SKIP** |
|
||
| Delayed sharing / live location | No — blog posts after the fact | Irrelevant | — | — | **SKIP** |
|
||
| Offline posting | Already works | Already works (Grav form offline) | — | — | **ALREADY EXISTS** |
|
||
| Scheduled / draft posts | Already exists | Already exists (publish_date) | — | — | **ALREADY EXISTS** |
|
||
| Step suggestions / nudges | No — push notifications not possible | No | — | — | **SKIP** |
|
||
| Eebook / export | No — out of scope | Possible but niche | — | — | **SKIP** |
|
||
|
||
---
|
||
|
||
## What to Build — Summary
|
||
|
||
### Keep (already exists, just needs to work reliably)
|
||
- Login-gated mobile posting form ✓
|
||
- Draft and scheduled publishing ✓
|
||
|
||
### Build
|
||
|
||
**1. Entry enrichment** — make each entry richer with zero extra effort from Mischa:
|
||
- Location name (city, country) captured at post time
|
||
- Weather auto-fetched via Open-Meteo at post time using lat/lng
|
||
- Photos displayed in a proper gallery (lightbox)
|
||
- Hero image shown on feed card
|
||
|
||
**2. Interactive map** — the single most "Polarsteps-like" thing that's genuinely achievable:
|
||
- `/map` page with Leaflet.js
|
||
- Marker per entry (lat/lng from frontmatter)
|
||
- Route line connecting entries in date order
|
||
- Popup with title, date, thumbnail, link to entry
|
||
- Mobile-friendly (touch pan/zoom)
|
||
|
||
**3. Trip statistics** — a simple stats page:
|
||
- Days on the road (count of entries with distinct dates)
|
||
- Entries posted
|
||
- Countries/regions visited (derived from location name field)
|
||
- Approx distance traveled (sum of haversine distances between GPS points)
|
||
|
||
---
|
||
|
||
## What to Skip — with reasons
|
||
|
||
| Feature | Reason skipped |
|
||
|---|---|
|
||
| Background GPS tracking | Requires native app. Grav runs on a server. |
|
||
| Social features (followers, comments, likes) | Adds spam risk, moderation burden, zero value for a solo travel blog with a personal audience. A "share link" is enough. |
|
||
| Video reels | App-side video processing pipeline, not available in a web CMS. |
|
||
| 3D flyover | Proprietary rendering. Not worth building from scratch. |
|
||
| Travel book printing | Out of scope. Mischa can use Polarsteps or FindPenguins for this if desired. |
|
||
| AI itinerary builder | Trip is already in progress. Out of scope. |
|
||
| Discovery / explore | Not a platform. No community. |
|
||
| Group trips | Solo traveler. |
|
||
| Flight detection | Requires native OS sensor access. |
|
||
| Delayed sharing | Moot — we don't broadcast real-time location at all. |
|
||
|
||
---
|
||
|
||
## Milestone Plan
|
||
|
||
### Milestone 1 — Entry Enrichment (2–3 days)
|
||
**Goal:** Every entry is richer out of the box — photo gallery works, location name shown, weather captured, hero image on feed.
|
||
|
||
Features:
|
||
- Location name field (city + country) added to post form and displayed on entries/cards
|
||
- Weather auto-fetch on post form (JS call to Open-Meteo using entered lat/lng, fills hidden fields)
|
||
- Weather displayed on entry page
|
||
- Photo gallery working (shortcode-gallery-plusplus or native media display)
|
||
- Hero image shown on tracker feed cards
|
||
|
||
**Value:** Immediate. Makes each entry feel like a real travel log entry, not just a text post.
|
||
|
||
---
|
||
|
||
### Milestone 2 — Interactive Map (2–3 days)
|
||
**Goal:** A `/map` page shows all entries as markers on an interactive Leaflet.js map, connected by a route line, with popups.
|
||
|
||
Features:
|
||
- New `map` page and template
|
||
- Leaflet.js loaded from CDN (no build step)
|
||
- Entries serialized to JSON in the template (lat/lng, title, date, url, hero_image)
|
||
- Route polyline in chronological order
|
||
- Marker popup: date, title, thumbnail, "Read entry →" link
|
||
- Map added to site navigation
|
||
|
||
**Value:** High for readers — gives a bird's-eye view of the trip. The single most compelling "where is Mischa?" feature.
|
||
|
||
---
|
||
|
||
### Milestone 3 — Statistics Page (1–2 days)
|
||
**Goal:** A `/stats` page with key trip numbers.
|
||
|
||
Features:
|
||
- Days on the road (first entry date to today)
|
||
- Total entries posted
|
||
- Unique countries visited (derived from location names)
|
||
- Approximate distance traveled (haversine between consecutive entry GPS points)
|
||
- Simple, scannable layout — no charts needed for v1
|
||
|
||
**Value:** Medium — nice context for readers, satisfying for Mischa to see progress.
|
||
|
||
---
|
||
|
||
### Milestone 4 — Map on Tracker Feed (1 day)
|
||
**Goal:** A mini-map showing recent positions above or alongside the feed, so the first thing readers see is "where is Mischa now?"
|
||
|
||
Features:
|
||
- Small embedded Leaflet map on the tracker/feed page
|
||
- Shows last 10 entries as markers, with the most recent highlighted
|
||
- Route line between them
|
||
- Tapping a marker opens the entry
|
||
|
||
**Value:** Medium — gives context to the feed without navigating away. Nice "current location" feel.
|
||
|
||
---
|
||
|
||
## Milestone Priority Order
|
||
|
||
**M1 first** — entry quality affects every post Mischa makes from day 1 of the trip. Get this right immediately.
|
||
|
||
**M2 second** — the map is the headline feature that makes this feel like a Polarsteps-style blog. Technically independent from M1 (uses lat/lng already in frontmatter).
|
||
|
||
**M3 third** — stats are a nice-to-have. Easy to add once M1 and M2 are stable.
|
||
|
||
**M4 fourth** — the mini-map on the feed is polish. Only worth doing once the full map (M2) is solid.
|