feat: added db transactions abstraction; cleaned up user registration; repos adapted new abstraction: all repos now support transactions, if present in ctx

This commit is contained in:
2026-09-01 14:55:20 +02:00
parent f87b0a0707
commit 2e3e82e776
14 changed files with 219 additions and 145 deletions
+49
View File
@@ -0,0 +1,49 @@
package domain
import (
"context"
"log/slog"
)
type RegistrationService struct {
tx Transactor
UserService *UserService
InviteService *InviteService
}
func NewRegistrationService(tx Transactor, u *UserService, i *InviteService) *RegistrationService {
return &RegistrationService{tx: tx, UserService: u, InviteService: i}
}
func (s *RegistrationService) Register(ctx context.Context, inviteCode string, email string, username string, password string) (*User, error) {
invite, err := s.InviteService.GetInvite(ctx, inviteCode)
if err != nil {
slog.ErrorContext(ctx, "failed to get invite", slog.Any("error", err))
return nil, err
}
var user *User
err = s.tx.WithinTx(ctx, func(ctx context.Context) error {
user, err = s.UserService.CreateUser(ctx, email, username, password)
if err != nil {
slog.ErrorContext(ctx, "failed to create user", slog.Any("error", err))
return err
}
err = s.InviteService.ConsumeInvite(ctx, invite.ID, user.ID)
if err != nil {
slog.ErrorContext(ctx, "failed to consume invite", slog.Any("error", err))
return err
}
return nil
})
if err != nil {
return nil, err
}
slog.InfoContext(ctx, "user registration complete",
slog.String("user_id", user.ID),
slog.String("invite_id", invite.ID))
return user, nil
}