feat(#206): backend cartes rose soin_enfant (3 sous-types, instant T, correction 24h)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,6 +14,7 @@ export enum TypeEvenementAgendaType {
|
|||||||
ABSENCE_ENFANT = 'absence_enfant',
|
ABSENCE_ENFANT = 'absence_enfant',
|
||||||
CONGE_AM = 'conge_am',
|
CONGE_AM = 'conge_am',
|
||||||
ARRET_MALADIE_AM = 'arret_maladie_am',
|
ARRET_MALADIE_AM = 'arret_maladie_am',
|
||||||
|
SOIN_ENFANT = 'soin_enfant',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum StatutEvenementAgendaType {
|
export enum StatutEvenementAgendaType {
|
||||||
|
|||||||
@@ -281,4 +281,96 @@ describe('CardsService (#194)', () => {
|
|||||||
);
|
);
|
||||||
expect(res.statut).toBe(CardInstanceStatutType.TRAITEE);
|
expect(res.statut).toBe(CardInstanceStatutType.TRAITEE);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('AM crée soin_enfant (fievre) → motif dérivé + payload structuré', async () => {
|
||||||
|
typesRepo.findOne.mockResolvedValue({
|
||||||
|
code: 'soin_enfant',
|
||||||
|
system: true,
|
||||||
|
emitter_roles: [RoleType.ASSISTANTE_MATERNELLE],
|
||||||
|
response_mode: CardResponseModeType.ACK,
|
||||||
|
retention_days: 7,
|
||||||
|
audience_resolver: 'couple_parents',
|
||||||
|
});
|
||||||
|
evenementsService.creer.mockResolvedValue({ id: 'ev-soin' });
|
||||||
|
cardsRepo.create.mockImplementation((c) => ({ ...c, id: 'card-soin' }));
|
||||||
|
cardsRepo.save.mockResolvedValue({ id: 'card-soin' });
|
||||||
|
cardsRepo.findOne.mockResolvedValue({
|
||||||
|
id: 'card-soin',
|
||||||
|
type_code: 'soin_enfant',
|
||||||
|
statut: CardInstanceStatutType.OUVERTE,
|
||||||
|
payload: {
|
||||||
|
date_debut: '2026-10-28',
|
||||||
|
date_fin: '2026-10-28',
|
||||||
|
motif: '38,5 °C à 14:30 (Médicament : Doliprane)',
|
||||||
|
sous_type: 'fievre',
|
||||||
|
heure_releve: '14:30',
|
||||||
|
temperature_c: 38.5,
|
||||||
|
medicament_donne: 'Doliprane',
|
||||||
|
},
|
||||||
|
type: { response_mode: CardResponseModeType.ACK },
|
||||||
|
});
|
||||||
|
|
||||||
|
const res = await service.creer('am-1', RoleType.ASSISTANTE_MATERNELLE, {
|
||||||
|
type_code: 'soin_enfant',
|
||||||
|
id_placement: 'pl-1',
|
||||||
|
date_debut: '2026-10-28',
|
||||||
|
date_fin: '2026-10-28',
|
||||||
|
payload: {
|
||||||
|
sous_type: 'fievre',
|
||||||
|
heure_releve: '14:30',
|
||||||
|
temperature_c: 38.5,
|
||||||
|
medicament_donne: 'Doliprane',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(evenementsService.creer).toHaveBeenCalledWith(
|
||||||
|
'am-1',
|
||||||
|
RoleType.ASSISTANTE_MATERNELLE,
|
||||||
|
expect.objectContaining({
|
||||||
|
type: TypeEvenementAgendaType.SOIN_ENFANT,
|
||||||
|
motif: '38,5 °C à 14:30 (Médicament : Doliprane)',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(res.payload.motif).toBe('38,5 °C à 14:30 (Médicament : Doliprane)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('AM corrige soin_enfant dans les 24h → historique + re-ack', async () => {
|
||||||
|
const creeLe = new Date();
|
||||||
|
cardsRepo.findOne.mockResolvedValue({
|
||||||
|
id: 'card-soin',
|
||||||
|
type_code: 'soin_enfant',
|
||||||
|
id_placement: 'pl-1',
|
||||||
|
id_evenement: 'ev-soin',
|
||||||
|
cree_par: 'am-1',
|
||||||
|
cree_le: creeLe,
|
||||||
|
statut: CardInstanceStatutType.TRAITEE, // déjà acquitté
|
||||||
|
payload: {
|
||||||
|
date_debut: '2026-10-28',
|
||||||
|
date_fin: '2026-10-28',
|
||||||
|
sous_type: 'fievre',
|
||||||
|
heure_releve: '14:30',
|
||||||
|
temperature_c: 38.5,
|
||||||
|
},
|
||||||
|
type: { retention_days: 7 },
|
||||||
|
});
|
||||||
|
evenementsService.maj.mockResolvedValue({});
|
||||||
|
|
||||||
|
await service.majEnAttente('am-1', RoleType.ASSISTANTE_MATERNELLE, 'card-soin', {
|
||||||
|
date_debut: '2026-10-28',
|
||||||
|
date_fin: '2026-10-28',
|
||||||
|
payload: {
|
||||||
|
sous_type: 'fievre',
|
||||||
|
heure_releve: '14:30',
|
||||||
|
temperature_c: 37.5, // correction
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(cardsRepo.manager.query).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining('UPDATE card_instances'),
|
||||||
|
expect.arrayContaining([
|
||||||
|
CardInstanceStatutType.OUVERTE, // repasse ouverte
|
||||||
|
expect.stringContaining('37,5'), // nouveau payload stringifié
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -136,23 +136,76 @@ export class CardsService {
|
|||||||
let absenceId = dto.id_evenement;
|
let absenceId = dto.id_evenement;
|
||||||
const absenceType = this.mapAbsenceType(dto.type_code);
|
const absenceType = this.mapAbsenceType(dto.type_code);
|
||||||
|
|
||||||
|
let motif = dto.motif ?? null;
|
||||||
|
let finalPayload = {
|
||||||
|
date_debut: dto.date_debut,
|
||||||
|
date_fin: dto.date_fin,
|
||||||
|
motif,
|
||||||
|
...(dto.payload ?? {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dto.type_code === 'soin_enfant') {
|
||||||
|
const p = dto.payload;
|
||||||
|
if (!p || !p.sous_type || !p.heure_releve) {
|
||||||
|
throw new BadRequestException('sous_type et heure_releve requis pour soin_enfant');
|
||||||
|
}
|
||||||
|
if (!/^([01]\d|2[0-3]):([0-5]\d)$/.test(p.heure_releve)) {
|
||||||
|
throw new BadRequestException('Format heure_releve invalide (HH:mm)');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.sous_type === 'fievre') {
|
||||||
|
if (typeof p.temperature_c !== 'number' || p.temperature_c < 34.0 || p.temperature_c > 43.0) {
|
||||||
|
throw new BadRequestException('temperature_c invalide (34.0 - 43.0)');
|
||||||
|
}
|
||||||
|
motif = `${p.temperature_c.toFixed(1).replace('.', ',')} °C à ${p.heure_releve}`;
|
||||||
|
if (p.medicament_donne && typeof p.medicament_donne === 'string' && p.medicament_donne.trim()) {
|
||||||
|
motif += ` (Médicament : ${p.medicament_donne.trim()})`;
|
||||||
|
}
|
||||||
|
} else if (p.sous_type === 'bobo') {
|
||||||
|
const natures = ['chute', 'coup', 'egratignure', 'piqure', 'brulure', 'autre'];
|
||||||
|
if (!natures.includes(p.bobo_nature)) {
|
||||||
|
throw new BadRequestException('bobo_nature invalide');
|
||||||
|
}
|
||||||
|
motif = `Bobo (${p.bobo_nature}) à ${p.heure_releve}`;
|
||||||
|
if (p.description && typeof p.description === 'string' && p.description.trim()) {
|
||||||
|
const desc = p.description.trim();
|
||||||
|
if (desc.length > 120) throw new BadRequestException('description trop longue (max 120)');
|
||||||
|
motif += ` : ${desc.length > 30 ? desc.substring(0, 30) + '...' : desc}`;
|
||||||
|
}
|
||||||
|
} else if (p.sous_type === 'medicament') {
|
||||||
|
if (!p.medicament_nom || typeof p.medicament_nom !== 'string' || !p.medicament_nom.trim()) {
|
||||||
|
throw new BadRequestException('medicament_nom requis');
|
||||||
|
}
|
||||||
|
motif = `Médicament (${p.medicament_nom.trim()}) à ${p.heure_releve}`;
|
||||||
|
if (p.contexte && typeof p.contexte === 'string' && p.contexte.trim()) {
|
||||||
|
if (p.contexte.trim().length > 120) throw new BadRequestException('contexte trop long (max 120)');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException('sous_type invalide pour soin_enfant');
|
||||||
|
}
|
||||||
|
finalPayload.motif = motif;
|
||||||
|
}
|
||||||
|
|
||||||
if (operation === CardOperationType.CREATE) {
|
if (operation === CardOperationType.CREATE) {
|
||||||
const absence = await this.evenementsService.creer(userId, role, {
|
const absence = await this.evenementsService.creer(userId, role, {
|
||||||
id_placement: dto.id_placement,
|
id_placement: dto.id_placement,
|
||||||
type: absenceType,
|
type: absenceType,
|
||||||
date_debut: dto.date_debut,
|
date_debut: dto.date_debut,
|
||||||
date_fin: dto.date_fin,
|
date_fin: dto.date_fin,
|
||||||
motif: dto.motif,
|
motif: motif ?? undefined,
|
||||||
});
|
});
|
||||||
absenceId = absence.id;
|
absenceId = absence.id;
|
||||||
} else {
|
} else {
|
||||||
|
if (dto.type_code === 'soin_enfant') {
|
||||||
|
throw new BadRequestException('operation=update interdite pour soin_enfant');
|
||||||
|
}
|
||||||
if (!absenceId) {
|
if (!absenceId) {
|
||||||
throw new BadRequestException('id_evenement requis pour operation=update');
|
throw new BadRequestException('id_evenement requis pour operation=update');
|
||||||
}
|
}
|
||||||
await this.evenementsService.maj(userId, role, absenceId, {
|
await this.evenementsService.maj(userId, role, absenceId, {
|
||||||
date_debut: dto.date_debut,
|
date_debut: dto.date_debut,
|
||||||
date_fin: dto.date_fin,
|
date_fin: dto.date_fin,
|
||||||
motif: dto.motif,
|
motif: motif ?? undefined,
|
||||||
// Congé accepté modifié → repasse en attente via cartes respond flow;
|
// Congé accepté modifié → repasse en attente via cartes respond flow;
|
||||||
// pour absence enfant update immédiat déjà fait.
|
// pour absence enfant update immédiat déjà fait.
|
||||||
...(dto.type_code === 'conge_am'
|
...(dto.type_code === 'conge_am'
|
||||||
@@ -173,11 +226,7 @@ export class CardsService {
|
|||||||
cree_par: userId,
|
cree_par: userId,
|
||||||
operation,
|
operation,
|
||||||
statut: statutInitial,
|
statut: statutInitial,
|
||||||
payload: {
|
payload: finalPayload,
|
||||||
date_debut: dto.date_debut,
|
|
||||||
date_fin: dto.date_fin,
|
|
||||||
motif: dto.motif ?? null,
|
|
||||||
},
|
|
||||||
purge_at: this.purgeAt(type.retention_days, statutInitial),
|
purge_at: this.purgeAt(type.retention_days, statutInitial),
|
||||||
});
|
});
|
||||||
const saved = await this.cardsRepo.save(card);
|
const saved = await this.cardsRepo.save(card);
|
||||||
@@ -280,12 +329,20 @@ export class CardsService {
|
|||||||
if (card.cree_par !== userId) {
|
if (card.cree_par !== userId) {
|
||||||
throw new ForbiddenException('Seul le créateur peut modifier cette carte');
|
throw new ForbiddenException('Seul le créateur peut modifier cette carte');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (card.type_code === 'soin_enfant') {
|
||||||
|
const msSinceCreation = Date.now() - new Date(card.cree_le).getTime();
|
||||||
|
if (msSinceCreation > 24 * 60 * 60 * 1000) {
|
||||||
|
throw new BadRequestException('Délai de correction de 24h dépassé');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (
|
if (
|
||||||
card.statut !== CardInstanceStatutType.OUVERTE &&
|
card.statut !== CardInstanceStatutType.OUVERTE &&
|
||||||
card.statut !== CardInstanceStatutType.REFUSEE
|
card.statut !== CardInstanceStatutType.REFUSEE
|
||||||
) {
|
) {
|
||||||
throw new BadRequestException('Carte non modifiable dans cet état');
|
throw new BadRequestException('Carte non modifiable dans cet état');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const debut =
|
const debut =
|
||||||
dto.date_debut ?? String(card.payload?.['date_debut'] ?? '');
|
dto.date_debut ?? String(card.payload?.['date_debut'] ?? '');
|
||||||
@@ -294,21 +351,79 @@ export class CardsService {
|
|||||||
throw new BadRequestException('Dates invalides');
|
throw new BadRequestException('Dates invalides');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let motif = dto.motif ?? card.payload?.['motif'] ?? null;
|
||||||
|
let finalPayload = {
|
||||||
|
...card.payload,
|
||||||
|
date_debut: debut,
|
||||||
|
date_fin: fin,
|
||||||
|
...(dto.payload ?? {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (card.type_code === 'soin_enfant') {
|
||||||
|
const p = finalPayload;
|
||||||
|
if (!p || !p.sous_type || !p.heure_releve) {
|
||||||
|
throw new BadRequestException('sous_type et heure_releve requis pour soin_enfant');
|
||||||
|
}
|
||||||
|
if (!/^([01]\d|2[0-3]):([0-5]\d)$/.test(p.heure_releve)) {
|
||||||
|
throw new BadRequestException('Format heure_releve invalide (HH:mm)');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.sous_type === 'fievre') {
|
||||||
|
if (typeof p.temperature_c !== 'number' || p.temperature_c < 34.0 || p.temperature_c > 43.0) {
|
||||||
|
throw new BadRequestException('temperature_c invalide (34.0 - 43.0)');
|
||||||
|
}
|
||||||
|
motif = `${p.temperature_c.toFixed(1).replace('.', ',')} °C à ${p.heure_releve}`;
|
||||||
|
if (p.medicament_donne && typeof p.medicament_donne === 'string' && p.medicament_donne.trim()) {
|
||||||
|
motif += ` (Médicament : ${p.medicament_donne.trim()})`;
|
||||||
|
}
|
||||||
|
} else if (p.sous_type === 'bobo') {
|
||||||
|
const natures = ['chute', 'coup', 'egratignure', 'piqure', 'brulure', 'autre'];
|
||||||
|
if (!natures.includes(p.bobo_nature)) {
|
||||||
|
throw new BadRequestException('bobo_nature invalide');
|
||||||
|
}
|
||||||
|
motif = `Bobo (${p.bobo_nature}) à ${p.heure_releve}`;
|
||||||
|
if (p.description && typeof p.description === 'string' && p.description.trim()) {
|
||||||
|
const desc = p.description.trim();
|
||||||
|
if (desc.length > 120) throw new BadRequestException('description trop longue (max 120)');
|
||||||
|
motif += ` : ${desc.length > 30 ? desc.substring(0, 30) + '...' : desc}`;
|
||||||
|
}
|
||||||
|
} else if (p.sous_type === 'medicament') {
|
||||||
|
if (!p.medicament_nom || typeof p.medicament_nom !== 'string' || !p.medicament_nom.trim()) {
|
||||||
|
throw new BadRequestException('medicament_nom requis');
|
||||||
|
}
|
||||||
|
motif = `Médicament (${p.medicament_nom.trim()}) à ${p.heure_releve}`;
|
||||||
|
if (p.contexte && typeof p.contexte === 'string' && p.contexte.trim()) {
|
||||||
|
if (p.contexte.trim().length > 120) throw new BadRequestException('contexte trop long (max 120)');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new BadRequestException('sous_type invalide pour soin_enfant');
|
||||||
|
}
|
||||||
|
finalPayload.motif = motif;
|
||||||
|
|
||||||
|
const hist = Array.isArray(card.payload?.['historique']) ? card.payload['historique'] : [];
|
||||||
|
const oldPayload = { ...card.payload };
|
||||||
|
delete oldPayload.historique;
|
||||||
|
hist.push({
|
||||||
|
...oldPayload,
|
||||||
|
corrige_le: new Date().toISOString(),
|
||||||
|
corrige_par: userId,
|
||||||
|
});
|
||||||
|
finalPayload.historique = hist;
|
||||||
|
finalPayload.corrige_le = new Date().toISOString();
|
||||||
|
} else {
|
||||||
|
finalPayload.motif = motif;
|
||||||
|
}
|
||||||
|
|
||||||
if (card.id_evenement) {
|
if (card.id_evenement) {
|
||||||
await this.evenementsService.maj(userId, role, card.id_evenement, {
|
await this.evenementsService.maj(userId, role, card.id_evenement, {
|
||||||
date_debut: debut,
|
date_debut: debut,
|
||||||
date_fin: fin,
|
date_fin: fin,
|
||||||
motif: dto.motif,
|
motif: motif ?? undefined,
|
||||||
statut: StatutEvenementAgendaType.EN_ATTENTE,
|
...(card.type_code !== 'soin_enfant' ? { statut: StatutEvenementAgendaType.EN_ATTENTE } : {}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
card.payload = {
|
card.payload = finalPayload;
|
||||||
...card.payload,
|
|
||||||
date_debut: debut,
|
|
||||||
date_fin: fin,
|
|
||||||
motif: dto.motif ?? card.payload?.['motif'] ?? null,
|
|
||||||
};
|
|
||||||
card.statut = CardInstanceStatutType.OUVERTE;
|
card.statut = CardInstanceStatutType.OUVERTE;
|
||||||
card.purge_at = this.purgeAt(card.type.retention_days, card.statut);
|
card.purge_at = this.purgeAt(card.type.retention_days, card.statut);
|
||||||
await this.cardsRepo.manager.query(
|
await this.cardsRepo.manager.query(
|
||||||
@@ -332,16 +447,25 @@ export class CardsService {
|
|||||||
if (card.cree_par !== userId) {
|
if (card.cree_par !== userId) {
|
||||||
throw new ForbiddenException('Seul le créateur peut supprimer cette carte');
|
throw new ForbiddenException('Seul le créateur peut supprimer cette carte');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (card.type_code === 'soin_enfant') {
|
||||||
|
const msSinceCreation = Date.now() - new Date(card.cree_le).getTime();
|
||||||
|
if (msSinceCreation > 24 * 60 * 60 * 1000) {
|
||||||
|
throw new BadRequestException('Délai de correction de 24h dépassé, suppression impossible');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const audienceIds = await this.audienceUserIds(card);
|
const audienceIds = await this.audienceUserIds(card);
|
||||||
if (card.id_evenement) {
|
if (card.id_evenement) {
|
||||||
const absStatut =
|
const absStatut =
|
||||||
card.statut === CardInstanceStatutType.TRAITEE
|
card.statut === CardInstanceStatutType.TRAITEE
|
||||||
? null
|
? null
|
||||||
: card.id_evenement;
|
: card.id_evenement;
|
||||||
// Supprime l’absence liée si pas encore acceptée définitivement
|
// Supprime l’absence liée si pas encore acceptée définitivement (ou si soin_enfant dans les 24h)
|
||||||
if (
|
if (
|
||||||
card.statut === CardInstanceStatutType.OUVERTE ||
|
card.statut === CardInstanceStatutType.OUVERTE ||
|
||||||
card.statut === CardInstanceStatutType.REFUSEE
|
card.statut === CardInstanceStatutType.REFUSEE ||
|
||||||
|
card.type_code === 'soin_enfant'
|
||||||
) {
|
) {
|
||||||
await this.evenementsService.supprimer(userId, role, card.id_evenement);
|
await this.evenementsService.supprimer(userId, role, card.id_evenement);
|
||||||
}
|
}
|
||||||
@@ -379,6 +503,9 @@ export class CardsService {
|
|||||||
if (typeCode === 'arret_maladie_am') {
|
if (typeCode === 'arret_maladie_am') {
|
||||||
return TypeEvenementAgendaType.ARRET_MALADIE_AM;
|
return TypeEvenementAgendaType.ARRET_MALADIE_AM;
|
||||||
}
|
}
|
||||||
|
if (typeCode === 'soin_enfant') {
|
||||||
|
return TypeEvenementAgendaType.SOIN_ENFANT;
|
||||||
|
}
|
||||||
throw new BadRequestException(`Type non mappé à une absence: ${typeCode}`);
|
throw new BadRequestException(`Type non mappé à une absence: ${typeCode}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ export class CreerCarteDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsEnum(CardOperationType)
|
@IsEnum(CardOperationType)
|
||||||
operation?: CardOperationType;
|
operation?: CardOperationType;
|
||||||
|
|
||||||
|
@ApiPropertyOptional()
|
||||||
|
@IsOptional()
|
||||||
|
payload?: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RepondreCarteDto {
|
export class RepondreCarteDto {
|
||||||
@@ -79,6 +83,10 @@ export class MajCarteDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@MaxLength(2000)
|
@MaxLength(2000)
|
||||||
motif?: string;
|
motif?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional()
|
||||||
|
@IsOptional()
|
||||||
|
payload?: Record<string, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CarteDto {
|
export class CarteDto {
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ export class EvenementsAgendaService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private statutInitial(type: TypeEvenementAgendaType): StatutEvenementAgendaType {
|
private statutInitial(type: TypeEvenementAgendaType): StatutEvenementAgendaType {
|
||||||
if (type === TypeEvenementAgendaType.ABSENCE_ENFANT) {
|
if (type === TypeEvenementAgendaType.ABSENCE_ENFANT || type === TypeEvenementAgendaType.SOIN_ENFANT) {
|
||||||
return StatutEvenementAgendaType.ACCEPTE;
|
return StatutEvenementAgendaType.ACCEPTE;
|
||||||
}
|
}
|
||||||
return StatutEvenementAgendaType.EN_ATTENTE;
|
return StatutEvenementAgendaType.EN_ATTENTE;
|
||||||
@@ -233,10 +233,11 @@ export class EvenementsAgendaService {
|
|||||||
if (role === RoleType.ASSISTANTE_MATERNELLE) {
|
if (role === RoleType.ASSISTANTE_MATERNELLE) {
|
||||||
if (
|
if (
|
||||||
type !== TypeEvenementAgendaType.CONGE_AM &&
|
type !== TypeEvenementAgendaType.CONGE_AM &&
|
||||||
type !== TypeEvenementAgendaType.ARRET_MALADIE_AM
|
type !== TypeEvenementAgendaType.ARRET_MALADIE_AM &&
|
||||||
|
type !== TypeEvenementAgendaType.SOIN_ENFANT
|
||||||
) {
|
) {
|
||||||
throw new ForbiddenException(
|
throw new ForbiddenException(
|
||||||
'Une AM ne peut créer que congé ou arrêt maladie',
|
'Une AM ne peut créer que congé, arrêt maladie ou soin enfant',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ DO $$ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'type_evenement_agenda_type') THEN
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'type_evenement_agenda_type') THEN
|
||||||
CREATE TYPE type_evenement_agenda_type AS ENUM (
|
CREATE TYPE type_evenement_agenda_type AS ENUM (
|
||||||
'absence_enfant', 'conge_am', 'arret_maladie_am'
|
'absence_enfant', 'conge_am', 'arret_maladie_am', 'soin_enfant'
|
||||||
);
|
);
|
||||||
END IF;
|
END IF;
|
||||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_evenement_agenda_type') THEN
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'statut_evenement_agenda_type') THEN
|
||||||
|
|||||||
@@ -108,6 +108,11 @@ INSERT INTO card_types (
|
|||||||
'arret_maladie_am', true, 'Arrêt maladie AM',
|
'arret_maladie_am', true, 'Arrêt maladie AM',
|
||||||
ARRAY['assistante_maternelle'], ARRAY['parent'],
|
ARRAY['assistante_maternelle'], ARRAY['parent'],
|
||||||
'couple_parents', 'ack', 14, 'pink'
|
'couple_parents', 'ack', 14, 'pink'
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'soin_enfant', true, 'Soins enfant',
|
||||||
|
ARRAY['assistante_maternelle'], ARRAY['parent'],
|
||||||
|
'couple_parents', 'ack', 7, 'pink'
|
||||||
)
|
)
|
||||||
ON CONFLICT (code) DO UPDATE SET
|
ON CONFLICT (code) DO UPDATE SET
|
||||||
titre = EXCLUDED.titre,
|
titre = EXCLUDED.titre,
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- Migration incrémentale : ajout du type soin_enfant à l'agenda
|
||||||
|
ALTER TYPE type_evenement_agenda_type ADD VALUE IF NOT EXISTS 'soin_enfant';
|
||||||
Reference in New Issue
Block a user