package migrate import ( "fmt" "github.com/spf13/cobra" "go.uber.org/zap" "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config" "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/storage/database" ) // MigrateCmd returns the migrate command with subcommands func MigrateCmd() *cobra.Command { cmd := &cobra.Command{ Use: "migrate", Short: "Database migration commands", } cmd.AddCommand(upCmd()) cmd.AddCommand(downCmd()) cmd.AddCommand(versionCmd()) cmd.AddCommand(forceCmd()) return cmd } // upCmd runs pending migrations func upCmd() *cobra.Command { return &cobra.Command{ Use: "up", Short: "Run all pending migrations", RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.Load() if err != nil { return fmt.Errorf("failed to load config: %w", err) } // Create simple logger for CLI logger := zap.NewNop() // Silent logger for migrate commands migrator := database.NewMigrator(cfg, logger) if err := migrator.Up(); err != nil { return fmt.Errorf("failed to run migrations: %w", err) } return nil }, } } // downCmd rolls back the last migration func downCmd() *cobra.Command { return &cobra.Command{ Use: "down", Short: "Rollback the last migration", RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.Load() if err != nil { return fmt.Errorf("failed to load config: %w", err) } // Create console logger for CLI output logger, _ := zap.NewDevelopment() defer logger.Sync() migrator := database.NewMigrator(cfg, logger) if err := migrator.Down(); err != nil { return fmt.Errorf("failed to rollback migration: %w", err) } logger.Info("Successfully rolled back last migration") return nil }, } } // versionCmd shows the current migration version func versionCmd() *cobra.Command { return &cobra.Command{ Use: "version", Short: "Show current migration version", RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.Load() if err != nil { return fmt.Errorf("failed to load config: %w", err) } // Create console logger for CLI output logger, _ := zap.NewDevelopment() defer logger.Sync() migrator := database.NewMigrator(cfg, logger) version, dirty, err := migrator.Version() if err != nil { return fmt.Errorf("failed to get version: %w", err) } if dirty { logger.Warn("Current migration version is DIRTY - requires manual intervention", zap.Uint("version", uint(version))) } else { logger.Info("Current migration version", zap.Uint("version", uint(version))) } return nil }, } } // forceCmd forces a specific migration version func forceCmd() *cobra.Command { var version int cmd := &cobra.Command{ Use: "force", Short: "Force database to a specific migration version (use with caution)", RunE: func(cmd *cobra.Command, args []string) error { cfg, err := config.Load() if err != nil { return fmt.Errorf("failed to load config: %w", err) } logger := zap.NewNop() migrator := database.NewMigrator(cfg, logger) if err := migrator.ForceVersion(version); err != nil { return fmt.Errorf("failed to force version: %w", err) } return nil }, } cmd.Flags().IntVarP(&version, "version", "v", 0, "Migration version to force") cmd.MarkFlagRequired("version") return cmd }