"""Historical evidence -> KB: temporal validity, lineage independence, conflicts, promotion audit, idempotent import. No provider is ever contacted.""" from sqlalchemy import select from sqlalchemy.orm import Session from central.app.enrichment import history, kb from central.app.enrichment.resolver import resolve from central.app.enrichment.quota import ProviderGateway from central.app.models import KbKnowledge, KbProduct, KbPromotionAudit from central.tests.test_product_enrichment_resolver import COSMOS, Fake, G1, G2, G3, env, gtin, seed # noqa: F401 G = "0" + G1 # 14-digit key def staging(client, gtin13, ncm, *, master=True, years=None, nfe=0, desc="REFRIGERANTE COLA LATA 350ML", code="1"): return {"client": client, "master": [{"code": code, "desc": desc, "gtin": gtin13, "codbarra": "", "ncm": ncm if master else "", "cest": ""}], "nfce": [{"code": code, "year": y, "ncm": ncm, "cest": "", "n": n} for y, n in (years or {}).items()], "nfe": [{"code": code, "codbarra": gtin13, "ncm": ncm, "desc": desc, "n": nfe}] if nfe else [], "barcodes": []} def run(session, stagings, dry=False): obs = history.build_observations(stagings) cur = history.official_sets(session) return history.apply(session, obs, lambda v: v in cur, dry_run=dry) def status(session, key=G): p = session.scalar(select(KbProduct).where(KbProduct.gtin == key)) cur = history.official_sets(session) return kb.evaluate(session, p, "ncm", lambda v: v in cur) def test_single_client_multi_year_history_is_corroborated_never_verified(env): r = run(env, [staging("A", G1, "22021000", years={2023: 300, 2024: 700, 2025: 900})]) assert r["by_status"] == {"CORROBORATED": 1} and r["WOULD_VERIFY"] == 0 assert env.scalars(select(KbPromotionAudit)).all() == [] def test_master_plus_documents_of_same_erp_are_one_family(env): run(env, [staging("A", G1, "22021000", master=True, years={2025: 5})]) # few docs, one year: weak assert status(env)["status"] == kb.OBSERVED and status(env)["families"] == [] def test_two_clients_corroborate_but_three_clients_alone_do_not_verify(env): r = run(env, [staging(c, G1, "22021000", years={2024: 2}) for c in ("A", "B", "C")]) assert r["by_status"] == {"CORROBORATED": 1} and r["multi_client"] == 1 and r["WOULD_VERIFY"] == 0 def test_history_plus_independent_provider_verifies_and_is_audited(env): run(env, [staging("A", G1, "22021000", years={2023: 50, 2024: 60})]) p = env.scalar(select(KbProduct).where(KbProduct.gtin == G)) kb.add_evidence(env, p, "ncm", "22021000", "provider:oscbr", family="PROVIDER:oscbr") ev = status(env) assert ev["status"] == kb.VERIFIED_KB and set(ev["families"]) == {"PROVIDER:oscbr", "CLIENT_DATA"} audit = env.scalars(select(KbPromotionAudit)).one() assert audit.new_status == "VERIFIED_KB" and audit.rule_version == kb.RULE_VERSION and audit.official_dataset["sha256"] and audit.sources["documents"] == 110 status(env) assert len(env.scalars(select(KbPromotionAudit)).all()) == 1 # no duplicate audit def test_different_current_ncms_are_a_conflict_not_majority(env): r = run(env, [staging("A", G1, "22021000", years={2024: 900, 2025: 900}), staging("B", G1, "19059090", years={2024: 5, 2025: 5}), staging("C", G1, "22021000", years={2024: 900})]) assert r["CONFLICTS"] == 1 res = resolve(env, ProviderGateway(env, []), gtin_raw=G1, description="REFRIGERANTE COLA LATA 350ML", current={}, allow_external=False) assert res["state"] == "CONFLICT" and res["fields"]["CLASSIFICACAO_FISCAL"]["status"] == "CONFLICT" def test_expired_ncm_is_history_not_a_candidate(env): run(env, [staging("A", G1, "11111111", years={2019: 900, 2020: 900})]) # expired in the fixture dataset ev = status(env) assert ev["value"] is None and ev["status"] == kb.OBSERVED row = env.scalar(select(KbKnowledge).where(KbKnowledge.knowledge_key == "ncm")) assert row.evidence["info"]["historical_state"] == "HISTORICAL_EXPIRED" and row.status == kb.STALE def test_ncm_changed_over_time_prefers_current(env): run(env, [staging("A", G1, "11111111", years={2019: 900, 2020: 900}), staging("A", G1, "22021000", master=False, years={2024: 50, 2025: 60})]) ev = status(env) assert ev["value"] == "22021000" and ev["status"] == kb.CORROBORATED def test_stale_ncm_with_equal_recency_does_not_count_as_stable(env): run(env, [staging("A", G1, "22021000", master=False, years={2024: 50, 2025: 60}), staging("B", G1, "11111111", master=False, years={2025: 500})]) assert status(env)["status"] in (kb.OBSERVED,) # the old code is as recent: not stable, so not even corroborated def test_import_is_idempotent_and_dry_run_writes_nothing(env): st = [staging("A", G1, "22021000", years={2023: 300, 2024: 700}), staging("B", G3, "19059090", desc="BISCOITO RECHEADO 130G", code="9", years={2024: 30, 2025: 30})] dry = run(env, st, dry=True) assert env.scalars(select(KbProduct)).all() == [] a, b = run(env, st), run(env, st) assert a["by_status"] == b["by_status"] == dry["by_status"] assert len(env.scalars(select(KbKnowledge).where(KbKnowledge.knowledge_key == "ncm")).all()) == 2 row = env.scalar(select(KbKnowledge).where(KbKnowledge.knowledge_key == "ncm", KbKnowledge.value == "22021000")) assert row.evidence["lineages"]["A"]["docs"] == 1000 # replaced, not doubled def test_aliases_and_no_company_tax_data_stored(env): run(env, [staging("A", G1, "22021000", years={2024: 30, 2025: 30}, desc="COCA COLA LT 350"), staging("B", G1, "22021000", master=False, desc="REFRIG COCA-COLA 350ML", code="2", years={2025: 5})]) p = env.scalar(select(KbProduct).where(KbProduct.gtin == G)) aliases = {r.value for r in env.scalars(select(KbKnowledge).where(KbKnowledge.kb_product_id == p.id, KbKnowledge.knowledge_key == "alias"))} assert len(aliases) >= 2 blob = repr([r.evidence for r in env.scalars(select(KbKnowledge))]).upper() assert "CFOP" not in blob and "CSOSN" not in blob and "CRT" not in blob def test_kb_hit_makes_zero_external_requests(env): run(env, [staging("A", G1, "22021000", years={2023: 50, 2024: 60})]) p = env.scalar(select(KbProduct).where(KbProduct.gtin == G)) kb.add_evidence(env, p, "ncm", "22021000", "provider:oscbr", family="PROVIDER:oscbr") env.commit() spy = Fake("cosmos", COSMOS(), True) r = resolve(env, ProviderGateway(env, [spy]), gtin_raw=G1, description="REFRIGERANTE COLA LATA 350ML", current={}) assert r["state"] == "EXACT_GTIN_VERIFIED" and spy.calls == 0 and r["fields"]["CLASSIFICACAO_FISCAL"]["status"] == "AUTO_FILL_SAFE" def test_revalidation_marks_stale_review_and_keeps_knowledge(env): run(env, [staging("A", G1, "22021000", years={2023: 50, 2024: 60})]) p = env.scalar(select(KbProduct).where(KbProduct.gtin == G)) kb.add_evidence(env, p, "ncm", "22021000", "provider:oscbr", family="PROVIDER:oscbr") assert status(env)["status"] == kb.VERIFIED_KB out = kb.revalidate(env, lambda v: True) assert out["stale"] == 0 and status(env)["status"] == kb.VERIFIED_KB # NCM still vigente: stays valid out = kb.revalidate(env, lambda v: False) # the official dataset dropped it row = env.scalar(select(KbKnowledge).where(KbKnowledge.knowledge_key == "ncm")) assert out["stale"] == 1 and row.status == kb.STALE and row.evidence["info"]["stale_reason"] == "STALE_REVIEW_REQUIRED" assert [a.new_status for a in env.scalars(select(KbPromotionAudit)).all()] == ["VERIFIED_KB", "STALE"] def test_provider_disagreeing_with_verified_kb_creates_conflict_not_overwrite(env): run(env, [staging("A", G1, "22021000", years={2023: 50, 2024: 60})]) p = env.scalar(select(KbProduct).where(KbProduct.gtin == G)) kb.add_evidence(env, p, "ncm", "22021000", "provider:oscbr", family="PROVIDER:oscbr") assert status(env)["status"] == kb.VERIFIED_KB kb.add_evidence(env, p, "ncm", "19059090", "provider:cosmos", family="PROVIDER:cosmos") ev = status(env) assert ev["status"] == kb.CONFLICT and ev["value"] is None # write blocked until a human resolves it def test_aliases_from_history_enable_name_only_match_and_generic_names_stay_ambiguous(env): run(env, [staging("A", G1, "22021000", years={2023: 50, 2024: 60}, desc="COCA-COLA ORIGINAL LATA 350 ML")]) p = env.scalar(select(KbProduct).where(KbProduct.gtin == G)) kb.add_evidence(env, p, "ncm", "22021000", "provider:oscbr", family="PROVIDER:oscbr") env.commit() r = resolve(env, ProviderGateway(env, []), gtin_raw="", description="COCA COLA LATA 350ML", current={}) assert r["state"] == "EXACT_KB_NAME_VERIFIED" and r["fields"]["CLASSIFICACAO_FISCAL"]["value"] == "22021000" g = resolve(env, ProviderGateway(env, []), gtin_raw="", description="REFRIGERANTE", current={}) assert g["state"] == "AMBIGUOUS" and all(f["status"] != "AUTO_FILL_SAFE" for f in g["fields"].values())