A multi-role supply-chain platform that lets customers order food and request cleaning or IT-support services, while six coordinated staff roles fulfil and track every job end-to-end through dedicated dashboards.
Total Supply unifies a Sri Lankan client's food orders and field services (cleaning, IT support) into one system. Customers order or request a service; six coordinated roles — admin, salesman, driver, cleaner, IT staff — fulfil and track each job through role-specific dashboards. Built on Next.js 16 with React Server Components, a Prisma 7 / Neon serverless-Postgres data layer, edge-middleware RBAC, an immutable audit log, a GDPR data-retention cron, and direct-to-GCS signed-URL uploads.
Role & Context
Sole full-stack engineer on a freelance engagement for a Sri Lanka-based supply-chain business. Owned everything end to end: requirements (171 features / 100+ user stories / 8-week roadmap), the 14-model Prisma data layer, all 83 API route handlers, six role-specific dashboards, NextAuth with an admin-approval gate, a Nodemailer pipeline (25+ templates), the GCS upload path, a GDPR data-retention cron, the landing performance pass, and Vercel deployment.
Problem
The client had no unified system: food orders were taken informally, cleaning and IT-support jobs were tracked off-platform, new-customer approvals and staff assignments were manual, and there was no audit trail or GDPR posture. The public landing page also shipped with a 3.2 s mobile Lighthouse Total Blocking Time, blocking first interaction on mid-tier devices.
Approach & Architecture
Loading diagram…
One Next.js 16 codebase: edge-middleware RBAC in front of Zod-validated handlers, Prisma on Neon, Nodemailer + GCS side-effects, and a daily Vercel cron for GDPR retention.
Best Practices Followed
Defence-in-depth RBAC at three layers: role + status in the NextAuth JWT, enforced at the edge by middleware (strict path-prefix routing), then re-checked inside each route handler
Audit logging on every privileged action (CREATE/UPDATE/DELETE/STATUS_CHANGE/LOGIN/LOGOUT) with actor, IP, user agent and JSON details, plus OrderStatusHistory at the order level
Compliance-by-design: GDPR export, soft-delete grace window, 30-day anonymisation, 730-day hard purge, and unsubscribe tokens on marketing-eligible email
Database-conscious queries: explicit Prisma select (no SELECT *), $transaction for multi-row mutations, capped pagination on every list endpoint, and indexes on every foreign key / filter column
Direct-to-storage uploads via 15-minute V4 signed URLs, so binary traffic never touches the serverless functions
Performance budget enforced in next.config.ts: optimizePackageImports tree-shaking, next/dynamic for below-the-fold sections and drawers, and route-scoped heavy CSS
Challenges & Resolution
ChallengeThe landing page shipped with a 3.2 s mobile Lighthouse Total Blocking Time — a 200 KB Swagger stylesheet imported in the root layout (loaded on every route), eagerly-bundled Chakra/Radix/icon libraries, and synchronously-mounted cart and mobile-nav drawers.
FixScoped the Swagger CSS to /api-docs, expanded optimizePackageImports for finer tree-shaking, converted the cart and mobile-nav drawers to next/dynamic (ssr:false), and code-split below-the-fold landing sections — the production build passes with 100/100 static pages.
ChallengeCoordinating six roles (CUSTOMER, ADMIN, SALESMAN, DRIVER, CLEANER, IT_STAFF) through one Next.js codebase without leaking admin endpoints or staff queues, plus a chicken-and-egg first-admin bootstrap.
FixEncoded role + status as NextAuth JWT claims; edge middleware enforces strict path-prefix RBAC and redirects mismatches; every protected handler re-checks via requireAdmin / requireRole; the first registrant auto-promotes to ADMIN+ACTIVE while later signups enter PENDING_APPROVAL until an admin approves.
Outcomes
Shipped on Vercel as a demo-ready deployment (production build green, 100/100 static pages, daily GDPR cron live)
End-to-end multi-role pipeline: order lifecycle PENDING → ACCEPTED → PREPARING → OUT_FOR_DELIVERY → DELIVERED with photo proof, plus a parallel CLEANING / IT_SUPPORT service pipeline with before/progress/after photos and 1-5 star ratings
Landing Lighthouse Total Blocking Time cut from 3.2 s (mobile) via route-scoped Swagger CSS, expanded tree-shaking, and next/dynamic code-splitting
14 Prisma models, 83 API route handlers, 25+ transactional email templates, and 6 role-specific dashboards in one Next.js 16 codebase
Compliance posture from day one: immutable audit log, GDPR export, soft-delete grace window, 30-day anonymisation, 730-day hard purge, per-user unsubscribe tokens
Role-Based Access Control (RBAC) with JWT claimsOAuth 2.0 / OpenID Connect (Google via NextAuth)React Server Components & the Next.js App RouterServerless PostgreSQL with an HTTP driver (Neon adapter for Prisma)Presigned URLs (V4 signing) for direct-to-bucket uploadsN+1 avoidance via Prisma select + $transactionTree-shaking & optimizePackageImportsCode-splitting via next/dynamic; Total Blocking Time / LCP optimisationGDPR data lifecycle (export, soft delete, anonymisation, hard purge)Immutable audit loggingTransactional email with unsubscribe tokens & retry-with-backoffVercel Cron Jobs for scheduled compliance work