# Phase 2: Database (Drizzle ORM) **Status:** ⏳ Todo **Progress:** 0/12 tasks (0%) **Started:** - **Completed:** - **Assigned to:** - --- ## Overview Setup Drizzle ORM, define complete database schema for all tables (users, products, carts, cart_items, orders, order_items), generate and apply migrations, and create database utilities. **Goal:** Fully functional database with all MVP tables ready for use. --- ## Dependencies - ✅ Phase 1: Foundation must be completed - ✅ PostgreSQL running in Docker (docker-compose.dev.yml) --- ## Tasks ### Drizzle Setup - [ ] Install Drizzle ORM & PostgreSQL driver ```bash pnpm add drizzle-orm postgres pnpm add -D drizzle-kit ``` - [ ] Configure drizzle.config.ts ```typescript import { defineConfig } from 'drizzle-kit' export default defineConfig({ schema: './server/database/schema.ts', out: './server/database/migrations', dialect: 'postgresql', dbCredentials: { url: process.env.DATABASE_URL!, }, }) ``` - [ ] Add database scripts to package.json ```json { "scripts": { "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", "db:studio": "drizzle-kit studio", "db:push": "drizzle-kit push" } } ``` ### Schema Definition - [ ] Create users table schema - File: `server/database/schema.ts` - Fields: id (UUID), experimenta_id (unique), email, first_name, last_name, salutation, date_of_birth, street, post_code, city, country_code, phone, created_at, updated_at - See: [ARCHITECTURE.md Section 4.1](../docs/ARCHITECTURE.md#41-datenbank-schema) - [ ] Create products table schema - Fields: id (UUID), nav_product_id (unique), name, description, price (decimal), stock_quantity, category, active, created_at, updated_at - Indexes: nav_product_id, active, category - [ ] Create carts table schema - Fields: id (UUID), user_id (FK to users, nullable), session_id, created_at, updated_at - Relations: hasMany cart_items - [ ] Create cart_items table schema - Fields: id (UUID), cart_id (FK to carts), product_id (FK to products), quantity, added_at - Relations: belongsTo cart, belongsTo product - [ ] Create orders table schema - Fields: id (UUID), order_number (unique), user_id (FK to users), total_amount, status, billing_address (JSON), payment_id, payment_completed_at, created_at, updated_at - Relations: hasMany order_items - Indexes: order_number, user_id, status - [ ] Create order_items table schema - Fields: id (UUID), order_id (FK to orders), product_id (FK to products), product_snapshot (JSON), quantity, price_snapshot, created_at - Relations: belongsTo order, belongsTo product ### Migrations - [ ] Generate initial migration ```bash pnpm db:generate ``` - Verify migration files in `server/database/migrations/` - [ ] Apply migrations to dev database ```bash pnpm db:migrate ``` - Verify tables exist in PostgreSQL ```bash docker exec -it experimenta-db-dev psql -U dev -d experimenta_dev -c "\dt" ``` ### Database Utilities - [ ] Create database connection utility - File: `server/utils/db.ts` ```typescript import { drizzle } from 'drizzle-orm/postgres-js' import postgres from 'postgres' import * as schema from '../database/schema' const config = useRuntimeConfig() const client = postgres(config.databaseUrl) export const db = drizzle(client, { schema }) ``` - [ ] Test CRUD operations - Create test endpoint: `server/api/test/db.get.ts` - Test insert, select, update, delete on users table - Verify relations work (e.g., fetch cart with items) - Remove test endpoint after verification ### Tools - [ ] Setup Drizzle Studio ```bash pnpm db:studio ``` - Open http://localhost:4983 - Verify all tables are visible - Test data manipulation via Studio - [ ] Document schema decisions - Add comments to schema.ts explaining design choices - Document why JSONB for billing_address - Document why UUID vs serial IDs --- ## Acceptance Criteria - [x] Drizzle ORM is installed and configured - [x] All 6 tables are defined in schema.ts (users, products, carts, cart_items, orders, order_items) - [x] Relations between tables are defined correctly - [x] Initial migration is generated and applied - [x] All tables exist in PostgreSQL database - [x] Database connection utility (db.ts) is working - [x] CRUD operations work as expected - [x] Drizzle Studio can connect and display tables - [x] Schema is documented with comments --- ## Notes - **UUID vs Serial:** Using UUIDs for better distributed systems support and security - **JSONB for billing_address:** Flexible address storage, avoids complex normalized address tables - **Decimal for prices:** Using decimal(10,2) for accurate money calculations - **created_at/updated_at:** Timestamps for audit trail --- ## Blockers - None currently --- ## Related Documentation - [ARCHITECTURE.md: Database Schema](../docs/ARCHITECTURE.md#41-datenbank-schema) - [TECH_STACK.md: Drizzle ORM](../docs/TECH_STACK.md#5-orm) - [TECH_STACK.md: PostgreSQL](../docs/TECH_STACK.md#4-datenbank) - [CLAUDE.md: Database Schema](../CLAUDE.md#database-schema)