diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index f48b5c9..eaf096f 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -3,15 +3,15 @@ package main import ( "context" "log/slog" - "net/http" "os" - "github.com/gin-gonic/gin" - "github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/stdlib" "github.com/pressly/goose/v3" "tanabata/backend/internal/config" + "tanabata/backend/internal/db/postgres" + "tanabata/backend/internal/handler" + "tanabata/backend/internal/service" "tanabata/backend/migrations" ) @@ -22,22 +22,14 @@ func main() { os.Exit(1) } - pool, err := pgxpool.New(context.Background(), cfg.DatabaseURL) + pool, err := postgres.NewPool(context.Background(), cfg.DatabaseURL) if err != nil { slog.Error("failed to connect to database", "err", err) os.Exit(1) } defer pool.Close() - - if err := pool.Ping(context.Background()); err != nil { - slog.Error("database ping failed", "err", err) - os.Exit(1) - } slog.Info("database connected") - // Run migrations using the embedded FS. - // stdlib.OpenDBFromPool wraps the pool in a *sql.DB without closing - // the pool when the sql.DB is closed. migDB := stdlib.OpenDBFromPool(pool) goose.SetBaseFS(migrations.FS) if err := goose.SetDialect("postgres"); err != nil { @@ -51,12 +43,24 @@ func main() { migDB.Close() slog.Info("migrations applied") - r := gin.New() - r.Use(gin.Recovery()) + // Repositories + userRepo := postgres.NewUserRepo(pool) + sessionRepo := postgres.NewSessionRepo(pool) - r.GET("/health", func(c *gin.Context) { - c.Status(http.StatusOK) - }) + // Services + authSvc := service.NewAuthService( + userRepo, + sessionRepo, + cfg.JWTSecret, + cfg.JWTAccessTTL, + cfg.JWTRefreshTTL, + ) + + // Handlers + authMiddleware := handler.NewAuthMiddleware(authSvc) + authHandler := handler.NewAuthHandler(authSvc) + + r := handler.NewRouter(authMiddleware, authHandler) slog.Info("starting server", "addr", cfg.ListenAddr) if err := r.Run(cfg.ListenAddr); err != nil { diff --git a/backend/migrations/001_init_schemas.sql b/backend/migrations/001_init_schemas.sql index 1309264..c9f435a 100644 --- a/backend/migrations/001_init_schemas.sql +++ b/backend/migrations/001_init_schemas.sql @@ -9,6 +9,7 @@ CREATE SCHEMA IF NOT EXISTS acl; CREATE SCHEMA IF NOT EXISTS activity; -- UUID v7 generator +-- +goose StatementBegin CREATE OR REPLACE FUNCTION public.uuid_v7(cts timestamptz DEFAULT clock_timestamp()) RETURNS uuid LANGUAGE plpgsql AS $$ DECLARE @@ -38,14 +39,17 @@ BEGIN substring(entropy from 1 for 12))::uuid; END; $$; +-- +goose StatementEnd -- Extract timestamp from UUID v7 +-- +goose StatementBegin CREATE OR REPLACE FUNCTION public.uuid_extract_timestamp(uuid_val uuid) RETURNS timestamptz LANGUAGE sql IMMUTABLE PARALLEL SAFE AS $$ SELECT to_timestamp( ('x' || left(replace(uuid_val::text, '-', ''), 12))::bit(48)::bigint / 1000.0 ); $$; +-- +goose StatementEnd -- +goose Down diff --git a/backend/migrations/007_seed_data.sql b/backend/migrations/007_seed_data.sql index c8bd4dc..af26cca 100644 --- a/backend/migrations/007_seed_data.sql +++ b/backend/migrations/007_seed_data.sql @@ -26,7 +26,11 @@ INSERT INTO activity.action_types (name) VALUES -- Sessions ('session_terminate'); +INSERT INTO core.users (name, password, is_admin, can_create) VALUES + ('admin', '$2a$10$zk.VTFjRRxbkTE7cKfc7KOWeZfByk1VEkbkgZMJggI1fFf.yDEHZy', true, true); + -- +goose Down +DELETE FROM core.users WHERE name = 'admin'; DELETE FROM activity.action_types; DELETE FROM core.object_types;