Liste des demandes de prêt (backoffice)
frontend/src/views/backoffice/LoanRequestsView.vue + backend/src/controllers/loan.controller.js (getLoanRequests, getLoanRequestCounts).
Vérifié le 2026-08-13.
1. Chargement à la demande (depuis le 2026-08-13)
Avant cette date, fetchRequests() chargeait l'intégralité des demandes de prêt du périmètre de l'utilisateur en un seul appel (GET /loan-requests), puis tout le regroupement (par type, par agence) et le filtrage se faisaient côté client sur ce tableau complet, en permanence en mémoire.
Le nouveau flux :
- Au chargement : un seul appel léger,
GET /loan-requests/counts, qui renvoie uniquement des compteurs — jamais les dossiers eux-mêmes :Peuple les boutons "Prêt Scolaire — 1 demande(s)" etc.{"scolaire": { "total": 1, "agencies": [{ "id_agence": 43, "designation": "UTB Centrale", "count": 1 }] },"immo": { "total": 0, "agencies": [] },...} - Clic sur un type : si
agencies.length <= 1(cas normal d'un agent/chef d'agence, qui n'a qu'une seule agence de toute façon — ou d'unCHEF_ZONE/SUPER_ADMINsi ce type n'a de dossiers que dans une seule agence), la liste se charge directement, sans étape intermédiaire. Siagencies.length > 1, des boutons par agence apparaissent d'abord ; il faut cliquer sur l'un d'eux pour charger sa liste. - Chaque liste chargée est mise en cache (
listCache, clétypeoutype_id_agence) — revenir sur un type/agence déjà consulté ne redéclenche pas d'appel réseau.
GET /loan-requests accepte désormais deux paramètres optionnels : loan_type et id_agence. Sans eux, comportement inchangé (tout le périmètre). id_agence est revérifié côté serveur via canAccessAgency avant d'être appliqué — un utilisateur ne peut pas obtenir les dossiers d'une agence hors de son périmètre en modifiant l'URL/les paramètres de la requête.
GET /loan-requests/:id existe déjà. GET /loan-requests/counts est déclarée avant cette route dans loan.routes.js — sinon Express interprète "counts" comme un id et getLoanRequestById plante sur BigInt("counts").
2. Recherche et filtre de statut : uniquement sur ce qui est déjà chargé
Contrairement à l'ancien comportement (recherche sur tout le tableau en mémoire), la recherche et le filtre de statut ne portent désormais que sur la liste actuellement affichée (le type + l'agence sélectionnés). Décision assumée : pas de recherche globale cross-type/cross-agence pour l'instant.
3. Pagination
Déplacée à l'intérieur de la liste actuellement affichée (10/page) — auparavant globale sur l'ensemble des résultats filtrés tous types confondus.
4. Dépendance directe sur le filtrage par agence/zone
Le comportement de cette page dépend entièrement de agencyScopeWhere/canAccessAgency (voir Agences, zones & GAB) : c'est ce qui détermine, pour un CHEF_ZONE, la liste des agences de sa zone renvoyée par /counts, et pour un agent/chef d'agence, le fait qu'une seule agence apparaisse (donc aucune étape de sélection d'agence à l'écran).