Merge branch 'develop' (squash) – Statut refusé #105, script Gitea fallback ~/.bashrc

Made-with: Cursor
This commit is contained in:
MARTIN Julien 2026-03-12 22:28:13 +01:00
parent af489f39b4
commit 94c8a0d97a
7 changed files with 83 additions and 4 deletions

View File

@ -29,6 +29,7 @@ export enum StatutUtilisateurType {
EN_ATTENTE = 'en_attente', EN_ATTENTE = 'en_attente',
ACTIF = 'actif', ACTIF = 'actif',
SUSPENDU = 'suspendu', SUSPENDU = 'suspendu',
REFUSE = 'refuse',
} }
export enum SituationFamilialeType { export enum SituationFamilialeType {

View File

@ -96,6 +96,12 @@ export class AuthService {
throw new UnauthorizedException('Votre compte a été suspendu. Contactez un administrateur.'); throw new UnauthorizedException('Votre compte a été suspendu. Contactez un administrateur.');
} }
if (user.statut === StatutUtilisateurType.REFUSE) {
throw new UnauthorizedException(
'Votre compte a été refusé. Vous pouvez corriger votre dossier et le soumettre à nouveau ; un gestionnaire pourra le réexaminer.',
);
}
return this.generateTokens(user.id, user.email, user.role); return this.generateTokens(user.id, user.email, user.role);
} }

View File

@ -50,6 +50,16 @@ export class UserController {
return this.userService.findPendingUsers(role); 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) // Lister tous les utilisateurs (super_admin uniquement)
@Get() @Get()
@Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR) @Roles(RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR)
@ -112,6 +122,18 @@ export class UserController {
return this.userService.validateUser(id, currentUser, comment); 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') @Patch(':id/suspendre')
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR) @Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
@ApiOperation({ summary: 'Suspendre un compte utilisateur' }) @ApiOperation({ summary: 'Suspendre un compte utilisateur' })

View File

