Skip to content

Stats coverage maps + per-leg transport + more safe simplifications - #28

Merged
davd-gzl merged 3 commits into
mainfrom
claude/journal-redesign-spec-kit-ku0l3d
Jul 22, 2026
Merged

davd-gzl merged 3 commits into
mainfrom
claude/journal-redesign-spec-kit-ku0l3d

Conversation

@davd-gzl

Copy link
Copy Markdown
Collaborator

Three commits.

Stats: a coverage map per country (replaces the to-do lists)

Under each country card, the long "regions to visit / monuments to see" text lists are replaced by a static, non-interactive coverage map — quicker to read at a glance:

  • the country silhouette (bundled offline Natural Earth geometry), framed to the mainland ring so a country with far-flung overseas territories doesn't zoom out to the whole globe;
  • soft "still to explore" blobs over the regions you haven't visited;
  • a dot per city you've been.

Pure SVG, computed lazily when a card opens (no MapLibre; nothing fetched beyond the shared, cached land geometry). It's a role="img" with a descriptive label, so it passes the axe gate; the full tappable lists still live on the country's own page.

Travel: per-leg transport (mix modes in one journey)

Reconstruct a journey that changes transport partway — fly Paris→Tokyo, then train Tokyo→Osaka. A compact transport picker sits on the connector between each pair of stops; a run of one mode reads as a sub-trip. New data field Trip.legModes (schema v12), saved only when a leg actually differs, so uniform single-mode trips stay byte-identical to pre-v12 files. travelTotals now splits distance per leg under its own mode, and the real map colours each leg by its transport.

More safe simplifications

The second batch from the app-wide analysis (shared placeFlag/nullableSanitized/optionalLabel helpers, defaultFetch/prefetchDisabled/runPrefetchPool in offline/tiles, dead-code and tighter-surface cleanups) — all type-checked and test-covered, no behavior change.


Gate: tsc clean · 466 unit tests (new tripLegs spec; schema artifact regenerated) · e2e green — new stats-covmap and trip-legmodes specs, plus trip-reconstruction, trip-routemap, tripedit, trips, and a11y (axe WCAG 2.1 AA).

🤖 Generated with Claude Code

https://claude.ai/code/session_014W6tgHRgLEugCsbKC9ccST


Generated by Claude Code

davd-gzl added 3 commits July 22, 2026 20:33
More from the app-wide analysis — each type-checked and test-covered, no
behavior change:

- Shared helpers replace duplicated logic: `placeFlag` (trip flag emoji, was
  copied in three travel components), `nullableSanitized`/`optionalLabel` (Zod
  transforms in models.ts, were repeated 4×/3× — the generated JSON-Schema
  artifact is byte-identical), a generic `ts` accessor in sync/engine, and
  `partitionTombs`/`snapFor` in sync/runSync.
- offline/tiles: one `defaultFetch`, one `prefetchDisabled()` guard, and one
  `runPrefetchPool()` replacing two near-identical 2-worker loops.
- Dead code / tighter surface: drop the unused `MOMENT_GROUP_ORDER`, the write-
  only `BrowseRow.lat/lon`, the `PackPlace` type, the never-passed `hint` prop
  on the stats NameList; collapse `fullCitiesOptedIn`/`fullCitiesEnabled` into
  one; drop unreferenced i18n barrel re-exports and the `export` on
  `MAX_PACK_PLACES`.
- Smaller reads: PassportScreen counts instead of allocating; PublishScreen
  reuses `passNorm`; importJson renames a shadowing loop var; guideNames gets
  its explicit return type; photoBlobs' decode is one loop.

Gate: tsc clean, 459 unit tests (incl. schema-artifact + import-security),
e2e green (trip-reconstruction, trip-routemap, offline, a11y).
Under each country card, the long "regions to visit / monuments to see" text
lists are replaced by a static, non-interactive coverage map — far quicker to
read at a glance:

- The country's silhouette (bundled offline Natural Earth geometry, matched by
  numeric code), framed to the MAINLAND ring so a country with far-flung
  overseas territories (France, the US) doesn't zoom out to the whole globe.
- Soft "still to explore" blobs over the regions you haven't visited (centroid
  + spread of each unvisited subdivision's cities).
- A dot per city you've been.

Pure SVG, computed lazily when the card opens (no MapLibre, nothing fetched
beyond the shared, cached land geometry). It's a role=img with a descriptive
label (region counts + what the marks mean), so it passes the axe WCAG 2.1 AA
gate; the full, tappable region/monument lists still live on the country's own
page (the "Open full page" link).

Gate: tsc clean, 459 unit tests, e2e green — a new stats-covmap spec (render +
axe) and stats-drill.
Reconstruct a journey that changes transport partway: fly Paris→Tokyo, then
take the train Tokyo→Osaka. Each leg (stop i → i+1) has its own mode, and a run
of the same mode reads as a sub-trip.

- Composer: a compact transport picker sits on the connector between each pair
  of stops (replacing the single trip-level "How" select). New legs continue the
  previous leg's mode, so tapping stops in a row keeps one transport until you
  change it. Live arcs on the real map colour each leg by its own mode.
- Data model: Trip.legModes (schema v12) — an optional per-leg array, saved ONLY
  when a leg actually differs from the trip's `mode`, so a uniform single-mode
  trip stays byte-identical to a pre-v12 file. A leg with no entry falls back to
  `mode`. Older apps reject a v12 file gracefully via the version guard.
- travelTotals now splits distance PER LEG under that leg's transport, and counts
  a trip once per distinct mode it uses — so the stats travel breakdown is right
  for mixed journeys (single-mode trips are unchanged).
- Pure chain helpers (appendStop/removeStopAt/moveStopTo/setLegMode/legModeAt)
  keep legModes in sync with the stops.

Gate: tsc clean, 466 unit tests (new tripLegs spec: chain sync, per-leg arcs,
per-leg totals; schema artifact regenerated), e2e green — a new trip-legmodes
spec (set → save → reopen persists), trip-reconstruction, tripedit, trips,
trip-routemap, and the composer a11y (axe WCAG 2.1 AA).
@davd-gzl
davd-gzl merged commit f9ae060 into main Jul 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant