vestige/supabase/migrations/0001_waitlist.sql
Sam Valladares cfe8d03d36 feat(landing): full-viewport GPU node-engine hero + waitlist + dashboard auth removal
The /launch landing page (bleeding-edge waitlist hero):
- Full-viewport WebGL node engine (src/lib/hero/nodeEngine.ts): 40k GPU particles
  on a two-FBO GPUComputationRenderer running an 18s looping cinematic — particles
  stream in from the screen edges, slam together and EXPLODE at center, reform into
  a brain / graph constellation / neural lattice, dissolve back out, loop. Glowing
  additive particles + UnrealBloom, fills the whole screen edge to edge.
- Key GPGPU fix: custom DataTexture shape targets read black in GPUComputationRenderer
  (three.js #15882), so shape targets are computed PROCEDURALLY in-shader from the
  per-particle seed. Position integrates raw per-frame velocity (Codrops pattern),
  texel-center reference attribute.
- AmbientField (god-ray glow + parallax starfield), phantomBrain (deterministic
  seed-from-identity memory graph), LandingHero/neuralFlow (WebGPU Cinema-storm
  reuse + WebGL fallback, kept as alternates). Manifesto copy, seed input, email
  capture. No em-dashes. SSR off + prerender for the WebGL route.

Waitlist backend (Supabase, owned data):
- supabase/migrations/0001_waitlist.sql (RLS-locked table, dedup), Edge Function
  waitlist-join (CORS, validation, honeypot, dedup, Resend confirmation), setup doc.

Dashboard auth removed (reverts the launch-polish auth wall that 401'd the dashboard
against itself): mod.rs/state.rs/websocket.rs back to no-token, api.ts/websocket.ts/
+layout.svelte stripped of the token client. Pending-review UX + Memory PR gating kept.

Research/spec docs under docs/launch/. Frontend typechecks 0/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 22:54:51 -05:00

37 lines
1.8 KiB
SQL

-- Vestige Pro waitlist capture.
--
-- One row per signup from the public /dashboard/waitlist form. The form POSTs
-- through the `waitlist-join` Edge Function (service-role), NOT directly to this
-- table, so Row-Level Security stays closed to anon clients while the function
-- can insert. We keep the table minimal and queryable for launch-day export.
create table if not exists public.waitlist (
id uuid primary key default gen_random_uuid(),
email text not null,
name text,
plan text, -- 'solo' | 'team' (free-form, not enforced)
priority text, -- 'sync' | 'team-memory' | 'postgres' | 'support'
notes text,
source text default 'vestige-pro-waitlist',
user_agent text,
-- Lowercased email for case-insensitive dedup. Generated so callers can't
-- desync it from `email`.
email_norm text generated always as (lower(trim(email))) stored,
created_at timestamptz not null default now()
);
-- One signup per email address. ON CONFLICT in the function turns a re-submit
-- into a friendly "already on the list" instead of a duplicate row or an error.
create unique index if not exists waitlist_email_norm_key
on public.waitlist (email_norm);
-- Newest-first export / dashboards.
create index if not exists waitlist_created_at_idx
on public.waitlist (created_at desc);
-- RLS ON, no anon policies: the anon/public key can do NOTHING here directly.
-- Only the service-role key used inside the Edge Function bypasses RLS to insert.
alter table public.waitlist enable row level security;
comment on table public.waitlist is
'Vestige Pro launch waitlist. Inserted only via the waitlist-join Edge Function (service-role). RLS blocks all anon access.';