# Database Migrations ButterRobot uses a simple database migration system to manage database schema changes. This document explains how the migration system works and how to extend it. ## Automatic Migrations Migrations in ButterRobot are applied automatically when the application starts. This ensures your database schema is always up to date without requiring manual intervention. The migration system: 1. Checks which migrations have been applied 2. Applies any pending migrations in sequential order 3. Records each successful migration in the `schema_migrations` table ## Initial State The initial migration (version 1) sets up the database with the following: - `channels` table for chat platforms - `channel_plugin` table for plugins associated with channels - `users` table for admin users with bcrypt password hashing - Default admin user with username "admin" and password "admin" This migration represents the current state of the database schema. It is not backwards compatible with previous versions of ButterRobot. ## Creating New Migrations To add a new migration, follow these steps: 1. Open `/internal/migration/migrations.go` 2. Add a new migration version in the `init()` function: ```go Register(2, "Add example table", migrateAddExampleTableUp, migrateAddExampleTableDown) ``` 3. Implement the up and down functions for your migration: ```go // Migration to add example table - version 2 func migrateAddExampleTableUp(db *sql.DB) error { _, err := db.Exec(` CREATE TABLE IF NOT EXISTS example ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) `) return err } func migrateAddExampleTableDown(db *sql.DB) error { _, err := db.Exec(`DROP TABLE IF EXISTS example`) return err } ``` ## Migration Guidelines 1. **Incremental Changes**: Each migration should make a small, focused change to the database schema. 2. **Backward Compatibility**: Ensure migrations are backward compatible with existing code when possible. 3. **Test Thoroughly**: Test both up and down migrations before deploying. 4. **Document Changes**: Add comments explaining the purpose of each migration. 5. **Version Numbers**: Use sequential version numbers for migrations. ## How Migrations Work The migration system tracks applied migrations in a `schema_migrations` table. When you run migrations, the system: 1. Checks which migrations have been applied 2. Applies any pending migrations in order 3. Records each successful migration in the `schema_migrations` table When rolling back, it performs the down migrations in reverse order. ## In Code Usage The application automatically runs pending migrations when starting up. This is done in the `initDatabase` function. You can also programmatically work with migrations: ```go // Get database instance database, err := db.New(cfg.DatabasePath) if err != nil { // Handle error } defer database.Close() // Run migrations if err := database.MigrateUp(); err != nil { // Handle error } // Check migration status applied, pending, err := database.MigrationStatus() if err != nil { // Handle error } ```