package main import ( "context" "embed" "fmt" "os" "git.umbrella.haus/ae/notatest/internal/data" "git.umbrella.haus/ae/notatest/internal/service" "github.com/caarlos0/env/v10" "github.com/golang-migrate/migrate/v4" _ "github.com/golang-migrate/migrate/v4/database/postgres" "github.com/golang-migrate/migrate/v4/source/iofs" "github.com/jackc/pgx/v5" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) //go:embed sql/migrations/*.sql var migrationsFS embed.FS var ( config Config ) type Config struct { JWTSecret string `env:"JWT_SECRET,notEmpty"` DatabaseURL string `env:"DB_URL,notEmpty"` LogLevel string `env:"LOG_LEVEL" envDefault:"info"` AdminUsername string `env:"ADMIN_USERNAME,notEmpty,unset"` AdminPassword string `env:"ADMIN_PASSWORD,notEmpty,unset"` } func init() { config = Config{} if err := env.Parse(&config); err != nil { log.Fatal().Err(err).Msg("Failed to parse environment variables") } initLogger() log.Debug().Msg("Initialization completed") } func main() { log.Debug().Msgf("Database URL: %s", config.DatabaseURL) conn, err := pgx.Connect(context.Background(), config.DatabaseURL) if err != nil { log.Fatal().Err(err).Msg("Failed to connect to database") } log.Info().Msg("Successfully connected to the database") log.Info().Msg("Applying migrations...") d, err := iofs.New(migrationsFS, "sql/migrations") if err != nil { log.Fatal().Err(err).Msg("Failed constructing io/fs driver") } migrator, err := migrate.NewWithSourceInstance("iofs", d, config.DatabaseURL) if err != nil { log.Fatal().Err(err).Msg("Failed to apply migrations") } defer migrator.Close() if err := migrator.Up(); err != nil && err != migrate.ErrNoChange { log.Fatal().Err(err).Msg("Failed to apply migrations") } q := data.New(conn) err = service.CreateAdminIfNotExists(context.Background(), q, config.AdminUsername, config.AdminPassword) if err != nil { log.Fatal().Err(err).Msg("Failed initial admin account creation") } log.Info().Msg("Migrations applied succesfully, proceeding to HTTP server startup") service.Run(conn, q, config.JWTSecret) } func initLogger() { fmt.Println(config.LogLevel) level, err := zerolog.ParseLevel(config.LogLevel) if err != nil { level = zerolog.InfoLevel } zerolog.SetGlobalLevel(level) output := zerolog.ConsoleWriter{ Out: os.Stdout, TimeFormat: "2006-01-02 15:04:05", } log.Logger = log.Output(output).With().Timestamp().Caller().Logger() log.Info().Msgf("Logger initialized (log level: %s)", level) }