import { Body, Controller, Delete, Get, HttpCode, Param, Patch, Post, Req, UseGuards, } from "@nestjs/common"; import { Request } from "express"; import { AuthenticatedGuard } from "../auth/authenticated.guard"; import { AbilityGuard } from "../auth/ability.guard"; import { RequireAbility } from "../auth/require-ability.decorator"; import { AuditService } from "../common/audit.service"; import { UsersService } from "./users.service"; import { CreateUserDto } from "./create-user.dto"; import { UpdateUserDto } from "./update-user.dto"; import { ResetPasswordDto } from "./reset-password.dto"; /** Every route here is ADMIN-only (ability "user:manage"). */ @UseGuards(AuthenticatedGuard, AbilityGuard) @RequireAbility("user:manage") @Controller("users") export class UsersController { constructor( private readonly users: UsersService, private readonly audit: AuditService, ) {} private actingId(req: Request): string { return (req.user as { id: string }).id; } @Get() list() { return this.users.list(); } @Post() async create(@Body() dto: CreateUserDto, @Req() req: Request) { const user = await this.users.create(dto); void this.audit.log(this.actingId(req), "user.create", { userId: user.id, email: user.email, role: user.role, }); return user; } @Patch(":id") async update( @Param("id") id: string, @Body() dto: UpdateUserDto, @Req() req: Request, ) { const user = await this.users.update(id, dto, this.actingId(req)); void this.audit.log(this.actingId(req), "user.update", { userId: id, changes: dto }); return user; } @Post(":id/reset-password") async resetPassword( @Param("id") id: string, @Body() dto: ResetPasswordDto, @Req() req: Request, ) { const user = await this.users.resetPassword(id, dto.password); void this.audit.log(this.actingId(req), "user.reset_password", { userId: id }); return user; } @Delete(":id") @HttpCode(204) async remove(@Param("id") id: string, @Req() req: Request) { const actingId = this.actingId(req); await this.users.remove(id, actingId); void this.audit.log(actingId, "user.delete", { userId: id }); } }