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) } 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) isTagValid(tag Tag) bool { err := core.ValidateString(tag.Name, "name") return err == nil }