The F1 Framework
13 architectural layers that turn a blank repo into a fully operational multi-tenant SaaS platform. Every layer is documented, tested, and already running in production.
13
Framework layers
6
Shared packages
100%
TypeScript strict
6/6
RLS tests passing
What's included
Frontend
- Next.js 15
- React 18
- TypeScript
- Tailwind CSS
Backend
- Server Actions
- API Routes
- Supabase Edge Functions
- Zod
Database
- Supabase Postgres
- Row Level Security
- Migrations
- pgTAP
Auth
- Supabase Auth
- JWT claims
- Multi-tenant RBAC
- Guards
Infrastructure
- Vercel
- Upstash Redis
- GitHub Actions
- Turborepo
Observability
- Sentry
- Structured logs
- Health checks
- Monitoring
13 foundational layers
Each layer is independently documented, tested, and wired into the working demo app. Fork it and your first day is architecture โ not plumbing.
Front-end foundations
A consistent, themeable UI shared across every app built on the framework.
- Server Components by default โ "use client" only when you need interactivity.
- Shared design tokens (light/dark CSS variables) in packages/ui/src/styles.css.
- All reusable UI lives in packages/ui so every app inherits it via @repo/ui.
- Forms use react-hook-form + Zod; server-side validation always re-checks.
Key files
packages/ui/src/packages/config/tailwind/preset.jsapps/web/app/globals.cssAPI & back-end logic
Typed, validated server logic with a single error/response convention.
- Three places server code lives: Server Actions (forms/mutations), API Routes (webhooks/external calls), and Supabase RPCs (complex DB logic).
- Every action returns a typed result union โ never throws unhandled exceptions.
- Validation at the boundary: every input validated with Zod before touching the DB.
- Rate-limit wrappers on all public endpoints (Layer 09).
Key files
apps/web/app/dashboard/**/actions.tsapps/web/app/api/packages/lib/src/errors.tsDatabase & storage
Postgres schema as code, typed access, and org-scoped file storage.
- Every schema change is a versioned migration file in supabase/migrations/.
- TypeScript types auto-generated from the live schema via pnpm db:types.
- Two clients: server client (service role, never in browser) and browser client (anon key + RLS).
- File storage uses org-scoped buckets with RLS policies matching the DB isolation model.
Key files
packages/db/src/supabase/migrations/packages/db/src/types/database.tsAuth & multi-tenant RBAC
Users belong to organizations; their role grants permissions; the database enforces it.
- Roles: owner > admin > member. Permissions are an explicit catalog โ never inferred at runtime.
- JWT custom access token hook stamps org memberships into the token so RLS can read them.
- requireUser() guard on every protected server component โ redirects if unauthenticated.
- canDo(role, action) helper prevents client-side permission guessing.
Key files
packages/auth/src/permissions.tspackages/auth/src/guards.tssupabase/migrations/Deployment
Push to Git โ app, database, and functions deploy automatically.
- Next.js app deploys to Vercel on every push to main (after CI passes).
- Database migrations run in CI via supabase db push โ never hand-applied.
- Edge functions deployed via supabase functions deploy in the deploy workflow.
- Preview deployments for every PR with isolated Supabase branch (optional).
Key files
.github/workflows/ci.yml.github/workflows/deploy.ymlapps/web/vercel.jsonCloud & compute
Know which workload runs on which compute, and why.
- Next.js server components run as Vercel Serverless Functions (Node.js runtime).
- Supabase hosts Postgres, Auth, Storage, and Edge Functions on managed infrastructure.
- Upstash Redis provides ephemeral key-value storage for rate limiting and caching.
- Third-party APIs (Stripe, Resend, Anthropic) are called server-side only โ keys never reach the browser.
Key files
packages/lib/src/redis.tspackages/lib/src/cache.tspackages/lib/src/env.tsCI/CD & version control
Nothing merges that isn't linted, typed, tested, built, and RLS-safe.
- CI runs on every push and PR: lint โ type-check โ unit tests โ build โ RLS pgTAP test.
- Turborepo remote cache skips unchanged packages โ a clean repo build takes ~45 s.
- Main branch is protected: requires CI green + PR review before merge.
- pgTAP tests run against a real Postgres instance to catch RLS regressions before deploy.
Key files
.github/workflows/ci.ymlturbo.jsonsupabase/tests/rls.test.sqlSecurity & Row Level Security
Tenant isolation enforced by the database โ not by application code alone.
- RLS is enabled on every table. A missing policy means no access โ fail closed.
- Policies extract org_id from the JWT claim set by the custom access token hook.
- Service role (admin client) bypasses RLS for background jobs and migrations only.
- All policies are covered by pgTAP tests that simulate different role/org combinations.
Key files
supabase/migrations/*_rls.sqlsupabase/tests/rls.test.sqlpackages/db/src/admin.tsRate limiting
Protect the app from abuse and runaway costs on every API boundary.
- Every public API route and server action wraps the rateLimit() helper.
- Limits are keyed by user ID when authenticated, falling back to IP address.
- Sliding window (not fixed bucket) โ prevents burst exploitation at window edges.
- Configurable limits per endpoint: auth endpoints are stricter than data endpoints.
Key files
packages/lib/src/rate-limit.tsapps/web/middleware.tsCaching & CDN
Serve fast, cheaply, without serving stale or cross-tenant data.
- Static assets and public pages served from Vercel's global edge network.
- Server component data is cached with Next.js unstable_cache + per-org cache tags.
- Mutations call revalidateTag() to invalidate only the affected org's cache.
- Never cache responses that contain user-specific or org-specific data without scoping the key.
Key files
packages/lib/src/cache.tsapps/web/lib/cache-keys.tsLoad balancing & scaling
Scale horizontally without manual operations.
- Vercel scales Next.js functions to zero and up automatically โ no instance management.
- Supabase PgBouncer pools connections so hundreds of serverless instances share a small pool.
- All server state is in Postgres or Redis โ functions are stateless and horizontally scalable.
- Session data lives in Supabase Auth (JWT) not in server memory.
Key files
packages/db/src/server.tspackages/lib/src/redis.tsError tracking & logs
Every error is captured, grouped, and traceable to one request.
- Sentry instruments both the browser bundle and the Next.js server runtime.
- Structured logger wraps console with level, timestamp, and request context.
- Every API error includes a request ID so logs and Sentry events correlate.
- Source maps are uploaded to Sentry on deploy so stack traces show original TypeScript.
Key files
packages/lib/src/logger.tsapps/web/sentry.client.config.tsapps/web/sentry.server.config.tsAvailability & recovery
Stay up, detect degradation early, and recover data fast.
- /api/health returns 200 with DB + Redis connectivity status for uptime monitors.
- /api/ready returns 503 until all dependencies are warm โ prevents cold-start routing errors.
- Supabase Point-in-Time Recovery (PITR) keeps 7-day backup history on Pro plan.
- Built-in monitoring dashboard (/dashboard/monitoring) shows platform health to owners.
Key files
apps/web/app/api/health/route.tsapps/web/app/api/ready/route.tsapps/web/app/dashboard/monitoring/How the layers connect
Each layer builds on the one below it. Swap any layer without touching the others.
Monorepo structure
Turborepo manages a single repo with one app and six shared packages. Import anything from anywhere with zero configuration.
apps/webAppThe Next.js 15 application. Pages, layouts, server actions, API routes, and all app-specific components.
packages/uiPackageShared React components (Button, Card, Input, etc.) and design tokens. Import as @repo/ui/button.
packages/dbPackageTyped Supabase clients (server, browser, admin) and auto-generated TypeScript types from the database schema.
packages/authPackageRBAC permission catalog, role definitions, and requireUser() / canDo() guard helpers.
packages/libPackageCross-cutting utilities: logger, rate limiter, cache helpers, email sender, error types, env validation.
packages/mcp-serverPackageClaude MCP server exposing app data as tools. Lets AI assistants read projects and tasks directly.
Start with everything wired
Fork the repo and your first commit is features, not infrastructure. Every layer in this framework is already running at f1.delbyn.com.