Next.js (App Router) app with TypeScript, Tailwind CSS, and a clear split between frontend, backend, and shared libs. Set up for digital intake, photo uploads, and background jobs (virus scanning, AI) with WCAG 2.1 Level AA in mind.
/src/frontend– UI components (shadcn/ui), hooks (React Query), global styles/src/backend– Business logic, services (image, PDF, queue)/src/app– Routes and API endpoints/prisma– Schema and migrations/lib– Shared instances (Prisma, R2 client)
-
Install dependencies (from project root):
npm install
-
Environment
Copy
.env.exampleto.envand set:DATABASE_URL– PostgreSQL connection string (Neon pooled string, used by the app and workers)DIRECT_URL– direct (non-pooled) PostgreSQL connection string, used by Prisma migrationsNEXTAUTH_SECRET– e.g.openssl rand -base64 32NEXTAUTH_URL– e.g.http://localhost:3000OPENAI_API_KEY,R2_ACCOUNT_ID,R2_BUCKET,REDIS_URLas needed
-
Database
npm run db:generate npm run db:push
-
Run
npm run dev
-
Browser → Next.js
Every request hits the App Router.src/app/layout.tsxwraps the app with fonts and Providers (React Query + NextAuth session). Page components insrc/appare server-rendered by default; client components insrc/frontendrun in the browser. -
Home page
src/app/page.tsxrenders the IntakeForm fromsrc/frontend/components/IntakeForm.tsx. The form uses React Hook Form + Zod for validation and the shared Button and Input fromsrc/frontend/components/ui(shadcn-style). Styling comes fromsrc/app/globals.cssand Tailwind (seetailwind.config.ts). -
Form submit (when wired)
On submit, the form would POST to an API route (e.g./api/intake). That route would use Prisma (lib/prisma.ts) to write to PostgreSQL. Any server state you fetch (e.g. with React Query) would call these same API routes from the client. -
Photo upload
A client posts multipart/form-data toPOST /api/upload(src/app/api/upload/route.ts). The route validates file size and type. When you’re ready, you’ll stream the file to S3 (usinglib/s3.ts) and push a job tosrc/backend/queue(BullMQ + Redis) for virus scanning. Workers created withcreateVirusScanWorkerwould run in a separate process or serverless function. -
Auth
NextAuth is mounted at/api/auth/*with a Credentials provider. Sign-in requires email + password validated againstpasswordHashin PostgreSQL. Session is JWT-based;session.user.idis available viauseSession().Testing locally: seed a user with
npx tsx scripts/seed-test-user.ts, then sign in from the home page. -
Backend services (placeholders)
src/backend/services/image.ts– Intended for Sharp: resize/compress uploads before S3.src/backend/services/pdf.ts– Intended for pdf-lib: generate grant PDFs.
Call these from API routes or queue workers when you implement them.
| You want to… | Use / look at… |
|---|---|
| Change the homepage UI | src/app/page.tsx, src/frontend/components |
| Add or change API routes | src/app/api/* |
| Read/write the database | lib/prisma.ts, prisma/schema.prisma |
| Handle auth (session, sign in/out) | src/app/api/auth/[...nextauth]/route.ts, useSession |
| Upload photos (validate → store → scan) | src/app/api/upload/route.ts, lib/s3.ts, src/backend/queue |
| Run background jobs | src/backend/queue (BullMQ), Redis |
| Shared UI (buttons, inputs) | src/frontend/components/ui |
| Global styles / theme | src/app/globals.css, tailwind.config.ts |
npm run dev– Dev server (Turbopack)npm run build/npm run start– Productionnpm run db:generate/npm run db:push/npm run db:migrate/npm run db:studio– Prismanpm run test/npm run test:watch– Jest + React Testing Librarynpm run test:e2e– Playwright E2E
docs/DISASTER_RECOVERY.md– Backup/restore RTO & RPO targets and the restore procedure.
- UI: Tailwind CSS, shadcn/ui (Button, Input in
src/frontend/components/ui) - Forms: React Hook Form + Zod
- Server state: React Query
- DB: Prisma + PostgreSQL
- Auth: NextAuth.js (Credentials provider boilerplate)
- Backend: Placeholders for Sharp, PDF-lib; Redis-backed queues (BullMQ) for virus scan and AI jobs
- Tests: Jest + RTL (unit), Playwright (E2E)
POST /api/upload– Multipart form-data photo upload (validates file, uploads to R2, queues virus scan)GET/POST /api/auth/[...nextauth]– NextAuth
- Focus visible styles and semantic HTML on the intake form.
- Aim for WCAG 2.1 Level AA; use the “Small Jobs Strategy” for incremental, senior-friendly changes.