← Back to portfolio
Full-Stack · Edge Web App · Case Study

Case Study — Lightside Frontiers Hub: an edge-rendered VC site on Cloudflare

What: the public site for Lightside Venture Capital — server-rendered at the edge, with a secure, edge-native pitch-submission flow. Role: architect & engineer (hybrid Lovable + Claude Code workflow) · Where it lives: ~/Projects/lightside-frontiers-hub Stack: TanStack Start (React 19) · Cloudflare Workers · Supabase · Zod · shadcn/Radix · Tailwind v4 · Bun Prepared 2026-07-12

Status & honesty note: this is a real, deployable edge app (56 .tsx files, 7 routes, 46 UI components) built in a hybrid AI-native workflow — Lovable owns the primary edit loop, Claude Code is a focused secondary editor, and a CLAUDE.md documents exactly which machine-generated files must never be hand-edited. The architecture and security decisions below are real and demonstrate judgment regardless of how the code was typed; representing the build workflow honestly is part of the point.


1. Summary

A venture fund's site is mostly static content — but the one interactive surface, "pitch us," is where the engineering matters: it's a public, unauthenticated form, which means spam, injection, and secret-handling risk. Lightside Frontiers Hub renders the marketing site at the edge (TanStack Start on Cloudflare Workers) and handles the pitch flow with an edge server function that validates with Zod, defends against bots with a honeypot + timing trap, escapes everything before it templates an email, and keeps its service-role secret strictly server-side.

It's a compact, modern demonstration of edge-first full-stack: file-based routing, SSR at the edge, server functions, a disciplined shadcn/Radix design system, complete SEO, and a security-minded approach to the one place users can submit data.


2. What it is

The public Lightside VC site — seven file-based routes: index, thesis, portfolio, team, story, and contact (plus root). Everything is presentational except contact, which submits a founder's pitch. That single write path is the engineering focus of this case study.


3. Architecture at a glance

┌──────────────────── TanStack Start (React 19, file-based routing) ────────────────────┐
│  7 routes · per-route SEO (title/description/OG/Twitter/canonical)                      │
│  UI: shadcn/ui (46 Radix components) · class-variance-authority + tailwind-merge · TW v4 │
├─────────────────────────────────────────────────────────────────────────────────────────┤
│  Edge runtime: Cloudflare Workers  (wrangler.jsonc · main: @tanstack/react-start/server) │
│    ├─ SSR of every route at the edge                                                     │
│    └─ Server functions (createServerFn) — the pitch handler runs here, not in the client │
├─────────────────────────────────────────────────────────────────────────────────────────┤
│  Data/email: Supabase (anon client + service-role server client)  ·  Resend (via gateway)│
└─────────────────────────────────────────────────────────────────────────────────────────┘
   Build: Vite (@lovable.dev/vite-tanstack-config) · Bun · TanStack Query · analytics shim

4. Front end


5. The edge server function — the engineering centerpiece

The pitch handler is a TanStack Start server function (createServerFn({ method: "POST" })) that executes on the Cloudflare Worker, never in the browser. It layers defenses:

1 · Schema validation (Zod). An .inputValidator runs ContactSchema.safeParse — names/emails/company/message with length caps and a constrained stage enum — and surfaces only a user-safe first-issue message (invalid_input:<field>), never raw validator internals.

2 · Anti-spam, defense-in-depth.

// Honeypot: a hidden `website` field must be empty. If a bot fills it,
// we RETURN SUCCESS anyway — so bots never learn what tripped them.
if (data.website) return { ok: true, id: null, submissionId: generateSubmissionId() }

// Timing trap: forms submitted in under 2s are almost certainly bots.
if (data.elapsedMs < 2000) return { ok: false, code: "too_fast", message: "…review your pitch…" }

The elapsedMs (time the form was on screen) and the hidden honeypot are both validated by the schema, and failures return typed error codes (invalid_input | honeypot | too_fast | config | send_failed) so the UI can respond precisely.

3 · Injection-safe email templating. Every user value is run through an escapeHtml() before it's interpolated into the HTML email body — the submitted message can't inject markup into the notification. A stable submissionId is generated for traceability.