@ -140,6 +140,15 @@ export class UserService {
return this.usersRepository.find({ where }); return this.usersRepository.find({ where });
} }
/** Comptes refusés (à corriger) : liste pour reprise par le gestionnaire */
async findRefusedUsers(role?: RoleType): Promise<Users[]> {
const where: any = { statut: StatutUtilisateurType.REFUSE };
if (role) {
where.role = role;
}
return this.usersRepository.find({ where });
}
async findAll(): Promise<Users[]> { async findAll(): Promise<Users[]> {
return this.usersRepository.find(); return this.usersRepository.find();
} }
@ -214,7 +223,7 @@ export class UserService {
return this.usersRepository.save(user); return this.usersRepository.save(user);
} }
// Valider un compte utilisateur // Valider un compte utilisateur (en_attente ou refuse -> actif)
async validateUser(user_id: string, currentUser: Users, comment?: string): Promise<Users> { async validateUser(user_id: string, currentUser: Users, comment?: string): Promise<Users> {
if (![RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE].includes(currentUser.role)) { if (![RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE].includes(currentUser.role)) {
throw new ForbiddenException('Accès réservé aux super admins, administrateurs et gestionnaires'); throw new ForbiddenException('Accès réservé aux super admins, administrateurs et gestionnaires');
@ -223,6 +232,10 @@ export class UserService {
const user = await this.usersRepository.findOne({ where: { id: user_id } }); const user = await this.usersRepository.findOne({ where: { id: user_id } });
if (!user) throw new NotFoundException('Utilisateur introuvable'); if (!user) throw new NotFoundException('Utilisateur introuvable');
if (user.statut !== StatutUtilisateurType.EN_ATTENTE && user.statut !== StatutUtilisateurType.REFUSE) {
throw new BadRequestException('Seuls les comptes en attente ou refusés (à corriger) peuvent être validés.');
}
user.statut = StatutUtilisateurType.ACTIF; user.statut = StatutUtilisateurType.ACTIF;
const savedUser = await this.usersRepository.save(user); const savedUser = await this.usersRepository.save(user);
if (user.role === RoleType.PARENT) { if (user.role === RoleType.PARENT) {
@ -270,6 +283,30 @@ export class UserService {
await this.validationRepository.save(suspend); await this.validationRepository.save(suspend);
return savedUser; return savedUser;
} }
/** Refuser un compte (en_attente -> refuse) ; tracé dans validations */
async refuseUser(user_id: string, currentUser: Users, comment?: string): Promise<Users> {
if (![RoleType.SUPER_ADMIN, RoleType.ADMINISTRATEUR, RoleType.GESTIONNAIRE].includes(currentUser.role)) {
throw new ForbiddenException('Accès réservé aux super admins, administrateurs et gestionnaires');
}
const user = await this.usersRepository.findOne({ where: { id: user_id } });
if (!user) throw new NotFoundException('Utilisateur introuvable');
if (user.statut !== StatutUtilisateurType.EN_ATTENTE) {
throw new BadRequestException('Seul un compte en attente peut être refusé.');
}
user.statut = StatutUtilisateurType.REFUSE;
const savedUser = await this.usersRepository.save(user);
const validation = this.validationRepository.create({
user: savedUser,
type: 'refus_compte',
status: StatutValidationType.REFUSE,
validated_by: currentUser,
comment,
});
await this.validationRepository.save(validation);
return savedUser;
}
/** /**
* Affecter ou modifier le numéro de dossier d'un utilisateur (parent ou AM). * Affecter ou modifier le numéro de dossier d'un utilisateur (parent ou AM).
* Permet au gestionnaire/admin de rapprocher deux dossiers (même numéro pour plusieurs personnes). * Permet au gestionnaire/admin de rapprocher deux dossiers (même numéro pour plusieurs personnes).

View File

@ -11,7 +11,7 @@ DO $$ BEGIN
CREATE TYPE genre_type AS ENUM ('H', 'F'); CREATE TYPE genre_type AS ENUM ('H', 'F');
END IF; END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_utilisateur_type') THEN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_utilisateur_type') THEN
CREATE TYPE statut_utilisateur_type AS ENUM ('en_attente','actif','suspendu'); CREATE TYPE statut_utilisateur_type AS ENUM ('en_attente','actif','suspendu','refuse');
END IF; END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_enfant_type') THEN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_enfant_type') THEN
CREATE TYPE statut_enfant_type AS ENUM ('a_naitre','actif','scolarise'); CREATE TYPE statut_enfant_type AS ENUM ('a_naitre','actif','scolarise');

View File

@ -0,0 +1,4 @@
-- Migration #105 : Statut utilisateur « refusé » (à corriger)
-- Ajout de la valeur 'refuse' à l'enum statut_utilisateur_type.
ALTER TYPE statut_utilisateur_type ADD VALUE IF NOT EXISTS 'refuse';

View File

@ -15,9 +15,18 @@ if [ -z "$GITEA_TOKEN" ]; then
GITEA_TOKEN=$(cat .gitea-token) GITEA_TOKEN=$(cat .gitea-token)
fi fi
fi fi
if [ -z "$GITEA_TOKEN" ] && [ -f ~/.bashrc ]; then
eval "$(grep '^export GITEA_TOKEN=' ~/.bashrc 2>/dev/null)" || true
fi
if [ -z "$GITEA_TOKEN" ] && [ -f docs/BRIEFING-FRONTEND.md ]; then
token_from_briefing=$(sed -n 's/.*Token: *\(giteabu_[a-f0-9]*\).*/\1/p' docs/BRIEFING-FRONTEND.md 2>/dev/null | head -1)
if [ -n "$token_from_briefing" ]; then
GITEA_TOKEN="$token_from_briefing"
fi
fi
if [ -z "$GITEA_TOKEN" ]; then if [ -z "$GITEA_TOKEN" ]; then
echo "Définir GITEA_TOKEN ou créer .gitea-token avec votre token Gitea." echo "Définir GITEA_TOKEN ou créer .gitea-token avec votre token Gitea (voir docs/PROCEDURE-API-GITEA.md)."
exit 1 exit 1
fi fi