package tag import ( "context" "spend-sparrow/internal/auth_types" "spend-sparrow/internal/core" "github.com/google/uuid" ) type Service interface { add(ctx context.Context, user *auth_types.User, tag Tag) (*Tag, error) update(ctx context.Context, user *auth_types.User, tag Tag) (*Tag, error) delete(ctx context.Context, user *auth_types.User, tagId uuid.UUID) error get(ctx context.Context, user *auth_types.User, tagId uuid.UUID) (*Tag, error) getAll(ctx context.Context, user *auth_types.User) ([]Tag, error) find(ctx context.Context, user *auth_types.User, search string) ([]Tag, error) } type ServiceImpl struct { db Db clock core.Clock random core.Random } func NewService(db Db, random core.Random, clock core.Clock) Service { return ServiceImpl{ db: db, clock: clock, random: random, } } func (s ServiceImpl) add(ctx context.Context, user *auth_types.User, tag Tag) (*Tag, error) { if user == nil { return nil, core.ErrUnauthorized } isValid := s.isTagValid(tag) if !isValid { return nil, core.ErrBadRequest } newId, err := s.random.UUID(ctx) if err != nil { return nil, core.ErrInternal } tag.Id = newId tag.UserId = user.Id tag.CreatedBy = user.Id tag.CreatedAt = s.clock.Now() return s.db.insert(ctx, tag) } func (s ServiceImpl) update(ctx context.Context, user *auth_types.User, input Tag) (*Tag, error) { if user == nil { return nil, core.ErrUnauthorized } tag, err := s.get(ctx, user, input.Id) if err != nil { return nil, err } tag.Name = input.Name if user.Id != tag.UserId { return nil, core.ErrBadRequest } isValid := s.isTagValid(*tag) if !isValid { return nil, core.ErrBadRequest } tag.UpdatedBy = &user.Id now := s.clock.Now() tag.UpdatedAt = &now return s.db.update(ctx, *tag) } func (s ServiceImpl) delete(ctx context.Context, user *auth_types.User, tagId uuid.UUID) error { if user == nil { return core.ErrUnauthorized } return s.db.delete(ctx, user.Id, tagId) } func (s ServiceImpl) get(ctx context.Context, user *auth_types.User, tagId uuid.UUID) (*Tag, error) { if user == nil { return nil, core.ErrUnauthorized } return s.db.get(ctx, user.Id, tagId) } func (s ServiceImpl) getAll(ctx context.Context, user *auth_types.User) ([]Tag, error) { if user == nil { return nil, core.ErrUnauthorized } return s.db.getAll(ctx, user.Id) } func (s ServiceImpl) find(ctx context.Context, user *auth_types.User, search string) ([]Tag, error) { if user == nil { return nil, core.ErrUnauthorized } return s.db.find(ctx, user.Id, search) } func (s ServiceImpl) isTagValid(tag Tag) bool { err := core.ValidateString(tag.Name, "name") return err == nil }