- Mark database setup tasks as completed - Update progress percentages and status - Document database implementation notes
189 lines
5.1 KiB
Markdown
189 lines
5.1 KiB
Markdown
# Phase 2: Database (Drizzle ORM)
|
|
|
|
**Status:** ✅ Done
|
|
**Progress:** 12/12 tasks (100%)
|
|
**Started:** 2025-10-30
|
|
**Completed:** 2025-10-30
|
|
**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
|
|
|
|
- [x] Install Drizzle ORM & PostgreSQL driver
|
|
|
|
```bash
|
|
pnpm add drizzle-orm postgres
|
|
pnpm add -D drizzle-kit
|
|
```
|
|
|
|
- [x] 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!,
|
|
},
|
|
})
|
|
```
|
|
|
|
- [x] 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
|
|
|
|
- [x] 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)
|
|
|
|
- [x] 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
|
|
|
|
- [x] Create carts table schema
|
|
- Fields: id (UUID), user_id (FK to users, nullable), session_id, created_at, updated_at
|
|
- Relations: hasMany cart_items
|
|
|
|
- [x] 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
|
|
|
|
- [x] 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
|
|
|
|
- [x] 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
|
|
|
|
- [x] Generate initial migration
|
|
|
|
```bash
|
|
pnpm db:generate
|
|
```
|
|
|
|
- Verify migration files in `server/database/migrations/`
|
|
|
|
- [x] 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
|
|
|
|
- [x] 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 })
|
|
```
|
|
|
|
- [x] 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
|
|
|
|
- [x] Setup Drizzle Studio
|
|
|
|
```bash
|
|
pnpm db:studio
|
|
```
|
|
|
|
- Open http://localhost:4983
|
|
- Verify all tables are visible
|
|
- Test data manipulation via Studio
|
|
|
|
- [x] 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)
|