Files
intotheeast-com/docs/working/milestones/milestone-1.md
T
m038andClaude Opus 5 8202d2a257 docs: reconcile documentation against the code; add a supersession ledger
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>
2026-07-25 00:13:37 +02:00

9.0 KiB
Raw Blame History

Milestone 1 Spec — Entry Enrichment

Goal: Every entry is richer out of the box — location name shown, weather auto-captured, photos in a proper gallery, hero image visible on the feed.

Historical — written 2026-06-21. Mostly shipped as specified; three details reversed.

Still true: the location badge, Open-Meteo weather auto-fetch with its eight weather_desc values, and the entry photo gallery. Reversed since:

  • §1.5 gallery is PhotoSwipe, not shortcode-gallery-plusplus (R10).
  • §1.6 hero_image no longer exists on entries — the hero is the first uploaded photo, and the owner controls photo order by drag-reorder (R7). Stories still use hero_image.
  • Photos are now required (16 per entry), not optional (R8).
  • "Tracker feed" is the trip page and the home active-trip view; there is no /tracker (R3).

Details: ../../reference/superseded-decisions.md.


User Stories

  • As a traveler (Mischa), when I submit the post form, I want my current weather conditions auto-filled so I don't have to look them up manually.
  • As a traveler, I want to type my city and country once and have it appear on the entry and in the feed card, so readers know where I am without reading the whole post.
  • As a reader, when I scan the feed, I want to see a thumbnail photo and location for each entry so I can quickly get a sense of where Mischa is and whether to read the full entry.
  • As a reader, when I open an entry, I want to see all uploaded photos in a gallery I can browse, not a wall of raw images.
  • As a traveler, when I submit a form without photos, the entry should still display cleanly with no broken image placeholders.

Feature Details

1.1 — Location Name Field on Post Form

What: Add two text fields to the post form: location_city and location_country.

Behavior:

  • Both are optional (GPS coordinates are also optional)
  • Placeholder text: "e.g. Kyoto" and "e.g. Japan"
  • Displayed below the lat/lng fields
  • On submit, stored in entry frontmatter as location_city and location_country
  • On the form, shown as a single labeled group "Location Name" with two side-by-side inputs on desktop, stacked on mobile

Edge cases:

  • If left blank: entry shows no location badge. No error, no broken UI.
  • Long city names (e.g. "Ulaanbaatar") must not overflow card layout.
  • Special characters (accents, non-Latin) must render correctly.

Mobile behavior: Both fields full-width, stacked, 44px min touch targets.


1.2 — Weather Auto-Fetch on Post Form

What: A "Get Weather" button on the post form that calls the Open-Meteo free API (no API key) using the lat/lng already entered, and fills hidden weather fields.

Fields to fetch and store:

  • weather_temp_c — temperature in Celsius (integer)
  • weather_desc — short description: one of: Sunny, Partly cloudy, Cloudy, Foggy, Drizzle, Rain, Snow, Thunderstorm (derived from WMO weather code)

WMO code mapping (Open-Meteo uses WMO codes):

  • 0 → Sunny
  • 1,2 → Partly cloudy
  • 3 → Cloudy
  • 45,48 → Foggy
  • 51,53,55,56,57 → Drizzle
  • 61,63,65,66,67,80,81,82 → Rain
  • 71,73,75,77,85,86 → Snow
  • 95,96,99 → Thunderstorm

API call:

https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lng}&current=temperature_2m,weather_code&temperature_unit=celsius

UX flow:

  1. User fills in lat/lng (manually or via "Get Location" button)
  2. User taps "Get Weather" button
  3. Button shows "Fetching…" while loading
  4. On success: fills temp and desc fields (visible, editable text inputs)
  5. On failure (no network, no lat/lng): shows inline error "Could not fetch weather — enter manually"

Edge cases:

  • If lat/lng not filled when button tapped: show inline error "Enter coordinates first"
  • Weather fields are always editable manually (auto-fill is a convenience, not mandatory)
  • If weather fields left blank: entry shows no weather badge. No broken UI.
  • Open-Meteo returns current conditions, not historical — this is fine for posting in real time

Mobile behavior: "Get Weather" button is full-width, 44px height, placed immediately below the lat/lng + location name fields.


1.3 — Weather Display on Entry Page

What: If weather_temp_c or weather_desc is present in frontmatter, display a weather badge on the entry page.

