Phase 01: Foundation - 5 plan(s) in 4 wave(s) - 2 parallel (wave 2: auth + tenant provisioning), 3 sequential - Ready for execution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
8.3 KiB
8.3 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-foundation | 01 | execute | 1 |
|
true |
|
Purpose: Every subsequent plan depends on this foundation existing. Nothing can be built without the project scaffold, database connection, and dev environment. Output: A running dockerized development environment with base schema and test infrastructure.
<execution_context> @C:\Users\KevinAsprec.claude/get-shit-done/workflows/execute-plan.md @C:\Users\KevinAsprec.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-foundation/01-CONTEXT.md Task 1: Create Next.js project with Docker Compose dev environment docker-compose.yml Dockerfile .dockerignore .env.example .env package.json tsconfig.json next.config.ts tailwind.config.ts postcss.config.mjs src/app/layout.tsx src/app/page.tsx src/app/globals.css Initialize a Next.js 15 project with App Router, TypeScript, and Tailwind CSS using `npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"` (answer yes to all prompts or use flags to avoid interactive mode).Create `docker-compose.yml` with three services:
1. **db**: PostgreSQL 16 image, port 5432, volume for data persistence, POSTGRES_USER=netforge, POSTGRES_PASSWORD=netforge_dev, POSTGRES_DB=netforge_dev
2. **redis**: Redis 7 image, port 6379
3. **app**: Builds from Dockerfile, port 3000, depends_on db and redis, mounts source code as volume for hot reload, environment variables from .env
Create a `Dockerfile` for development (Node 20 alpine, installs deps, runs `npm run dev`).
Create `.env.example` and `.env` with:
- DATABASE_URL=postgresql://netforge:netforge_dev@db:5432/netforge_dev
- REDIS_URL=redis://redis:6379
- NEXTAUTH_SECRET=dev-secret-change-in-production
- NEXTAUTH_URL=http://localhost:3000
Create `.dockerignore` excluding node_modules, .next, .git.
Update `src/app/page.tsx` to render a simple "NetForge" heading so we can verify the app loads.
IMPORTANT: Also create a local DATABASE_URL variant in .env for running Prisma commands from the host (outside Docker):
- DATABASE_URL_LOCAL=postgresql://netforge:netforge_dev@localhost:5432/netforge_dev
Add a note in .env.example explaining when to use each.
Run `docker compose up -d` and verify all three services start. Run `docker compose ps` to confirm all services are healthy/running. Visit http://localhost:3000 and confirm the page loads.
All three Docker services (db, redis, app) start successfully. Next.js app serves at localhost:3000.
Task 2: Prisma schema with base models and Vitest setup
prisma/schema.prisma
src/lib/prisma.ts
vitest.config.ts
src/lib/__tests__/setup.test.ts
package.json
Install Prisma: `npm install prisma @prisma/client` and `npm install -D vitest @vitejs/plugin-react`.
Create `prisma/schema.prisma` with PostgreSQL provider and the following base models:
**Tenant** model:
- id: String @id @default(uuid())
- name: String (business name)
- slug: String @unique (URL-friendly identifier, auto-generated from name)
- ownerEmail: String
- status: TenantStatus enum (ACTIVE, SUSPENDED, PENDING_SUSPENSION)
- suspendedAt: DateTime? (when suspension was triggered)
- gracePeriodEndsAt: DateTime? (when service actually stops — 7 day grace period)
- createdAt: DateTime @default(now())
- updatedAt: DateTime @updatedAt
- users: User[]
**User** model:
- id: String @id @default(uuid())
- email: String
- passwordHash: String
- firstName: String
- lastName: String
- tenantId: String? (nullable for super-admins who are not tenant-scoped)
- tenant: Tenant? @relation
- roles: Role[] (array of enum values — multi-role support)
- isActive: Boolean @default(true)
- isSuperAdmin: Boolean @default(false)
- createdAt: DateTime @default(now())
- updatedAt: DateTime @updatedAt
- @@unique([email, tenantId]) — email unique within tenant
- @@index([tenantId])
**Role** enum: ADMIN, OFFICE_STAFF, COLLECTOR, TECHNICIAN, CLIENT
**TenantStatus** enum: ACTIVE, SUSPENDED, PENDING_SUSPENSION
IMPORTANT: Add a comment block at the top of schema.prisma noting that tenant_id is included on all tenant-scoped models for RLS. Future models (Subscriber, Invoice, etc.) MUST include tenantId.
Create `src/lib/prisma.ts` — singleton PrismaClient pattern (check for existing instance on globalThis in dev to avoid hot-reload connection exhaustion).
Create `vitest.config.ts` with:
- resolve alias for @/* pointing to src/*
- test.globals: true
- test.environment: 'node'
Create `src/lib/__tests__/setup.test.ts` — a smoke test that imports prisma client and asserts it's defined (does NOT need DB connection, just verifies the import chain works).
Run `npx prisma generate` to generate the Prisma client.
Run `npx prisma db push` to sync the schema to the Dockerized PostgreSQL (use DATABASE_URL_LOCAL if running from host, or exec into app container).
Add to package.json scripts:
- "test": "vitest run"
- "test:watch": "vitest"
- "db:push": "prisma db push"
- "db:generate": "prisma generate"
- "db:studio": "prisma studio"
Run `npx vitest run` — the smoke test passes. Run `npx prisma db push` — schema syncs without errors. Run `npx prisma studio` briefly to confirm Tenant and User tables exist in the database.
Prisma schema with Tenant and User models is synced to PostgreSQL. Vitest runs and passes the smoke test. PrismaClient singleton is importable from @/lib/prisma.
1. `docker compose up -d` starts all services without errors
2. `docker compose ps` shows db, redis, and app running
3. http://localhost:3000 renders the Next.js app
4. `npx prisma db push` succeeds (schema matches DB)
5. `npx vitest run` passes all tests
6. `npx prisma studio` shows Tenant and User tables
<success_criteria>
- Docker Compose starts PostgreSQL 16, Redis 7, and Next.js 15 dev server with one command
- Prisma schema has Tenant and User models with RLS-ready tenantId field
- Vitest is configured and runs at least one passing test
- All environment variables are documented in .env.example </success_criteria>