package main import ( "context" "log" "net/http" "os" "gitea.michaelthomson.dev/mthomson/habits/internal/auth" authhandler "gitea.michaelthomson.dev/mthomson/habits/internal/auth/handler" authservice "gitea.michaelthomson.dev/mthomson/habits/internal/auth/service" "gitea.michaelthomson.dev/mthomson/habits/internal/logging" "gitea.michaelthomson.dev/mthomson/habits/internal/middleware" "gitea.michaelthomson.dev/mthomson/habits/internal/migrate" todohandler "gitea.michaelthomson.dev/mthomson/habits/internal/todo/handler" todorepository "gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository" todoservice "gitea.michaelthomson.dev/mthomson/habits/internal/todo/service" userhandler "gitea.michaelthomson.dev/mthomson/habits/internal/user/handler" userrepository "gitea.michaelthomson.dev/mthomson/habits/internal/user/repository" userservice "gitea.michaelthomson.dev/mthomson/habits/internal/user/service" pgxuuid "github.com/jackc/pgx-gofrs-uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/joho/godotenv" ) func main() { // create logger logger := logging.NewLogger() // load env err := godotenv.Load() if err != nil { logger.Error(err.Error()) os.Exit(1) } jwtSecretKey := os.Getenv("JWT_SECRET_KEY") postgresqlConnectionString := os.Getenv("POSTGRESQL_CONNECTION_STRING") // create hasher instance argon2IdHash := auth.NewArgon2IdHash(1, 32, 64*1024, 32, 256) // create middlewares traceMiddleware := middleware.TraceMiddleware(logger) loggingMiddleware := middleware.LoggingMiddleware(logger) authMiddleware := middleware.AuthMiddleware(logger, []byte(jwtSecretKey)) unauthenticatedStack := []middleware.Middleware{ traceMiddleware, loggingMiddleware, } authenticatedStack := []middleware.Middleware{ traceMiddleware, loggingMiddleware, authMiddleware, } // create db pool dbconfig, err := pgxpool.ParseConfig(postgresqlConnectionString) if err != nil { logger.Error(err.Error()) os.Exit(1) } dbconfig.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error { pgxuuid.Register(conn.TypeMap()) return nil } db, err := pgxpool.NewWithConfig(context.Background(), dbconfig) if err != nil { logger.Error(err.Error()) os.Exit(1) } // run migrations migrate.Migrate(logger, db) // create repos todoRepository := todorepository.NewTodoRepository(logger, db) userRepository := userrepository.NewUserRepository(logger, db) // create services todoService := todoservice.NewTodoService(logger, todoRepository) userService := userservice.NewUserService(logger, userRepository, argon2IdHash) authService := authservice.NewAuthService(logger, []byte(jwtSecretKey), userRepository, argon2IdHash) // create mux mux := http.NewServeMux() // register handlers // auth mux.Handle("POST /login", middleware.CompileMiddleware(authhandler.HandleLogin(logger, authService), unauthenticatedStack)) // users mux.Handle("POST /register", middleware.CompileMiddleware(userhandler.HandleRegisterUser(logger, userService), unauthenticatedStack)) // todos mux.Handle("GET /todo/{id}", middleware.CompileMiddleware(todohandler.HandleTodoGet(logger, todoService), authenticatedStack)) mux.Handle("POST /todo", middleware.CompileMiddleware(todohandler.HandleTodoCreate(logger, todoService), authenticatedStack)) mux.Handle("DELETE /todo/{id}", middleware.CompileMiddleware(todohandler.HandleTodoDelete(logger, todoService), authenticatedStack)) mux.Handle("PUT /todo/{id}", middleware.CompileMiddleware(todohandler.HandleTodoUpdate(logger, todoService), authenticatedStack)) // create server server := &http.Server{ Addr: ":8080", Handler: mux, } err = server.ListenAndServe() if err != nil { log.Fatalf("Failed to start server: %v", err) } }