ADR-009: Application Framework Stack
Status: Accepted Owner: @bilal @deen Date: 2025-12-16
Context
Envo needs a concrete technology stack for the application layer. Requirements: GraphQL API, ORM with GraphQL integration, end-to-end type safety, Supabase RLS compatibility, SSR capability, and good developer experience.
Decision
Next.js App Router as the application framework with:
Core Stack
| Layer | Technology | Purpose |
|---|---|---|
| Framework | Next.js (App Router) | Full-stack React, SSR, API routes |
| ORM | Prisma | Type-safe database access |
| GraphQL Schema | Pothos | Code-first GraphQL schema builder |
| GraphQL Server | GraphQL Yoga | Performant server with subscription support |
| GraphQL Client | Apollo Client | Caching, devtools, React integration |
| UI Components | ShadCN/ui | Accessible, customisable components |
| Styling | Tailwind CSS | Utility-first CSS |
Architecture Pattern
Modular monolith structured by domain:
app/ # Next.js App Router
├── (auth)/ # Auth pages
├── (dashboard)/ # Landlord dashboard
│ ├── issues/, properties/, vendors/, settings/
├── (admin)/ # Envo admin panel
├── api/graphql/ # GraphQL endpoint
└── v/[token]/ # Vendor acceptance pages
lib/ # Shared utilities
graphql/ # Schema builder, types, resolvers
components/ # ShadCN + custom components
prisma/ # Schema + migrations
GraphQL Auto-Generation
prisma-generator-pothos-codegen auto-generates GraphQL types, CRUD queries/mutations, and input types from Prisma models. Custom resolvers for complex business logic.
Security Layers
- Database (RLS) — Row-level security in Supabase
- ORM (Prisma) — Middleware for organisation scoping
- GraphQL (Pothos) — Auth plugin for field-level permissions
- Transport — Route Handler (not publicly documented)
Apollo over Relay
Apollo selected for flexibility, moderate learning curve, excellent DevTools, and team familiarity.
Consequences
Positive
- End-to-end type safety: Prisma → Pothos → Apollo → React
- Minimal CRUD boilerplate (auto-generated)
- Single deployment (frontend + API in one app)
- Subscription-ready (Yoga supports WebSocket + SSE)
Negative
- Prisma migrations must handle Supabase-specific features via raw SQL
- Apollo Client adds to frontend bundle
- Team must learn Pothos patterns