System Design
Architecture Overview
A simplified, portable architecture designed for enterprise needs with security and compliance built in from day one.
Tech Stack
NextJS 14
App Router, Server Components
PostgreSQL
Reliable, scalable database
Prisma ORM
Type-safe database access
NextAuth.js
Flexible authentication
Zod
Runtime validation
shadcn/ui
Accessible components
4-Layer Security Model
Every API endpoint implements all four layers. No exceptions.
1
Authentication
NextAuth.js
Verify user identity before any operation
const session = await getServerSession(authOptions);
if (!session) return unauthorized();2
Validation
Zod Schemas
Sanitize and validate all user inputs
const validated = receiptSchema.parse(body);
// Throws ZodError on invalid input3
ORM Protection
Prisma
Parameterized queries prevent SQL injection
await prisma.receipt.findMany({
where: { userId: session.user.id }
});4
Secrets Management
Environment Variables
Sensitive data isolated from code
DATABASE_URL=***
NEXTAUTH_SECRET=***Folder Structure
nextjs_space/
├── app/ # NextJS App Router
│ ├── api/ # API routes
│ │ ├── auth/ # NextAuth endpoints
│ │ └── receipts/ # CRUD endpoints
│ ├── dashboard/ # Protected pages
│ └── (auth)/ # Auth pages
├── components/
│ ├── ui/ # shadcn/ui primitives
│ ├── layout/ # Header, Footer, Nav
│ └── receipts/ # Feature components
├── lib/
│ ├── auth.ts # NextAuth config
│ ├── db.ts # Prisma client
│ ├── validation.ts # Zod schemas
│ └── utils.ts # Helpers
├── prisma/
│ └── schema.prisma # Database schema
├── AGENTS.md # AI context file
├── PRD.md # Product requirements
└── progress.txt # Ralph iteration logKey Design Decisions
NextJS API Routes over separate backend
Simpler deployment, shared types, reduced latency
May need to split for very high scale
Prisma over raw SQL
Type safety, migrations, prevents SQL injection
Slight performance overhead
shadcn/ui over component library
Own the code, full customization, no lock-in
More initial setup than npm install
AGENTS.md pattern
AI context persistence, team onboarding
Must keep updated