package main import ( "log" "net/http" "os" "time" "smoop-api/internal/config" "smoop-api/internal/crypto" "smoop-api/internal/db" "smoop-api/internal/models" "smoop-api/internal/router" "smoop-api/internal/storage" "gorm.io/gorm" ) func main() { // 1) Load config from Vault // useDev := os.Getenv("CONFIG_MODE") == "dev" var err error var cfg *config.Config // if useDev { // cfg, err = config.LoadDev() // } else { // cfg, err = config.Load() // } // if err != nil { // log.Printf("config: %v", err) // } cfg, err = config.LoadDev() if err != nil { log.Fatalf("config: %v", err) } // 2) DB gormDB, err := db.Open(cfg.DB.DSN) if err != nil { log.Fatalf("db: %v", err) } if err := db.AutoMigrate(gormDB); err != nil { log.Fatalf("migrate: %v", err) } if err := seedAdmin(gormDB); err != nil { log.Fatalf("seed admin: %v", err) } // 3) MinIO minioClient, err := storage.NewMinio(cfg.MinIO) if err != nil { log.Fatalf("minio: %v", err) } if err := storage.EnsureBuckets(minioClient, cfg.MinIO); err != nil { log.Fatalf("ensure buckets: %v", err) } // 4) Router engine := router.Build(gormDB, minioClient, cfg) srv := &http.Server{ Addr: ":8080", Handler: engine, ReadHeaderTimeout: 10 * time.Second, } log.Println("listening on :8080") log.Fatal(srv.ListenAndServe()) } func seedAdmin(g *gorm.DB) error { password := os.Getenv("ADMIN_PASSWORD") if password == "" { return nil // nothing to do } username := os.Getenv("ADMIN_USERNAME") if username == "" { username = "admin" } var count int64 if err := g.Model(&models.User{}).Where("username = ?", username).Count(&count).Error; err != nil { return err } if count > 0 { return nil } hash, err := crypto.Hash(password, crypto.DefaultArgon2) if err != nil { return err } u := models.User{Username: username, Password: hash, Role: models.RoleAdmin} if err := g.Create(&u).Error; err != nil { return err } log.Printf("created admin user %s", username) return nil }