chore: Add autonomous agent infrastructure and cleanup old files
- Disable CLAUDE.md confirmation rules for autonomous agent operation - Add utility scripts: check_linear_status.py, check_meta_issue.py, move_issues_to_todo.py - Add works filter specification: prompts/app_spec_works_filter.txt - Update .linear_project.json with works filter issues - Remove old/stale scripts and documentation files - Update search.html template This commit completes the infrastructure for the autonomous agent that successfully implemented all 13 works filter issues (LRP-136 to LRP-148). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
650
prompts/app_spec_works_filter.txt
Normal file
650
prompts/app_spec_works_filter.txt
Normal file
@@ -0,0 +1,650 @@
|
||||
<project_specification>
|
||||
<project_name>Library RAG - Filtrage par œuvres dans la conversation</project_name>
|
||||
|
||||
<overview>
|
||||
Système de filtrage par œuvres pour la page de conversation RAG, permettant aux utilisateurs de sélectionner les œuvres sur lesquelles effectuer la recherche sémantique.
|
||||
|
||||
**Objectif :**
|
||||
Ajouter une section "Filtrer par œuvres" dans la sidebar droite (au-dessus du "Contexte RAG") avec des cases à cocher pour chaque œuvre disponible. Chaque message de la conversation recherchera uniquement dans les œuvres sélectionnées.
|
||||
|
||||
**Architecture :**
|
||||
- Backend : Nouvelle route API + modification de la recherche Weaviate avec filtres
|
||||
- Frontend : Nouvelle section UI avec checkboxes + JavaScript pour état et persistance
|
||||
- Persistance : localStorage pour sauvegarder la sélection entre les sessions
|
||||
|
||||
**Comportement par défaut :**
|
||||
- Toutes les œuvres cochées au démarrage
|
||||
- Section collapsible avec chevron
|
||||
- Boutons "Tout" / "Aucun" pour sélection rapide
|
||||
- Badge compteur : "X/Y sélectionnées"
|
||||
- Responsive mobile : section pliable au-dessus de l'input
|
||||
|
||||
**Contraintes :**
|
||||
- Ne pas modifier l'export Word/PDF existant
|
||||
- Conserver la structure grid 60%/40% (conversation/sidebar)
|
||||
- Compatibilité avec les 3 modes de recherche (simple, hiérarchique, summary)
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<backend>
|
||||
<framework>Flask 3.0+</framework>
|
||||
<database>Weaviate 1.34.4 + text2vec-transformers (BGE-M3)</database>
|
||||
<python>Python 3.10+</python>
|
||||
</backend>
|
||||
<frontend>
|
||||
<template_engine>Jinja2</template_engine>
|
||||
<javascript>Vanilla JavaScript (ES6+)</javascript>
|
||||
<css>Custom CSS (variables CSS existantes)</css>
|
||||
<storage>localStorage (Web Storage API)</storage>
|
||||
</frontend>
|
||||
</technology_stack>
|
||||
|
||||
<implementation_steps>
|
||||
<feature_1>
|
||||
<title>Backend - Route API /api/get-works</title>
|
||||
<description>
|
||||
Créer une route GET qui retourne la liste de toutes les œuvres disponibles avec métadonnées.
|
||||
|
||||
Tasks:
|
||||
- Ajouter route @app.route("/api/get-works") dans flask_app.py (après ligne ~1380)
|
||||
- Utiliser get_weaviate_client() context manager
|
||||
- Query collection "Chunk" pour extraire toutes les œuvres uniques
|
||||
- Parser propriété nested "work" (work.title, work.author)
|
||||
- Compter les chunks par œuvre (chunks_count)
|
||||
- Retourner JSON trié par auteur puis titre
|
||||
- Gérer les erreurs de connexion Weaviate
|
||||
- Ajouter logging pour debug
|
||||
|
||||
Format de sortie JSON :
|
||||
[
|
||||
{
|
||||
"title": "Ménon",
|
||||
"author": "Platon",
|
||||
"chunks_count": 127
|
||||
},
|
||||
...
|
||||
]
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Démarrer Weaviate : docker compose up -d
|
||||
2. Démarrer Flask : python flask_app.py
|
||||
3. Tester route : curl http://localhost:5000/api/get-works
|
||||
4. Vérifier JSON retourné contient toutes les œuvres
|
||||
5. Vérifier tri alphabétique par auteur
|
||||
6. Vérifier chunks_count > 0 pour chaque œuvre
|
||||
7. Tester avec Weaviate arrêté : vérifier erreur 500 propre
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<title>Backend - Modification route /chat/send</title>
|
||||
<description>
|
||||
Modifier la route POST /chat/send pour accepter le paramètre selected_works et le passer à la fonction de recherche.
|
||||
|
||||
Tasks:
|
||||
- Localiser route @app.route("/chat/send", methods=["POST"]) (ligne ~1756)
|
||||
- Ajouter extraction paramètre selected_works du JSON body
|
||||
- Type : List[str] (liste des titres d'œuvres)
|
||||
- Valeur par défaut : [] (liste vide = toutes les œuvres)
|
||||
- Valider que selected_works est bien une liste
|
||||
- Passer selected_works à la fonction de recherche sémantique
|
||||
- Logger les œuvres sélectionnées pour debug
|
||||
- Gérer cas où selected_works = [] (pas de filtre)
|
||||
|
||||
Exemple JSON input :
|
||||
{
|
||||
"question": "Qu'est-ce que la justice ?",
|
||||
"provider": "openai",
|
||||
"model": "gpt-4o",
|
||||
"limit": 5,
|
||||
"selected_works": ["Ménon", "La pensée-signe"]
|
||||
}
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Modifier /chat/send pour accepter selected_works
|
||||
2. Tester POST avec selected_works vide : curl -X POST -H "Content-Type: application/json" -d '{"question":"test","provider":"openai","model":"gpt-4o","selected_works":[]}' http://localhost:5000/chat/send
|
||||
3. Vérifier que la recherche fonctionne sans filtre
|
||||
4. Tester POST avec selected_works = ["Ménon"]
|
||||
5. Vérifier que le paramètre est bien reçu (ajouter print/log temporaire)
|
||||
6. Tester POST avec selected_works invalide (pas une liste)
|
||||
7. Vérifier gestion d'erreur propre
|
||||
</test_steps>
|
||||
</feature_2>
|
||||
|
||||
<feature_3>
|
||||
<title>Backend - Filtre Weaviate par œuvres</title>
|
||||
<description>
|
||||
Implémenter la logique de filtrage Weaviate pour rechercher uniquement dans les œuvres sélectionnées.
|
||||
|
||||
Tasks:
|
||||
- Localiser la fonction de recherche sémantique dans /chat/send
|
||||
- Identifier les requêtes Weaviate (near_text sur Chunk et Summary)
|
||||
- Ajouter paramètre selected_works à ces fonctions
|
||||
- Construire filtre Weaviate si selected_works non vide :
|
||||
- Pour Chunk : Filter.by_property("work").by_property("title").contains_any(selected_works)
|
||||
- Pour Summary : Idem si Summary a work nested
|
||||
- Appliquer filtre dans :
|
||||
- Recherche simple (Chunk.query.near_text)
|
||||
- Recherche hiérarchique (Summary → Chunk)
|
||||
- Recherche summary uniquement
|
||||
- Tester syntaxe filtre Weaviate v4 (contains_any sur nested property)
|
||||
- Gérer cas où aucun résultat trouvé avec filtre
|
||||
- Logger requêtes Weaviate pour debug
|
||||
|
||||
Note critique : Weaviate v4 syntax pour nested properties
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Identifier fonction de recherche actuelle dans flask_app.py
|
||||
2. Ajouter filtre Weaviate pour selected_works
|
||||
3. Tester recherche sans filtre (selected_works=[])
|
||||
4. Vérifier résultats de toutes les œuvres
|
||||
5. Tester recherche avec filtre (selected_works=["Ménon"])
|
||||
6. Vérifier que SEULS les chunks de Ménon sont retournés
|
||||
7. Tester avec œuvre inexistante : vérifier 0 résultats
|
||||
8. Tester mode hiérarchique avec filtre
|
||||
9. Vérifier que Summary ET Chunk sont filtrés
|
||||
</test_steps>
|
||||
</feature_3>
|
||||
|
||||
<feature_4>
|
||||
<title>Frontend - HTML section filtrage œuvres</title>
|
||||
<description>
|
||||
Créer la section HTML "Filtrer par œuvres" dans la sidebar droite, au-dessus du "Contexte RAG".
|
||||
|
||||
Tasks:
|
||||
- Ouvrir templates/chat.html
|
||||
- Localiser ligne ~710 (début de .context-sidebar)
|
||||
- AVANT la div .context-sidebar, ajouter nouvelle div .works-filter-section
|
||||
- Structure HTML :
|
||||
- Header avec titre + badge compteur + bouton collapse
|
||||
- Content avec boutons "Tout"/"Aucun"
|
||||
- Div .works-list (remplie dynamiquement par JS)
|
||||
- IDs pour JavaScript :
|
||||
- works-filter-section
|
||||
- works-filter-content
|
||||
- works-collapse-btn
|
||||
- works-count-badge
|
||||
- works-list
|
||||
- select-all-works
|
||||
- select-none-works
|
||||
- Classe sidebar-empty pour état de chargement
|
||||
- Respecter structure HTML existante (sidebar-header, sidebar-content)
|
||||
|
||||
Note : Ne pas modifier la div .context-sidebar existante
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir http://localhost:5000/chat dans le navigateur
|
||||
2. Vérifier que nouvelle section apparaît AU-DESSUS du Contexte RAG
|
||||
3. Vérifier header avec titre "📚 Filtrer par œuvres"
|
||||
4. Vérifier badge compteur visible
|
||||
5. Vérifier bouton collapse (chevron ▼)
|
||||
6. Vérifier boutons "Tout" et "Aucun" présents
|
||||
7. Vérifier div .works-list vide au démarrage
|
||||
8. Vérifier que la section Contexte RAG est toujours visible en-dessous
|
||||
</test_steps>
|
||||
</feature_4>
|
||||
|
||||
<feature_5>
|
||||
<title>Frontend - CSS pour section filtrage</title>
|
||||
<description>
|
||||
Ajouter les styles CSS pour la section de filtrage par œuvres, cohérents avec le design existant.
|
||||
|
||||
Tasks:
|
||||
- Dans templates/chat.html, section <style> (ligne ~6)
|
||||
- Ajouter styles pour :
|
||||
- .works-filter-section (structure générale)
|
||||
- .works-filter-content (max-height 250px, scroll)
|
||||
- .works-count-badge (badge compteur)
|
||||
- .works-filter-actions (boutons Tout/Aucun)
|
||||
- .btn-mini (style boutons)
|
||||
- .works-list (liste des œuvres)
|
||||
- .work-item (chaque œuvre)
|
||||
- .work-checkbox (case à cocher)
|
||||
- .work-info (titre + auteur)
|
||||
- .work-title, .work-author (typographie)
|
||||
- .work-count (badge nombre de passages)
|
||||
- Utiliser variables CSS existantes :
|
||||
- --color-accent, --color-accent-alt
|
||||
- --color-text-main, --color-text-strong
|
||||
- --font-body, --font-title
|
||||
- Ajouter hover effects
|
||||
- Responsive : @media (max-width: 992px) pour mobile
|
||||
- Cohérence avec .context-sidebar existante
|
||||
|
||||
Note : Réutiliser les styles de .context-chunk pour cohérence
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Recharger page /chat
|
||||
2. Vérifier styles appliqués sur section filtrage
|
||||
3. Vérifier bordures, border-radius cohérents
|
||||
4. Vérifier couleurs cohérentes avec palette existante
|
||||
5. Tester hover sur boutons "Tout"/"Aucun"
|
||||
6. Tester hover sur work-item
|
||||
7. Vérifier scrollbar sur .works-list si >250px
|
||||
8. Tester responsive : réduire fenêtre < 992px
|
||||
9. Vérifier que section est collapsible sur mobile
|
||||
</test_steps>
|
||||
</feature_5>
|
||||
|
||||
<feature_6>
|
||||
<title>Frontend - JavaScript état et rendu</title>
|
||||
<description>
|
||||
Implémenter la logique JavaScript pour gérer l'état des œuvres sélectionnées et le rendu de la liste.
|
||||
|
||||
Tasks:
|
||||
- Dans templates/chat.html, section <script> (après ligne ~732)
|
||||
- Déclarer variables globales :
|
||||
- availableWorks: Array<Work> (liste complète)
|
||||
- selectedWorks: Array<string> (titres sélectionnés)
|
||||
- Créer fonction loadAvailableWorks() :
|
||||
- Fetch GET /api/get-works
|
||||
- Stocker dans availableWorks
|
||||
- Initialiser selectedWorks (tous par défaut ou localStorage)
|
||||
- Appeler renderWorksList()
|
||||
- Créer fonction renderWorksList() :
|
||||
- Vider works-list
|
||||
- Pour chaque work, créer HTML :
|
||||
- Checkbox (checked si dans selectedWorks)
|
||||
- work-info (titre + auteur)
|
||||
- work-count (nombre passages)
|
||||
- Ajouter event listeners sur checkboxes
|
||||
- Click sur work-item toggle checkbox
|
||||
- Créer fonction toggleWorkSelection(title, isSelected)
|
||||
- Créer fonction updateWorksCount()
|
||||
- Appeler loadAvailableWorks() au chargement de la page
|
||||
|
||||
Note : Utiliser addEventListener, pas d'inline onclick
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir console navigateur (F12)
|
||||
2. Recharger page /chat
|
||||
3. Vérifier que fetch /api/get-works est appelé (Network tab)
|
||||
4. Vérifier que availableWorks contient les œuvres (console.log)
|
||||
5. Vérifier que .works-list contient des work-item
|
||||
6. Cocher/décocher une œuvre
|
||||
7. Vérifier que selectedWorks est mis à jour (console.log)
|
||||
8. Vérifier que badge compteur est mis à jour
|
||||
9. Cliquer sur work-item (pas la checkbox)
|
||||
10. Vérifier que checkbox est togglee
|
||||
</test_steps>
|
||||
</feature_6>
|
||||
|
||||
<feature_7>
|
||||
<title>Frontend - JavaScript persistance localStorage</title>
|
||||
<description>
|
||||
Implémenter la sauvegarde automatique de la sélection dans localStorage pour persister entre les sessions.
|
||||
|
||||
Tasks:
|
||||
- Créer fonction saveSelectedWorksToStorage() :
|
||||
- localStorage.setItem('selectedWorks', JSON.stringify(selectedWorks))
|
||||
- Appeler saveSelectedWorksToStorage() après chaque modification :
|
||||
- Dans toggleWorkSelection()
|
||||
- Dans selectAllWorksBtn click
|
||||
- Dans selectNoneWorksBtn click
|
||||
- Modifier loadAvailableWorks() :
|
||||
- Charger localStorage.getItem('selectedWorks')
|
||||
- Parser JSON si existe
|
||||
- Sinon, sélectionner toutes les œuvres par défaut
|
||||
- Gérer cas où œuvres ont changé :
|
||||
- Filtrer selectedWorks pour ne garder que celles qui existent
|
||||
- Mettre à jour localStorage
|
||||
- Ajouter fonction clearWorksStorage() pour debug (optionnel)
|
||||
|
||||
Note : Vérifier que localStorage est disponible (try-catch)
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir /chat et sélectionner 2 œuvres uniquement
|
||||
2. Vérifier dans DevTools → Application → Local Storage
|
||||
3. Vérifier clé 'selectedWorks' contient JSON des 2 œuvres
|
||||
4. Rafraîchir la page (F5)
|
||||
5. Vérifier que les 2 œuvres sont toujours cochées
|
||||
6. Cliquer "Tout" puis rafraîchir
|
||||
7. Vérifier que toutes les œuvres sont cochées
|
||||
8. Cliquer "Aucun" puis rafraîchir
|
||||
9. Vérifier qu'aucune œuvre n'est cochée
|
||||
10. Tester en navigation privée (pas de localStorage)
|
||||
</test_steps>
|
||||
</feature_7>
|
||||
|
||||
<feature_8>
|
||||
<title>Frontend - JavaScript intégration recherche</title>
|
||||
<description>
|
||||
Modifier la fonction startRAGSearch() pour envoyer les œuvres sélectionnées au backend lors de la recherche.
|
||||
|
||||
Tasks:
|
||||
- Localiser fonction startRAGSearch(question, provider, model) (ligne ~943)
|
||||
- Modifier le fetch POST /chat/send :
|
||||
- Ajouter clé "selected_works" au JSON body
|
||||
- Valeur : selectedWorks (array global)
|
||||
- Ajouter validation avant envoi :
|
||||
- Si selectedWorks.length === 0, afficher warning ?
|
||||
- Ou laisser passer (recherche sur toutes)
|
||||
- Tester que le filtre fonctionne :
|
||||
- Contexte RAG affiché ne contient QUE les œuvres sélectionnées
|
||||
- Réponse LLM basée uniquement sur ces œuvres
|
||||
- Ajouter logging console.log pour debug
|
||||
- Gérer erreur si aucun résultat trouvé avec filtre
|
||||
|
||||
Note : Pas besoin de modifier displayContext() si backend filtre correctement
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir /chat
|
||||
2. Sélectionner uniquement œuvre "Ménon"
|
||||
3. Poser question : "Qu'est-ce que la vertu ?"
|
||||
4. Vérifier dans Network tab : POST /chat/send contient selected_works: ["Ménon"]
|
||||
5. Vérifier que contexte RAG ne contient QUE des chunks de Ménon
|
||||
6. Vérifier que réponse LLM mentionne Ménon (pas d'autres œuvres)
|
||||
7. Sélectionner 2 œuvres : "Ménon" + "La pensée-signe"
|
||||
8. Poser nouvelle question
|
||||
9. Vérifier contexte contient ces 2 œuvres uniquement
|
||||
10. Désélectionner toutes les œuvres et tester
|
||||
</test_steps>
|
||||
</feature_8>
|
||||
|
||||
<feature_9>
|
||||
<title>Frontend - Boutons actions et collapse</title>
|
||||
<description>
|
||||
Implémenter les boutons "Tout" / "Aucun" et le comportement de collapse de la section.
|
||||
|
||||
Tasks:
|
||||
- Event listener selectAllWorksBtn :
|
||||
- selectedWorks = availableWorks.map(w => w.title)
|
||||
- Appeler renderWorksList()
|
||||
- Appeler updateWorksCount()
|
||||
- Appeler saveSelectedWorksToStorage()
|
||||
- Event listener selectNoneWorksBtn :
|
||||
- selectedWorks = []
|
||||
- Appeler renderWorksList()
|
||||
- Appeler updateWorksCount()
|
||||
- Appeler saveSelectedWorksToStorage()
|
||||
- Event listener worksCollapseBtn :
|
||||
- Toggle display de works-filter-content
|
||||
- Changer texte chevron (▼ / ▲)
|
||||
- Changer title tooltip ("Réduire" / "Développer")
|
||||
- Optionnel : sauvegarder état collapse dans localStorage
|
||||
- Ajouter transition CSS pour collapse smooth
|
||||
|
||||
Note : Réutiliser logique existante de collapseBtn du Contexte RAG
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir /chat
|
||||
2. Cliquer bouton "Tout"
|
||||
3. Vérifier que toutes les œuvres sont cochées
|
||||
4. Vérifier badge compteur : "X/X sélectionnées"
|
||||
5. Cliquer bouton "Aucun"
|
||||
6. Vérifier qu'aucune œuvre n'est cochée
|
||||
7. Vérifier badge compteur : "0/X sélectionnées"
|
||||
8. Cliquer chevron collapse
|
||||
9. Vérifier que .works-filter-content disparaît
|
||||
10. Vérifier chevron change (▼ → ▲)
|
||||
11. Recliquer chevron : section réapparaît
|
||||
</test_steps>
|
||||
</feature_9>
|
||||
|
||||
<feature_10>
|
||||
<title>Frontend - Responsive mobile</title>
|
||||
<description>
|
||||
Adapter l'interface de filtrage pour les écrans mobiles (< 992px).
|
||||
|
||||
Tasks:
|
||||
- Ajouter @media (max-width: 992px) dans CSS
|
||||
- Sur mobile :
|
||||
- .works-filter-section : order: -2 (avant contexte RAG)
|
||||
- max-height: 200px
|
||||
- .works-filter-content : max-height: 150px
|
||||
- Section collapsée par défaut
|
||||
- Badge compteur plus visible
|
||||
- Tester sur petits écrans :
|
||||
- iPhone (375px)
|
||||
- iPad (768px)
|
||||
- Desktop réduit (900px)
|
||||
- Vérifier que section ne prend pas trop de place
|
||||
- Vérifier scroll horizontal n'apparaît pas
|
||||
- Vérifier touch events fonctionnent (pas que click)
|
||||
|
||||
Note : La structure grid actuelle passe déjà en 1 colonne sur mobile
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir DevTools → Toggle device toolbar (Ctrl+Shift+M)
|
||||
2. Sélectionner iPhone 12 Pro (390x844)
|
||||
3. Vérifier que section filtrage apparaît
|
||||
4. Vérifier hauteur limitée à 200px
|
||||
5. Vérifier scroll fonctionne si liste longue
|
||||
6. Tester checkbox touch/click
|
||||
7. Tester boutons "Tout"/"Aucun"
|
||||
8. Tester collapse fonctionne
|
||||
9. Passer en iPad (768px)
|
||||
10. Vérifier layout correct
|
||||
11. Revenir desktop (>992px) : vérifier layout normal
|
||||
</test_steps>
|
||||
</feature_10>
|
||||
|
||||
<feature_11>
|
||||
<title>Testing - Tests backend routes</title>
|
||||
<description>
|
||||
Créer tests unitaires pour les nouvelles routes backend et la logique de filtrage.
|
||||
|
||||
Tasks:
|
||||
- Créer tests/test_works_filter.py
|
||||
- Tester route /api/get-works :
|
||||
- Mock get_weaviate_client()
|
||||
- Mock collection Chunk avec données test
|
||||
- Vérifier JSON retourné correct
|
||||
- Vérifier tri par auteur
|
||||
- Vérifier chunks_count calculé
|
||||
- Tester erreur Weaviate
|
||||
- Tester /chat/send avec selected_works :
|
||||
- Mock fonction de recherche
|
||||
- Vérifier paramètre passé correctement
|
||||
- Tester avec selected_works vide
|
||||
- Tester avec selected_works = ["Ménon"]
|
||||
- Tester logique filtre Weaviate :
|
||||
- Mock Weaviate query
|
||||
- Vérifier filtre contains_any appliqué
|
||||
- Vérifier résultats filtrés
|
||||
- Utiliser pytest et pytest-mock
|
||||
- Vérifier couverture >80%
|
||||
|
||||
Note : Ne pas faire d'appels API réels en tests
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>testing</category>
|
||||
<test_steps>
|
||||
1. Installer pytest : pip install pytest pytest-mock
|
||||
2. Créer tests/test_works_filter.py
|
||||
3. Exécuter : pytest tests/test_works_filter.py -v
|
||||
4. Vérifier tous les tests passent
|
||||
5. Exécuter avec coverage : pytest --cov=flask_app tests/test_works_filter.py
|
||||
6. Vérifier couverture >80% pour routes concernées
|
||||
7. Tester avec Weaviate mock : aucun appel réseau réel
|
||||
8. Vérifier temps d'exécution <5s
|
||||
</test_steps>
|
||||
</feature_11>
|
||||
|
||||
<feature_12>
|
||||
<title>Testing - Tests frontend JavaScript</title>
|
||||
<description>
|
||||
Tests manuels de la logique JavaScript dans le navigateur.
|
||||
|
||||
Tasks:
|
||||
- Tester loadAvailableWorks() :
|
||||
- Console : vérifier availableWorks peuplé
|
||||
- Vérifier selectedWorks initialisé
|
||||
- Tester renderWorksList() :
|
||||
- Vérifier work-items créés dynamiquement
|
||||
- Vérifier checkboxes cochées selon selectedWorks
|
||||
- Tester toggleWorkSelection() :
|
||||
- Cocher/décocher plusieurs œuvres
|
||||
- Vérifier selectedWorks mis à jour
|
||||
- Vérifier badge compteur synchronisé
|
||||
- Tester localStorage :
|
||||
- Modifier sélection
|
||||
- Rafraîchir page
|
||||
- Vérifier persistance
|
||||
- Tester intégration recherche :
|
||||
- Sélectionner œuvre
|
||||
- Envoyer question
|
||||
- Vérifier filtre appliqué
|
||||
- Tester boutons Tout/Aucun
|
||||
- Tester collapse
|
||||
- Tester responsive
|
||||
|
||||
Note : Tests manuels car pas de framework test JS configuré
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>testing</category>
|
||||
<test_steps>
|
||||
1. Ouvrir /chat avec DevTools (F12)
|
||||
2. Console : taper availableWorks puis Enter
|
||||
3. Vérifier array d'œuvres affiché
|
||||
4. Console : taper selectedWorks puis Enter
|
||||
5. Vérifier array de titres sélectionnés
|
||||
6. Cocher/décocher œuvre
|
||||
7. Retaper selectedWorks : vérifier mise à jour
|
||||
8. Application tab → Local Storage → selectedWorks
|
||||
9. Vérifier JSON synchronisé
|
||||
10. Envoyer question test
|
||||
11. Network tab → POST /chat/send → Preview
|
||||
12. Vérifier selected_works dans payload
|
||||
</test_steps>
|
||||
</feature_12>
|
||||
|
||||
<feature_13>
|
||||
<title>Documentation - Guide utilisateur</title>
|
||||
<description>
|
||||
Documenter la nouvelle fonctionnalité de filtrage par œuvres.
|
||||
|
||||
Tasks:
|
||||
- Mettre à jour README.md ou créer WORKS_FILTER.md
|
||||
- Documenter :
|
||||
- Fonctionnalité de filtrage
|
||||
- Comportement par défaut (toutes cochées)
|
||||
- Boutons "Tout" / "Aucun"
|
||||
- Persistance localStorage
|
||||
- Impact sur la recherche sémantique
|
||||
- Cas d'usage recommandés
|
||||
- Ajouter captures d'écran (optionnel)
|
||||
- Documenter API /api/get-works
|
||||
- Documenter modification /chat/send
|
||||
- Ajouter troubleshooting :
|
||||
- Que faire si aucune œuvre affichée ?
|
||||
- Que faire si filtre ne fonctionne pas ?
|
||||
- Comment réinitialiser la sélection ?
|
||||
|
||||
Note : Documentation utilisateur, pas technique
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>documentation</category>
|
||||
<test_steps>
|
||||
1. Lire README.md ou WORKS_FILTER.md
|
||||
2. Vérifier clarté des explications
|
||||
3. Vérifier exemples concrets fournis
|
||||
4. Tester instructions étape par étape
|
||||
5. Vérifier troubleshooting couvre cas courants
|
||||
6. Vérifier API documentée (endpoints, params, retour)
|
||||
7. Relire pour fautes orthographe/grammaire
|
||||
</test_steps>
|
||||
</feature_13>
|
||||
</implementation_steps>
|
||||
|
||||
<testing_strategy>
|
||||
<backend_tests>
|
||||
<structure>
|
||||
tests/
|
||||
└── test_works_filter.py
|
||||
</structure>
|
||||
|
||||
<coverage>
|
||||
- Route /api/get-works (mock Weaviate)
|
||||
- Route /chat/send avec selected_works (mock recherche)
|
||||
- Logique filtre Weaviate (mock query)
|
||||
- Cas limites (liste vide, œuvre inexistante)
|
||||
</coverage>
|
||||
</backend_tests>
|
||||
|
||||
<frontend_tests>
|
||||
<manual_testing>
|
||||
- Tests manuels dans navigateur (Chrome, Firefox)
|
||||
- Tests console JavaScript
|
||||
- Tests localStorage DevTools
|
||||
- Tests Network DevTools
|
||||
- Tests responsive (DevTools device mode)
|
||||
</manual_testing>
|
||||
|
||||
<no_automated_js_tests>
|
||||
Pas de framework de test JS (Jest, Mocha) configuré.
|
||||
Tests manuels suffisants pour cette feature.
|
||||
</no_automated_js_tests>
|
||||
</frontend_tests>
|
||||
</testing_strategy>
|
||||
|
||||
<success_criteria>
|
||||
<functional>
|
||||
- Route /api/get-works retourne toutes les œuvres avec métadonnées
|
||||
- Section "Filtrer par œuvres" visible dans sidebar droite
|
||||
- Checkboxes fonctionnelles pour chaque œuvre
|
||||
- Sélection persiste entre les sessions (localStorage)
|
||||
- Recherche filtrée uniquement sur œuvres sélectionnées
|
||||
- Contexte RAG ne contient QUE les œuvres sélectionnées
|
||||
- Boutons "Tout" / "Aucun" fonctionnels
|
||||
- Section collapsible avec chevron
|
||||
- Badge compteur synchronisé
|
||||
- Responsive mobile fonctionnel
|
||||
</functional>
|
||||
|
||||
<quality>
|
||||
- Code backend suit conventions Flask existantes
|
||||
- Code frontend suit conventions JavaScript existantes
|
||||
- CSS cohérent avec design existant (variables CSS)
|
||||
- Pas de console errors JavaScript
|
||||
- Pas d'erreurs 500 backend
|
||||
- Tests backend passent (>80% coverage)
|
||||
</quality>
|
||||
|
||||
<performance>
|
||||
- /api/get-works répond en <500ms
|
||||
- Rendu liste œuvres <100ms
|
||||
- Pas de lag lors du check/uncheck
|
||||
- localStorage lecture/écriture instantanée
|
||||
</performance>
|
||||
|
||||
<ux>
|
||||
- Comportement par défaut intuitif (toutes cochées)
|
||||
- Feedback visuel immédiat sur sélection
|
||||
- Badge compteur toujours à jour
|
||||
- Pas de confusion avec section Contexte RAG
|
||||
- Mobile : section accessible et utilisable
|
||||
</ux>
|
||||
</success_criteria>
|
||||
|
||||
<deployment>
|
||||
<no_deployment>
|
||||
Modification de l'application Flask existante.
|
||||
Pas de déploiement séparé nécessaire.
|
||||
|
||||
Redémarrage Flask après modifications :
|
||||
- Ctrl+C pour arrêter
|
||||
- python flask_app.py pour redémarrer
|
||||
</no_deployment>
|
||||
</deployment>
|
||||
</project_specification>
|
||||
Reference in New Issue
Block a user