Overview
The JOIP Web Application uses Drizzle ORM for type-safe database operations and schema management. All database schema definitions are centralized inshared/schema.ts, which serves as the single source of truth for:
- Database table structures
- Column definitions and constraints
- Foreign key relationships
- Validation schemas (via Zod)
- TypeScript types
Schema Architecture
Schema File Organization
Theshared/schema.ts file contains all database table definitions:
Database Connection Configuration
The database connection is configured inserver/db.ts with connection pooling:
Running Migrations
Push Schema Changes
The primary migration command isnpm run db:push, which applies schema changes from shared/schema.ts to your database:
Alternative: Generate Migration Files
For more control over migrations, you can generate SQL migration files:migrations/ directory that you can review before applying.
Common Schema Patterns
Adding a New Table
When adding a new table to the schema:Adding Foreign Keys
Foreign key relationships ensure referential integrity:The
onDelete: "cascade" option ensures that when a session is deleted, all associated media items are automatically deleted.Adding Indexes
Indexes improve query performance for frequently accessed columns:Array Columns
PostgreSQL array columns for storing lists:JSON Columns
For storing complex structured data:Validation with Zod
Creating Insert Schemas
Drizzle integrates with Zod for runtime validation:Using Validation in API Routes
Database Constraints
The JOIP database schema includes comprehensive constraints for data integrity:Primary Keys and Unique Constraints
Foreign Key Constraints
The database includes 13 foreign key relationships ensuring referential integrity:Performance Indexes
Optimized indexes for common query patterns:Common Migration Tasks
Adding a Column with Default Value
Renaming a Column
Changing Column Type
Dropping a Column
Environment-Specific Migrations
Development
Staging
Production
Drizzle Kit Commands
Introspect Existing Database
Generate schema from an existing database:Generate Migration Files
Create SQL migration files based on schema changes:Drop All Tables
Best Practices
Schema Design
- Use VARCHAR for User IDs: Supports both Replit OIDC (string IDs) and local auth (UUID)
- Add Timestamps: Include
createdAtandupdatedAton all tables - Default Values: Provide sensible defaults for optional fields
- Array Columns: Use PostgreSQL arrays for lists instead of join tables
- JSONB for Complex Data: Store structured data that doesn’t need querying
Migration Strategy
- Test Locally First: Always run migrations in development before staging
- Backup Before Migration: Create database backups before production migrations
- Incremental Changes: Make small, incremental schema changes
- Review Generated SQL: Check migration SQL for unexpected changes
- Document Breaking Changes: Note any breaking changes in commit messages
Validation
- Validate Early: Use Zod schemas at API boundaries
- Client-Side Validation: Mirror validation rules in React Hook Form
- Custom Validators: Add custom Zod refinements for complex validation
- Error Messages: Provide clear, user-friendly validation messages
Troubleshooting
Migration Fails with Constraint Violation
Issue: Adding a NOT NULL column to a table with existing data Solution: Add column with NULL first, populate data, then set NOT NULL:Schema Out of Sync
Issue: Local schema doesn’t match database Solution:Connection Pool Exhausted
Issue: Too many concurrent connections Solution: Adjust pool configuration in.env: