From 19ad59ac30bc0bd6825189fcbdae705213b39b99 Mon Sep 17 00:00:00 2001 From: Robin Dittmar Date: Tue, 1 Sep 2026 16:42:40 +0200 Subject: [PATCH 1/4] feat: added /version endpoint --- cmd/api/main.go | 7 +++++-- internal/api/handler/version.go | 23 +++++++++++++++++++++++ internal/api/router/router.go | 9 +++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 internal/api/handler/version.go diff --git a/cmd/api/main.go b/cmd/api/main.go index 1acd796..5db0d82 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -136,8 +136,11 @@ func setupLogging() { func makeServer(db *sql.DB, cfg *config.Config) *http.Server { routerConfig := router.Config{ - Database: db, - JWTSecret: cfg.JWTSecret, + Database: db, + JWTSecret: cfg.JWTSecret, + ServiceVersion: Version, + ServiceCommit: Commit, + ServiceBuildTime: BuildTime, } mux := router.NewMux(routerConfig) diff --git a/internal/api/handler/version.go b/internal/api/handler/version.go new file mode 100644 index 0000000..37f3bec --- /dev/null +++ b/internal/api/handler/version.go @@ -0,0 +1,23 @@ +package handler + +import ( + "net/http" + + "github.com/robindittmar/dttmr-api/internal/api/response" +) + +type Version struct { + Version string `json:"version"` + Commit string `json:"commit"` + BuildTime string `json:"buildTime"` +} + +func VersionHandler(version string, commit string, buildTime string) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + response.JSON(r.Context(), w, http.StatusOK, Version{ + Version: version, + Commit: commit, + BuildTime: buildTime, + }) + } +} diff --git a/internal/api/router/router.go b/internal/api/router/router.go index f1f74bc..2a3f3f2 100644 --- a/internal/api/router/router.go +++ b/internal/api/router/router.go @@ -11,8 +11,11 @@ import ( ) type Config struct { - Database *sql.DB - JWTSecret string + Database *sql.DB + JWTSecret string + ServiceVersion string + ServiceCommit string + ServiceBuildTime string } func NewMux(cfg Config) http.Handler { @@ -32,6 +35,8 @@ func NewMux(cfg Config) http.Handler { protected := middleware.WithJWT(authService) apiMux := http.NewServeMux() + apiMux.HandleFunc("GET /version", handler.VersionHandler( + cfg.ServiceVersion, cfg.ServiceCommit, cfg.ServiceBuildTime)) apiMux.HandleFunc("GET /health", handler.HealthHandler) // Auth From 62a5324e6dbf6dc3fd40631a58daed278e6c2627 Mon Sep 17 00:00:00 2001 From: Robin Dittmar Date: Tue, 1 Sep 2026 16:57:49 +0200 Subject: [PATCH 2/4] feat: added docstring for /version endpoint --- internal/api/handler/version.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/api/handler/version.go b/internal/api/handler/version.go index 37f3bec..0ced842 100644 --- a/internal/api/handler/version.go +++ b/internal/api/handler/version.go @@ -6,15 +6,24 @@ import ( "github.com/robindittmar/dttmr-api/internal/api/response" ) -type Version struct { +type VersionResponse struct { Version string `json:"version"` Commit string `json:"commit"` BuildTime string `json:"buildTime"` } +// VersionHandler handles the version route +// +// @Summary Service version +// @Description Reports the version of the API +// @Tags Version +// @Accept json +// @Produce json +// @Success 200 {object} VersionResponse +// @Router /version [get] func VersionHandler(version string, commit string, buildTime string) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { - response.JSON(r.Context(), w, http.StatusOK, Version{ + response.JSON(r.Context(), w, http.StatusOK, VersionResponse{ Version: version, Commit: commit, BuildTime: buildTime, From 3778ab7d584a2647688f2c5f455aee691c63caf7 Mon Sep 17 00:00:00 2001 From: Robin Dittmar Date: Tue, 1 Sep 2026 17:03:04 +0200 Subject: [PATCH 3/4] feat: create list now runs in a transaction --- internal/api/router/router.go | 2 +- internal/domain/list.go | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/internal/api/router/router.go b/internal/api/router/router.go index 2a3f3f2..fb94676 100644 --- a/internal/api/router/router.go +++ b/internal/api/router/router.go @@ -25,7 +25,7 @@ func NewMux(cfg Config) http.Handler { inviteService := domain.NewInviteService(store.Invite) userService := domain.NewUserService(store.User) registrationService := domain.NewRegistrationService(store, userService, inviteService) - listService := domain.NewListService(store.List) + listService := domain.NewListService(store, store.List) authHandler := handler.NewAuthHandler(authService) inviteHandler := handler.NewInviteHandler(inviteService) diff --git a/internal/domain/list.go b/internal/domain/list.go index a3f9240..22df20f 100644 --- a/internal/domain/list.go +++ b/internal/domain/list.go @@ -49,11 +49,12 @@ type ListRepository interface { } type ListService struct { + tx Transactor repo ListRepository } -func NewListService(r ListRepository) *ListService { - return &ListService{repo: r} +func NewListService(tx Transactor, r ListRepository) *ListService { + return &ListService{tx: tx, repo: r} } func (s *ListService) CreateList(ctx context.Context, authUserID string, name string) (*List, error) { @@ -61,12 +62,21 @@ func (s *ListService) CreateList(ctx context.Context, authUserID string, name st return nil, ErrListNameMissing } - list, err := s.repo.CreateList(ctx, name) - if err != nil { - return nil, err - } + var list *List + err := s.tx.WithinTx(ctx, func(ctx context.Context) error { + l, err := s.repo.CreateList(ctx, name) + if err != nil { + return err + } - err = s.repo.AddUserToList(ctx, list.ID, authUserID) + err = s.repo.AddUserToList(ctx, list.ID, authUserID) + if err != nil { + return err + } + + list = l + return nil + }) if err != nil { return nil, err } From 2c50d75f88a121ffac97d8567f531ad218dccb8c Mon Sep 17 00:00:00 2001 From: Robin Dittmar Date: Tue, 1 Sep 2026 17:10:29 +0200 Subject: [PATCH 4/4] fix: nil pointer dereference --- internal/domain/list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/domain/list.go b/internal/domain/list.go index 22df20f..7c93f32 100644 --- a/internal/domain/list.go +++ b/internal/domain/list.go @@ -69,7 +69,7 @@ func (s *ListService) CreateList(ctx context.Context, authUserID string, name st return err } - err = s.repo.AddUserToList(ctx, list.ID, authUserID) + err = s.repo.AddUserToList(ctx, l.ID, authUserID) if err != nil { return err }