Skip to content

feat(v1.42): privacy + terms pages, global footer#54

Merged
MP2EZ merged 1 commit into
devfrom
feat/v1.42-legal-and-footer
May 31, 2026
Merged

feat(v1.42): privacy + terms pages, global footer#54
MP2EZ merged 1 commit into
devfrom
feat/v1.42-legal-and-footer

Conversation

@MP2EZ
Copy link
Copy Markdown
Owner

@MP2EZ MP2EZ commented May 31, 2026

Summary

  • New /privacy and /terms pages, hand-written in Campable voice (not Termly).
  • Global <Footer/> rendered on every page with About, Pricing, Privacy, Terms, and Contact links plus the copyright year.
  • hello@palouselabs.com wired as the support mailto in the footer and on both legal pages.
  • Roadmap table updated: About marked as shipped early; Privacy and Terms reflect the hand-written-not-Termly decision; Footer reflects the dropped version string.

Why now

  • Stripe live-mode review flags missing Privacy and ToS URLs on subscription products (called out as the unblocking step in v1.4's post-ship notes).
  • Apple v1.45 App Store submission requires a Privacy URL. Having it live and reachable now lets the URL marinate before submission.
  • v1.4's deferred footer-with-ToS-link item lives here.

Decisions that diverge from the original roadmap entry

  • Hand-written legal text, not Termly. About 400 lines of Termly boilerplate per page would violate the no-marketing-copy quality bar and break voice continuity with About and Pricing. Honest disclosure of actual services (Supabase, Stripe, PostHog, Mapbox, Visual Crossing, Cloudflare, Fly.io) is more legally defensible than "we may share with our service providers." Confirmed with the operator before writing.
  • No version string in the footer. package.json is 0.0.0, the site is continuously deployed, and there's no semver discipline that would make the number meaningful to users. Just © {year} Campable.
  • Cloudflare RUM disabled in the CF dashboard as part of this ship, since PostHog already captures Core Web Vitals automatically. Removes a beacon the operator wasn't reading and keeps the Privacy disclosure clean. Cloudflare's only listed role is now DNS and TLS, which is fully accurate post-disable.

Privacy accuracy notes (verified during self-review)

  • Account deletion claim: wired in UserMenu.tsx:94.
  • First-party PostHog cookies: api_host: '/ingest' reverse proxy in index.html:23 confirms.
  • IP-not-forwarded claim: api.py:570 header allowlist drops x-forwarded-for by omission.
  • Cloudflare in request path: cf-ray header on curl -I https://campable.co/.
  • OAuth claim originally drafted included Google and Apple. Removed after verifying useAuth.ts:107 only wires signInWithPassword. Privacy now says social login isn't wired in yet.

Test plan

  • npm test passes 213/213 (203 prior + 10 new)
  • tsc -b clean
  • npm run build clean; Privacy and Terms code-split into roughly 6KB chunks each
  • e2e grep confirms no v1.41 Playwright spec references footer, about, privacy, or terms selectors
  • Manual: load /privacy, /terms, /about, /pricing in both themes; tab through footer; resize to 375px
  • Manual: load /map route at 375px and confirm Footer isn't pushed off-screen by MapView's full-viewport container (gate Footer behind useLocation() if it is)
  • Manual: Lighthouse a11y on /privacy and /terms (target 95 or above)
  • After merge to main: curl -I https://campable.co/privacy returns 200 with no auth redirect (Apple submission requirement)

Out-of-code follow-ups (post-deploy)

  1. Stripe Dashboard, Settings, Business, Public details: paste Privacy and Terms URLs, set support email.
  2. Stripe Dashboard, Settings, Billing, Customer Portal: add Privacy and Terms URLs.
  3. Submit Stripe live-mode activation.

🤖 Generated with Claude Code

Adds /privacy and /terms (hand-written in Campable voice, not Termly), a
global Footer rendered outside <Routes> on every page, and the contact
mailto for hello@palouselabs.com. Unblocks Stripe live-mode review
(which flags missing Privacy + ToS URLs on subscription products) and
preps the Privacy URL Apple requires for v1.45 App Store submission.

Privacy honestly names every third party in the request path: Supabase
(auth, US), Stripe (billing), PostHog (analytics, EU-hosted, reverse-
proxied through /ingest so user IPs aren't forwarded), Mapbox (drive
times), Visual Crossing (weather, server-side only), Cloudflare (DNS +
TLS), Fly.io (hosting). About page (already shipped pre-v1.42) marked
done in the roadmap table.

Footer mounted between </ErrorBoundary> and </div> of .app — full-width
border-top, inner constrained to --max-w-app, theme-token-driven so it
works in dark and light without overrides. Version string dropped:
package.json is 0.0.0 and the site is continuously deployed, so the
number would be meaningless to users.

10 new Vitest tests guard structure (h1, mailto, year, third-party list,
WA jurisdiction, 30-day refund language). Full suite green at 213/213.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MP2EZ MP2EZ merged commit 7f351b7 into dev May 31, 2026
6 checks passed
@MP2EZ MP2EZ deleted the feat/v1.42-legal-and-footer branch May 31, 2026 08:05
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