Architecture
Stack: TanStack Start (React 19, Vite 7) on Cloudflare Workers · Tailwind v4 · Lovable Cloud (Supabase) · Lovable AI Gateway · ElevenLabs Conversational AI
Layers
┌─────────────────────────────────────────────────────┐
│ Browser — React 19 / TanStack Router │
│ • Ritual UI (index.tsx) │
│ • SVG visualizers (HexagramGlyph, ZodiacWheel) │
│ • ElevenLabs WebRTC client (@elevenlabs/react) │
│ • localStorage: birthdate, session history │
└──────────────┬──────────────────────────────────────┘
│ RPC (createServerFn) + fetch
▼
┌─────────────────────────────────────────────────────┐
│ Cloudflare Worker — TanStack Start SSR │
│ • src/lib/*.functions.ts (server functions) │
│ - divination · interpret · sigil · vision │
│ - astrology · elevenlabs token route │
│ • Middleware: requireSupabaseAuth (RLS as user) │
└─────┬─────────────────┬──────────────┬──────────────┘
│ │ │
▼ ▼ ▼
┌───────────┐ ┌──────────────┐ ┌────────────────┐
│ Supabase │ │ Lovable AI │ │ ElevenLabs API │
│ Postgres │ │ Gateway │ │ • WebRTC token │
│ + Storage │ │ • Gemini │ │ • Voice agent │
│ + Auth │ │ text/img │ │ (WebRTC) │
│ (anon + │ │ • GPT-Image │ └────────────────┘
│ RLS) │ └──────────────┘
└───────────┘
Frontend
- Routing: file-based (
src/routes/), single ritual page at/. - State: local React state +
localStoragefor birthdate, history arc, sigil intent. - Visualizers: hand-rolled SVG — Rider-Waite-Smith images for tarot, procedural hexagrams with changing-line indicators, zodiac wheel for horoscope, deterministic seeded sigil geometry.
- Voice:
@elevenlabs/reactuseConversationover WebRTC; livesendContextualUpdatepushes the full altar state (cards, sigil, vision, horoscope, history, birthdate) to the agent on every change.
Backend (server functions)
All app logic is createServerFn in src/lib/*.functions.ts — typed RPC, no REST layer:
divination.functions.ts— Fisher–Yates tarot shuffle, 3-coin I Ching cast, seeded RNG on the server.interpret.functions.ts— Gemini call for per-position significance + full-reading synthesis, birthdate-aware, history-aware.astrology.functions.ts— natal + transit Sun/Moon calc, timeframe-scoped horoscope.sigil.functions.ts— chaos-magic reduction → seeded SVG seal → Gemini image ornamentation → Supabase Storage.vision.functions.ts— GPT-Image symbolic scene from the drawn cards.routes/api/elevenlabs/token.ts— mints WebRTC conversation tokens withELEVENLABS_API_KEY+ELEVENLABS_AGENT_ID.
Data
- Postgres:
symbols(78 tarot + 64 hexagrams),spreads,sessions,readings,sigils,visions,uploads. - RLS: every table locked to
auth.uid(); anonymous sign-in on page load gives each visitor a scoped identity. - Storage: private buckets
sigils,visions,uploads; signed URLs returned by server functions.
AI
- Text/interpretation: Lovable AI Gateway →
google/gemini-*-flash(chat completions). - Images: Gateway →
google/gemini-3.1-flash-image(sigil ornament) andopenai/gpt-image-2(visions). - Voice: ElevenLabs Conversational AI agent, configured server-side by agent ID.
Key patterns
- Isomorphic loaders, server-only secrets —
process.envreads only inside.handler()bodies. - Context streaming, not tool calling — the voice agent sees the whole altar via
sendContextualUpdate, so no tool round-trips. - Deterministic seeded generation — FNV-1a + Mulberry32 makes sigils reproducible per intent while still varied.
- Session arc as prompt fuel — prior readings are re-injected into every new interpretation so the narrative compounds.
Built With
- claude
- lovable
- supabase
Log in or sign up for Devpost to join the conversation.