# Veille Réglementaire Itinova — TODO ## Fonctionnalités principales - [x] Schéma BDD : tables veille_entries, aap_entries, import_logs, app_settings, local_users - [x] Migrations Drizzle poussées avec succès - [x] Module d'import Excel (xlsx) avec déduplication intelligente - [x] Support source locale (fichier local) - [x] Support source OneDrive (Microsoft Graph API) - [x] Support source FTP (basic-ftp) - [x] Support source SharePoint (Microsoft Graph API) - [x] Tâche cron quotidienne à 06h00 pour l'import automatique - [x] Authentification locale (bcrypt + JWT) avec gestion des utilisateurs - [x] API tRPC complète : veille, aap, import, settings, users, auth - [x] Tableau de bord Veille Stratégique (4 onglets : réglementaire, concurrentielle, technologique, générale) - [x] Tableau de bord Appels à Projets (6 onglets : Handicap, PA, Enfance, Précarité, Sanitaire, Autre) - [x] Mode d'affichage Liste / Vignettes avec bouton de basculement - [x] Filtres multi-critères (recherche texte, catégorie, niveau, territoire, région, département, date) - [x] Tri chronologique du plus récent au plus ancien - [x] Page Paramètres (source fichiers, chemins, planification, authentification) - [x] Page Gestion des utilisateurs (création, modification, suppression, activation/désactivation) - [x] Page Logs d'import (statistiques, historique, import manuel) - [x] Layout sidebar avec navigation complète - [x] Page de connexion élégante - [x] Thème visuel Itinova (bleu marine, palette professionnelle) - [x] 13 tests Vitest passants (auth + veille) - [x] Compte admin par défaut créé au démarrage du serveur ## Bugs à corriger - [x] Import Excel affiche 0 nouvelles entrées alors que les fichiers contiennent des données ## Nouvelles fonctionnalités - [x] Backend : endpoint POST /api/upload-excel (multipart) pour recevoir les fichiers Excel - [x] Backend : stocker les fichiers uploadés en S3 et déclencher l'import immédiatement - [x] Frontend : bouton "Importer un fichier" dans la page Logs d'import avec sélecteur veille/AAP - [x] Frontend : zone de dépôt (drag & drop) dans la page Paramètres pour les deux fichiers - [x] Frontend : afficher le résultat de l'import (nouvelles entrées, erreurs) après upload - [x] Page Paramètres : afficher les zones d'upload (drag & drop) quand la source "local" est sélectionnée - [x] Veille : bouton "Détail" sur chaque ligne ouvrant une boîte de dialogue avec toutes les infos complètes - [x] Boîte de dialogue Veille : couleurs douces distinctes pour les vignettes Niveau, Territoire et Source - [x] Vue liste Veille : coloriser les boutons d'action (Détail et Lien externe) - [x] Vignettes AAP : coloriser les étiquettes Région (violet) et Date (orange) - [x] Vignettes Veille : coloriser les étiquettes Niveau (violet), Territoire (teal) et Date (orange) - [x] Page Login : supprimer l'encart affichant les identifiants du compte par défaut - [x] Login : accepter un identifiant (e-mail ou nom d'utilisateur) au lieu d'un e-mail obligatoire - [x] Page Login : logo Itinova en haut, "powered by" + logo Santinova en bas ## Boîte à idées - [x] BDD : table ideas (id, userId, titre, message, statut, réponseAdmin, createdAt, updatedAt) - [x] API tRPC : créer une idée, lister toutes les idées (admin), mes idées (user), répondre (admin) - [x] Page BoiteAIdees : liste avec date, titre, demandeur, texte, statut, réponse admin - [x] Bouton "Nouvelle demande" en haut à droite ouvrant une boîte de dialogue - [x] Menu "Boîte à idées" dans la sidebar accessible à tous les utilisateurs ## Authentification username - [x] BDD : ajouter colonne username (unique, nullable) dans la table users - [x] Backend : loginLocalUser cherche par username OU email - [x] Backend : createLocalUser accepte username optionnel - [x] Frontend : page Gestion utilisateurs affiche et permet de saisir le username - [x] Mettre à jour le compte adminItinova avec username = adminItinova - [x] Migration BDD recette : ajouter colonne username dans local_users et recréer compte adminItinova ## Bugs recette - [x] BUG: Déconnexion lors de l'import Excel sur le VPS — la session expire et redirige vers /login pendant l'upload - [x] BUG: Déconnexion immédiate après sélection du fichier Excel à importer (avant même l'upload) ## Flux RSS - [x] Schéma BDD : tables rss_feeds et rss_settings - [x] Helpers DB pour CRUD flux RSS et paramètres - [x] Procédures tRPC : rss.list, rss.create, rss.update, rss.delete, rss.settings.get, rss.settings.save - [x] Page RssFeeds.tsx : liste des flux, ajout/édition/suppression, config fréquence, règles d'automatisme - [x] Navigation : ajouter l'entrée RSS dans le menu latéral (DashboardLayout) - [x] Déploiement VPS via Gitea CI/CD ## Moteur RSS automatique - [x] Installer le parseur RSS (fast-xml-parser) côté serveur - [x] Ajouter table rss_seen_articles (guid unique pour éviter les doublons) - [x] Ajouter champ last_fetched_at sur rss_feeds - [x] Créer server/rssEngine.ts : parseur RSS + application des règles d'automatisme - [x] Créer endpoint POST /api/scheduled/rss-fetch (auth cookie session) - [x] Configurer la tâche planifiée Manus à 06h00 quotidien - [x] Déployer sur le VPS ## Purge des données - [x] Procédures tRPC : veille.purge et aap.purge (adminProcedure) - [x] Bouton "Purger les données" en haut à droite de VeilleDashboard.tsx (admin uniquement) - [x] Bouton "Purger les données" en haut à droite de AAPDashboard.tsx (admin uniquement) - [x] Boîte de dialogue de confirmation avec message d'avertissement - [x] Déploiement VPS ## Classification IA des articles RSS - [x] Ajouter champs IA dans veille_items : iaRelevant (boolean nullable), iaCategorie, iaClassifiedBy, iaReason - [x] Ajouter champs IA dans aap_items : iaRelevant (boolean nullable), iaCategorie, iaClassifiedBy, iaReason - [x] Migration base de données (pnpm db:push) - [x] Créer server/aiClassifier.ts avec prompt 1 (filtre pertinence) et prompt 2 (classification catégorie) - [x] Intégrer aiClassifier dans rssEngine.ts (remplacer mots-clés par IA, fallback sur règles) - [x] Procédure tRPC veille.reclassifyWithAI (reclassifier les articles existants) - [x] Procédure tRPC aap.reclassifyWithAI - [x] Badge "IA" dans VeilleDashboard.tsx sur les articles classés par IA - [x] Bouton "Reclassifier avec l'IA" dans l'interface admin - [x] Tests vitest pour aiClassifier.ts - [x] Déploiement recette ## Simplification classification IA (automatique + nettoyage UI) - [x] rssEngine.ts : classifier automatiquement chaque article à l'insertion (appel classifyArticle dans processFeed) — déjà en place - [x] VeilleDashboard.tsx : supprimer le badge IA violet dans la colonne Catégorie - [x] VeilleDashboard.tsx : supprimer le bouton "Classer avec l'IA" - [x] Tester visuellement en sandbox - [x] Déployer en recette ## Mise à jour AAPDashboard — Classification IA - [x] Vérifier que aap.list retourne bien les champs IA (iaRelevant, iaCategorie, iaClassifiedBy, iaReason) - [x] Ajouter les champs IA dans le type AapItem de AAPDashboard.tsx - [x] Afficher la catégorie IA dans la colonne Catégorie d'AAPDashboard (même logique que VeilleDashboard) - [x] Vérifier que rssEngine.ts classe bien les AAP via l'IA à l'insertion - [x] Tester visuellement en sandbox - [x] Déployer en recette ## Résumé IA automatique + Marquage Lu/Non lu - [x] Schéma BDD : ajouter iaResume (text) dans veille_items et aap_items - [x] Schéma BDD : créer table article_reads (id, userId, articleType, articleId, readAt) - [x] Migration pnpm db:push - [x] aiClassifier.ts : ajouter generateSummary() — résumé 3-5 lignes en français adapté au secteur médico-social - [x] rssEngine.ts : appeler generateSummary() après classifyArticle() pour chaque article pertinent - [x] Procédures tRPC : veille.markAsRead, veille.unreadCount - [x] Procédures tRPC : aap.markAsRead, aap.unreadCount - [x] VeilleDashboard : afficher iaResume dans la boîte de dialogue détail (à la place du résumé brut si disponible) - [x] VeilleDashboard : point bleu sur les articles non lus, clic sur article = markAsRead automatique - [x] AAPDashboard : même logique lu/non lu - [x] Sidebar DashboardLayout : compteur non lus sur les entrées Veille et AAP - [x] Tests visuels en sandbox - [x] Checkpoint ## Corrections urgentes — Classification IA + Déploiement recette - [x] Corriger le prompt de pertinence dans aiClassifier.ts (articles hors périmètre passent le filtre) - [x] Tester en sandbox que les articles hors périmètre (pêche, sport, économie générale) sont bien rejetés - [x] Finaliser le déploiement recette : copier les fichiers frontend (marqueur lu/non lu) dans le conteneur - [x] Vérifier visuellement en recette que le marqueur lu/non lu et les compteurs s'affichent ## Simplification : suppression catégorie médico-sociale dans Veille Stratégique - [x] aiClassifier.ts : fusionner les deux prompts en un seul (pertinence + type de veille en une étape) - [x] aiClassifier.ts : le résultat retourne uniquement typeVeille (reglementaire/concurrentielle/technologique/informationnelle) ou null si hors périmètre - [x] rssEngine.ts : mettre à jour l'appel à classifyArticle pour utiliser le nouveau retour simplifié - [x] VeilleDashboard.tsx : supprimer la colonne Catégorie de la vue liste - [x] VeilleDashboard.tsx : supprimer tout filtre ou affichage lié à iaCategorie - [x] Tester visuellement en sandbox - [x] Checkpoint ## Amélioration prompt IA — 5 secteurs d'activité - [x] aiClassifier.ts : remplacer le prompt de pertinence générique ESMS par une définition explicite des 5 secteurs (handicap, précarité/logement, protection de l'enfance, personnes âgées, sanitaire SMR) - [x] 0 erreur TypeScript, 21 tests passés - [x] Checkpoint ## Récupération du 1er paragraphe pour la classification IA - [x] Créer server/articleFetcher.ts : fetch HTTP avec timeout 5s, extraction des 500 premiers mots du contenu textuel (balises p, h1-h3), fallback silencieux si erreur - [x] Intégrer articleFetcher dans rssEngine.ts : enrichir le contenu envoyé à classifyArticle avec le 1er paragraphe récupéré - [x] Mettre à jour la signature de classifyArticle pour accepter un paramètre optionnel contenuPage - [x] 0 erreur TypeScript, tests passés - [x] Checkpoint ## Filtre de pertinence strict à l'insertion + mise à jour prompt IA - [x] aiClassifier.ts : mettre à jour le prompt avec la formulation exacte fournie (expert ESMS, 5 secteurs, liste noire, "doute = false") - [x] rssEngine.ts : ajouter filtre `if (!aiResult.relevant) { skip; continue; }` avant insertion veille_items - [x] rssEngine.ts : même filtre avant insertion aap_items - [x] 21 tests passés, 0 erreur TypeScript - [x] Déployer en recette - [x] Déployer en production (en attente validation recette — intentionnel) - [x] Mode vignette par défaut - [x] Alternance de couleurs en mode liste (pair=blanc, impair=gris clair) - [x] Couleur de sélection au clic sur une ligne (bg-primary/10) - [x] Filtre Lu/Non lu avec bouton segmenté (Non lu par défaut) - [x] Message vide adapté selon le filtre actif ## Paramétrage fréquence des mises à jour - [x] BDD : fetch_mode et fetch_interval_minutes stockés comme clés/valeurs dans app_settings (pas de migration nécessaire) - [x] Backend index.ts : lire fetch_mode et fetch_interval_minutes pour construire l'expression cron - [x] Backend routers.ts : exposer et sauvegarder ces deux nouveaux paramètres - [x] Frontend Settings.tsx : sélecteur mode (heure fixe / intervalle) + sélecteur intervalle (1h, 2h, 4h, 6h, 12h, 24h) - [x] Déployer en recette ## Évolutions planification et rétention - [x] Afficher la prochaine date d'exécution dynamique dans les Paramètres (selon mode/heure/jour choisi) - [x] Ajouter la règle de rétention configurable dans les Paramètres (supprimer articles > N mois) - [x] Implémenter la purge automatique au démarrage du serveur selon la règle de rétention - [x] Déployer en recette - [x] Répliquer BDD recette vers production et déployer le code en production ## Audit de robustesse et nettoyage technique - [x] Remplacer les captures d’erreur silencieuses sur le marquage lu par une gestion explicite des doublons et des erreurs SQL. - [x] Centraliser le comportement du marquage lu pour les flux Veille et AAP afin d’éviter les divergences fonctionnelles. - [x] Ajouter des commentaires techniques sur les invariants métier sensibles (lectures, classification IA et déduplication RSS). - [x] Ajouter des tests unitaires couvrant la persistance et la restitution des articles lus. - [x] Supprimer les composants non référencés et les artefacts de développement du dépôt applicatif. - [x] Vérifier TypeScript, Vitest et le build de production après refactoring. ## Déploiement recette et supervision de classification - [x] Empêcher le workflow de production de s’exécuter depuis le Gitea et le runner de recette. - [x] Déployer le refactoring et appliquer la migration d’unicité des lectures en recette. - [ ] Tester en recette la persistance des articles lus après déconnexion et reconnexion. - [x] Ajouter un rapport administrateur des erreurs de classification RSS avec date, flux, article et cause. - [ ] Corriger le découpage frontend qui empêchait React de s’afficher après le build de recette.