mengstack-api/cmd/migrate/main.go
MengStack Dev df809f1045
Some checks failed
CI / Build & Test (push) Failing after 1m31s
feat: user CRUD API + dashboard stats + kernel infrastructure
- Add user management endpoints (list/create/get/update/delete) with pagination and search
- Add dashboard stats endpoint with tenant/user/online counts and growth metrics
- Add tenant resolver middleware for multi-tenant request scoping
- Add i18n kernel with zh/en message files and AcceptLanguage middleware
- Add WebSocket hub/handler for real-time communication
- Add job scheduler kernel with cron support
- Add plugin sandbox for isolated execution
- Add storage kernel (local filesystem)
- Add event bus kernel for pub/sub
- Add cache kernel abstraction
- Add database migration runner and version upgrade checker
- Add rate limiting middleware with Redis backend
- Add SQL migrations for rbac, audit_logs, settings, notifications, examples
- Extend user repository with list/delete/count operations
- Register all module routes with tenant resolver
2026-10-03 03:42:58 +08:00

108 lines
2.6 KiB
Go

package main
import (
"flag"
"fmt"
"os"
"mengstack/internal/config"
"mengstack/migrations"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/iofs"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: migrate <command> [flags]")
fmt.Println("Commands: up, down, status")
fmt.Println(" up [steps] Run pending migrations (optional step count)")
fmt.Println(" down [steps] Rollback migrations (optional step count, 0=all)")
fmt.Println(" status Show current migration status")
os.Exit(1)
}
cfg, err := config.Load()
if err != nil {
fmt.Fprintf(os.Stderr, "Error loading config: %v\n", err)
os.Exit(1)
}
dsn := fmt.Sprintf(
"postgres://%s:%s@%s:%d/%s?sslmode=%s&search_path=public",
cfg.Database.User, cfg.Database.Password,
cfg.Database.Host, cfg.Database.Port,
cfg.Database.DBName, cfg.Database.SSLMode,
)
source, err := iofs.New(migrations.Files, ".")
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating migration source: %v\n", err)
os.Exit(1)
}
m, err := migrate.NewWithSourceInstance("iofs", source, dsn)
if err != nil {
fmt.Fprintf(os.Stderr, "Error creating migrator: %v\n", err)
os.Exit(1)
}
cmd := os.Args[1]
switch cmd {
case "up":
steps := 0
fs := flag.NewFlagSet("up", flag.ExitOnError)
fs.IntVar(&steps, "steps", 0, "number of migrations to run (0=all)")
fs.Parse(os.Args[2:])
if steps > 0 {
err = m.Steps(steps)
} else {
err = m.Up()
}
if err != nil && err != migrate.ErrNoChange {
fmt.Fprintf(os.Stderr, "Migration error: %v\n", err)
os.Exit(1)
}
if err == migrate.ErrNoChange {
fmt.Println("No pending migrations")
} else {
fmt.Println("Migrations applied successfully")
}
case "down":
steps := 1
fs := flag.NewFlagSet("down", flag.ExitOnError)
fs.IntVar(&steps, "steps", 1, "number of migrations to rollback (0=all)")
fs.Parse(os.Args[2:])
if steps == 0 {
err = m.Down()
} else {
err = m.Steps(-steps)
}
if err != nil && err != migrate.ErrNoChange {
fmt.Fprintf(os.Stderr, "Rollback error: %v\n", err)
os.Exit(1)
}
fmt.Println("Rollback completed")
case "status":
v, dirty, err := m.Version()
if err != nil && err != migrate.ErrNoChange {
fmt.Fprintf(os.Stderr, "Status error: %v\n", err)
os.Exit(1)
}
if err == migrate.ErrNoChange {
fmt.Println("No migrations applied yet")
} else {
fmt.Printf("Current version: %d, dirty: %v\n", v, dirty)
}
default:
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", cmd)
os.Exit(1)
}
}