Hapus seluruh fitur embedding/Qdrant (tidak dipakai lagi): - gateway: drop embeddingClient.ts, qdrantClient.ts, archiveEmbedder.ts dan tes qdrantEnsure.test.ts; moderationOrchestrator kembali ke exact-hash cache -> LLM (tanpa phase-2 semantic lookup); textCacheStore kehilangan findSimilarTextModeration / parseQdrantVerdict / isSemanticBandAccepted / upsertBareKeyToQdrant; cache-prune hanya menyapu Postgres. - backend: drop embed.ts + qdrant.ts, endpoint messages.semanticSearch dan schema/type terkait; kolom embedding dilepas dari schema text_analysis_cache. - frontend: hapus toggle EXACT/SEMANTIC, hook useSemanticSearch, API client + tipe SemanticSearchResult. - config: buang AI_LLM_EMBEDDING_* dan QDRANT_* (env + .env.example). - docs: ARCHITECTURE.md / AGENTS.md / README.md / diagram arsitektur disesuaikan (LLM caller - vision, cache = exact-hash saja). Verifikasi: tsc 0 (backend, gateway, frontend); bun test 135 pass + 37 pass, 0 fail; biome 0 error.
38 lines
2.0 KiB
TypeScript
38 lines
2.0 KiB
TypeScript
// ═══════════════════════════════════════════════════════════════════════════
|
|
// Stored-status normalization — "warn" verdicts must survive the cache
|
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
// Bug (2026-08-22): getCachedTextModeration() narrowed its return type to
|
|
// "clean" | "flagged". A stored "warn" verdict with flags (e.g.
|
|
// ["conflict_instigation"]) fell into the legacy `flags.length === 0 ?
|
|
// clean : flagged` branch and was read back as FLAGGED. Downstream this
|
|
// broke auto-delete eligibility gating and mislabelled warnings on the
|
|
// dashboard.
|
|
//
|
|
// Fix: normalizeStoredStatus() accepts the full clean/warn/flagged union;
|
|
// unknown/legacy values still derive from flags.
|
|
import { describe, expect, it } from "vitest";
|
|
import { normalizeStoredStatus } from "../src/modules/ai-moderation/textCacheStore.js";
|
|
|
|
describe("normalizeStoredStatus — warn survives cache round-trip", () => {
|
|
it("keeps a stored 'warn' status as 'warn'", () => {
|
|
expect(normalizeStoredStatus("warn", ["conflict_instigation"])).toBe(
|
|
"warn",
|
|
);
|
|
});
|
|
|
|
it("keeps stored 'clean' and 'flagged' unchanged", () => {
|
|
expect(normalizeStoredStatus("clean", [])).toBe("clean");
|
|
expect(normalizeStoredStatus("flagged", ["sara"])).toBe("flagged");
|
|
});
|
|
|
|
it("derives from flags for legacy entries without a stored status", () => {
|
|
expect(normalizeStoredStatus(undefined, [])).toBe("clean");
|
|
expect(normalizeStoredStatus(undefined, ["spam"])).toBe("flagged");
|
|
});
|
|
|
|
it("treats an unknown stored status like a legacy entry", () => {
|
|
expect(normalizeStoredStatus("processing", [])).toBe("clean");
|
|
expect(normalizeStoredStatus("processing", ["spam"])).toBe("flagged");
|
|
});
|
|
});
|