Spaces:
Running
Running
Commit History
Yesterday
-
feat(jasmine): chat et contenu de la carte Logistique (Mapbox) transmis au chat
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>57c9004 -
feat(jasmine): le chat lit tous les graphiques de la page (Plotly et natifs), par module
Les graphiques affiches sont captes (core/graphiques_contexte.py) et transmis au chat de leur page via graphiques_affiches ; le chat lit ceux du run precedent. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>2ce0542
2 days ago
-
fix(signature): localisation facultative — le code email reste saisissable sans position
Le lieu non communique est inscrit a la place (refusee / non recue) avec l'IP. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>06df37a -
fix(sheets): colonnes sans titre ne bloquent plus get_all_records
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>8caf834 -
feat(signature): apercu des contrats dans la page, plus de PDF dans les emails
Lien de signature et confirmation sans piece jointe ; apercu par page (client et preteur), telechargement immediat apres signature, PDF definitifs envoyes a la contresignature. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>966c823
3 days ago
-
feat(logistique): carte de renseignement — liens adresses/IP/tel/email/piece entre clients et garants
- core/liens_logistique.py : croisement pur (adresses normalisees + GPS, IP publiques, telephones, emails, pieces, employeurs, garants). IP d'audit limitees aux sessions publiques. - modules/carte_html.py : carte plein ecran noire, clic = dossier du lieu + liens, recherche, alertes. - map_dashboard : retrait du bloc ANSD (donnees externes) et des KPI codes en dur. - sheets_quota : invalidation par onglet (l'audit ne vide plus les autres feuilles). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>1030d8c
4 days ago
-
feat(ui): base du benefice Accordé et theme Gotham par defaut
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>6cefb3d -
perf(sheets): bouclier anti-429 global (cache GET gspread, invalidation sur ecriture, secours perime, reessais)
Cache au niveau HTTPClient.request : valeurs 60 s, metadonnees 10 min, Drive 1 h, dedoublonnage des lectures concurrentes, disjoncteur + cache perime sur 429. Bouton ACTUALISER LES DONNEES, lecture fraiche pour la generation d'ID. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>dd08ad5 -
style(ui): emojis remplaces par des balises tactiques sobres
- [OK] [ECHEC] [ATTENTION] [ALERTE] [REFUS] [STOP] [ANALYSE] [IA] [DOSSIER]... a la place des emojis dans tous les libelles, messages et journaux - puces d'etat (couleurs) remplacees par des carres/ronds geometriques - aucun changement de logique : les tests et la detection des messages suivent la nouvelle forme Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>495d60d -
feat(signature): localisation obligatoire pour signer et contresigner
- Etape 3 de la page de signature : lieu detecte (ville, quartier) affiche avant le formulaire ; sans position, pas de formulaire. - Apres un refus : case obligatoire qui relance la demande au navigateur (audit_log.redemander_gps, nouvelle cle du composant) ; aide pour reactiver une localisation bloquee. - signer/contresigner(exiger_position=True) refusent une position vide, refusee ou non recue (verification cote service, pas seulement dans l'interface). - Contresignature du preteur : meme localisation (Localisation_Preteur, GPS_Preteur) imprimee dans son bloc ; module partage localisation_ui. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>cfbb492 -
feat(ui): theme NOIR "poste de commandement" (Gotham) + style tactique partout
- core/theme.py : theme BLEU (defaut, inchange) et NOIR ; interrupteur "MODE NOIR · GOTHAM" dans la barre laterale (connexion et admin), choix memorise par navigateur (cookie 1 an) - NOIR = table de correspondance BLEU -> NOIR appliquee au rendu de tout le HTML/CSS injecte (st.markdown, st.html, components.html) et des figures Plotly : fonds noirs, gris neutres, accent ambre, etats desatures ; une seule source de style pour les deux themes - composants natifs habilles dans les deux themes : fonds, champs, listes, boutons, onglets, expanders, metriques, code, progression, chat, barres de defilement - alertes encapsulees en bandeau tactique : CONFIRMATION / INFORMATION / AVERTISSEMENT / ALERTE / EXCEPTION SYSTEME (liserai de couleur, etiquette), toasts au meme style - NOIR : titres fins en capitales espacees (style mission suite) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>4aa6677 -
feat(signature): localisation (ville, quartier) dans le bloc de signature
- GPS du navigateur reutilise (audit_log) : geocodage inverse Nominatim en "Ville, Quartier" ; refus ou absence = mention explicite. - Ligne "Localisation (GPS)" dans le contrat, IP conservee a cote ; absente des signatures anterieures (PDF identiques octet pour octet). - Signatures_Contrats : Localisation_Signature et GPS_Signature (coordonnees brutes + precision, jamais imprimees) ; journal de signature enrichi. - Page de signature : information sur l'enregistrement de la position. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>3f6c2b9
5 days ago
-
feat(erreurs): incidents techniques en bloc Gotham explique par l'IA + Telemetrie
- core/incidents.py : bloc sobre (bleu-gris, jamais rouge) avec DIAGNOSTIC et ACTION en une phrase chacune (call_llm, repli sur regles locales), fleche "Journal technique" avec les lignes de log en texte simple (type, message, traceback) - chaque incident part dans la Telemetrie (ERREUR / INCIDENT) avec ses valeurs : type, message, contexte, traceback, diagnostic, action, analyse ; dedoublonne 60 s - appels IA bornes : cache par signature (24 h), 15/heure, 15 s au total ; emails, numeros et jetons masques avant envoi, traceback jamais envoyee - branche sur : exceptions non gerees d'un module admin, st.error technique (pas les consignes de saisie), afficher_erreur_sheets ; le public ne voit jamais le detail - tests : aucun appel IA reel (garde-fou conftest), un test lent ne bloque plus la suite Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>001eb74 -
feat(ui): bandeau jaune 429 partout dans l'application
- core.errors.est_quota() : detecte [429], code 429, Quota exceeded, RESOURCE_EXHAUSTED, Too Many Requests, rate limit (sans faux positif sur un nombre comme 1 429 000) - core.errors.installer_bandeau_429() : tout st.error / st.warning (sidebar, container...) dont le message est un quota s'affiche en bandeau jaune explicatif au lieu d'un cadre rouge (texte Google Sheets ou service externe selon le message) - bandeau unique partage avec afficher_erreur_sheets ; gestionnaire global du module utilise la meme detection Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>a62a48f -
feat(signature): faire signer tous les prets en cours, avec ou sans remboursement
- lister_prets_a_signer : inclut les prets avec remboursements (colonne Remboursements), exclut seulement ceux deja signes par toutes les parties. - Un pret avec remboursements reste ACTIF pendant l'attente de signature (journal PRET_RESTE_ACTIF) ; sans remboursement il passe EN_ATTENTE_SIGNATURE. - Onglet "Prets a faire signer" : case "Tout selectionner". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>bc03a3d -
feat(signature): suivi d'ouverture des emails de lien de signature
- Les emails de lien (et rappels) portent le tag Brevo vortex-signature et sont enregistres dans Suivi_Emails (Type=SIGNATURE, ID_Signature, ID_Pret). - Onglet Signatures > Ouvertures : liens envoyes / ouverts / signes, delai entre premiere ouverture et signature, filtres. - Plus de copie cachee admin sur le lien (son ouverture fausserait le suivi). - envoyer_email accepte tags et meta (message_id Brevo). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>c44d4c8
7 days ago
-
feat(communications): suivi d'ouverture des emails (Brevo)
- Envoi HTML tague par campagne, une ligne par destinataire dans Suivi_Emails. - Synchronisation des evenements Brevo (delivre, ouvertures, proxy Apple, clics, rebonds, spam) a la demande et toutes les heures (scheduler). - Onglet Statistiques d'ouverture : tableau par campagne + detail par personne. - Recapitulatif unique a l'admin au lieu d'une copie cachee par email. - Lecture du messageId Brevo sans jamais faire echouer un envoi reussi. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>c45c242 -
fix(securite): XSS sur donnees publiques, limite d'envoi des liens simulateur
- echappement HTML des donnees saisies par le public avant rendu brut : analyse IA des documents KYC (kyc_form), profession/secteur (request_loans), nom et valeurs des garants (Data_exploration). Plus important depuis que le cookie de session est lisible en JavaScript. - simulateur public : email valide obligatoire, 3 liens/heure par adresse, 40 liens/heure au total (protege le compte Brevo et la feuille des tokens) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>c4a01d3 -
feat(signature): mention manuscrite "Bon pour..." saisie par le debiteur
- reconnaissance de dette : montant en toutes lettres (snapshots v2), mention recopiee par le signataire, verifiee avant l'OTP, stockee (Mention_Manuscrite) et imprimee - echeancier du contrat repris tel quel des donnees du pret (recalcul en controle seulement) - mention bornee a 300 caracteres (texte public) Travail d'une autre session, relu et teste avant commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>6122be7 -
feat(auth): cookie "Rester connecte" (survit aux redeploiements)
- jeton signe HMAC (SESSION_SECRET, sinon cle derivee de SIGNATURE_SECRET), 30 jours, renouvele a l'usage ; aucun etat en memoire, donc valable apres un push - invalide si mot de passe change, compte supprime, ou deconnexion (hash du jeton inscrit dans la feuille Sessions_Revoquees, cookie efface) - role et modules relus a chaque restauration - case "Rester connecte sur cet appareil" (cochee par defaut) a l'ecran de connexion Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>5f4c0ba
8 days ago
-
fix(ui): bandeau explicite au lieu de la traceback sur quota Sheets (429)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>b6cc722 -
feat(signature): email au signataire quand sa demande est annulee
- annulation par l'admin : email "lien annule, ne l'utilisez plus" (journal ANNULATION_NOTIFIEE) - nouveau lien a la meme adresse : le mail du nouveau lien annonce que l'ancien est annule - nouveau lien a une adresse corrigee : l'ancienne adresse recoit l'email d'annulation - ecran admin : confirme l'envoi ou signale l'echec de l'email d'annulation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>103bca0
9 days ago
-
feat(ontology): module serieux (vue 360, fraude, coherence, terminal IA fiable)
Exactitude - core/kg_data.py : une ligne par pret (Prets_Master + derniere version Prets_Update), classes canoniques (Prêt = Pret), ID_Officiel n'est plus classe "Officiel", identifiants normalises (telephone, email, piece) - montant_net = Montant_Total de la version courante (plus le MAX de tout "montant") - qualite RDF sur toutes les classes : completude reelle + cardinalites - controles de coherence : references orphelines, doublons, chaine des soldes (solde de depart = Montant_Total), statuts incoherents - fraude : identifiants partages entre personnes distinctes (client = garant compte pour une personne), auto-garantie, garantie croisee, garant multi-emprunteurs Securite - plus aucun HTML brut issu des donnees (chat en st.chat_message, infobulles neutralisees) - identifiants sensibles masques dans le RDF, l'export et tout ce qui part vers LLM/Jev - SPARQL de l'agent en lecture seule (SERVICE/INSERT/DROP... refuses) Robustesse - lecture groupee en cache (values_batch_get)…c6c39e9 -
fix(sidebar): base du benefice en liste deroulante, libelles courts
Le segmented_control coupait les libelles longs dans une sidebar etroite. Liste "Encaissé" / "Accordé", definition en legende. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>a798bd8 -
feat(ui): cases carrees sur tous les st.radio, module Suppressions
- CSS radio : structure react-aria (stRadioOption / data-selected), remplace l'ancien [data-baseweb="radio"] inoperant en Streamlit 1.64 - maintien de session (fragment run_every 5 min) - module Suppressions (admin) et son journal, entree dans l'overlay orb Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>f7df762 -
fix(signature): journal chaine, lecture groupee et arret propre sur quota Sheets
- lot_envoi() : lit Clients_KYC/Garants_KYC une fois par envoi groupe et reutilise la feuille du journal (quota 429) - envoi groupe : arret propre sur APIError avec liste des prets restants - journal de signature chaine (verifier_journal), cache par classeur reinitialise entre tests Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>bbab97f -
fix(telemetrie): heure de Dakar (et non d'Abidjan) dans les libelles
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>4208fca -
feat(exercice): base du benefice globale (encaisse / accorde)
Le bouton "Base du benefice" passe dans la barre laterale et pilote tous les modules : - Dashboard : KPI, analyse mensuelle, repartition. - Optimizer : realise selon la base ; interets restant a echoir ajoutes seulement en base encaissee. - Digital Twin : projection du benefice jusqu'au 31/12 de l'exercice (realise + part interets/penalites simulee) au lieu de la tresorerie totale sur 52 semaines ; base accordee = realise. - Rapports IA et JASMINE : base retenue dans les donnees et la consigne. Echeancier contractuel : vraies dates (Dates_Versements) si renseignees. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>2d6c8b9 -
feat(exercice): separation de toute l'application par annee civile
- core/exercice.py : source unique (lecture des dates FR/ISO, bornes, selecteur EXERCICE de la barre laterale, regle A : chaque flux dans l'annee de sa propre date, echeancier contractuel, synthese par exercice). - Objectifs de benefice par exercice (2026 = 2,2 M, 2027 = 3,5 M XOF, annees futures = dernier objectif connu), editables par annee. - Dashboard, Optimizer, rapports IA, JASMINE, Digital Twin : chiffres de l'exercice choisi + comparaison N-1 ; benefice = interets + penalites encaisses dans l'annee. - IA : consigne d'exercice dans tous les prompts. ML : variable Annee_Deblocage + erreur hors echantillon par exercice. - Correctif : "2026-03-01" n'est plus lu comme le 3 janvier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>631cd58 -
feat(ui): overlay de chargement thinking-orb (fond flouté) sur chaque exécution
- core/orb_overlay.py : injection dans le document principal (components.html height=0 + window.parent), état d'orbe par module - core/assets/vortex_orb.js : bundle IIFE du moteur thinking-orbs (sans React) - vendor/thinking-orbs/vortex/ : source overlay.ts + README (rebuild esbuild) - streamlit_app.py : installer_orb() juste après set_page_config Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>b9c04ed
10 days ago
-
feat(signature): contresignature du preteur (contrat et caution) avant activation
- Le preteur contresigne le dossier une fois client et garant signes (code par email, admin connecte) - Bloc preteur ajoute au contrat et a l'acte de caution ; reconnaissance de dette inchangee - Pret ACTIF seulement apres contresignature ; documents definitifs envoyes a chaque signataire - Onglet admin 'A contresigner' ; verification publique du sceau preteur - Mention 'loi ivoirienne' retiree du bandeau public Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>db7f3f2 -
feat: journal d'audit, pénalités, cohérence remboursements et signature
- Journal d'audit (core/audit_log.py, module audit_viewer) : traces des envois d'email, connexions et jobs - Pénalités : consommation de l'occurrence à l'octroi uniquement, idempotente - Correctifs remboursements, rappels et décimaux du Sheet (virgule française) - Pages et module de signature électronique restants (voir commit précédent) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>56277f7 -
feat(signature): signature electronique des contrats (lien email + 4 derniers car. ID_Officiel + OTP + case a cocher)
- Pret cree EN_ATTENTE_SIGNATURE (bloque), ACTIF quand client (et garant) ont signe - Pages publiques ?sign=<token> et ?verifysig=<ID> ; bloc de signature electronique en fin de PDF - PDF deterministes (invariant=1) + snapshot JSON : documents reconstituables sans stockage de fichier - Sceau HMAC (secret SIGNATURE_SECRET), token et OTP jamais stockes en clair, journal append-only - Relances 24 h, re-emission automatique apres expiration (3 max), alerte admin - Module admin Signatures : suivi, rattrapage des prets sans remboursement, actions, journal - Branche sur octroi direct, demandes approuvees et Check-Up ; EN_ATTENTE_SIGNATURE compte dans la limite de prets - 79 tests (faux classeur Sheets, AppTest Streamlit) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>de5e25f
12 days ago
-
perf+fix(simulateur): Jasmine plus rapide, capacite de remboursement lue par la grille
LLM : modeles non textuels exclus (image, audio, deep-research...) ; un modele en echec est ecarte un moment (15 min quota, 6 h modele absent, 2 min panne) au lieu d'etre reessaye a chaque appel ; mode rapide (modeles flash d'abord) et delai de 25 s par modele pour l'analyse Jasmine. Jev : Jasmine recoit la capacite de remboursement calculee par la grille de l'entreprise et doit la recopier ; la trace envoyee a Jev contient cette lecture et la grille. Mots de decision interdits dans le rapport, phrase de non-garantie imposee. Outil tools/jev_diagnostic.py pour tester quelles formulations passent. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>5183195 -
fix: decimaux du Sheet lus correctement (17,61 n'est plus lu 1761) et logs LLM/Jev
Le classeur est en locale francaise : gspread supprimait la virgule des decimaux a la lecture ("17,61" -> 1761, "1,5" -> 15, "252,4" -> 2524). core/gspread_fr.py lit desormais une virgule decimale comme un decimal, pour toute l'application (get_all_records, cache partage) et le job de rappels. Neutralise la rustine "diviser par 10 tant que > maximum" de Demandes Prets qui reduisait un taux legitime de 24,11 % en 2,41 %. Diagnostic : [LLM] modele, duree et erreur de chaque tentative ; [JEV <etape>] trace envoyee et reponse brute complete. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>c73b85c -
fix: remboursements, pénalités, rappels et cohérence des calculs
Remboursements (AnalyseRepayment, repayments): - Un paiement en retard qui ne couvre pas les pénalités est PARTIEL et ne clôture plus le prêt tant qu'un solde reste dû (garde-fou 1 %) - Pénalités dues une seule fois par échéance (celles déjà encaissées sont retirées), prélevées en premier dans la limite du versement : plus d'intérêts négatifs ; trop-perçu refusé avec message ; la dernière échéance absorbe le reliquat cumulé ; scénario de pénalités obligatoire en cas de retard - Registre des retards pardonnés : une échéance qui a déjà encaissé des pénalités n'est plus comptée comme pardonnée - Numéro de reçu et ID de transaction : plus grand numéro émis + 1, lus du même instantané juste avant l'écriture - Rappels : pénalités annoncées = pénalités encaissées (une seule règle pour le bouton, le tir groupé et le job de 12 h) ; bilan du tir groupé conservé après rechargement, clients sans email journalisés - Reçu PDF : adresse échappée (balisage dans l'adresse ne casse plus …92d7dac
16 days ago
-
fix: parcours client plus fiable (onboarding, KYC, demande de pret)
- Noms avec accents acceptes dans le formulaire KYC (client et contact d'urgence) - Lien d'onboarding verifie a l'ouverture mais consomme seulement apres l'enregistrement du dossier (validite 7 jours) ; lien simulateur reouvrable pendant 2 h - Documents KYC repartis en plusieurs e-mails selon la taille, resultat journalise dans l'onglet Audit_Documents, client prevenu en cas d'echec - Mail de confirmation de demande de pret : echec sans fausse erreur - ID du dossier releve a l'envoi, apercu en cache, erreurs lisibles - Mail d'onboarding : liste des documents et informations a preparer, conseil d'ouvrir le lien dans Chrome ou Safari - APP_BASE_URL : valeur par defaut partagee par tous les liens - Attente forcee par document reduite de 4 s a 1 s Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>bba08b3
18 days ago
-
fix(sheets): tolerate rows wider than header, stop writing geo cells to Garants_KYC
Simulator crashed with "42 columns passed, passed data had 48 columns" after a new guarantor signed up: KYC form appended 5 geoloc cells past the 42-column Garants_KYC header. Reader now truncates rows to header width (like get_all_records); geoloc only appended for Clients_KYC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>e6b6e8c
21 days ago
-
fix: consolide get_credential, log silences critiques, securise MIME/SPARQL/Mapbox
- Rapport IA : filtre mois/trimestres multi-select par cases a cocher (union exacte des mois coches, non contigu) - get_credential() centralisee dans core/email_client.py : supprime 10 copies dupliquees (client_simulator, Check_Up_Loans, loans_engine, repayments x2, notifications, geoip_client, sim_gate, map_dashboard, geoloc_verify) - except Exception: pass nus remplaces par log_swallowed() ou Weitere silences critiques (demarrage scheduler, cache Usis, schema_cache AIP, prediction ML post-reentrainement) - Logs InvoiceRepayment.py : retrait numero_recu/trans_id des print() (fuite potentielle dans les logs du Space) - validation_engine.py : validation du format cls/prop avant interpolation SPARQL - map_dashboard.py : token Mapbox echappe via json.dumps au lieu de concatenation brute en JS - document_validator.py : verification magic bytes avant Docling (fichier renomme ne passe plus silencieusement) - Ajout tests/ (62 tests : penalites_retard, AnalyseFinance, doc…2fe4365
25 days ago
-
Corriger le pourcentage et diagnostiquer les refus Jev
e3cb468 -
Ajouter les validations Jev et l'estimation de remboursement
e07d8ff
27 days ago
-
Add Jev validation to ontology agent
3aa39eb -
Add email gate for public simulator access
7258df9 -
Capture request origin for fraud review
5b425ba -
Enrich AIP with ontology business context
1437a48 -
Réduit la consommation de quota Google Sheets : lectures groupées + cache étendu
- core/sheets_cache.py : ajoute get_cached_dfs_batch() (1 appel API via values_batch_get au lieu de N appels par feuille), tout en reproduisant la numérisation par défaut de get_all_records() pour un résultat identique. - request_loans.py, client_simulator.py, Usis.py, map_dashboard.py, logistique.py, communications.py, ml_dashboard.py : lectures regroupées en un seul appel (avec repli feuille par feuille si une feuille optionnelle manque), ou mises en cache quand elles ne l'étaient pas. - regles_metier.py : cache la lecture de Clients_KYC (liste déroulante), inchangé pour les lectures qui doivent rester immédiates (règles de tarification en direct). - Laissé volontairement sans cache : Check_Up_Loans.py (désactive la numérisation gspread pour éviter une corruption des décimales françaises — incompatible avec le nouveau cache groupé), les lectures juste après une écriture (forecasting, règles métier), et les tâches planifiées en arrière-plan (notifications).c20487a -
Score_Jasmine en Markdown sûr (plus de HTML brut stocké/affiché), et garde anti double-clic sur les boutons d'écriture
- client_simulator.py : l'audit financier/algorithmique stocké dans Score_Jasmine est généré en Markdown standard au lieu de HTML brut, pour ne plus persister de balises dans Prets_Requests. - request_loans.py : affichage du rapport JASMINE via st.markdown() natif (sans unsafe_allow_html) au lieu d'un échappement manuel qui cassait la mise en forme de l'audit. - core/ui_guards.py (nouveau) : garde-fou générique anti double-soumission pour les boutons qui écrivent dans Google Sheets ou envoient un email, appliqué à l'octroi de prêt, à l'encaissement de remboursement, à l'envoi de rappels/reçus et à la validation KYC.c638843 -
Barème de majoration par montant, détail des frais, et fix quota 429
Barème : la majoration pour retard pardonné dépend désormais du montant du prêt simulé (5% < 50k, 2,5% entre 50k et 150k, 2% > 150k XOF), remplaçant le forfait unique précédent. Pilotable dans Règles Métier. Détail des frais : le simulateur écrit maintenant la composition du taux (frais de transfert, risque brut IA, marge, majoration retard) dans de nouvelles colonnes de Prets_Requests, affichées dans le module Demandes Prêts. Quota 429 : l'initialisation du registre de pénalités ouvrait la feuille et écrivait une ligne par client/occurrence, épuisant le quota de lecture Google Sheets. Elle n'ouvre désormais la feuille qu'une fois et écrit toutes les lignes en un seul appel. Nouvelle fonction afficher_erreur_sheets() (bandeau jaune 429 / rouge générique) appliquée au chargement du simulateur et aux appels Sheets de Règles Métier ; la majoration se dégrade silencieusement en cas d'échec plutôt que de casser la page du client. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>4d00d77
30 days ago
-
Securite et fiabilite : corrections sur l'ensemble du simulateur/octroi/notifications
Relecture complete (17 fichiers modifies + 4 nouveaux) des corrections suivantes, apportees en parallele sur le poste : Securite : - Simulateur public : recherche client remplacee (ne liste plus toute la base), mot de passe partage remplace par un lien d'onboarding a usage unique, outils JASMINE (portefeuille reel) retires cote page publique (allowed_tools=[]). - Mots de passe hashes PBKDF2-HMAC-SHA256 (core/auth.py), compatible avec les comptes pas encore migres, comparaison en temps constant y compris pour un identifiant inconnu (anti-enumeration). - Verrouillage apres 5 tentatives de connexion echouees (5 min). - IP client lue depuis le dernier maillon de X-Forwarded-For (celui ajoute par le proxy de confiance) plutot que le premier (falsifiable par le client) ; bug qui empechait l'enregistrement du GPS corrige. - Motif libre du client (et l'analyse JASMINE qui en decoule) traite comme une donnee a citer, jamais une instruction, avec echappement HTML avant afficha…397b23d -
Corrige les doublons de pret a l'octroi et l'ID base sur un comptage de lignes
L'ID de pret genere par comptage de lignes (len(ws.get_all_values())) peut reutiliser l'identifiant d'un pret existant des qu'une ligne a ete supprimee/deplacee dans la feuille — or c'est cet ID qui relie un pret a ses remboursements. Ajoute un generateur partage (core/id_generator.py) base sur le MAX des numeros deja utilises cette annee, et l'utilise a la fois dans Init Loan (loans_engine.py) et dans l'octroi via Demandes Prets (request_loans.py), qui dupliquaient deja des logiques legerement differentes. Ajoute aussi une garde anti-doublon a l'octroi : le pret est ecrit dans Prets_Master puis le statut de la demande est mis a jour dans Prets_Requests en 2 ecritures separees. Si la 2e echoue (ex: 429), le message invitait a reessayer l'octroi, ce qui creait un 2e pret pour la meme demande. Avant d'ecrire, on verifie maintenant si un pret correspondant a cette demande (meme ID_Client + Date_Creation, stables sur toute nouvelle tentative) existe deja dans Prets_Master ; si oui, l'octr…47776fe