Ouvre POST/PATCH /gestionnaires et POST /users/admin aux administrateurs (en plus du super_admin). Garde-fou front : pas de création staff sur le dashboard gestionnaire.
170 lines
6.3 KiB
TypeScript
170 lines
6.3 KiB
TypeScript
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
|
||
import { ApiBearerAuth, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||
import { AuthGuard } from 'src/common/guards/auth.guard';
|
||
import { RolesGuard } from 'src/common/guards/roles.guard';
|
||
import { Roles } from 'src/common/decorators/roles.decorator';
|
||
import { User } from 'src/common/decorators/user.decorator';
|
||
import { RoleType, Users } from 'src/entities/users.entity';
|
||
import { UserService } from './user.service';
|
||
import { CreateUserDto } from './dto/create_user.dto';
|
||
import { CreateAdminDto } from './dto/create_admin.dto';
|
||
import { UpdateUserDto } from './dto/update_user.dto';
|
||
import { AffecterNumeroDossierDto } from './dto/affecter-numero-dossier.dto';
|
||
import { SuppressionService } from '../suppressions/suppression.service';
|
||
|
||
@ApiTags('Utilisateurs')
|
||
@ApiBearerAuth('access-token')
|
||
@UseGuards(AuthGuard, RolesGuard)
|
||
@Controller('users')
|
||
export class UserController {
|
||
constructor(
|
||
private readonly userService: UserService,
|
||
private readonly suppressionService: SuppressionService,
|
||
) { }
|
||
|
||
// Création d'un administrateur (admin + super admin) — #161
|
||
@Post('admin')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR)
|
||
@ApiOperation({ summary: 'Créer un nouvel administrateur (admin / super admin)' })
|
||
createAdmin(
|
||
@Body() dto: CreateAdminDto,
|
||
@User() currentUser: Users
|
||
) {
|
||
return this.userService.createAdmin(dto, currentUser);
|
||
}
|
||
|
||
// Création d'un utilisateur (réservée aux super admins)
|
||
@Post()
|
||
@Roles(RoleType.SUPER_ADMIN)
|
||
@ApiOperation({ summary: 'Créer un nouvel utilisateur (super admin seulement)' })
|
||
createUser(
|
||
@Body() dto: CreateUserDto,
|
||
@User() currentUser: Users
|
||
) {
|
||
return this.userService.createUser(dto, currentUser);
|
||
}
|
||
|
||
// Lister les utilisateurs en attente de validation
|
||
@Get('pending')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE)
|
||
@ApiOperation({ summary: 'Lister les utilisateurs en attente de validation' })
|
||
findPendingUsers(
|
||
@Query('role') role?: RoleType
|
||
) {
|
||
return this.userService.findPendingUsers(role);
|
||
}
|
||
|
||
// Lister les comptes refusés (à corriger / reprise)
|
||
@Get('reprise')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE)
|
||
@ApiOperation({ summary: 'Lister les comptes refusés (reprise)' })
|
||
findRefusedUsers(
|
||
@Query('role') role?: RoleType
|
||
) {
|
||
return this.userService.findRefusedUsers(role);
|
||
}
|
||
|
||
// Lister tous les utilisateurs (super_admin uniquement)
|
||
@Get()
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR)
|
||
@ApiOperation({ summary: 'Lister tous les utilisateurs' })
|
||
findAll() {
|
||
return this.userService.findAll();
|
||
}
|
||
|
||
// Récupérer un utilisateur par son ID
|
||
@Get(':id')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE)
|
||
@ApiOperation({ summary: 'Trouver un utilisateur par son id' })
|
||
@ApiParam({ name: 'id', description: "UUID de l'utilisateur" })
|
||
findOne(@Param('id') id: string) {
|
||
return this.userService.findOne(id);
|
||
}
|
||
|
||
// Modifier un utilisateur (réservé super_admin et admin)
|
||
@Patch(':id')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR)
|
||
@ApiOperation({ summary: 'Mettre à jour un utilisateur' })
|
||
@ApiParam({ name: 'id', description: "UUID de l'utilisateur" })
|
||
updateUser(
|
||
@Param('id') id: string,
|
||
@Body() dto: UpdateUserDto,
|
||
@User() currentUser: Users
|
||
) {
|
||
return this.userService.updateUser(id, dto, currentUser);
|
||
}
|
||
|
||
@Patch(':id/numero-dossier')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE)
|
||
@ApiOperation({
|
||
summary: 'Affecter un numéro de dossier à un utilisateur',
|
||
description: 'Permet de rapprocher deux dossiers ou d’attribuer un numéro existant à un parent/AM. Réservé aux gestionnaires et administrateurs.',
|
||
})
|
||
@ApiParam({ name: 'id', description: "UUID de l'utilisateur (parent ou AM)" })
|
||
@ApiResponse({ status: 200, description: 'Numéro de dossier affecté' })
|
||
@ApiResponse({ status: 400, description: 'Format invalide, rôle non éligible, ou dossier déjà associé à 2 parents' })
|
||
@ApiResponse({ status: 404, description: 'Utilisateur introuvable' })
|
||
affecterNumeroDossier(
|
||
@Param('id') id: string,
|
||
@Body() dto: AffecterNumeroDossierDto,
|
||
) {
|
||
return this.userService.affecterNumeroDossier(id, dto.numero_dossier);
|
||
}
|
||
|
||
@Patch(':id/valider')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
|
||
@ApiOperation({ summary: 'Valider un compte utilisateur' })
|
||
@ApiParam({ name: 'id', description: "UUID de l'utilisateur" })
|
||
@ApiResponse({ status: 400, description: 'ID invalide' })
|
||
@ApiResponse({ status: 403, description: 'Accès refusé' })
|
||
@ApiResponse({ status: 200, description: 'Compte validé avec succès' })
|
||
validate(
|
||
@Param('id') id: string,
|
||
@User() currentUser: Users,
|
||
@Body('comment') comment?: string,
|
||
) {
|
||
return this.userService.validateUser(id, currentUser, comment);
|
||
}
|
||
|
||
@Patch(':id/refuser')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
|
||
@ApiOperation({ summary: 'Refuser un compte (à corriger)' })
|
||
@ApiParam({ name: 'id', description: "UUID de l'utilisateur" })
|
||
refuse(
|
||
@Param('id') id: string,
|
||
@User() currentUser: Users,
|
||
@Body('comment') comment?: string,
|
||
) {
|
||
return this.userService.refuseUser(id, currentUser, comment);
|
||
}
|
||
|
||
@Patch(':id/suspendre')
|
||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
|
||
@ApiOperation({ summary: 'Suspendre un compte utilisateur' })
|
||
@ApiParam({ name: 'id', description: "UUID de l'utilisateur" })
|
||
suspend(
|
||
@Param('id') id: string,
|
||
@User() currentUser: Users,
|
||
@Body('comment') comment?: string,
|
||
) {
|
||
return this.userService.suspendUser(id, currentUser, comment);
|
||
}
|
||
|
||
// Supprimer un utilisateur — cascades métier #159
|
||
@Delete(':id')
|
||
@Roles(
|
||
RoleType.SUPER_ADMIN,
|
||
RoleType.ADMINISTRATEUR,
|
||
RoleType.GESTIONNAIRE,
|
||
)
|
||
@ApiOperation({
|
||
summary: 'Supprimer un utilisateur (cascades métier #159)',
|
||
description:
|
||
'Parent / AM / staff selon matrice. Gestionnaire ne peut pas supprimer un autre gestionnaire. Self interdit.',
|
||
})
|
||
@ApiParam({ name: 'id', description: "UUID de l'utilisateur" })
|
||
remove(@Param('id') id: string, @User() currentUser: Users) {
|
||
return this.suppressionService.deleteUser(id, currentUser);
|
||
}
|
||
}
|