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

LayerTechnologyPurpose
FrameworkNext.js (App Router)Full-stack React, SSR, API routes
ORMPrismaType-safe database access
GraphQL SchemaPothosCode-first GraphQL schema builder
GraphQL ServerGraphQL YogaPerformant server with subscription support
GraphQL ClientApollo ClientCaching, devtools, React integration
UI ComponentsShadCN/uiAccessible, customisable components
StylingTailwind CSSUtility-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

  1. Database (RLS) — Row-level security in Supabase
  2. ORM (Prisma) — Middleware for organisation scoping
  3. GraphQL (Pothos) — Auth plugin for field-level permissions
  4. 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