Skip to main content

Overview

The JOIP Web Application uses Drizzle ORM for type-safe database operations and schema management. All database schema definitions are centralized in shared/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

The shared/schema.ts file contains all database table definitions:

Database Connection Configuration

The database connection is configured in server/db.ts with connection pooling:

Running Migrations

Push Schema Changes

The primary migration command is npm run db:push, which applies schema changes from shared/schema.ts to your database:
1

Modify Schema

Edit shared/schema.ts to add, modify, or remove table definitions:
shared/schema.ts
2

Run Migration

Apply the schema changes to your database:
Output:
3

Verify Changes

Check your database to confirm the changes:
Destructive Changes: The db:push command can be destructive. It will drop columns or tables that are removed from the schema. Always backup your database before running migrations in production.

Alternative: Generate Migration Files

For more control over migrations, you can generate SQL migration files:
This creates migration files in the migrations/ directory that you can review before applying.

Common Schema Patterns

Adding a New Table

When adding a new table to the schema:
1

Define Table Schema

shared/schema.ts
2

Create Validation Schema

shared/schema.ts
3

Export TypeScript Types

shared/schema.ts
4

Apply Migration

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

Manual Migration Required: Drizzle’s db:push cannot safely rename columns. You must use SQL migrations for renames.

Changing Column Type

Dropping a Column

1

Remove from Schema

shared/schema.ts
2

Apply Migration

The column will be dropped from the database.
Data Loss: Dropping columns is irreversible. Ensure you have backups before removing columns in production.

Environment-Specific Migrations

Development

Staging

Production

Production Safety: Always test migrations in staging before applying to production. Use transaction-based migrations for critical changes.

Drizzle Kit Commands

Introspect Existing Database

Generate schema from an existing database:

Generate Migration Files

Create SQL migration files based on schema changes:
Output:

Drop All Tables

Destructive Command: This will delete all data. Only use in development.

Best Practices

Schema Design

  1. Use VARCHAR for User IDs: Supports both Replit OIDC (string IDs) and local auth (UUID)
  2. Add Timestamps: Include createdAt and updatedAt on all tables
  3. Default Values: Provide sensible defaults for optional fields
  4. Array Columns: Use PostgreSQL arrays for lists instead of join tables
  5. JSONB for Complex Data: Store structured data that doesn’t need querying

Migration Strategy

  1. Test Locally First: Always run migrations in development before staging
  2. Backup Before Migration: Create database backups before production migrations
  3. Incremental Changes: Make small, incremental schema changes
  4. Review Generated SQL: Check migration SQL for unexpected changes
  5. Document Breaking Changes: Note any breaking changes in commit messages

Validation

  1. Validate Early: Use Zod schemas at API boundaries
  2. Client-Side Validation: Mirror validation rules in React Hook Form
  3. Custom Validators: Add custom Zod refinements for complex validation
  4. 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:

Next Steps