Skip to main content

Mécanismes génériques : documents, numéros de ticket, archivage

Trois services backend utilisés en arrière-plan par les prêts et (partiellement) les comptes, jamais documentés pour eux-mêmes bien que référencés dans plusieurs autres pages.

Dernière vérification contre le code

Vérifié le 2026-08-12.

1. documents.service.js / documents.controller.js

Stockage 100% en base de données : la colonne documents.url contient directement le base64 complet du fichier — il n'y a pas de fichier écrit sur disque dans ce flux (le disque n'intervient que via l'archivage, section 3, un mécanisme séparé et redondant).

Schéma : id_documents (BigInt), original_name, stored_name, url, type, object_id (BigInt), entity_type, created_at. Pas de clé étrangère réelle vers loan_requests/account_requestsobject_id/entity_type forment une clé polymorphe applicative (entity_type: 'loan' ou 'account_request').

PATCH ne modifie que stored_name — c'est le mécanisme utilisé par le backoffice pour attribuer a posteriori un document dont l'association n'était pas garantie à l'envoi (voir Fiche détail prêt, attribution manuelle). Un log d'activité loan_document_attributed n'est créé que si entity_type === 'loan' — les comptes n'ont pas cet historique (cohérent avec Fiche détail compte, historique factice).

2. ticket-number.service.js

Format UTB-YYYYMMDD-XXXX (déjà connu pour sa faiblesse de sécurité, voir API de suivi de dossier). Génération : date du jour + 4 caractères tirés par Math.random() (pas un générateur cryptographique) dans l'alphabet A-Z0-9. Unicité garantie par retry avec vérification en base : le service régénère un nouveau suffixe tant que le ticket existe déjà dans account_requests ou loan_requests, sans limite de tentatives (boucle en théorie infinie, improbable vu l'espace ~1,68M de combinaisons/jour).

3. archive.service.js — archivage disque, séparé du stockage en base

archiveLoanRequest(loan, documents, agence, typeName) écrit sur le système de fichiers du serveur (pas en base), en plus du stockage déjà fait par documents.service.js — les mêmes fichiers existent donc en double, sans déduplication ni purge coordonnée.

  • Racine configurable via site_settings (clé LOAN_ARCHIVE_ROOT_PATH), avec repli codé en dur sur ./archives si absente.
  • Arborescence : {root}/PRETS/{TYPE}/{VILLE}/{AGENCE}/{TICKET} - {NOM PRENOM}/.
  • Génère aussi un PDF récapitulatif du dossier (pdfkit) incluant les champs dynamiques.
  • Uniquement pour les prêts — aucune référence à ce service pour les comptes.
Échec totalement silencieux

L'appel dans loan.controller.js n'est ni awaité ni suivi de .catch (fire-and-forget). En cas d'échec (chemin réseau indisponible, permissions...), tout est absorbé par un try/catch interne qui se contente d'un console.error et retourne false — aucune alerte, aucune table de suivi des échecs, la création de la demande de prêt réussit normalement côté client. Des dossiers peuvent manquer sur le stockage d'archivage sans que personne ne le sache, sauf en surveillant activement les logs serveur.

Pièges connus

  • Le chemin d'archivage réseau, s'il devient indisponible, ne fait jamais échouer une demande de prêt visible côté client — seul un console.error serveur en garde trace.
  • Math.random() pour le suffixe de ticket n'est pas cryptographiquement sûr — cohérent avec la faiblesse déjà documentée dans API de suivi de dossier, mentionné ici uniquement comme fait d'implémentation.