Maintained reference application for the OpenElement × Supabase × Cloudflare fullstack delivery path (epic #981, issue #983). Composition only: no framework-owned auth/database abstractions — Supabase owns data/Auth/RLS, Cloudflare owns edge delivery, OpenElement is the Web Components-native application layer.
- application shell + request-time routes (login, signup, Magic Link, PKCE callback, recovery/reset, notes, upload, admin)
- real sign-in/sign-out via @supabase/ssr cookies on the ADR-0129
response-header channel (
lib/supabase-server.ts) - /notes loader: getUser + RLS-scoped query; anonymous renders the denied branch over a hard database-level RLS floor
- explicit
middleware.corsOriginallowlist (deployed worker + localhost) - /upload: no-JS multipart upload/list/delete in the private
notes-attachmentsbucket; unpredictable object ids, MIME/size guards, 60-second signed downloads, Storage RLS, and atomic Postgres quota reservation/release reject anonymous, cross-user, and quota-race access; objects are immutable after INSERT (no UPDATE/upsert policy) - application-owned Cloudflare module entry composes Nitro
fetchwith Queue scan and Cron reconciliation handlers; unscanned objects stay hidden, duplicate verdicts are idempotent, and lifecycle events are audited - Tier 3 deployment can render a generated bounded Queue/DLQ/Cron overlay from the one safe Wrangler source; DLQ rows persist before ack and admin replay is durable; no duplicate provider config is maintained
- notes-live island: Supabase Realtime INSERT subscription in the browser,
RLS-scoped via the user's short-lived access token + a hard
user_idfilter, with bounded/deduplicated state, reconnect recovery, token refresh, and explicit unsubscribe on disconnect - admin authorization reads issuer-controlled
app_metadata.roleonly; matching RLS and immutable append-only audit migration included - Stripe webhook ingress preserves and verifies the raw body before JSON parsing, enforces timestamp tolerance, durably deduplicates provider event ids, and applies only monotonic order-state transitions
- one-time card Checkout uses a server-owned catalog, retry-stable attempt ids and Stripe idempotency keys; Session and PaymentIntent metadata carry the order id, paid events must reconcile amount/currency, and the success URL never grants payment state
- verified Stripe events persist a minimal envelope before Queue handoff; the Queue consumer owns state transitions, exhausted delivery becomes a durable admin-visible DLQ row, and Cron safely re-enqueues received events and requested replays
- Deno (workspace tasks), Node (Nitro
nodepreset run), - Supabase CLI + Docker (local emulator; migrations), or a hosted project,
- Cloudflare account for deployment (wrangler, secret-boundary runbook).
- A self-hosted OPSWAT MetaDefender Core HTTPS endpoint and API key for real attachment qualification; the scanner fails closed when these are absent.
deno task build # OpenElement build (dist/, request-time server entry)
deno task nitro:build # Nitro build (OPEN_ELEMENT_NITRO_PRESET=cloudflare_module → .output-workers/)
deno task start # local run of the built server (http://localhost:4173)
deno task check # type-check routes, islands, shell, lib
deno task test # unit smoke for route logic (stubbed Supabase client)supabase link --project-ref <ref>
supabase db push # applies ordered, manifest-checked migrationsProduction migration checks and deployment use the pinned
Supabase project smoke (real project) workflow and the dedicated credentials documented in
docs/runbooks/supabase-migrations.md. Runtime
service-role credentials are not migration credentials.
Payment delivery, DLQ recovery, and replay operations are documented in
docs/runbooks/payment-events.md.
Required worker env (server-side only, never in the client bundle):
SUPABASE_URL
SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
STRIPE_WEBHOOK_SECRET
STRIPE_LIVEMODE
STRIPE_SECRET_KEY
STRIPE_PRICE_ID
STRIPE_CHECKOUT_HOST
APP_ORIGIN
METADEFENDER_CORE_URL
METADEFENDER_API_KEY
Optional OAuth provider switches (default off; a provider renders on /login
only when its flag is exactly true and the provider is configured in the
Supabase dashboard — otherwise the page shows
"OAuth providers: not configured" and the oauth action fails closed):
SUPABASE_OAUTH_GOOGLE_ENABLED
SUPABASE_OAUTH_GITHUB_ENABLED
The anon key is additionally rendered into the /notes page as a data attribute
for the realtime island — it is a public key by design; row visibility stays
enforced by RLS and the island's user_id filter. The service-role and Stripe
webhook secrets are server-only Worker bindings used by lifecycle/webhook
handlers and must never be rendered or prefixed with VITE_.
- Tier 2 real Supabase password/OAuth/RLS/Realtime matrix.
- Tier 3 deployed Workers journey and Cloudflare production rate limiting.
- Production SMTP domain/authentication and bounce handling — execute
docs/runbooks/production-smtp-checklist.md.