template-monorepo/internal/model/member/usecase/tenant_usecase.go

81 lines
2.5 KiB
Go

package usecase
import (
"context"
"errors"
"strings"
"time"
member "gateway/internal/model/member/domain"
"gateway/internal/model/member/domain/entity"
"gateway/internal/model/member/domain/enum"
domrepo "gateway/internal/model/member/domain/repository"
domusecase "gateway/internal/model/member/domain/usecase"
)
type tenantUseCase struct {
tenants domrepo.TenantRepository
}
// TenantUseCaseParam wires TenantUseCase.
type TenantUseCaseParam struct {
Tenants domrepo.TenantRepository
}
// MustTenantUseCase constructs TenantUseCase.
func MustTenantUseCase(param TenantUseCaseParam) domusecase.TenantUseCase {
if param.Tenants == nil {
panic("member: tenant repository is required")
}
return &tenantUseCase{tenants: param.Tenants}
}
func (uc *tenantUseCase) Create(ctx context.Context, req *domusecase.CreateTenantRequest) (*domusecase.TenantDTO, error) {
if req == nil || req.TenantID == "" || req.Slug == "" || req.Name == "" {
return nil, errb.InputMissingRequired("tenant_id, slug and name are required")
}
prefix := normalizeUIDPrefix(req.UIDPrefix)
if prefix == "" {
prefix = normalizeUIDPrefix(req.Slug)
}
if len(prefix) < member.UIDPrefixMinLength || len(prefix) > member.UIDPrefixMaxLength {
return nil, errb.InputInvalidFormat("uid_prefix must be 2-4 uppercase letters")
}
if _, err := uc.tenants.GetByUIDPrefix(ctx, prefix); err == nil {
return nil, errb.ResAlreadyExist("uid_prefix already exists")
} else if !errors.Is(err, member.ErrTenantNotFound) {
return nil, errb.SysInternal("read tenant failed").WithCause(err)
}
now := time.Now().UTC().UnixMilli()
rec := &entity.Tenant{
TenantID: req.TenantID,
Slug: strings.ToLower(req.Slug),
Name: req.Name,
UIDPrefix: prefix,
Status: enum.TenantStatusActive,
CreateAt: now,
UpdateAt: now,
}
if err := uc.tenants.Insert(ctx, rec); err != nil {
if errors.Is(err, member.ErrDuplicateTenant) {
return nil, errb.ResAlreadyExist("tenant already exists").WithCause(err)
}
return nil, errb.SysInternal("create tenant failed").WithCause(err)
}
return tenantToDTO(rec), nil
}
func (uc *tenantUseCase) ResolveBySlug(ctx context.Context, slug string) (*domusecase.TenantDTO, error) {
if slug == "" {
return nil, errb.InputMissingRequired("slug is required")
}
rec, err := uc.tenants.GetBySlug(ctx, strings.ToLower(slug))
if err != nil {
if errors.Is(err, member.ErrTenantNotFound) {
return nil, errb.ResNotFound("tenant", slug).WithCause(err)
}
return nil, errb.SysInternal("read tenant failed").WithCause(err)
}
return tenantToDTO(rec), nil
}