feat: backend service

This commit is contained in:
Ilia Denisov
2026-05-06 10:14:55 +03:00
committed by GitHub
parent 3e2622757e
commit f446c6a2ac
1486 changed files with 49720 additions and 266401 deletions
+56
View File
@@ -0,0 +1,56 @@
package admin
import (
"context"
"fmt"
"galaxy/backend/internal/config"
"go.uber.org/zap"
"golang.org/x/crypto/bcrypt"
)
// Bootstrap inserts the seed admin row when the env-driven
// `BACKEND_ADMIN_BOOTSTRAP_USER` / `BACKEND_ADMIN_BOOTSTRAP_PASSWORD`
// values are supplied and no row with that username exists yet. The
// insert is idempotent across restarts so operators can leave the env
// vars set after the first deploy without re-creating the row on
// every boot.
//
// Bootstrap runs *before* `Cache.Warm` so the warm read picks up the
// seed row. Errors are returned to the caller; the boot path in
// `cmd/backend/main.go` aborts startup if Bootstrap fails (a missing
// admin would lock the surface out anyway, so failing fast is the
// safer default).
//
// When both env vars are empty the function logs "skipped" and
// returns nil. `config.Validate()` already enforces that the username
// and password are set together, so by the time Bootstrap runs the
// remaining "user set without password" combination is impossible.
func Bootstrap(ctx context.Context, store *Store, cfg config.AdminBootstrapConfig, logger *zap.Logger) error {
if logger == nil {
logger = zap.NewNop()
}
logger = logger.Named("admin.bootstrap")
if cfg.User == "" {
logger.Info("skipped (no env vars)")
return nil
}
hash, err := bcrypt.GenerateFromPassword([]byte(cfg.Password), bootstrapBcryptCost)
if err != nil {
return fmt.Errorf("admin bootstrap: hash password: %w", err)
}
inserted, err := store.BootstrapInsert(ctx, cfg.User, hash)
if err != nil {
return fmt.Errorf("admin bootstrap: %w", err)
}
if inserted {
logger.Info("inserted seed admin", zap.String("admin_username", cfg.User))
} else {
logger.Info("skipped (admin exists)", zap.String("admin_username", cfg.User))
}
return nil
}