package tenant import ( "context" "go.uber.org/zap" tenantusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/tenant" "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/logger" ) // CreateTenantService handles tenant creation operations type CreateTenantService interface { CreateTenant(ctx context.Context, input *tenantusecase.CreateTenantInput) (*tenantusecase.CreateTenantOutput, error) } type createTenantService struct { // Focused usecases validateSlugUC *tenantusecase.ValidateTenantSlugUniqueUseCase createEntityUC *tenantusecase.CreateTenantEntityUseCase saveTenantToRepoUC *tenantusecase.SaveTenantToRepoUseCase logger *zap.Logger } // NewCreateTenantService creates a new CreateTenantService func NewCreateTenantService( validateSlugUC *tenantusecase.ValidateTenantSlugUniqueUseCase, createEntityUC *tenantusecase.CreateTenantEntityUseCase, saveTenantToRepoUC *tenantusecase.SaveTenantToRepoUseCase, logger *zap.Logger, ) CreateTenantService { return &createTenantService{ validateSlugUC: validateSlugUC, createEntityUC: createEntityUC, saveTenantToRepoUC: saveTenantToRepoUC, logger: logger.Named("create-tenant-service"), } } // CreateTenant orchestrates the tenant creation workflow func (s *createTenantService) CreateTenant(ctx context.Context, input *tenantusecase.CreateTenantInput) (*tenantusecase.CreateTenantOutput, error) { // CWE-532: Use redacted tenant slug for logging s.logger.Info("creating tenant", logger.TenantSlugHash(input.Slug), logger.SafeTenantSlug("tenant_slug_redacted", input.Slug), zap.String("name", input.Name)) // Step 1: Validate slug uniqueness (fail fast) if err := s.validateSlugUC.Execute(ctx, input.Slug); err != nil { // CWE-532: Use redacted tenant slug for logging s.logger.Error("slug validation failed", logger.TenantSlugHash(input.Slug), logger.SafeTenantSlug("tenant_slug_redacted", input.Slug), zap.Error(err)) return nil, err } // Step 2: Create and validate tenant entity tenant, err := s.createEntityUC.Execute(input) if err != nil { // CWE-532: Use redacted tenant slug for logging s.logger.Error("entity creation failed", logger.TenantSlugHash(input.Slug), logger.SafeTenantSlug("tenant_slug_redacted", input.Slug), zap.Error(err)) return nil, err } // Step 3: Save tenant to repository if err := s.saveTenantToRepoUC.Execute(ctx, tenant); err != nil { s.logger.Error("failed to save tenant", zap.String("tenant_id", tenant.ID), zap.Error(err)) return nil, err } // CWE-532: Use redacted tenant slug for logging s.logger.Info("tenant created successfully", zap.String("tenant_id", tenant.ID), logger.TenantSlugHash(tenant.Slug), logger.SafeTenantSlug("tenant_slug_redacted", tenant.Slug)) // Step 4: Build output return &tenantusecase.CreateTenantOutput{ ID: tenant.ID, Name: tenant.Name, Slug: tenant.Slug, Status: string(tenant.Status), CreatedAt: tenant.CreatedAt, }, nil }