espace-paie-odentas/lib/pdf/uploadPdf.ts
odentas 6485db4a75 feat(naa): Amélioration UX modal EditNAA - replier/déplier
- Tous les clients repliés par défaut à l'ouverture du modal
- Boutons 'Tout replier' / 'Tout déplier' pour gérer tous les clients
- Section factures repliable avec bouton Afficher/Masquer
- Affichage résumé facture sélectionnée quand section repliée
- Nouveau client déplié automatiquement pour faciliter la saisie
- Améliore la lisibilité pour NAA avec nombreux clients
2025-10-31 15:28:44 +01:00

125 lines
3.4 KiB
TypeScript

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
const REGION = process.env.AWS_REGION || 'eu-west-3';
const BUCKET = (process.env.AWS_S3_BUCKET || 'odentas-docs').trim();
const s3Client = new S3Client({
region: REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});
export interface UploadPdfOptions {
/** Buffer du PDF à uploader */
pdfBuffer: Buffer;
/** Clé S3 (chemin + nom du fichier), ex: 'contrats/2025/contrat-123.pdf' */
key: string;
/** Type de contenu (par défaut: application/pdf) */
contentType?: string;
/** Métadonnées supplémentaires */
metadata?: Record<string, string>;
}
/**
* Upload un PDF généré sur S3
*
* @param options - Options d'upload
* @returns La clé S3 du fichier uploadé
*
* @example
* ```typescript
* const pdfBuffer = await generateContratPdf(data);
* const s3Key = await uploadPdfToS3({
* pdfBuffer,
* key: `contrats/${organizationId}/${contractId}.pdf`,
* metadata: {
* contractId: contractId,
* organizationId: organizationId,
* generatedAt: new Date().toISOString(),
* }
* });
* ```
*/
export async function uploadPdfToS3(options: UploadPdfOptions): Promise<string> {
const { pdfBuffer, key, contentType = 'application/pdf', metadata = {} } = options;
console.log('📤 [S3 Upload] Début de l\'upload du PDF:', {
key,
bucket: BUCKET,
region: REGION,
size: pdfBuffer.byteLength,
metadata,
});
try {
const command = new PutObjectCommand({
Bucket: BUCKET,
Key: key,
Body: pdfBuffer,
ContentType: contentType,
Metadata: metadata,
});
await s3Client.send(command);
console.log('✅ [S3 Upload] PDF uploadé avec succès:', {
key,
bucket: BUCKET,
size: pdfBuffer.byteLength,
});
return key;
} catch (error) {
console.error('❌ [S3 Upload] Erreur lors de l\'upload du PDF:', error);
throw new Error(`Échec de l'upload du PDF sur S3: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Génère une clé S3 pour un contrat CDDU
*
* @param organizationId - ID de l'organisation
* @param contractId - ID du contrat
* @param year - Année du contrat (par défaut: année courante)
* @returns Clé S3 formatée
*
* @example
* ```typescript
* const key = generateContractS3Key('org-123', 'contract-456', 2025);
* // Retourne: 'contrats/org-123/2025/contract-456.pdf'
* ```
*/
export function generateContractS3Key(
organizationId: string,
contractId: string,
year: number = new Date().getFullYear()
): string {
return `contrats/${organizationId}/${year}/${contractId}.pdf`;
}
/**
* Génère une clé S3 pour une fiche de paie
*
* @param organizationId - ID de l'organisation
* @param payslipId - ID de la fiche de paie
* @param year - Année de la fiche de paie
* @param month - Mois de la fiche de paie (1-12)
* @returns Clé S3 formatée
*
* @example
* ```typescript
* const key = generatePayslipS3Key('org-123', 'payslip-456', 2025, 10);
* // Retourne: 'fiches-paie/org-123/2025/10/payslip-456.pdf'
* ```
*/
export function generatePayslipS3Key(
organizationId: string,
payslipId: string,
year: number,
month: number
): string {
const monthPadded = String(month).padStart(2, '0');
return `fiches-paie/${organizationId}/${year}/${monthPadded}/${payslipId}.pdf`;
}