119 lines
2.5 KiB
Go
119 lines
2.5 KiB
Go
package org
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gitea.d3m0k1d.ru/HellreigN/Control-plane/internal/db"
|
|
)
|
|
|
|
var (
|
|
ErrNotFound = errors.New("organization not found")
|
|
ErrSlugExists = errors.New("slug already taken")
|
|
)
|
|
|
|
type Service struct {
|
|
repo OrgRepository
|
|
}
|
|
|
|
func NewService(repo OrgRepository) *Service {
|
|
return &Service{repo: repo}
|
|
}
|
|
|
|
func (s *Service) Create(ctx context.Context, req CreateOrgRequest) (*Organization, error) {
|
|
req.Slug = strings.ToLower(strings.TrimSpace(req.Slug))
|
|
|
|
org := &Organization{
|
|
Name: req.Name,
|
|
Slug: req.Slug,
|
|
}
|
|
|
|
if err := s.repo.Create(ctx, org); err != nil {
|
|
if isUniqueViolation(err) {
|
|
return nil, ErrSlugExists
|
|
}
|
|
return nil, fmt.Errorf("failed to create organization: %w", err)
|
|
}
|
|
|
|
return org, nil
|
|
}
|
|
|
|
func (s *Service) GetByID(ctx context.Context, id string) (*Organization, error) {
|
|
org, err := s.repo.FindByID(ctx, id)
|
|
if err != nil {
|
|
if errors.Is(err, db.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
return nil, fmt.Errorf("failed to find organization: %w", err)
|
|
}
|
|
return org, nil
|
|
}
|
|
|
|
func (s *Service) List(ctx context.Context, limit, offset int) (*OrgListResponse, error) {
|
|
if limit <= 0 {
|
|
limit = 20
|
|
}
|
|
if offset < 0 {
|
|
offset = 0
|
|
}
|
|
|
|
total, err := s.repo.Count(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to count organizations: %w", err)
|
|
}
|
|
|
|
orgs, err := s.repo.FindAll(ctx, limit, offset)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list organizations: %w", err)
|
|
}
|
|
if orgs == nil {
|
|
orgs = []Organization{}
|
|
}
|
|
return &OrgListResponse{
|
|
Organizations: orgs,
|
|
Total: total,
|
|
Limit: limit,
|
|
Offset: offset,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Service) Update(
|
|
ctx context.Context,
|
|
id string,
|
|
req UpdateOrgRequest,
|
|
) (*Organization, error) {
|
|
org, err := s.repo.FindByID(ctx, id)
|
|
if err != nil {
|
|
if errors.Is(err, db.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
return nil, fmt.Errorf("failed to find organization: %w", err)
|
|
}
|
|
|
|
org.Name = req.Name
|
|
|
|
if err := s.repo.Update(ctx, org); err != nil {
|
|
return nil, fmt.Errorf("failed to update organization: %w", err)
|
|
}
|
|
|
|
return org, nil
|
|
}
|
|
|
|
func (s *Service) Delete(ctx context.Context, id string) error {
|
|
found, err := s.repo.Delete(ctx, id)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete organization: %w", err)
|
|
}
|
|
if !found {
|
|
return ErrNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func isUniqueViolation(err error) bool {
|
|
return err != nil &&
|
|
(strings.Contains(err.Error(), "unique") || strings.Contains(err.Error(), "23505"))
|
|
}
|