ADR-0002: Supabase for auth/DB/storage, NestJS as the API in front
Status: AcceptedDate: 2026-05-02Owner: @satyaContext
Section titled “Context”Treeper needs:
- Auth (email + Google + Apple at minimum) with minimal in-house code.
- Postgres.
- Object storage for trip cover images and inline photos.
- Realtime channels later (community feed, trip group chat).
- A backend tier for non-trivial business logic: AI worker orchestration, scraper coordination, marketplace verification, search.
Two natural ends of the spectrum:
- Pure Supabase: clients call PostgREST/Edge Functions directly; RLS enforces auth.
- Pure NestJS: roll our own Postgres + custom auth, ignore Supabase.
Both are wrong for us.
Decision
Section titled “Decision”Supabase owns auth, primary Postgres, and Storage. NestJS sits in front of it as the canonical REST API. Mobile clients only talk to NestJS, except for direct uploads to Supabase Storage with short-lived signed URLs issued by NestJS.
NestJS verifies Supabase-issued JWTs via passport-jwt against Supabase’s
JWKS. RLS in Postgres is treated as a defence-in-depth layer, not the only
authorisation gate.
Alternatives considered
Section titled “Alternatives considered”| Option | Why not |
|---|---|
| Pure Supabase (PostgREST + EFns) | Forces Edge Functions for non-CRUD logic; harder to test, harder to host elsewhere. |
| Pure NestJS + custom Postgres | Reinvents auth and storage, and we lose Supabase’s free OAuth providers. |
| Hasura / PostGraphQL | More tooling than this team needs at v0. Revisit if/when we need a federated graph. |
| Firebase | Lock-in to Google’s auth + Firestore data model; we want Postgres. |
Consequences
Section titled “Consequences”Positive
Section titled “Positive”- Auth ships in a day, not a sprint.
- Postgres = real schema, real migrations, real query power.
- We can leave Supabase later by replacing only the auth and storage adapters; the API surface stays the same.
- One source of truth for the mobile client: the NestJS API.
Negative / risks
Section titled “Negative / risks”- Two systems to operate (Supabase project + our own backend host).
- JWT verification adds a small per-request hop; cache JWKS aggressively.
- RLS rules duplicate some checks NestJS also enforces; we accept that as defence-in-depth.
Follow-ups
Section titled “Follow-ups”- ADR on schema migration tool (Prisma vs Drizzle vs raw SQL).
- ADR on file upload flow (signed URLs vs proxy through NestJS).
- Spec out auth UX in feature 0001’s scope: sign in, sign out, account delete.
References
Section titled “References”apps/backend/README.md- Supabase Auth JWT spec: https://supabase.com/docs/guides/auth/jwts