feat(#205): renommer absences_garde → evenements_agenda
Migration live + BDD.sql from-scratch, module Nest / API /evenements-agenda, FK cartes id_evenement. Front stub path aligné. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -65,7 +65,7 @@ export class CardsController {
|
||||
@Roles(RoleType.PARENT, RoleType.ASSISTANTE_MATERNELLE)
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@ApiOperation({
|
||||
summary: 'Créer une bulle (+ hook absences_garde) — #194',
|
||||
summary: 'Créer une bulle (+ hook evenements_agenda) — #194',
|
||||
})
|
||||
@ApiBody({ type: CreerCarteDto })
|
||||
@ApiResponse({ status: 201, type: CarteDto })
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Module } from '@nestjs/common';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { JwtModule } from '@nestjs/jwt';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { AbsencesGardeModule } from '../absences-garde';
|
||||
import { EvenementsAgendaModule } from '../evenements-agenda';
|
||||
import { CardType } from 'src/entities/card_types.entity';
|
||||
import { CardInstance } from 'src/entities/card_instances.entity';
|
||||
import { CardAudienceMember } from 'src/entities/card_audience_members.entity';
|
||||
@@ -16,7 +16,7 @@ import { CardsRealtimeService } from './cards-realtime.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
AbsencesGardeModule,
|
||||
EvenementsAgendaModule,
|
||||
TypeOrmModule.forFeature([
|
||||
CardType,
|
||||
CardInstance,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
import { ForbiddenException } from '@nestjs/common';
|
||||
import { CardsService } from './cards.service';
|
||||
import { CardsRealtimeService } from './cards-realtime.service';
|
||||
import { AbsencesGardeService } from '../absences-garde/absences-garde.service';
|
||||
import { EvenementsAgendaService } from '../evenements-agenda/evenements-agenda.service';
|
||||
import { CardType, CardResponseModeType } from 'src/entities/card_types.entity';
|
||||
import {
|
||||
CardInstance,
|
||||
@@ -15,7 +15,7 @@ import { CardResponse } from 'src/entities/card_responses.entity';
|
||||
import { AmChildren } from 'src/entities/am_children.entity';
|
||||
import { ParentsChildren } from 'src/entities/parents_children.entity';
|
||||
import { RoleType } from 'src/entities/users.entity';
|
||||
import { StatutAbsenceGardeType, TypeAbsenceGardeType } from 'src/entities/absences_garde.entity';
|
||||
import { StatutEvenementAgendaType, TypeEvenementAgendaType } from 'src/entities/evenements_agenda.entity';
|
||||
|
||||
describe('CardsService (#194)', () => {
|
||||
let service: CardsService;
|
||||
@@ -41,7 +41,7 @@ describe('CardsService (#194)', () => {
|
||||
};
|
||||
const amChildrenRepo = { findOne: jest.fn() };
|
||||
const parentsChildrenRepo = { find: jest.fn(), findOne: jest.fn() };
|
||||
const absencesService = {
|
||||
const evenementsService = {
|
||||
creer: jest.fn(),
|
||||
maj: jest.fn(),
|
||||
supprimer: jest.fn(),
|
||||
@@ -58,7 +58,7 @@ describe('CardsService (#194)', () => {
|
||||
{ provide: getRepositoryToken(CardResponse), useValue: responsesRepo },
|
||||
{ provide: getRepositoryToken(AmChildren), useValue: amChildrenRepo },
|
||||
{ provide: getRepositoryToken(ParentsChildren), useValue: parentsChildrenRepo },
|
||||
{ provide: AbsencesGardeService, useValue: absencesService },
|
||||
{ provide: EvenementsAgendaService, useValue: evenementsService },
|
||||
{ provide: CardsRealtimeService, useValue: realtime },
|
||||
],
|
||||
}).compile();
|
||||
@@ -88,10 +88,10 @@ describe('CardsService (#194)', () => {
|
||||
enfantId: 'e-1',
|
||||
date_fin: null,
|
||||
});
|
||||
absencesService.creer.mockResolvedValue({
|
||||
evenementsService.creer.mockResolvedValue({
|
||||
id: 'abs-1',
|
||||
type: TypeAbsenceGardeType.CONGE_AM,
|
||||
statut: StatutAbsenceGardeType.EN_ATTENTE,
|
||||
type: TypeEvenementAgendaType.CONGE_AM,
|
||||
statut: StatutEvenementAgendaType.EN_ATTENTE,
|
||||
});
|
||||
parentsChildrenRepo.find.mockResolvedValue([
|
||||
{ parentId: 'p-1', enfantId: 'e-1' },
|
||||
@@ -101,7 +101,7 @@ describe('CardsService (#194)', () => {
|
||||
id: 'card-1',
|
||||
type_code: 'conge_am',
|
||||
id_placement: 'pl-1',
|
||||
id_absence: 'abs-1',
|
||||
id_evenement: 'abs-1',
|
||||
cree_par: 'am-1',
|
||||
operation: CardOperationType.CREATE,
|
||||
statut: CardInstanceStatutType.OUVERTE,
|
||||
@@ -130,7 +130,7 @@ describe('CardsService (#194)', () => {
|
||||
date_fin: '2026-11-07',
|
||||
});
|
||||
|
||||
expect(absencesService.creer).toHaveBeenCalled();
|
||||
expect(evenementsService.creer).toHaveBeenCalled();
|
||||
expect(audienceRepo.save).toHaveBeenCalled();
|
||||
expect(realtime.emitToUsers).toHaveBeenCalledWith(
|
||||
['am-1', 'p-1', 'p-2'],
|
||||
|
||||
@@ -6,11 +6,11 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
import { AbsencesGardeService } from '../absences-garde/absences-garde.service';
|
||||
import { EvenementsAgendaService } from '../evenements-agenda/evenements-agenda.service';
|
||||
import {
|
||||
StatutAbsenceGardeType,
|
||||
TypeAbsenceGardeType,
|
||||
} from 'src/entities/absences_garde.entity';
|
||||
StatutEvenementAgendaType,
|
||||
TypeEvenementAgendaType,
|
||||
} from 'src/entities/evenements_agenda.entity';
|
||||
import { AmChildren } from 'src/entities/am_children.entity';
|
||||
import { ParentsChildren } from 'src/entities/parents_children.entity';
|
||||
import { RoleType } from 'src/entities/users.entity';
|
||||
@@ -49,7 +49,7 @@ export class CardsService {
|
||||
private readonly amChildrenRepo: Repository<AmChildren>,
|
||||
@InjectRepository(ParentsChildren)
|
||||
private readonly parentsChildrenRepo: Repository<ParentsChildren>,
|
||||
private readonly absencesService: AbsencesGardeService,
|
||||
private readonly evenementsService: EvenementsAgendaService,
|
||||
private readonly realtime: CardsRealtimeService,
|
||||
) {}
|
||||
|
||||
@@ -110,11 +110,11 @@ export class CardsService {
|
||||
);
|
||||
const operation = dto.operation ?? CardOperationType.CREATE;
|
||||
|
||||
let absenceId = dto.id_absence;
|
||||
let absenceId = dto.id_evenement;
|
||||
const absenceType = this.mapAbsenceType(dto.type_code);
|
||||
|
||||
if (operation === CardOperationType.CREATE) {
|
||||
const absence = await this.absencesService.creer(userId, role, {
|
||||
const absence = await this.evenementsService.creer(userId, role, {
|
||||
id_placement: dto.id_placement,
|
||||
type: absenceType,
|
||||
date_debut: dto.date_debut,
|
||||
@@ -124,16 +124,16 @@ export class CardsService {
|
||||
absenceId = absence.id;
|
||||
} else {
|
||||
if (!absenceId) {
|
||||
throw new BadRequestException('id_absence requis pour operation=update');
|
||||
throw new BadRequestException('id_evenement requis pour operation=update');
|
||||
}
|
||||
await this.absencesService.maj(userId, role, absenceId, {
|
||||
await this.evenementsService.maj(userId, role, absenceId, {
|
||||
date_debut: dto.date_debut,
|
||||
date_fin: dto.date_fin,
|
||||
motif: dto.motif,
|
||||
// Congé accepté modifié → repasse en attente via cartes respond flow;
|
||||
// pour absence enfant update immédiat déjà fait.
|
||||
...(dto.type_code === 'conge_am'
|
||||
? { statut: StatutAbsenceGardeType.EN_ATTENTE }
|
||||
? { statut: StatutEvenementAgendaType.EN_ATTENTE }
|
||||
: {}),
|
||||
});
|
||||
}
|
||||
@@ -146,7 +146,7 @@ export class CardsService {
|
||||
const card = this.cardsRepo.create({
|
||||
type_code: type.code,
|
||||
id_placement: dto.id_placement,
|
||||
id_absence: absenceId,
|
||||
id_evenement: absenceId,
|
||||
cree_par: userId,
|
||||
operation,
|
||||
statut: statutInitial,
|
||||
@@ -211,15 +211,15 @@ export class CardsService {
|
||||
comment: dto.comment?.trim() || undefined,
|
||||
});
|
||||
|
||||
if (card.id_absence) {
|
||||
if (card.id_evenement) {
|
||||
if (dto.action === CardResponseActionType.ACCEPT || dto.action === CardResponseActionType.ACK) {
|
||||
await this.absencesService.maj(userId, role, card.id_absence, {
|
||||
statut: StatutAbsenceGardeType.ACCEPTE,
|
||||
await this.evenementsService.maj(userId, role, card.id_evenement, {
|
||||
statut: StatutEvenementAgendaType.ACCEPTE,
|
||||
});
|
||||
card.statut = CardInstanceStatutType.TRAITEE;
|
||||
} else if (dto.action === CardResponseActionType.REFUSE) {
|
||||
await this.absencesService.maj(userId, role, card.id_absence, {
|
||||
statut: StatutAbsenceGardeType.REFUSE,
|
||||
await this.evenementsService.maj(userId, role, card.id_evenement, {
|
||||
statut: StatutEvenementAgendaType.REFUSE,
|
||||
motif: dto.comment!.trim(),
|
||||
});
|
||||
card.statut = CardInstanceStatutType.REFUSEE;
|
||||
@@ -264,12 +264,12 @@ export class CardsService {
|
||||
throw new BadRequestException('Dates invalides');
|
||||
}
|
||||
|
||||
if (card.id_absence) {
|
||||
await this.absencesService.maj(userId, role, card.id_absence, {
|
||||
if (card.id_evenement) {
|
||||
await this.evenementsService.maj(userId, role, card.id_evenement, {
|
||||
date_debut: debut,
|
||||
date_fin: fin,
|
||||
motif: dto.motif,
|
||||
statut: StatutAbsenceGardeType.EN_ATTENTE,
|
||||
statut: StatutEvenementAgendaType.EN_ATTENTE,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -298,17 +298,17 @@ export class CardsService {
|
||||
throw new ForbiddenException('Seul le créateur peut supprimer cette carte');
|
||||
}
|
||||
const audienceIds = await this.audienceUserIds(card);
|
||||
if (card.id_absence) {
|
||||
if (card.id_evenement) {
|
||||
const absStatut =
|
||||
card.statut === CardInstanceStatutType.TRAITEE
|
||||
? null
|
||||
: card.id_absence;
|
||||
: card.id_evenement;
|
||||
// Supprime l’absence liée si pas encore acceptée définitivement
|
||||
if (
|
||||
card.statut === CardInstanceStatutType.OUVERTE ||
|
||||
card.statut === CardInstanceStatutType.REFUSEE
|
||||
) {
|
||||
await this.absencesService.supprimer(userId, role, card.id_absence);
|
||||
await this.evenementsService.supprimer(userId, role, card.id_evenement);
|
||||
}
|
||||
void absStatut;
|
||||
}
|
||||
@@ -336,13 +336,13 @@ export class CardsService {
|
||||
return rows.map((r) => r.id_utilisateur);
|
||||
}
|
||||
|
||||
private mapAbsenceType(typeCode: string): TypeAbsenceGardeType {
|
||||
private mapAbsenceType(typeCode: string): TypeEvenementAgendaType {
|
||||
if (typeCode === 'absence_enfant' || typeCode === 'absence_enfant_modif') {
|
||||
return TypeAbsenceGardeType.ABSENCE_ENFANT;
|
||||
return TypeEvenementAgendaType.ABSENCE_ENFANT;
|
||||
}
|
||||
if (typeCode === 'conge_am') return TypeAbsenceGardeType.CONGE_AM;
|
||||
if (typeCode === 'conge_am') return TypeEvenementAgendaType.CONGE_AM;
|
||||
if (typeCode === 'arret_maladie_am') {
|
||||
return TypeAbsenceGardeType.ARRET_MALADIE_AM;
|
||||
return TypeEvenementAgendaType.ARRET_MALADIE_AM;
|
||||
}
|
||||
throw new BadRequestException(`Type non mappé à une absence: ${typeCode}`);
|
||||
}
|
||||
@@ -350,7 +350,7 @@ export class CardsService {
|
||||
private async linkAbsenceCard(absenceId: string, cardId: string): Promise<void> {
|
||||
// Update direct pour éviter droits maj vides
|
||||
await this.cardsRepo.manager.query(
|
||||
`UPDATE absences_garde SET id_card_instance = $1, modifie_le = now() WHERE id = $2`,
|
||||
`UPDATE evenements_agenda SET id_card_instance = $1, modifie_le = now() WHERE id = $2`,
|
||||
[cardId, absenceId],
|
||||
);
|
||||
}
|
||||
@@ -471,7 +471,7 @@ export class CardsService {
|
||||
titre: card.type?.titre ?? card.type_code,
|
||||
couleur: card.type?.couleur ?? null,
|
||||
id_placement: card.id_placement,
|
||||
id_absence: card.id_absence ?? null,
|
||||
id_evenement: card.id_evenement ?? null,
|
||||
operation: card.operation,
|
||||
statut: card.statut,
|
||||
payload: card.payload ?? {},
|
||||
|
||||
@@ -38,11 +38,11 @@ export class CreerCarteDto {
|
||||
motif?: string;
|
||||
|
||||
@ApiPropertyOptional({
|
||||
description: 'Requis pour operation=update (même id absences_garde)',
|
||||
description: 'Requis pour operation=update (même id evenements_agenda)',
|
||||
})
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
id_absence?: string;
|
||||
id_evenement?: string;
|
||||
|
||||
@ApiPropertyOptional({ enum: CardOperationType, default: CardOperationType.CREATE })
|
||||
@IsOptional()
|
||||
@@ -98,7 +98,7 @@ export class CarteDto {
|
||||
id_placement: string;
|
||||
|
||||
@ApiPropertyOptional()
|
||||
id_absence?: string | null;
|
||||
id_evenement?: string | null;
|
||||
|
||||
@ApiProperty({ enum: CardOperationType })
|
||||
operation: CardOperationType;
|
||||
|
||||
Reference in New Issue
Block a user