Checkpoint: Ajout de la table processed_dedup_keys : chaque article traité par le moteur RSS est enregistré dans cette table. Lors des passages suivants du cron, si la dedupKey est présente dans cette table, l'article est ignoré même s'il a été supprimé de veille_items ou aap_items.
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
rssFeeds,
|
||||
veilleItems,
|
||||
aapItems,
|
||||
processedDedupKeys,
|
||||
type RssFeed,
|
||||
} from "../drizzle/schema";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
@@ -525,6 +526,15 @@ async function processFeed(feed: RssFeed): Promise<FetchResult> {
|
||||
const normalizedTitle = buildMergeKey(title);
|
||||
const dedupKey = dedupHash(normalizedTitle + "|" + (feed.feedType ?? ""));
|
||||
|
||||
// ─── Tombstone : ignorer les articles déjà traités (même supprimés) ─────────
|
||||
const tombstone = await db.select().from(processedDedupKeys)
|
||||
.where(eq(processedDedupKeys.dedupKey, dedupKey))
|
||||
.limit(1);
|
||||
if (tombstone.length > 0) {
|
||||
result.skippedItems++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (feed.feedType === "veille") {
|
||||
// ── Classification IA (avec fallback sur mots-clés) ──────────────────────────────────────
|
||||
const { niveau, territoire } = detectVeilleNiveauTerritoire(fullText);
|
||||
@@ -578,6 +588,8 @@ async function processFeed(feed: RssFeed): Promise<FetchResult> {
|
||||
iaReason: aiResult.reason,
|
||||
iaResume: iaResume || null,
|
||||
});
|
||||
// Enregistrer le tombstone pour éviter la réinsertion après purge
|
||||
await db.insert(processedDedupKeys).values({ dedupKey, feedType: "veille" }).onDuplicateKeyUpdate({ set: { dedupKey } });
|
||||
result.newItems++;
|
||||
} catch (e: any) {
|
||||
if (e?.code === "ER_DUP_ENTRY" || e?.cause?.code === "ER_DUP_ENTRY" || e?.message?.includes("Duplicate entry") || e?.cause?.message?.includes("Duplicate entry")) {
|
||||
@@ -652,6 +664,8 @@ async function processFeed(feed: RssFeed): Promise<FetchResult> {
|
||||
iaReason: aiResult.reason,
|
||||
iaResume: iaResume || null,
|
||||
});
|
||||
// Enregistrer le tombstone pour éviter la réinsertion après purge
|
||||
await db.insert(processedDedupKeys).values({ dedupKey, feedType: "aap" }).onDuplicateKeyUpdate({ set: { dedupKey } });
|
||||
result.newItems++;
|
||||
} catch (e: any) {
|
||||
if (e?.code === "ER_DUP_ENTRY" || e?.cause?.code === "ER_DUP_ENTRY" || e?.message?.includes("Duplicate entry") || e?.cause?.message?.includes("Duplicate entry")) {
|
||||
|
||||
Reference in New Issue
Block a user