From f7cd8feced864e323a4d08f05aa1a83add3b1f91 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 01:13:10 +0000 Subject: [PATCH 1/2] docs(backlog): file ODY-125/126 from owner mobile testing round 2 Traveler stat double-counts across trips + wraps ugly on mobile (ODY-125); notes sections default-expanded pushes itinerary below the fold, needs default-collapse + discoverability toast + packing moved to its own tab with event-linking scope (ODY-126). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01A79ZCq9WjREZDDA9z93pMT --- BACKLOG.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/BACKLOG.md b/BACKLOG.md index 646e5f8..0784991 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -24,7 +24,9 @@ Size: S (<1h) Β· M (1–3h) Β· L (3h+) Β· Model hint: `haiku` for S mechanical, ## πŸš€ MVP release punch-list (2026-09-01 β€” owner mobile testing) Filed from live mobile testing of `odyssey-trips.vercel.app`. Owner flagged all as **essential for MVP release.** Priority order for the release: **ODY-121 β†’ ODY-120 β†’ -ODY-124 β†’ ODY-122 β†’ ODY-123** (ODY-123 is research/decision, so it gates itself). +ODY-124 β†’ ODY-122 β†’ ODY-125 β†’ ODY-126 β†’ ODY-123** (ODY-123 is research/decision, so +it gates itself; ODY-126 folds packing/event-linking scope into ODY-067 Stage B if +that's picked up separately). ### ODY-120 Β· New-trip wizard: "Add member" is easy to miss on mobile β€” S, sonnet (P1) β€” πŸ”΄ MVP > **In plain terms:** On the create-a-trip form you type a collaborator's email, but on mobile it's not obvious you then have to tap a separate "Add" button β€” so people finish the wizard thinking they invited someone, then find the members list empty and have to re-add them. @@ -57,6 +59,22 @@ ODY-124 β†’ ODY-122 β†’ ODY-123** (ODY-123 is research/decision, so it gates its - **Fix:** replace the redundant weekday heading with the day's **location**. Deriving the location: the trip `destination` (single-city trips) or, for multi-city, infer per-day from that day's events' `location`/city (first event with a city), falling back to the trip destination. Keep the date line as-is. Consider a small `deriveDayLocation(day, trip)` helper (pure, unit-testable). Editorial styling unchanged (serif display heading, just different text). - **Acceptance:** each day header reads "DAY NN Β· "; the weekday is no longer duplicated; a multi-destination trip shows different cities on different days; a single-destination trip shows the trip city. +### ODY-125 Β· Dashboard: "N travelers" stat double-counts repeat collaborators and wraps ugly β€” S, haiku (P2) β€” πŸ”΄ MVP +> **In plain terms:** The dashboard's "travelers" stat counts a member once per trip they're on, so a person who collaborates on 3 trips gets counted 3 times β€” the number doesn't mean anything real. It also line-wraps awkwardly next to "adventures" and "days planned" on mobile. +- **Repro (owner, screenshot):** dashboard stats row shows "9 adventures Β· 41 days planned Β· 31 travelers" β€” 31 is a sum of per-trip member counts, not distinct people, and the third stat drops to its own line at 375px instead of staying inline or wrapping cleanly. +- **Fix:** compute the travelers stat as the count of **distinct users** across all of the owner's trips (dedupe by user id, e.g. via `TripMember` grouped/distinct query in the dashboard's data-loading action), not a per-trip sum. Pair with a mobile layout fix for the stats row β€” either allow it to wrap as a proper multi-line flex/grid with consistent gaps, or keep it on one line with a smaller/responsive type size at narrow widths β€” whichever keeps the editorial stat row from breaking mid-number. +- **Files:** dashboard data query (wherever the trips-overview stats are aggregated, e.g. `app/(dashboard)` or `app/page.tsx` server action / `lib/prisma`), stats row component + its CSS in `globals.css`. +- **Acceptance:** a user who collaborates with the same 5 people across multiple trips sees "5 travelers," not an inflated per-trip sum; at 375px the stats row reads cleanly with no orphaned single stat on its own line. + +### ODY-126 Β· Trip notes sections: default-collapse noise, add-section toast, and move Packing List to its own mappable tab β€” M, sonnet (P2) β€” πŸ”΄ MVP +> **In plain terms:** The itinerary page currently opens with "Important Reminders," "Packing List," and "To Do" all expanded, pushing the actual day-by-day plan below the fold β€” travelers have to scroll past empty boilerplate to get to planning. This collapses that noise by default, tells people what else they can add there, and moves packing into its own tab where it can eventually link an item to a specific event (e.g. hiking boots β†’ the hiking day). +- **Repro (owner, screenshots):** itinerary page opens showing all three note sections (Reminders/Packing/To Do) expanded with "Add items…" placeholders before any itinerary content is visible. +- **Fix, three parts:** + 1. **Default-collapse:** in `TripNotes.tsx`/`NoteSection.tsx` (ODY-104/105), only **Important Reminders** defaults to open; **Packing List** and **To Do** (and any other non-default section) default to **collapsed** on first render. Respect the user's own toggle thereafter (don't fight an explicit expand). + 2. **Discoverability toast:** when a trip's notes have no custom sections yet (or on first visit to the itinerary page), show a one-time toast (reuse `src/components/shared/Toast`, ODY-013 pattern) suggesting example sections a user can add via "Add section" (e.g. "Packing List," "To Do," "Emergency Contacts"). Don't nag β€” dismiss persists per-trip the same way ODY-085's welcome dismissal does (cookie/db flag, **not localStorage** per project rules). + 3. **Move Packing List off the itinerary page:** remove the Packing List section from the itinerary's notes area entirely; its own tab (already liked by the owner) becomes the single home for packing. In that tab, extend the packing item model so an item can optionally be linked to one or more specific events/days (e.g. a join table or an `eventIds`/`dayId` field on the packing item) so "hiking boots" can be tied to the hiking-trail event or a specific day/time. Filed as the follow-up ODY-067 Stage B in this backlog already covers per-event packing β€” **this ticket's linking scope should fold into that Stage B work rather than duplicate it**; if ODY-067 Stage B is picked up separately, split part 3 out and only ship parts 1–2 here. +- **Acceptance:** itinerary page loads with only Important Reminders expanded (Packing/To Do collapsed) and no Packing List section present at all; a first-time-per-trip toast names example sections; the Packing tab is the only place packing lives, with a path (even if Stage B ships later) to associate an item with a specific event/day. + --- ## P0 β€” Correctness & Security From a89f1c46de570c3167708f5e2261079654fd6380 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 01:23:08 +0000 Subject: [PATCH 2/2] docs: add MVP roadmap planning doc (not backlog tickets) Highlight-level sequencing for Clerk prod, design refresh, mobile audit, Explore provider research, globe recolor, and mobile checklist cross-check, grounded against current BACKLOG.md and git history. Planning only -- no BACKLOG.md tickets filed. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01A79ZCq9WjREZDDA9z93pMT --- docs/mvp-roadmap-2026-09-02.md | 178 +++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 docs/mvp-roadmap-2026-09-02.md diff --git a/docs/mvp-roadmap-2026-09-02.md b/docs/mvp-roadmap-2026-09-02.md new file mode 100644 index 0000000..d95ef86 --- /dev/null +++ b/docs/mvp-roadmap-2026-09-02.md @@ -0,0 +1,178 @@ +# Odyssey β€” MVP Roadmap Planning Doc (2026-09-02) + +> **Status: PLANNING ONLY.** Nothing here is committed to `BACKLOG.md` yet. This +> is a highlight-level map of the six workstreams the owner raised in one sitting, +> grounded against current git history (`main` @ `2c62ef8`, verified 2026-09-02), +> so we can sequence and scope before turning any of it into tickets. Once a +> workstream is agreed, split it into properly-scoped `ODY-###` tickets in +> `BACKLOG.md` following the existing format (In plain terms β†’ repro/files β†’ +> acceptance). + +--- + +## Why this order + +Two things gate everything else and should move first: + +1. **Clerk production domain** (ODY-036) β€” until real auth exists, invite links, + real user identities, and any "who's on this trip" feature are all built on + a placeholder. This is the single biggest launch blocker already logged. +2. **A safe checkpoint before the design refresh** β€” fonts + spacing changes + touch nearly every screen. We want a clean, tagged commit to hand to Claude + Design and a clean branch to hand back to Claude Code, so a visual pass + doesn't get tangled with in-flight feature branches. + +Everything else (mobile audit, Explore provider swap, globe recolor, doc +cross-check) can run in parallel once those two are moving. + +--- + +## 1. Clerk production auth + real invite links (launch blocker) + +**Already scoped in the backlog** as ODY-036 (prod Clerk + Google OAuth) and +ODY-037 (real invitations/join flow/guest access) β€” ODY-037 explicitly depends +on ODY-036. Nothing new to invent here; this is a sequencing decision, not a +research task. + +- **ODY-036** β€” point the app at a production Clerk instance (not the dev + "practice mode" instance), wire up Google OAuth for prod. +- **ODY-037** β€” once prod auth exists, invite emails need to carry a **real + domain link** (not a placeholder/dev URL) that lands the invitee on the join + flow for that specific trip. +- **Cross-cutting ask from this session:** audit `BACKLOG.md` itself once + ODY-036/037 ship β€” confirm every ticket in the doc that assumed "prod auth + not stable yet" (there are several: ODY-045 follow-ons, ODY-068 offline, + ODY-112 receipt capture gating) gets its gate lifted or explicitly re-gated, + rather than silently going stale. This is a documentation-hygiene pass, not + new code β€” same spirit as the "ground truth is git, not the doc" rule already + in the backlog's header. + +**Owner action needed:** the actual domain (what real domain the invite link +points to) and DNS/Clerk dashboard access are outside what a coding session can +decide β€” needs the domain name + Clerk production keys before ODY-036 can be +implemented, not just planned. + +--- + +## 2. Design refresh β€” typography, spacing, safe checkpoint for Claude Design handoff + +Three distinct pieces, sequenced so nothing gets designed against code that's +about to move: + +1. **Cut a safe checkpoint.** Before any visual work starts: confirm `main` is + green (tests/build/lint), tag or branch it (e.g. + `checkpoint/pre-design-refresh-2026-09`), and hand that exact commit to + Claude Design. This makes "handoff back to Claude Code" unambiguous β€” Claude + Code resumes from the tagged commit, not from whatever `main` has drifted to. +2. **New font pairing, less "AI-generated" look.** Current stack is DM Serif + Display / DM Sans / JetBrains Mono β€” these are legitimate, purposeful + choices already but read as a common "safe AI pick" pairing. Needs a + **design research pass** (Claude Design, using the `design`/`design-mockup` + skill) to propose 2–3 alternate serif+sans pairings that keep the + "boarding pass + printed map" editorial feel β€” same personality, different + typefaces β€” plus a mockup to approve before wiring into + `next/font/google` and the `globals.css` `@theme` tokens. +3. **Desktop white-space audit.** Independent of fonts β€” likely a layout/ + container-width issue (max-width too narrow relative to viewport, or + vertical rhythm too generous) rather than a token problem. Needs a screen- + by-screen desktop pass (dashboard, itinerary, map, budget, schedule) to + find where the editorial "breathing room" tips into "empty." + +**Sequencing:** checkpoint tag β†’ Claude Design mockup (fonts + fixes for the +worst white-space offenders) β†’ owner approval β†’ Claude Code implements against +the tagged checkpoint, not against whatever else has merged to `main` since. + +--- + +## 3. Mobile UI audit β€” seamless user journey + +This is broader than the ODY-120–126 mobile fixes already filed (add-member +visibility, date-picker spacing, Explore action buttons, traveler stat wrap, +notes-section collapse). Those are **point fixes** found from one round of +owner testing. What's being asked for now is a **structured, full-journey +audit**: sign-up β†’ create trip β†’ invite β†’ build itinerary β†’ explore β†’ schedule +β†’ budget β†’ settle-up, walked end-to-end on a real phone (or Playwright at +375–428px), looking for friction rather than isolated bugs. + +- Reuse the existing pattern from ODY-046 ("full user-journey QA audit") and + ODY-108 (full UI/UX design audit) β€” same audit discipline, mobile-scoped. + ODY-046 is already listed as open in the backlog; this may simply be that + ticket, executed now. +- Deliverable: a findings doc (like `docs/ody-108-design-audit.md` / + `docs/ody-118-accessibility-audit.md`) ranking friction points, which then + get filed as individual tickets β€” not one giant ticket. + +--- + +## 4. Explore provider research β€” Google Places swap + +**Research + decision, not a build yet** β€” this direction already exists in +the backlog as **ODY-123** (research+decision ticket for richer Explore +preview: map thumbnail, photos, reviews, "open in Google Maps"), filed +specifically because it was flagged as "decide before build." What's new in +this ask: + +- **Reviews** β€” Google Places has them; current provider (Foursquare, chosen + for its free tier per ODY-119's notes) doesn't expose review content the + same way. +- **Map view with distance/info** β€” an in-card or in-panel map preview, + distance from other itinerary stops, richer place info. +- **Multi-city support** β€” partially exists already: `splitDestinations` + (`src/lib/destinations.ts`, shipped 2026-09-01) parses multi-city trip + destinations and Explore filters by city chip. What's *not* yet covered: + whether a Google Places swap changes how multi-city search/ranking works, + and whether itinerary-side multi-city display (ODY-124, city-per-day + headers) needs to know about the same city list. + +**This should extend ODY-123's existing research memo**, not start a second +one β€” add a Google Places section (cost per call, review data availability, +attribution/ToS requirements, quota) alongside the "zero-provider-switch" +option (static map + deep-link) it already proposed. The owner explicitly +flagged this earlier as a cost tradeoff to decide, not rubber-stamp β€” that +constraint still holds. + +--- + +## 5. Three.js globe β€” recolor to purple gradient + +Small, isolated, cosmetic. `Globe3D` (landing page) already exists and already +has a reduced-motion accessibility fix (ODY-118 F4, ships idle-spin stillness +for `prefers-reduced-motion`). This is a shader/material color-parameter +change β€” swap whatever current gradient/color uniforms it uses for a purple +gradient consistent with the `--peri` token family, not a new component. Low +risk, easy to slot in alongside the design refresh (workstream 2) since it's +touching the same "brand look" surface β€” worth doing in the same pass rather +than as a separate thread. + +--- + +## 6. Mobile app development checklist β€” cross-check against current plans + +The owner has a Google Doc checklist for mobile app development that needs to +be diffed against what's already in `BACKLOG.md`'s mobile-related tickets +(ODY-058/059 mobile chrome, ODY-096 mobile overflow, ODY-102/103 notes mobile +fixes, the new ODY-120–126 punch list, and the "Post-MVP: ODY-073 native" +line already in the backlog's priority list). + +**Blocked on access** β€” I don't have a way to read a Google Doc from here. +**Owner action needed:** either paste the checklist content in, share it as an +exported file, or grant a way to fetch it, and the next session can do the +gap analysis (what's covered, what's missing, what's redundant) in one pass. + +--- + +## Suggested sequencing (once this doc is reviewed) + +| Order | Workstream | Depends on | Can run in parallel with | +|---|---|---|---| +| 1 | Clerk prod domain (ODY-036) | owner's domain + Clerk prod keys | 3, 4, 5, 6 | +| 2 | Real invite links + backlog audit (ODY-037 + doc hygiene) | (1) | 3, 4, 5, 6 | +| 3 | Mobile UI audit (full journey) | none | 1, 2, 4, 5, 6 | +| 4 | Explore/Google Places research (extends ODY-123) | none | 1, 2, 3, 5, 6 | +| 5 | Design checkpoint β†’ fonts + spacing + globe recolor | a tagged checkpoint commit | 1, 2, 3, 4 | +| 6 | Google Doc checklist gap analysis | owner shares the doc | everything | + +Nothing above is committed to `BACKLOG.md`. Next step is the owner picking +which of these become real tickets first (or confirming this order), then a +session turns each into properly-scoped `ODY-###` entries the same way +ODY-120–126 were filed.