Skip to content

M5 — Share link, public preview and "Copy day as text"

Status: agreed · Last session: 2026-10-01

Revision 1 Oct (P45): one link, one switch. Share opens a popup (not the drawer or a bottom sheet) with one switch. On: anyone with the link can view; the link sits in a box with a copy icon at its end (and the phone's share menu). Off: the trip is private again and the link stops working at once; turning it on again brings the same link back. No Publish, no public preview page, no "Make a new link" control (the backend can still replace a leaked link). Everything below about the public preview (/t/<slug>), the Publish warning and "Make a new link" is not built. The private link view, ?day=N, the credit footer and "Copy day as text" stand.

Sources: requirements.md M4, M5 · decisions.md P28, P36, P37, P39–P43, A6 · security.md S1, S3, S4, S7, S16, S22 · M1 day plan · M13 maps · evidence: the church leader's real Messenger schedules (founder-only, kept outside this repo).

Who and the job

  • Group leader: "Tonight I post tomorrow's plan in our group chat" — today typed by hand in Facebook Messenger, every evening (three real samples, 30 Sep). They want to send it in one tap, with the full plan behind a link.
  • Traveller in the group: opens the link from Messenger, with no NepWalk account, and sees the day: times, places, map, directions, tonight's hotel.
  • Anyone else (friends, family, people thinking of joining): sees a public preview only when the creator has published the trip.
  • Creator (P36, today the founder): makes, copies and replaces the links.

Value

Without it the leader keeps retyping the plan, the group asks "where do we meet?" in the chat, and NepWalk never reaches the travellers. The copied text puts a NepWalk link in every evening post (P42). Security: SEC-01 closes only when the share link reuses the public allowlist (S3, S7).

Two views, one rule each

Public preview /t/<slug> Private trip link /s/<token>
Exists when the creator has published the trip (isPublic) the creator makes a link (any trip)
Who has it anyone whoever the creator shares it with
Shows the overview (design 03): title, dates, towns with nights, the trip map (P39), the days with their titles; stops with public place fields the full day plan, view-only: every stop, story, tip, duration, map, directions, tonight's hotel, the hotel-to-hotel flow, culture; "Copy day as text"
Never shows contacts, emails, headcount, rooms, the leader's basics, prices, booking status, vendors (S4) the same (S4); no edit control of any kind
Stops working when unpublished when the creator makes a new link (the old one dies at once)

Join requests (a traveller asks from the public preview, the leader accepts) come right after launch (P40) and are not in this card.

Placement — and why

Element Mobile Web Why
Share (trip header) opens a bottom sheet opens the right drawer (P38) the drawer is the trip's quick-action layer; no new page
Private link in the sheet link + Copy + Share… (phone share menu: Messenger, WhatsApp) link + Copy the leader posts from their phone
"Make a new link" under the link, asks first same the only way to stop a leaked link
Public link in the sheet shown when published; otherwise one line "Publish the trip to get a public preview" same publishing stays a deliberate step
Copy day as text in the day header (⋯ menu on phones is not used: it is the leader's main action, so it stays visible) day header, next to Share the evening job, one tap
Credit footer bottom of both shared views same "NepWalk · made in Kathmandu by Prakash" (P42)

Wireframe

Share sheet (creator, mobile)

┌──────────────────────────────┐
│ Share this trip           ✕  │
│                              │
│ PRIVATE TRIP LINK            │
│ Your group sees the full     │
│ plan: stops, map, hotel.     │
│ No account needed.           │
│ ┌──────────────────────────┐ │
│ │ nepwalk…/s/k3F9…         │ │
│ └──────────────────────────┘ │
│ [ Copy link ]  [ Share… ]    │
│ Make a new link (old one     │
│ stops working)               │
│ ──────────────────────────── │
│ PUBLIC PREVIEW               │
│ Not published. Publish the   │
│ trip to get a public link.   │
└──────────────────────────────┘
┌──────────────────────────────┐
│ Nepal over New Year          │  no app header, no edit
│ Day 2 │ Day 3 │ Day 4 …      │
│ DAY 3 · THU 31 DEC · POKHARA │
│ 🌙 Tonight: Hotel Barahi      │
│ [ Copy day as text ] [ Map ] │
│ 🚶 15 min from Hotel Barahi   │
│ ┌ 1 · Phewa Lake ──────────┐ │
│ │ photo · story · Directions│ │
│ └──────────────────────────┘ │
│ …                            │
│ Tomorrow · Day 4 ›           │
│ NepWalk · made in Kathmandu  │
│ by Prakash                   │
└──────────────────────────────┘

Public preview (web, design 03 without edit)

┌──────────────────────────────────────────────────────────┐
│ nepwalk                                  [ Sign in ]      │
│ Nepal over New Year                                       │
│ 29 Dec 2026 – 7 Jan 2027 · 10 days                        │
│ ┌──────── cover photo ─────────┐ ┌── Trip map ─────────┐ │
│ │                              │ │ Kathmandu (3)       │ │
│ └──────────────────────────────┘ │ Pokhara (5) ✈ dashed│ │
│ Days                              └─────────────────────┘ │
│ 1 · Arrive in Kathmandu · Stay in Kathmandu            ›  │
│ 2 · Fly to Pokhara · Stay in Pokhara                   ›  │
│ …                                                         │
│ NepWalk · made in Kathmandu by Prakash                    │
└──────────────────────────────────────────────────────────┘

Copied text (P42, the leader's own format)

Plan for Thu 31 Dec (Day 3, Pokhara):
• Tonight: Hotel Barahi
• 7:00–7:55 Breakfast
• 8:00 Devo at Himalayan Java
• 9:00 Leave for Lele (drive about 1 h)
• 10:00–12:00 Soccer time
• 12:30–14:00 Lunch at Fire and Ice (pay locally)

Full plan and map: https://…/s/k3F9…?day=3 · made with NepWalk

States

  • Private link, unknown or replaced: "This link is no longer active. Ask the person who shared it for a new one." No trip name, no detail (design 13).
  • Public preview, unpublished or unknown slug: the same generic not-found page; never says whether a trip exists.
  • Loading: grey day skeleton (as today). Error: "Couldn't load this plan" + Retry.
  • Day with no stops: "Nothing planned yet for this day." Trip with no days: "The plan is on its way."
  • ?day=N out of range: open Day 1.
  • Copy fails (browser blocks the clipboard): show the text in a box to select by hand.
  • Long titles: wrap in the header, truncate in the day tabs.

Rules and edge cases

  • One read rule (S1): the share endpoint resolves the token to a trip and returns a dedicated allowlist view (shareTripView, built like publicTripView, S3). It adds the trip-insider place fields (story, tip, duration, coordinates) the day plan needs; it never adds S4 fields. Amend S7: a share-link viewer gets the place insider tier (P40) but nothing from S4.
  • Tokens (S7): 128-bit random, URL-safe; one active link per trip; "Make a new link" revokes the old one in the same transaction. Unknown and revoked tokens get the same 404. Rate-limited per visitor (like the place page).
  • No token in logs (S22): request logging must mask /share/<token> and /s/<token>; a share token is not an auth token, but it opens the trip.
  • View-only: no endpoint accepts the share token for writing. The share view renders the day plan with the leader/traveller view (no edit controls, no helper warnings — M1).
  • Private stops (P41): until the October feature, sensitive places are custom stops without a library place, so they have no public page and no coordinates. At launch the church trip stays unpublished; only the private link goes to the group. The Publish action warns: "Everyone can see every stop of this trip."
  • Booking status line (P28, M12) is not part of the share view: travellers never see bookings. It belongs to build day 15.
  • Copy day as text: times as H:MM, ranges H:MM–H:MM when there is an end time; travel items as "Leave for …" with the time from the connector when known; meals end "(pay locally)" (P34); the last line is always the private link with ?day=N and "made with NepWalk". Nepal time, as the day plan (M1 Revision 2).
  • Credit footer on both shared views, never in the signed-in app.

Decided

  • Two views: public preview (published trips) and private trip link (P40); join requests right after launch.
  • Maps and directions public; stories and tips for insiders, which includes the private link (P39, P40).
  • Private stops never public (P41).
  • "Copy day as text" with the NepWalk link line; credit footer (P42).
  • The share view reuses the day plan components, view-only.
  • Answered 30 Sep (founder, all six as suggested):
  • The public preview lists the day titles (only published trips have one; Publish warns first).
  • The token is stored, so the creator can copy the private link again at any time; "Make a new link" cuts access.
  • The private link does not expire on its own; it lives until a new one is made.
  • "Copy day as text" is for everyone on the private link and every trip insider.
  • The copied text includes "Tonight: " and the travel lines.
  • If Thursday runs short, the public preview page (task 6) moves to Sunday; the private link, share view and copy text come first.

TBD

  • None open.

Backlog (after launch)

  • Join requests with leader approval (P40) — first after launch.
  • Private places for sensitive sites (P41).
  • Link expiry, several named links per trip, view counts.
  • The public preview becomes the members' Overview tab (M4).
  • A "Tomorrow" shortcut in the share sheet: copy tomorrow's text straight from there.

Tasks

For build day 14 (Thu 1 Oct), in order:

  1. [be] ShareLink table (additive migration): trip, token, created by, created at, revoked at; creator-only GET / POST /trips/:id/share-link (get or create) and POST /trips/:id/share-link/rotate; e2e: creator only, one active link, rotate kills the old one.
  2. [be] GET /share/:token → shareTripView allowlist (S3) with insider place fields; same 404 for unknown and revoked; rate limit; token masked in logs. Access tests (closes SEC-01): no token, revoked token, changed ids, every S4 field populated and absent, no write accepted.
  3. [fe] Share popup: the link (made on first open), Copy, Share… on phones (P45). ✅ 1 Oct, nepwalk-fe ea0e4b2, de38525.
  4. [fe] /s/[token] view-only trip page reusing the day plan, ?day=N, credit footer, "no longer active" state.
  5. [fe] "Copy day as text": pure formatter in src/lib/ (Vitest) + button in the day header (insiders and private link).
  6. ~~[fe] /t/[slug] public preview~~ — dropped (P45).
  7. [be] Templates use one read rule (S1). ✅ 1 Oct, owner or public (P44), nepwalk-be 9853b28.