0fd8c52724
Roadmap item #13. Ships the frontend Amplitude SDK behind the v0.13.0 cookie/privacy consent gate. The analytics wrapper lives at `frontend/src/lib/analytics.js` and exposes `track`, `identify`, and `anonymize` over a stable nine-event taxonomy (Page Viewed, RFC Viewed, User Signed In / Signed Out, RFC Proposed, PR Opened, Comment Posted, Beta Access Requested, Admin Permission Decision). The wrapper reads consent via `getConsent()` / `onConsentChange()` from `frontend/src/lib/consent.js` (v0.13.0); the SDK module is dynamically `import()`-ed only after `consent.analytics === true`, and a later granted→denied flip calls `setOptOut(true)` so events stop without a page reload. The Amplitude API key is read from `VITE_AMPLITUDE_API_KEY` at build time; when unset the wrapper logs one console warning and no-ops so dev environments keep working. Wired into App.jsx (route-change Page Viewed + sign-in identify + sign-out anonymize), Login.jsx (User Signed In with method = otc/passcode/trust-device, Beta Access Requested on capture-profile submit), ProposeModal.jsx (RFC Proposed), RFCView.jsx (RFC Viewed), PRModal.jsx (PR Opened), RFCDiscussionPanel.jsx (Comment Posted with surface=discussion), PRView.jsx (Comment Posted with surface=pr), Admin.jsx (Admin Permission Decision with action=grant/revoke). Event bodies carry only ids and enums — no titles, no comment bodies, no names, no emails. The user binding passes only `String(viewer.id)`. Secret-vs-overlay binding caveat: Amplitude browser API keys are visible in the shipped bundle via dev tools. Per the roadmap, the key is still bound through `flotilla secret set` (rather than `flotilla overlay set`) to keep all-keys-in-Secret-Manager regularity for the OHM deployment; the CHANGELOG documents the choice. Operator pre-deploy gesture (in the Upgrade steps block): `pbpaste | ... ohm-rfc-app-flotilla secret set ohm-rfc-app AMPLITUDE_API_KEY` — the wave-paused step before this release can deploy. No backend events ship in this release (Amplitude SaaS holds the events); no schema migration; backend is unchanged. Migration slot 015 remains unused and available for the next minor that needs a schema bump. New dependency: `@amplitude/analytics-browser`. `VITE_AMPLITUDE_API_KEY` documented in `frontend/.env.example` with the binding-choice caveat. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
83 lines
3.8 KiB
Bash
83 lines
3.8 KiB
Bash
# Frontend build-time configuration. Copy to `frontend/.env` and fill in.
|
|
#
|
|
# Vite picks up VITE_* variables from these files at build (`npm run build`)
|
|
# and dev (`npm run dev`) time. Real `.env` files are gitignored; only this
|
|
# `.env.example` is committed.
|
|
|
|
# The user-visible name of this deployment. Used as the browser tab title,
|
|
# the header brand, and the landing page H1. Required — the framework
|
|
# ships no default on purpose so each deployment names itself. If unset,
|
|
# `npm run build` fails with a clear message.
|
|
#
|
|
# Examples:
|
|
# VITE_APP_NAME=Wiggleverse RFC
|
|
# VITE_APP_NAME=Wiggleverse Open Human Model
|
|
VITE_APP_NAME=
|
|
|
|
# Optional contact line shown on the /beta-pending page when a deployment
|
|
# is in private-beta mode (i.e. the backend's `allowed_emails` table has
|
|
# rows). Free-text — an email address, a URL, or a one-line instruction
|
|
# tells visitors how to request an invitation. If unset, the page falls
|
|
# back to a generic "contact the deployment operator" line.
|
|
#
|
|
# Examples:
|
|
# VITE_BETA_CONTACT=ben@wiggleverse.org
|
|
# VITE_BETA_CONTACT=DM @ben on Matrix
|
|
VITE_BETA_CONTACT=
|
|
|
|
# Optional URL to the deployment's privacy policy (v0.13.0+, SPEC §14.5).
|
|
# The framework ships a minimal default privacy policy at `/privacy`
|
|
# that describes the framework's stance and lists the cookies the
|
|
# framework sets. When this var is set to an http(s) URL, the page
|
|
# renders the framework's stub above a link to the configured URL —
|
|
# deployments use this to layer their own policy content on top
|
|
# without forking the framework. Unset is OK; the stub is sufficient
|
|
# for a deployment that has nothing specific to add.
|
|
#
|
|
# Examples:
|
|
# VITE_PRIVACY_POLICY_URL=https://wiggleverse.org/privacy
|
|
VITE_PRIVACY_POLICY_URL=
|
|
|
|
# Optional URL to the deployment's cookies policy (v0.13.0+, SPEC §14.6).
|
|
# Same shape as VITE_PRIVACY_POLICY_URL. The framework's default
|
|
# `/cookies` page lists exactly which cookies the framework sets
|
|
# (rfc_session, the consent-choice localStorage entry); a deployment
|
|
# that adds its own cookies (analytics SDK once #13 lands, third-party
|
|
# embeds) points this var at a page that documents the full list.
|
|
# Unset is OK; the stub is sufficient for a default-config deployment.
|
|
#
|
|
# Examples:
|
|
# VITE_COOKIES_POLICY_URL=https://wiggleverse.org/cookies
|
|
VITE_COOKIES_POLICY_URL=
|
|
|
|
# v0.12.0 / roadmap item #10: CloudFlare Turnstile site key (public).
|
|
# Provision a Turnstile site at dash.cloudflare.com → Turnstile → Add
|
|
# site. The site key (this var) is embedded into the frontend bundle at
|
|
# build time and rendered by the Turnstile widget on the /login email-
|
|
# entry step. The secret key (private) lives in the backend env as
|
|
# CLOUDFLARE_TURNSTILE_SECRET — see backend/.env.example. Leave unset
|
|
# in dev to skip the widget; the backend's TURNSTILE_REQUIRED policy
|
|
# decides what happens to a tokenless request.
|
|
#
|
|
# Examples:
|
|
# VITE_TURNSTILE_SITE_KEY=0x4AAAAAAA...
|
|
VITE_TURNSTILE_SITE_KEY=
|
|
|
|
# v0.15.0 / roadmap item #13: Amplitude project API key. Embedded in
|
|
# the frontend bundle at build time and used by the analytics wrapper
|
|
# (`frontend/src/lib/analytics.js`) when the user has granted analytics
|
|
# consent (v0.13.0 cookie banner). Provision an Amplitude project at
|
|
# app.amplitude.com → Projects → New, copy the API key.
|
|
#
|
|
# Caveat — secret-vs-overlay binding choice: Amplitude browser API
|
|
# keys are visible to anyone with browser dev tools (they ride in the
|
|
# shipped bundle). They are conventionally treated as semi-sensitive,
|
|
# not truly secret. The roadmap binds the value through flotilla's
|
|
# `secret set` verb anyway, to keep all-keys-in-Secret-Manager
|
|
# regularity for the OHM deployment. Leave unset in dev; the wrapper
|
|
# logs one console warning and no-ops (the app continues to work).
|
|
#
|
|
# Examples:
|
|
# VITE_AMPLITUDE_API_KEY=01234567890abcdef01234567890abcd
|
|
VITE_AMPLITUDE_API_KEY=
|