Overview

The Go backend utilizes GORM’s AutoMigrate feature grouped within a dedicated Migrator service. Migrations are decoupled from the main server startup to allow for safer deployment strategies.

Migration Structure

Migrations are defined in internal/shared/infrastructure/database/postgresql/migrations/.
  • migrator.go: contains the list of models and the logic to run migrations and seeding.
  • models_test.go: ensures all migration models are correctly defined.

Running Migrations

The migration tool is located at cmd/migrate/main.go.

Basic Usage

go run cmd/migrate/main.go
This will:
  1. Enable required PostgreSQL extensions (like pgvector).
  2. Synchronize the schema for all registered models.
  3. Seed default system data (e.g., subscription plans).

Seeding Sample Data

For development and testing environments, you can seed the database with demo organizations, users, and products:
go run cmd/migrate/main.go --seed-sample

Adding a New Table

  1. Define your GORM model in a relevant module or directly in migrator.go if it’s a shared core model.
  2. Register the model in the RunMigrations() method in internal/shared/infrastructure/database/postgresql/migrations/migrator.go.
  3. Re-run the migration tool.

Troubleshooting

Constraint Errors

If you receive a “column contains null values” error when adding a NOT NULL column to a table with existing data:
  1. Make the column nullable in the model temporarily.
  2. Run migration.
  3. Populate the column with data.
  4. Set not null back in the model and run migration again.

Type Cast Errors

If changing a column type (e.g., byteajsonb): GORM might fail to auto-cast. You may need to run a manual ALTER TABLE query:
ALTER TABLE outbox_events ALTER COLUMN payload TYPE jsonb USING payload::jsonb;