package service import ( "context" "github.com/calendarapi/internal/models" "github.com/calendarapi/internal/repository" "github.com/calendarapi/internal/utils" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) type UserService struct { pool *pgxpool.Pool queries *repository.Queries audit *AuditService } func NewUserService(pool *pgxpool.Pool, queries *repository.Queries, audit *AuditService) *UserService { return &UserService{pool: pool, queries: queries, audit: audit} } func (s *UserService) GetMe(ctx context.Context, userID uuid.UUID) (*models.User, error) { u, err := s.queries.GetUserByID(ctx, utils.ToPgUUID(userID)) if err != nil { if err == pgx.ErrNoRows { return nil, models.ErrNotFound } return nil, models.ErrInternal } user := userFromIDRow(u) return &user, nil } func (s *UserService) Update(ctx context.Context, userID uuid.UUID, timezone *string) (*models.User, error) { if timezone != nil { if err := utils.ValidateTimezone(*timezone); err != nil { return nil, err } } u, err := s.queries.UpdateUser(ctx, repository.UpdateUserParams{ ID: utils.ToPgUUID(userID), Timezone: utils.ToPgTextPtr(timezone), }) if err != nil { if err == pgx.ErrNoRows { return nil, models.ErrNotFound } return nil, models.ErrInternal } user := userFromUpdateRow(u) return &user, nil } func (s *UserService) Delete(ctx context.Context, userID uuid.UUID) error { tx, err := s.pool.Begin(ctx) if err != nil { return models.ErrInternal } defer tx.Rollback(ctx) qtx := s.queries.WithTx(tx) pgID := utils.ToPgUUID(userID) if err := qtx.SoftDeleteContactsByOwner(ctx, pgID); err != nil { return models.ErrInternal } if err := qtx.SoftDeleteEventsByCreator(ctx, pgID); err != nil { return models.ErrInternal } if err := qtx.SoftDeleteCalendarsByOwner(ctx, pgID); err != nil { return models.ErrInternal } if err := qtx.RevokeAllUserAPIKeys(ctx, pgID); err != nil { return models.ErrInternal } if err := qtx.RevokeAllUserRefreshTokens(ctx, pgID); err != nil { return models.ErrInternal } if err := qtx.SoftDeleteUser(ctx, pgID); err != nil { return models.ErrInternal } if err := tx.Commit(ctx); err != nil { return models.ErrInternal } s.audit.Log(ctx, "user", userID, "DELETE_USER", userID) return nil }