package service import ( "baron-sso-backend/internal/domain" "baron-sso-backend/internal/repository" "context" "errors" "log/slog" "gorm.io/gorm" ) type TenantService interface { RegisterTenant(ctx context.Context, name, slug, description string, domains []string) (*domain.Tenant, error) GetTenantByDomain(ctx context.Context, emailDomain string) (*domain.Tenant, error) GetTenantBySlug(ctx context.Context, slug string) (*domain.Tenant, error) } type tenantService struct { repo repository.TenantRepository } func NewTenantService(repo repository.TenantRepository) TenantService { return &tenantService{repo: repo} } func (s *tenantService) RegisterTenant(ctx context.Context, name, slug, description string, domains []string) (*domain.Tenant, error) { // 1. Check if slug exists existing, err := s.repo.FindBySlug(ctx, slug) if err == nil && existing != nil { return nil, errors.New("tenant slug already exists") } if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return nil, err } // 2. Create Tenant tenant := &domain.Tenant{ Name: name, Slug: slug, Description: description, Status: "active", } if err := s.repo.Create(ctx, tenant); err != nil { return nil, err } // 3. Add Domains for _, d := range domains { if err := s.repo.AddDomain(ctx, tenant.ID, d); err != nil { slog.Error("Failed to add domain to tenant", "tenant", slug, "domain", d, "error", err) // Continue adding other domains? Or fail? For now, log and continue. } } return s.repo.FindBySlug(ctx, slug) // Return with preloaded domains } func (s *tenantService) GetTenantByDomain(ctx context.Context, emailDomain string) (*domain.Tenant, error) { return s.repo.FindByDomain(ctx, emailDomain) } func (s *tenantService) GetTenantBySlug(ctx context.Context, slug string) (*domain.Tenant, error) { return s.repo.FindBySlug(ctx, slug) }