4 · Graceful configuration degradation. If the email provider keys are absent, the function doesn't crash — it returns a config error with a human fallback ("email abhi@lightside.vc directly"). Missing infra degrades to a helpful message, never a 500.

5 · Delivery. The email is sent through a Resend connector gateway (bearer + connection-key headers), with reply_to set to the founder so replies just work.


6. Supabase — the client/server secret split

Two deliberately separate clients enforce secret hygiene:

Client Key Runs Purpose
client.ts publishable/anon (VITE_*, build-time) browser + SSR safe, RLS-bounded reads
client.server.ts service-role (process.env only) edge server only privileged writes — never shipped to the client

A TanStack requireSupabaseAuth middleware (auth-middleware.ts) guards server functions that need a session. The service-role key exists only in process.env on the Worker — it can never leak into the client bundle, which is exactly the mistake this split prevents.


7. Observability

A small, SSR-safe analytics shim (src/lib/analytics.ts) forwards a trackEvent to whichever provider is loaded on the page — Plausible, PostHog, GA4, or a GTM dataLayer — guarding typeof window and falling back to a console log in dev. One call site, provider-agnostic, no crash if none is present.


8. Engineering patterns

  1. Edge-first — SSR and the write path both run on Cloudflare Workers; there's no separate origin server to operate.
  2. Defense-in-depth on the one public write — Zod + honeypot + timing + typed errors + HTML-escaping, layered rather than relying on any single check.
  3. Secret hygiene by construction — the anon/service-role split makes leaking the privileged key structurally hard.
  4. Graceful degradation — absent email config returns a helpful fallback, not an error page.
  5. SEO/link-preview completeness — per-route OG/Twitter/canonical, treated as a feature.
  6. Disciplined AI-native workflow — a CLAUDE.md enumerates machine-generated files (router codegen, the Lovable-owned Supabase client, auth middleware) that must never be hand-edited, preventing drift between the Lovable and local edit loops. Working cleanly inside a hybrid human/AI pipeline is itself a 2026 skill.

9. Outcomes & what it demonstrates

Net: a small surface, engineered with the same discipline as a large one — which is exactly what "production instincts" means.


10. What's next

  1. Add server-side rate limiting on the pitch endpoint (Cloudflare KV / Durable Objects or Upstash) to complement the honeypot/timing checks.
  2. Persist submissions to a Supabase table (audit + CRM) in addition to the email, with RLS.
  3. A brief edge-vs-origin write-up (why Workers here, trade-offs) as a companion to the PartnerOS full-stack study.

Appendix · Stack & code map

Layer Technology
Framework TanStack Start (@tanstack/react-start), React 19
Routing TanStack Router — file-based (src/routes/, 7 routes)
Runtime Cloudflare Workers (wrangler.jsonc, nodejs_compat)
UI shadcn/ui (46 Radix components), class-variance-authority, tailwind-merge, Tailwind v4
Data / auth Supabase (anon client + service-role server client, auth middleware)
Validation Zod (react-hook-form + @hookform/resolvers)
Email Resend (via connector gateway)
Build / tooling Vite (@lovable.dev/vite-tanstack-config), Bun, ESLint, Prettier
Analytics SSR-safe multi-provider shim (Plausible/PostHog/GA4/GTM)
Path Responsibility
src/routes/*.tsx File-based routes + per-route SEO head()
src/server/contact.functions.ts Edge server function: Zod + honeypot + timing + escaped email
src/integrations/supabase/client.ts Browser/SSR anon client (RLS-bounded)
src/integrations/supabase/client.server.ts Edge-only service-role admin client
src/integrations/supabase/auth-middleware.ts requireSupabaseAuth server middleware
src/components/ui/* (46) shadcn/Radix design system
src/lib/analytics.ts Provider-agnostic, SSR-safe event shim
wrangler.jsonc Cloudflare Workers config
CLAUDE.md AI-workflow guardrails (hands-off codegen files)

Grounded entirely in the code on file in ~/Projects/lightside-frontiers-hub as read on 2026-07-12 (route/component counts, the server-function logic, and the Supabase client split are from the repository). The hybrid Lovable + Claude Code build workflow is stated plainly; no sole-hand-authorship claim is made.