Display format: ☀️ Sunny · 28°C (icon + description + temperature)

  • Icon chosen from a small set based on weather_desc:
    • Sunny → ☀️
    • Partly cloudy →
    • Cloudy → ☁️
    • Foggy → 🌫️
    • Drizzle → 🌦️
    • Rain → 🌧️
    • Snow → ❄️
    • Thunderstorm → ⛈️

Placement: In the entry header, between the date and the body text. Same line as GPS coordinates if those are shown.

Edge cases:

  • Only temp, no desc → show temp only
  • Only desc, no temp → show desc only
  • Neither → hide weather section entirely
  • Temperature should always be integer (round if float)

1.4 — Location Badge on Feed Cards and Entry Page

What: Display location_city, location_country as a small badge on tracker feed cards and at the top of entry pages.

Feed card: Below the date, above the excerpt. Format: 📍 Kyoto, Japan

Entry page: In the header below the date, above the content. Format: 📍 Kyoto, Japan

Edge cases:

  • Only city, no country → 📍 Kyoto
  • Only country, no city → 📍 Japan
  • Neither → location badge hidden entirely
  • Long location names: truncate with ellipsis at 30 chars on cards (full text on entry page)

1.5 — Photo Gallery on Entry Page

What: Photos uploaded to an entry should display in a responsive grid gallery with lightbox (click to enlarge).

Implementation approach: Use Grav's native media collection for the entry page. Each .entry folder contains its photos. Render them in a grid in entry.html.twig. Use a minimal vanilla JS lightbox — no external framework.

Gallery behavior:

  • Photos displayed in a 2-column grid on mobile, 3-column on desktop
  • Each thumbnail is square-cropped, 150px on mobile
  • Clicking/tapping a thumbnail opens a lightbox overlay
  • Lightbox: dark overlay, full-size image centered, tap/click outside or press Escape to close
  • Left/right navigation arrows in lightbox (swipe on mobile)
  • No captions needed for v1

Edge cases:

  • 0 photos: gallery section hidden entirely
  • 1 photo: still uses grid (single item), lightbox works
  • Many photos (>10): gallery still renders (no hard limit on display)
  • Non-image files in the media folder: skip them (only render jpg, jpeg, png, webp, gif)

1.6 — Hero Image on Tracker Feed Cards

What: If an entry has photos, the first photo (or the one named in hero_image frontmatter) appears as a thumbnail on the tracker feed card.

Implementation: In tracker.html.twig, for each entry:

  1. If entry.header.hero_image is set, use entry.media[entry.header.hero_image]
  2. Else, use the first image in entry.media sorted by name
  3. Render as a 16:9 aspect-ratio thumbnail, full width of card, above the title

Edge cases:

  • No photos: card shows no image, just text. No broken <img> tag.
  • hero_image set but file missing: fall back to first media file, or no image
  • Very tall/wide images: CSS object-fit: cover maintains card aspect ratio

Out of Scope (Milestone 1)

  • Map features (Milestone 2)
  • Statistics page (Milestone 3)
  • Video support
  • Comments or reactions
  • Automated reverse geocoding (city name comes from form input, not auto-detected)
  • Altitude display (data may not be present)
  • Historical weather (Open-Meteo current endpoint only)

Acceptance Criteria

  1. Post form has location_city and location_country fields that save to entry frontmatter
  2. Post form has "Get Weather" button that fills weather_temp_c and weather_desc via Open-Meteo when lat/lng are provided
  3. Entry page shows weather badge when weather fields are present; hidden when absent
  4. Entry page shows location badge 📍 City, Country when location fields are present; hidden when absent
  5. Tracker feed card shows location badge when present
  6. Tracker feed card shows a hero image when photos exist for an entry
  7. Entry page shows a 2-col (mobile) / 3-col (desktop) photo grid
  8. Clicking any photo opens a full-screen lightbox with prev/next navigation
  9. Pressing Escape or clicking outside lightbox closes it
  10. All fields are optional — empty values produce no broken UI elements
  11. All interactive elements meet 44px minimum touch target on mobile
  12. Form submits correctly with all new fields populated or all blank

Design Notes

  • Weather and location badges should be subtle — small text, muted color, not the visual focus
  • Use emoji icons for weather — universal, no icon font dependency
  • Gallery grid: gap: 4px between thumbs, no borders, square crops
  • Lightbox: background: rgba(0,0,0,0.92), image centered with max-height: 90vh
  • Feed card image: aspect-ratio: 16/9, object-fit: cover, rounded top corners matching card