fix(cards): audience absence_enfant = AM + co-parents du foyer
Le resolver couple_am n’incluait que le créateur et l’AM ; le co-parent ne voyait pas la notification. Docs : V1 réponses + modifs via agenda. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -155,4 +155,75 @@ describe('CardsService (#194)', () => {
|
||||
}),
|
||||
).rejects.toBeInstanceOf(ForbiddenException);
|
||||
});
|
||||
|
||||
it('parent crée absence_enfant → audience AM + co-parent', async () => {
|
||||
typesRepo.findOne.mockResolvedValue({
|
||||
code: 'absence_enfant',
|
||||
system: true,
|
||||
titre: 'Absence enfant',
|
||||
emitter_roles: [RoleType.PARENT],
|
||||
recipient_roles: [RoleType.ASSISTANTE_MATERNELLE],
|
||||
audience_resolver: 'couple_am',
|
||||
response_mode: CardResponseModeType.NONE,
|
||||
retention_days: 7,
|
||||
});
|
||||
amChildrenRepo.findOne.mockResolvedValue({
|
||||
id: 'pl-1',
|
||||
amId: 'am-1',
|
||||
enfantId: 'e-1',
|
||||
date_fin: null,
|
||||
});
|
||||
parentsChildrenRepo.findOne.mockResolvedValue({
|
||||
parentId: 'p-1',
|
||||
enfantId: 'e-1',
|
||||
});
|
||||
parentsChildrenRepo.find.mockResolvedValue([
|
||||
{ parentId: 'p-1', enfantId: 'e-1' },
|
||||
{ parentId: 'p-2', enfantId: 'e-1' },
|
||||
]);
|
||||
evenementsService.creer.mockResolvedValue({
|
||||
id: 'abs-1',
|
||||
type: TypeEvenementAgendaType.ABSENCE_ENFANT,
|
||||
statut: StatutEvenementAgendaType.ACCEPTE,
|
||||
});
|
||||
cardsRepo.findOne.mockResolvedValue({
|
||||
id: 'card-abs',
|
||||
type_code: 'absence_enfant',
|
||||
id_placement: 'pl-1',
|
||||
id_evenement: 'abs-1',
|
||||
cree_par: 'p-1',
|
||||
operation: CardOperationType.CREATE,
|
||||
statut: CardInstanceStatutType.OUVERTE,
|
||||
payload: { date_debut: '2026-10-28', date_fin: '2026-10-29' },
|
||||
purge_at: new Date(),
|
||||
cree_le: new Date(),
|
||||
modifie_le: new Date(),
|
||||
type: {
|
||||
titre: 'Absence enfant',
|
||||
response_mode: CardResponseModeType.NONE,
|
||||
retention_days: 7,
|
||||
},
|
||||
responses: [],
|
||||
audience: [
|
||||
{ id_utilisateur: 'p-1' },
|
||||
{ id_utilisateur: 'am-1' },
|
||||
{ id_utilisateur: 'p-2' },
|
||||
],
|
||||
});
|
||||
|
||||
await service.creer('p-1', RoleType.PARENT, {
|
||||
type_code: 'absence_enfant',
|
||||
id_placement: 'pl-1',
|
||||
date_debut: '2026-10-28',
|
||||
date_fin: '2026-10-29',
|
||||
});
|
||||
|
||||
const saved = audienceRepo.save.mock.calls[0][0] as Array<{
|
||||
id_utilisateur: string;
|
||||
is_creator: boolean;
|
||||
}>;
|
||||
const ids = saved.map((m) => m.id_utilisateur).sort();
|
||||
expect(ids).toEqual(['am-1', 'p-1', 'p-2']);
|
||||
expect(saved.find((m) => m.id_utilisateur === 'p-2')?.is_creator).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -395,12 +395,25 @@ export class CardsService {
|
||||
];
|
||||
|
||||
if (type.audience_resolver === 'couple_am') {
|
||||
// Destinataire métier = AM + miroir foyer : tous les co-parents de l’enfant
|
||||
members.push({
|
||||
id_card: card.id,
|
||||
id_utilisateur: placement.amId,
|
||||
role_snapshot: RoleType.ASSISTANTE_MATERNELLE,
|
||||
is_creator: false,
|
||||
});
|
||||
const liensAm = await this.parentsChildrenRepo.find({
|
||||
where: { enfantId: placement.enfantId },
|
||||
});
|
||||
for (const l of liensAm) {
|
||||
if (l.parentId === creatorId) continue;
|
||||
members.push({
|
||||
id_card: card.id,
|
||||
id_utilisateur: l.parentId,
|
||||
role_snapshot: RoleType.PARENT,
|
||||
is_creator: false,
|
||||
});
|
||||
}
|
||||
} else if (type.audience_resolver === 'couple_parents') {
|
||||
const liens = await this.parentsChildrenRepo.find({
|
||||
where: { enfantId: placement.enfantId },
|
||||
|
||||
Reference in New Issue
Block a user