package useCases import ( "RenewCMS/internal/domain/audit" "RenewCMS/internal/domain/contenttype" "RenewCMS/internal/domain/role" "RenewCMS/internal/domain/user" "context" ) type CreateRoleUseCase struct { roles role.Repository contentTypes contenttype.Repository recorder audit.Recorder viewer roleViewer } type CreateRoleCommand struct { Caller ContentCaller Name string Description string Grants []role.Grant } func NewCreateRoleUseCase(roles role.Repository, users user.Repository, contentTypes contenttype.Repository, recorder audit.Recorder) *CreateRoleUseCase { return &CreateRoleUseCase{roles: roles, contentTypes: contentTypes, recorder: recorder, viewer: roleViewer{roles, users, contentTypes}} } func (u *CreateRoleUseCase) Create(ctx context.Context, command CreateRoleCommand) (RoleView, error) { name, err := role.NormalizeName(command.Name) if err != nil { return RoleView{}, err } if err := validateRoleGrants(u.contentTypes, command.Grants); err != nil { return RoleView{}, err } draft := role.Role{Name: name, Description: command.Description, Version: 1, Grants: normalizedGrants(command.Grants)} if err := ensureCovered(command.Caller, u.contentTypes, draft); err != nil { return RoleView{}, err } if err := ensureNameFree(u.roles, name, 0); err != nil { return RoleView{}, err } event := audit.NewEvent(audit.ActionRoleCreate, audit.CategoryRoles) event.Target = audit.Target{Type: audit.TargetRole, Name: name} created, err := u.roles.Create(draft) if err != nil { recordRoleWriteFailure(ctx, u.recorder, event, err) return RoleView{}, err } event.Target = roleTarget(created) event.Params[audit.ParamAdded] = created.EffectiveGrants() u.recorder.Record(ctx, event) return u.viewer.one(created, 0) }