Feature description
Implémenter le service NestJS qui prend la requête utilisateur en entrée, applique les filtres payload si un contexte utilisateur est disponible, exécute la recherche vectorielle dans Qdrant et retourne les top-K cours au service appelant (chatbot service). Ce service s'arrête avant la construction du prompt LLM — il retourne une liste structurée de cours.
Proposed solution
Embedding de la requête. Appel à bge-m3 avec input_type=query. Même worker que le job d'indexation, réutilisé au runtime. Pas de retry à cette couche — si l'embedding échoue, on propage l'erreur.
Construction du filtre payload. Pour sprint 2, programme et cycle sont hardcodés (génie logiciel, cycle 1). Le filtre est construit conditionnellement : si le contexte est absent, la recherche s'exécute sans filtre.
// Sprint 2 : hardcodé
const filter = {
must: [
{ key: "programs", match: { any: ["génie logiciel"] } },
{ key: "cycle", match: { value: 1 } },
]
};
Recherche Qdrant. search() avec top_k=10, score_threshold=0.6, filtre ci-dessus. Si zéro résultat au-dessus du seuil, retourner un tableau vide (le service appelant gère le cas "aucun cours trouvé" — pas ce service).
Valeur de retour. Liste de cours avec code, title, description, score, prerequisite_codes. Pas de mise en forme — c'est le chatbot service qui construit le prompt.
Definition of Done
Feature description
Implémenter le service NestJS qui prend la requête utilisateur en entrée, applique les filtres payload si un contexte utilisateur est disponible, exécute la recherche vectorielle dans Qdrant et retourne les top-K cours au service appelant (chatbot service). Ce service s'arrête avant la construction du prompt LLM — il retourne une liste structurée de cours.
Proposed solution
Embedding de la requête. Appel à bge-m3 avec
input_type=query. Même worker que le job d'indexation, réutilisé au runtime. Pas de retry à cette couche — si l'embedding échoue, on propage l'erreur.Construction du filtre payload. Pour sprint 2, programme et cycle sont hardcodés (
génie logiciel, cycle1). Le filtre est construit conditionnellement : si le contexte est absent, la recherche s'exécute sans filtre.Recherche Qdrant.
search()avectop_k=10,score_threshold=0.6, filtre ci-dessus. Si zéro résultat au-dessus du seuil, retourner un tableau vide (le service appelant gère le cas "aucun cours trouvé" — pas ce service).Valeur de retour. Liste de cours avec
code,title,description,score,prerequisite_codes. Pas de mise en forme — c'est le chatbot service qui construit le prompt.Definition of Done
retrieveCourses(query: string, context?: UserSessionContext): CourseResult[]implémentée et exportée