import { Body, Controller, Get, Param, ParseUUIDPipe, Patch, Post, Query, } from '@nestjs/common'; import { SchemaPipe } from '../common/validation.pipe'; import { CurrentPrincipal, RequirePermission } from './access.decorator'; import { UserStore } from './user.store'; import { RoleStore } from './role.store'; import { createUserSchema, statusSchema, assignmentsSchema, pageSchema, type CreateUserInput, type PageInput, } from './identity.schemas'; import type { Principal } from './identity.types'; @Controller('users') export class UsersController { constructor( private readonly users: UserStore, private readonly roles: RoleStore, ) {} @Get() @RequirePermission('users.read') list( @CurrentPrincipal() actor: Principal, @Query(new SchemaPipe(pageSchema)) page: PageInput, ) { return this.users.list(actor, page); } @Post() @RequirePermission('users.create') create( @CurrentPrincipal() actor: Principal, @Body(new SchemaPipe(createUserSchema)) input: CreateUserInput, ) { return this.users.create(actor, input); } @Patch(':id/status') @RequirePermission('users.approve') status( @CurrentPrincipal() actor: Principal, @Param('id', ParseUUIDPipe) id: string, @Body(new SchemaPipe(statusSchema)) input: { status: 'ACTIVE' | 'SUSPENDED' }, ) { return this.users.setStatus(actor, id, input.status); } @Patch(':id/roles') @RequirePermission('users.roles.assign') async assign( @CurrentPrincipal() actor: Principal, @Param('id', ParseUUIDPipe) id: string, @Body(new SchemaPipe(assignmentsSchema)) input: { roleIds: string[] }, ) { await this.roles.assign(actor, id, input.roleIds); return { id }; } }