Files
demat-facturation/todo.md
Manus 72c3f503a3 Checkpoint: Système de gestion des automatismes pour remplissage automatique des factures
Nouvelle fonctionnalité majeure :
 Page "Automatismes" complète pour gérer les règles de remplissage automatique
 Système de règles conditionnelles SI...ALORS pour automatiser le remplissage des champs métier
 Support de conditions multiples avec logique AND/OR
 Application automatique des règles lors de l'import de factures
 Gestion de la priorité des règles (ordre d'exécution)
 Activation/désactivation des règles individuelles

Architecture technique :
- drizzle/schema.ts : Table automationRules avec conditions JSON et actions JSON
- server/db.ts : Fonctions CRUD complètes pour les règles (create, update, delete, list)
- server/routers.ts : Routes tRPC pour gérer les automatismes
- server/automationEngine.ts : Moteur d'évaluation et d'application des règles
- client/src/pages/AutomationRules.tsx : Interface complète de gestion des règles
- Migration 0009_regular_warhawk.sql appliquée avec succès

Fonctionnement des règles :
1. **Conditions (SI)** : Définissez des critères basés sur les champs de la facture
   - Champs disponibles : Fournisseur, N° Facture, Montant, Date, N° Commande, N° Bon de livraison
   - Opérateurs : contient, égal à, commence par, finit par, >, <, >=, <=
   - Logique : AND (toutes les conditions) ou OR (au moins une condition)

2. **Actions (ALORS)** : Définissez les champs à remplir automatiquement
   - Type d'achat (CAPEX/OPEX)
   - Service concerné (depuis la liste des services)
   - Ventilation comptable (depuis la liste des ventilations)

3. **Priorité** : Les règles sont appliquées dans l'ordre de priorité
   - Une règle de priorité supérieure ne peut pas être écrasée par une règle de priorité inférieure

4. **Application automatique** : Les règles s'appliquent automatiquement lors de l'import de factures

Exemples d'utilisation :
- SI Fournisseur contient "Microsoft" ET Montant > 1000 ALORS Type d'achat = CAPEX, Service = DSI
- SI Fournisseur contient "EDF" ALORS Type d'achat = OPEX, Ventilation = TOUS
- SI N° Facture commence par "AB" ALORS Service = Administration

Interface utilisateur :
- Liste des règles avec nom, conditions, actions et statut
- Formulaire de création/édition avec interface intuitive
- Boutons d'activation/désactivation rapide
- Suppression avec confirmation
- Affichage lisible des conditions et actions

Cette fonctionnalité permet de gagner un temps considérable en automatisant le remplissage des champs métier selon des règles métier prédéfinies.
2026-02-11 12:35:26 -05:00

17 KiB

Invoice Analyzer - TODO

Phase 1: Base de données et schéma

  • Créer table users avec support authentification locale + Azure AD
  • Créer table sourceFiles pour fichiers PDF uploadés
  • Créer table invoices pour factures extraites
  • Créer table userSettings pour paramètres utilisateur
  • Créer table importLogs pour historique des imports
  • Créer table llmLogs pour logs des appels LLM
  • Pousser les migrations avec pnpm db:push

Phase 2: Authentification

  • Implémenter authentification locale (email/password avec bcrypt)
  • Implémenter authentification Azure AD avec MSAL
  • Créer helpers de génération de tokens JWT
  • Créer middleware de vérification des rôles (user/admin)

Phase 3: Stockage et extraction IA

  • Créer helper de stockage local avec préfixe YYYY-MM
  • Implémenter extraction PDF avec Mistral OCR
  • Implémenter extraction de métadonnées avec Mistral LLM
  • Créer système de scoring de qualité (0-100)
  • Implémenter détection de doublons
  • Créer helper de génération de fichiers JSON de métadonnées
  • Implémenter logger LLM pour debug

Phase 4: Export SFTP

  • Créer helper de connexion SFTP
  • Implémenter export manuel de factures
  • Implémenter export automatique de factures
  • Créer test de connexion SFTP

Phase 5: Routes tRPC

  • Routes auth (me, loginLocal, getAzureLoginUrl, logout)
  • Routes invoices (upload, list, getById, update, delete, search, getStats)
  • Routes sourceFiles (getByIds pour polling)
  • Routes settings (get, upsert)
  • Routes admin (createUser, getAllUsers, updatePassword, toggleActive, deleteUser)
  • Routes sftp (testConnection, exportInvoices)
  • Routes importLogs (getByUser)
  • Routes llmLogs (getBySourceFile, getByInvoice)

Phase 6: Pages Frontend

  • Page Login avec formulaire local + bouton Azure AD
  • Page Dashboard avec statistiques et graphiques
  • Page Upload avec drag-and-drop et suivi temps réel
  • Page Invoices avec liste, recherche, filtres, pagination
  • Page Settings avec configuration LLM, keywords, SFTP
  • Page History avec logs et détails
  • Page Users (admin) pour gestion des utilisateurs
  • Layout avec navigation adaptée (DashboardLayout)
  • Configuration des routes dans App.tsx

Phase 7: Tests et finalisation

  • Tests unitaires d'authentification (hashPassword, verifyPassword, JWT)
  • Tests de logout avec cookies multiples
  • Vérification du build et de la compilation TypeScript
  • Vérification du serveur de développement
  • Créer le checkpoint final

Corrections et améliorations

  • Créer un utilisateur administrateur avec login adminServFacturation

  • Tester la connexion locale avec le nouvel utilisateur

  • Modifier l'email de l'administrateur de adminServFacturation à o.pareige@itinova.org

  • Diagnostiquer le problème de connexion locale avec o.pareige@itinova.org

  • Corriger l'authentification locale (ajout support cookie auth_token)

Amélioration du Dashboard

  • Créer route tRPC pour statistiques détaillées (factures par semaine, top fournisseurs)
  • Créer cartes de statistiques (Factures traitées, Montant total, Score moyen, Dernière activité)
  • Créer graphique en barres des factures par semaine (Recharts)
  • Créer graphique circulaire du top 10 fournisseurs (Recharts)
  • Créer liste détaillée des fournisseurs avec nombre de factures
  • Ajouter bouton "Voir les statistiques détaillées"

Modification page Factures - Export PDF

  • Ajouter champ exportStatus dans le schéma invoices (exported/not_exported/export_error)
  • Ajouter champ exportedAt dans le schéma invoices (déjà existant)
  • Créer route tRPC pour exporter les factures en PDF
  • Créer route tRPC pour mettre à jour le statut d'export
  • Ajouter cases à cocher pour sélection multiple dans la page Factures
  • Ajouter case "Tout sélectionner"
  • Modifier l'affichage des statuts (Exporté/Non exporté/Erreur export)
  • Ajouter bouton "Exporter" (actif uniquement pour score 100%)
  • Implémenter le téléchargement de PDF pour les factures sélectionnées
  • Valider que seules les factures avec score 100% peuvent être exportées

Nouvelles fonctionnalités

  • Ajouter des boutons de filtre par statut d'export (Tous/Exportés/Non exportés/Erreurs)
  • Créer route tRPC pour export Excel
  • Créer page InvoiceDetail avec visualisation des métadonnées
  • Ajouter formulaire d'édition manuelle des champs
  • Implémenter la mise à jour des métadonnées
  • Recalculer le score de qualité après édition manuelle
  • Ajouter bouton "Export Excel" dans la page Factures
  • Générer fichier Excel avec toutes les métadonnées

Correction export PDF

  • Diagnostiquer le problème d'export PDF (URLs non accessibles)
  • Corriger la route exportToPdf pour retourner les bonnes URLs
  • Modifier le code client pour ouvrir les PDFs dans de nouveaux onglets
  • Ajouter un délai entre chaque ouverture pour éviter le blocage des popups

Correction erreur 404 PDF

  • Vérifier la configuration Express pour servir les fichiers statiques
  • Vérifier les URLs générées pour les fichiers PDF
  • Identifier que les fichiers n'ont pas été stockés lors de l'import initial
  • Ajouter bouton "Supprimer" pour supprimer les factures sélectionnées
  • Créer le dossier storage pour le stockage local

Correction bouton Supprimer

  • Permettre la sélection de toutes les factures pour suppression (pas seulement celles à 100%)
  • Séparer la logique de sélection pour export et suppression
  • Supprimer les restrictions disabled sur les checkboxes
  • Ajouter validation pour export PDF (seulement score 100%)

Diagnostic problème 404 persistant

  • Vérifier si les fichiers sont stockés dans le dossier storage
  • Vérifier les URLs générées dans la base de données
  • Vérifier la configuration Express pour servir les fichiers statiques
  • Corriger le chemin d'accès aux fichiers PDF

Correction formulaire d'édition

  • Pré-remplir les valeurs existantes dans le formulaire d'édition de facture
  • Utiliser useEffect pour initialiser les valeurs du formulaire

Amélioration visuelle formulaire d'édition

  • Ajouter un bord rouge sur les champs vides du formulaire d'édition
  • Identifier visuellement les données manquantes non extraites par l'IA

Correction stockage PDF

  • Diagnostiquer pourquoi localStoragePut ne sauvegarde pas les fichiers
  • Vérifier si les données PDF sont bien reçues dans la route upload
  • Identifier le bug: l'URL de localStoragePut était écrasée par une URL locale
  • Corriger la route upload pour utiliser l'URL retournée par localStoragePut
  • Tester le stockage avec un upload réel

Paramètres de réception

  • Créer table importSettings dans le schéma de base de données
  • Ajouter routes tRPC pour gérer les paramètres de réception (get, update)
  • Créer page Paramètres de réception avec configuration import manuel/automatique/email
  • Implémenter activation/désactivation import manuel
  • Implémenter activation/désactivation import automatique avec dossier source et fréquence
  • Implémenter activation/désactivation import par email avec compte mail et mot de passe
  • Tester la sauvegarde et récupération des paramètres

Correction page Paramètres de réception

  • Ajouter DashboardLayout à la page ImportSettings pour afficher le menu latéral

Import automatique par email

  • Installer les dépendances npm pour IMAP (imap et mailparser)
  • Créer le service emailImportService.ts pour se connecter à IMAP
  • Implémenter la détection des nouveaux emails non lus avec pièces jointes PDF
  • Implémenter le téléchargement et traitement des pièces jointes
  • Implémenter le marquage des emails comme lus après traitement
  • Créer un scheduler pour exécuter le service selon la fréquence configurée
  • Ajouter des routes tRPC pour démarrer/arrêter le service
  • Ajouter des boutons de contrôle du service dans la page Paramètres de réception
  • Tester l'import automatique par email avec un vrai compte

Import automatique depuis dossier

  • Installer la dépendance chokidar pour surveiller les dossiers
  • Créer le service folderImportService.ts pour surveiller un dossier
  • Implémenter la détection des nouveaux fichiers PDF dans le dossier
  • Implémenter le traitement des fichiers détectés
  • Implémenter le déplacement des fichiers traités vers un sous-dossier "processed"
  • Créer un scheduler pour vérifier le dossier selon la fréquence configurée
  • Ajouter des routes tRPC pour démarrer/arrêter le service
  • Ajouter des boutons de contrôle dans la page Paramètres de réception

Système de notifications

  • Créer le service notificationService.ts pour gérer les notifications
  • Implémenter l'envoi de notifications après import automatique email
  • Implémenter l'envoi de notifications après import automatique dossier
  • Inclure le résumé : nombre de factures importées, doublons ignorés, erreurs
  • Tester les fonctionnalités avec des données réelles

Bouton effacer les logs d'import

  • Ajouter fonction deleteAllImportLogs dans db.ts
  • Ajouter route tRPC importLogs.deleteAll
  • Ajouter bouton "Effacer les logs" dans la page History
  • Ajouter confirmation avant suppression (AlertDialog)
  • Tester la fonctionnalité

Bug : Import automatique par email ne fonctionne pas

  • Vérifier la configuration IMAP dans la base de données
  • Vérifier si le service d'import email est démarré
  • Ajouter un bouton "Vérifier maintenant" pour forcer une vérification immédiate
  • Ajouter fonction triggerEmailCheck dans emailImportService
  • Ajouter route tRPC emailImportService.checkNow
  • Tester avec un email réel et diagnostiquer les erreurs IMAP

Bugs interface ImportSettings

  • Corriger l'encodage Unicode du bouton "Vérifier maintenant"
  • Ajouter rafraîchissement automatique du statut du service après démarrage/arrêt (email et dossier)

Champs métier pour les factures

  • Ajouter colonnes service_concerne, type_achat, ventilation_comptable à la table invoices
  • Créer table departmentList pour gérer la liste "Service concerné"
  • Créer table accountingAllocationList pour gérer la liste "Ventilation comptable"
  • Ajouter routes tRPC pour CRUD des listes enrichissables
  • Créer page d'administration pour gérer les listes (ListsAdmin.tsx)
  • Ajouter les champs dans le formulaire d'édition de facture (InvoiceDetail.tsx)
  • Ajouter les colonnes dans la liste des factures (Invoices.tsx)
  • Initialiser les valeurs par défaut dans les tables (initializeDefaultLists)
  • Ajouter le lien "Administration des listes" dans le menu de navigation

Bug : Erreur lors de l'ajout d'un service

  • Corriger la fonction initializeDefaultLists pour éviter les erreurs de duplication
  • Vérifier que l'ajout de services et ventilations fonctionne correctement

Chargement dynamique des listes dans le formulaire

  • Modifier InvoiceDetail.tsx pour charger les listes depuis la base de données
  • Remplacer les valeurs codées en dur par des appels tRPC
  • Tester que les valeurs personnalisées apparaissent dans les menus déroulants

Boutons Modifier et Supprimer dans la liste des factures

  • Ajouter une colonne "Actions" dans le tableau des factures
  • Ajouter un bouton "Modifier" qui redirige vers InvoiceDetail
  • Ajouter un bouton "Supprimer" avec confirmation (AlertDialog)
  • Utiliser la route tRPC existante pour supprimer une facture
  • Tester la suppression avec confirmation

Édition directe des champs métier dans la liste

  • Charger les listes de services et ventilations dans la page Invoices
  • Transformer la cellule Service en menu déroulant éditable
  • Transformer la cellule Type d'achat en menu déroulant éditable
  • Transformer la cellule Ventilation en menu déroulant éditable
  • Sauvegarder automatiquement les modifications (mutation updateFieldMutation)
  • Afficher une notification de succès après sauvegarde

Ajout dynamique depuis les menus déroulants

  • Ajouter option "➜ Ajouter..." dans le menu Service
  • Ajouter option "➜ Ajouter..." dans le menu Ventilation
  • Créer une boîte de dialogue pour saisir le nouveau nom
  • Sauvegarder la nouvelle entrée dans la base de données (createDepartmentMutation, createAllocationMutation)
  • Sélectionner automatiquement la nouvelle valeur pour la facture
  • Rafraîchir les listes après ajout (invalidate queries)

Affichage du texte extrait de la facture

  • Ajouter une colonne extractedText dans la table invoices
  • Modifier le prompt Mistral pour demander le texte extrait
  • Modifier le type ExtractedInvoiceData pour inclure extractedText
  • Modifier routers.ts, emailImportService.ts et folderImportService.ts pour sauvegarder extractedText
  • Ajouter un bouton "Détail" (icône FileText) dans la liste des factures
  • Créer une boîte de dialogue pour afficher le texte complet
  • Tester l'affichage du texte extrait avec une nouvelle facture importée

Champ Abonnement pour les factures

  • Ajouter colonne isSubscription (OUI/NON) à la table invoices avec valeur par défaut NON
  • Ajouter champ subscriptionKeywords dans la table userSettings
  • Ajouter interface pour gérer les mots-clés d'abonnement dans la page Settings
  • Modifier l'extraction pour détecter automatiquement les abonnements via mots-clés
  • Modifier le prompt Mistral pour demander isSubscription
  • Modifier routers.ts, emailImportService.ts et folderImportService.ts pour utiliser subscriptionKeywords
  • Ajouter la colonne Abonnement dans la liste des factures
  • Permettre l'édition directe du champ Abonnement dans la liste (select OUI/NON)
  • Ajouter isSubscription dans le schéma de validation update
  • Tester la détection automatique avec une nouvelle facture importée

Bug : Détection incorrecte du champ Abonnement

  • Analyser le prompt Mistral pour comprendre pourquoi isSubscription est à OUI
  • Identifier le problème: mots-clés génériques codés en dur au lieu d'utiliser subscriptionKeywords
  • Corriger le prompt pour utiliser UNIQUEMENT les mots-clés configurés dans subscriptionKeywords
  • Ajouter logique: si subscriptionKeywords est vide, isSubscription = false par défaut
  • Tester avec une nouvelle facture importée et le mot-clé "BLOB" (ne devrait pas détecter)

Nouvelle page Factures BAP

  • Créer une nouvelle page InvoicesBAP.tsx affichant uniquement les factures avec Abonnement = NON
  • Inclure les colonnes Type d'achat et Ventilation dans la page Factures BAP
  • Ajouter la route /invoices-bap dans App.tsx
  • Ajouter le lien "Factures BAP" dans le menu de navigation
  • Supprimer les colonnes Type d'achat et Ventilation de la page Factures principale
  • Tester le filtrage et l'affichage des factures BAP

Page Factures BAP

  • Créer nouvelle page InvoicesBAP.tsx basée sur Invoices.tsx
  • Filtrer uniquement les factures avec Abonnement = NON (isSubscription = 0)
  • Inclure les colonnes Type d'achat et Ventilation dans Factures BAP
  • Supprimer les colonnes Type d'achat et Ventilation de la page Factures principale
  • Ajouter la route /invoices-bap dans App.tsx
  • Ajouter le menu "Factures BAP" dans DashboardLayout
  • Tester le filtrage et l'édition directe dans la nouvelle page

Paramètre Dossier d'export

  • Ajouter le champ exportFolder dans la table importSettings du schéma
  • Pousser la migration avec pnpm db:push
  • Ajouter le champ dans l'interface ImportSettings.tsx
  • Tester la sauvegarde et récupération du paramètre

Système de gestion des automatismes

  • Créer la table automationRules dans le schéma pour stocker les règles
  • Définir la structure JSON pour les conditions (SI) et actions (ALORS)
  • Pousser la migration avec pnpm db:push
  • Créer les fonctions CRUD dans db.ts pour les règles
  • Créer les routes tRPC pour gérer les règles (list, create, update, delete, reorder)
  • Créer la page AutomationRules.tsx pour l'interface de gestion
  • Ajouter le menu "Automatismes" dans DashboardLayout
  • Implémenter le formulaire de création/édition de règles
  • Implémenter l'affichage de la liste des règles avec ordre de priorité
  • Créer la fonction d'évaluation des règles (applyAutomationRules)
  • Intégrer l'application des règles dans le processus d'import
  • Tester avec des règles réelles