import { Injectable } from '@nestjs/common'; import { EntityManager } from 'typeorm'; const FORMAT_MAX_SEQUENCE = 990000; /** * Service de génération du numéro de dossier (ticket #103). * Format AAAA-NNNNNN (année + 6 chiffres), séquence par année. * Si séquence >= 990000, overflowWarning est true (alerte gestionnaire). */ @Injectable() export class NumeroDossierService { /** * Génère le prochain numéro de dossier dans le cadre d'une transaction. * À appeler avec le manager de la transaction pour garantir l'unicité. */ async getNextNumeroDossier(manager: EntityManager): Promise<{ numero: string; overflowWarning: boolean; }> { const year = new Date().getFullYear(); // Garantir l'existence de la ligne pour l'année await manager.query( `INSERT INTO numero_dossier_sequence (annee, prochain) VALUES ($1, 1) ON CONFLICT (annee) DO NOTHING`, [year], ); // Prendre le prochain numéro et incrémenter (FOR UPDATE pour concurrence) const selectRows = await manager.query( `SELECT prochain FROM numero_dossier_sequence WHERE annee = $1 FOR UPDATE`, [year], ); const currentVal = selectRows?.[0]?.prochain ?? 1; await manager.query( `UPDATE numero_dossier_sequence SET prochain = prochain + 1 WHERE annee = $1`, [year], ); const nextVal = currentVal; const overflowWarning = nextVal >= FORMAT_MAX_SEQUENCE; if (overflowWarning) { // Log pour alerte gestionnaire (ticket #103) console.warn( `[NumeroDossierService] Séquence année ${year} >= ${FORMAT_MAX_SEQUENCE} (valeur ${nextVal}). Prévoir renouvellement ou format.`, ); } const numero = `${year}-${String(nextVal).padStart(6, '0')}`; return { numero, overflowWarning }; } }