import { afterEach, describe, expect, it, vi } from "vitest"; const PROBLEM_UNITS_FLAG = "FEATURE_ASSISTANT_PROBLEM_UNITS_V1"; const ORIGINAL_PROBLEM_UNITS_FLAG = process.env[PROBLEM_UNITS_FLAG]; function restoreFlag(): void { if (ORIGINAL_PROBLEM_UNITS_FLAG === undefined) { delete process.env[PROBLEM_UNITS_FLAG]; } else { process.env[PROBLEM_UNITS_FLAG] = ORIGINAL_PROBLEM_UNITS_FLAG; } } async function normalizeWithFlag(flagValue: "0" | "1") { process.env[PROBLEM_UNITS_FLAG] = flagValue; vi.resetModules(); const { normalizeRetrievalResult } = await import("../src/services/retrievalResultNormalizer"); return normalizeRetrievalResult("F1", ["R1"], "hybrid_store_plus_live", { status: "ok", result_type: "list", items: [ { source_entity: "Document", source_id: "DOC-1", risk_score: 4 } ], summary: { broad_query_detected: false }, evidence: [ { evidence_id: "ev-1", claim_ref: "requirement:R1", source_type: "retrieval_item", pointer: { fragment_id: "F1", route: "hybrid_store_plus_live", source: { namespace: "snapshot_2020", entity: "Document", id: "DOC-1", period: "2020-06" }, locator: { field_path: "risk_score", item_index: 0 } }, failed_expected_edge: "statement_to_document", anomaly_patterns: ["period_close_risk"], confidence: "medium" } ], why_included: ["test"], selection_reason: ["test"], risk_factors: ["test"], business_interpretation: ["test"], confidence: "medium", limitations: [], errors: [] }); } describe.sequential("retrieval dual payload compatibility for problem units", () => { afterEach(() => { restoreFlag(); vi.resetModules(); }); it("keeps legacy payload intact when FEATURE_ASSISTANT_PROBLEM_UNITS_V1 is OFF", async () => { const result = await normalizeWithFlag("0"); expect(Array.isArray(result.items)).toBe(true); expect(result.items.length).toBe(1); expect(result.raw_entities).toBeUndefined(); expect(result.candidate_evidence).toBeUndefined(); expect(result.problem_units).toBeUndefined(); expect(result.problem_unit_summary).toBeUndefined(); }); it("adds Stage 2 dual payload fields when FEATURE_ASSISTANT_PROBLEM_UNITS_V1 is ON", async () => { const off = await normalizeWithFlag("0"); const on = await normalizeWithFlag("1"); expect(on.items).toEqual(off.items); expect(on.raw_entities).toEqual(off.items); expect(Array.isArray(on.candidate_evidence)).toBe(true); expect(on.candidate_evidence?.length).toBeGreaterThan(0); expect(Array.isArray(on.problem_units)).toBe(true); expect(on.problem_units?.length).toBeGreaterThan(0); expect(on.problem_unit_summary?.schema_version).toBe("problem_unit_summary_v0_1"); expect(on.problem_unit_summary?.units_total).toBe(on.problem_units?.length); expect(on.summary.problem_units_enabled).toBe(true); expect(on.summary.candidate_evidence_count).toBe(on.candidate_evidence?.length); expect(on.summary.problem_units_count).toBe(on.problem_units?.length); expect(on.summary.problem_unit_duplicate_collapses).toBe(on.problem_unit_summary?.duplicate_collapses); expect(on.summary.problem_unit_types).toEqual(on.problem_unit_summary?.unit_types); expect(on.summary.problem_unit_severity_distribution).toEqual(on.problem_unit_summary?.severity_distribution); expect(on.summary.problem_unit_confidence_distribution).toEqual(on.problem_unit_summary?.confidence_distribution); }); });