feat(#156): création dossier AM staff — API + wizard dashboard.
Squash depuis develop : POST /assistantes-maternelles/dossier (actif + mail MDP), AmDossierWizard create/review, validations inscription. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+51
-2
@@ -1,20 +1,69 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { AssistantesMaternellesController } from './assistantes_maternelles.controller';
|
||||
import { AssistantesMaternellesService } from './assistantes_maternelles.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { AuthGuard } from 'src/common/guards/auth.guard';
|
||||
import { RolesGuard } from 'src/common/guards/roles.guard';
|
||||
|
||||
describe('AssistantesMaternellesController', () => {
|
||||
let controller: AssistantesMaternellesController;
|
||||
const authServiceMock = {
|
||||
createAmDossierStaff: jest.fn(),
|
||||
};
|
||||
const amServiceMock = {};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [AssistantesMaternellesController],
|
||||
providers: [AssistantesMaternellesService],
|
||||
}).compile();
|
||||
providers: [
|
||||
{ provide: AssistantesMaternellesService, useValue: amServiceMock },
|
||||
{ provide: AuthService, useValue: authServiceMock },
|
||||
],
|
||||
})
|
||||
.overrideGuard(AuthGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.overrideGuard(RolesGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.compile();
|
||||
|
||||
controller = module.get<AssistantesMaternellesController>(AssistantesMaternellesController);
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
|
||||
it('createDossier delegates to authService.createAmDossierStaff with CGU accepted', async () => {
|
||||
authServiceMock.createAmDossierStaff.mockResolvedValue({
|
||||
message: 'ok',
|
||||
user_id: 'u1',
|
||||
statut: 'actif',
|
||||
numero_dossier: '2026-000001',
|
||||
});
|
||||
|
||||
const body = {
|
||||
email: 'am.staff@test.fr',
|
||||
prenom: 'Marie',
|
||||
nom: 'TEST',
|
||||
telephone: '0689567890',
|
||||
consentement_photo: false,
|
||||
lieu_naissance_ville: 'Paris',
|
||||
lieu_naissance_pays: 'France',
|
||||
nir: '285017512345678',
|
||||
numero_agrement: 'AGR-TEST-001',
|
||||
capacite_accueil: 3,
|
||||
places_disponibles: 2,
|
||||
};
|
||||
|
||||
const res = await controller.createDossier(body as any);
|
||||
expect(authServiceMock.createAmDossierStaff).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
email: body.email,
|
||||
acceptation_cgu: true,
|
||||
acceptation_privacy: true,
|
||||
}),
|
||||
);
|
||||
expect(res.numero_dossier).toBe('2026-000001');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
Param,
|
||||
Delete,
|
||||
UseGuards,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
} from '@nestjs/common';
|
||||
import { AssistantesMaternellesService } from './assistantes_maternelles.service';
|
||||
import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
@@ -16,17 +18,49 @@ import { RoleType, Users } from 'src/entities/users.entity';
|
||||
import { CreateAssistanteDto } from '../user/dto/create_assistante.dto';
|
||||
import { UpdateAssistanteDto } from '../user/dto/update_assistante.dto';
|
||||
import { UpdateAmFicheAdminDto } from './dto/update-am-fiche-admin.dto';
|
||||
import { StaffCreateAmDossierDto } from './dto/staff-create-am-dossier.dto';
|
||||
import { StaffCreateAmDossierResponseDto } from './dto/staff-create-am-dossier-response.dto';
|
||||
import { RolesGuard } from 'src/common/guards/roles.guard';
|
||||
import { AuthGuard } from 'src/common/guards/auth.guard';
|
||||
import { User } from 'src/common/decorators/user.decorator';
|
||||
import { mapAmForApi, mapAmsForApi } from './assistantes_maternelles.mapper';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { RegisterAMCompletDto } from '../auth/dto/register-am-complet.dto';
|
||||
|
||||
@ApiTags("Assistantes Maternelles")
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(AuthGuard, RolesGuard)
|
||||
@Controller('assistantes-maternelles')
|
||||
export class AssistantesMaternellesController {
|
||||
constructor(private readonly assistantesMaternellesService: AssistantesMaternellesService) { }
|
||||
constructor(
|
||||
private readonly assistantesMaternellesService: AssistantesMaternellesService,
|
||||
private readonly authService: AuthService,
|
||||
) { }
|
||||
|
||||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE, RoleType.ADMINISTRATEUR)
|
||||
@Post('dossier')
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@ApiOperation({
|
||||
summary: 'Créer un dossier AM complet (staff) — ticket #156',
|
||||
description:
|
||||
'Crée user + fiche AM avec statut actif, n° dossier, et envoie l’e-mail de création de mot de passe. ' +
|
||||
'Ne pas utiliser POST /auth/register/am depuis le dashboard.',
|
||||
})
|
||||
@ApiBody({ type: StaffCreateAmDossierDto })
|
||||
@ApiResponse({ status: 201, type: StaffCreateAmDossierResponseDto })
|
||||
@ApiResponse({ status: 400, description: 'Validation métier / NIR' })
|
||||
@ApiResponse({ status: 403, description: 'Rôle non autorisé' })
|
||||
@ApiResponse({ status: 409, description: 'Email / NIR / agrément déjà pris' })
|
||||
async createDossier(
|
||||
@Body() dto: StaffCreateAmDossierDto,
|
||||
): Promise<StaffCreateAmDossierResponseDto> {
|
||||
const registerDto = {
|
||||
...dto,
|
||||
acceptation_cgu: true,
|
||||
acceptation_privacy: true,
|
||||
} as RegisterAMCompletDto;
|
||||
return this.authService.createAmDossierStaff(registerDto);
|
||||
}
|
||||
|
||||
@Roles(RoleType.SUPER_ADMIN, RoleType.GESTIONNAIRE)
|
||||
@ApiOperation({ summary: 'Créer nounou' })
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { StatutUtilisateurType } from 'src/entities/users.entity';
|
||||
|
||||
/** Réponse 201 POST /assistantes-maternelles/dossier (#156). */
|
||||
export class StaffCreateAmDossierResponseDto {
|
||||
@ApiProperty()
|
||||
message: string;
|
||||
|
||||
@ApiProperty({ format: 'uuid' })
|
||||
user_id: string;
|
||||
|
||||
@ApiProperty({
|
||||
enum: StatutUtilisateurType,
|
||||
example: StatutUtilisateurType.ACTIF,
|
||||
})
|
||||
statut: StatutUtilisateurType;
|
||||
|
||||
@ApiProperty({
|
||||
example: '2026-000042',
|
||||
description: 'Numéro de dossier attribué',
|
||||
})
|
||||
numero_dossier: string;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { ApiPropertyOptional, OmitType } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsOptional } from 'class-validator';
|
||||
import { RegisterAMCompletDto } from 'src/routes/auth/dto/register-am-complet.dto';
|
||||
|
||||
/**
|
||||
* Création dossier AM par staff (#156).
|
||||
* Mêmes champs que l'inscription publique, sans CGU/privacy obligatoires
|
||||
* (acceptées côté serveur pour le compte du gestionnaire).
|
||||
*/
|
||||
export class StaffCreateAmDossierDto extends OmitType(RegisterAMCompletDto, [
|
||||
'acceptation_cgu',
|
||||
'acceptation_privacy',
|
||||
] as const) {
|
||||
@ApiPropertyOptional({
|
||||
description: 'Ignoré côté staff (CGU acceptées serveur). Conservé pour compat éventuelle.',
|
||||
default: true,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
acceptation_cgu?: boolean;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: 'Ignoré côté staff (privacy acceptée serveur).',
|
||||
default: true,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
acceptation_privacy?: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user