// Command seed-admin creates or refreshes the admin user so it survives DB // resets (test suites drop the users table). Runs as part of `make db-up`. // Env: ADMIN_EMAIL (default admin@where-woof.com), ADMIN_PASSWORD (default // dev-only "AdminPass123!"), ADMIN_NAME (default "Admin"). package main import ( "context" "fmt" "os" "github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgxpool" "wherewoof/frontend/internal/auth" "wherewoof/frontend/internal/db" ) func main() { dsn := os.Getenv("DATABASE_URL") if dsn == "" { fmt.Fprintln(os.Stderr, "error: DATABASE_URL not set") os.Exit(1) } email := os.Getenv("ADMIN_EMAIL") if email == "" { email = "admin@where-woof.com" } password := os.Getenv("ADMIN_PASSWORD") if password == "" { password = "AdminPass123!" // dev default; override in production env } name := os.Getenv("ADMIN_NAME") if name == "" { name = "Admin" } hash, err := auth.HashPassword(password) if err != nil { fmt.Fprintln(os.Stderr, "hash:", err) os.Exit(1) } // Go's bcrypt emits "$2a$"; PHP/Laravel login requires "$2y$" (same // algorithm, different marker). Rewrite the prefix so the admin can log // into the Filament panel. Both Go and PHP verify either prefix. hash = "$2y$" + hash[4:] ctx := context.Background() pool, err := pgxpool.New(ctx, dsn) if err != nil { fmt.Fprintln(os.Stderr, "connect:", err) os.Exit(1) } defer pool.Close() if _, err := db.New(pool).UpsertAdmin(ctx, db.UpsertAdminParams{ Email: email, PasswordHash: hash, Name: pgtype.Text{String: name, Valid: name != ""}, }); err != nil { fmt.Fprintln(os.Stderr, "upsert admin:", err) os.Exit(1) } fmt.Println("admin ready:", email) }