Checkpoint: Ajout de server/articleFetcher.ts (fetch HTTP + extraction 500 mots, timeout 5s, fallback silencieux). Intégration dans rssEngine.ts : si le résumé RSS est court (<150 car.), le 1er paragraphe de l'article est récupéré et transmis à classifyArticle. Signature de classifyArticle mise à jour avec paramètre contenuPage optionnel. 0 erreur TypeScript, 21 tests passés.

This commit is contained in:
Manus
2026-06-19 09:27:59 -04:00
parent 165599bc83
commit dde3d8b6b8
5 changed files with 130 additions and 10 deletions

View File

@@ -23,6 +23,7 @@ import {
} from "../drizzle/schema";
import { eq, sql } from "drizzle-orm";
import { classifyArticle, generateSummary } from "./aiClassifier";
import { fetchArticleFirstParagraph } from "./articleFetcher";
// ─── Types internes ───────────────────────────────────────────────────────────
@@ -351,9 +352,14 @@ async function processFeed(feed: RssFeed): Promise<FetchResult> {
const dedupKey = dedupHash(normalizedTitle + "|" + (feed.feedType ?? ""));
if (feed.feedType === "veille") {
// ── Classification IA (avec fallback sur mots-clés) ──────────────────
// ── Classification IA (avec fallback sur mots-clés) ──────────────────────────────────────
const { niveau, territoire } = detectVeilleNiveauTerritoire(fullText);
// Enrichissement : récupérer le 1er paragraphe si le résumé RSS est court (<150 car.)
const contenuPage = description.length < 150 && link
? await fetchArticleFirstParagraph(link)
: null;
const aiResult = await classifyArticle(
title,
description,
@@ -363,7 +369,8 @@ async function processFeed(feed: RssFeed): Promise<FetchResult> {
typeVeille: (matchedRule?.typeVeille ?? feed.defaultTypeVeille ?? "informationnelle") as
"reglementaire" | "concurrentielle" | "technologique" | "informationnelle",
};
}
},
contenuPage
);
const typeVeille = (aiResult.typeVeille ?? feed.defaultTypeVeille ?? "informationnelle") as
@@ -420,12 +427,18 @@ async function processFeed(feed: RssFeed): Promise<FetchResult> {
// ── Classification IA pour les AAP ───────────────────────────────────
const { region, departement } = detectAapGeo(fullText);
// Enrichissement : récupérer le 1er paragraphe si le résumé RSS est court (<150 car.)
const contenuPageAap = description.length < 150 && link
? await fetchArticleFirstParagraph(link)
: null;
const aiResult = await classifyArticle(
title,
description,
() => ({
typeVeille: "informationnelle" as const,
})
}),
contenuPageAap
);
const categorie = (feed.defaultCategorieAap ?? "Autre") as