VERIFY PASS pe corpus k-NN exemple etichetate (seed real 17181 Haiku, comis
in 756f777): suita 1392 passed, 1 deselected (live); smoke init_db seeder
(17181/NUL=2200/idempotent); toate codurile in nomenclator.
US-007 (cerere user la CLOSE) — badge sursa pe sugestia fuzzy din editor:
- _mapari.html: chip confirmat (GOLD) / similar (SILVER+k-NN) / non-operatie (NUL)
- base.html: .sugg-sursa--{confirmat,similar,nul} pe tokeni de tema (color-mix)
- routes.py: cheia `nul` adaugata in surse_sugestie default (finding cross-file)
- tests/test_web_badge_sursa.py: gold/silver/nul/fara-sursa (4 teste)
- E2E render live verificat in serverul real (/_fragments/mapari)
CLOSE /code-review high (main..HEAD, 3 finder x 8 unghiuri) — runtime curat,
invariant #13 intact; 3 findings low/cosmetic REPARATE + lock-uite:
- shared_store.seed_suggestions: cod whitespace -> NULL (era ''), + test lock
- genereaza_seed.py: with open(...) in loc de open().read() (FD leak tool offline)
- embeddings.py: docstring-uri aliniate la [{cod, is_nul, similaritate}]
ROADMAP: 5.18 LIVRAT. PRD: raport VERIFY/CLOSE scris.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
306 lines
11 KiB
Python
306 lines
11 KiB
Python
"""TDD pentru L14-S3 — shared_store: SILVER (mapping_suggestions) + GOLD partajat (shared_mappings).
|
|
|
|
Scenarii acoperite:
|
|
- seed_suggestions: idempotent (INSERT OR IGNORE, nu clobberuie randuri existente)
|
|
- seed_suggestions: NUL marcat -> cod_prestatie NULL, is_nul=1 (supresie, #4)
|
|
- lookup_suggestion: cauta pe denumire_normalizata
|
|
- lookup_shared_gold: cauta pe denumire_normalizata
|
|
- record_human_validation: insert nou + increment confirmations la al doilea apel
|
|
- provenance/source/confidence pastrate (#5)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Fixtures #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
@pytest.fixture()
|
|
def env(monkeypatch):
|
|
"""DB temporara cu schema initiata."""
|
|
tmp = tempfile.mkdtemp()
|
|
monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "shared_store_test.db"))
|
|
from app.config import get_settings
|
|
get_settings.cache_clear()
|
|
from app.db import init_db
|
|
init_db()
|
|
yield monkeypatch
|
|
get_settings.cache_clear()
|
|
|
|
|
|
@pytest.fixture()
|
|
def conn(env):
|
|
from app.db import get_connection
|
|
c = get_connection()
|
|
yield c
|
|
c.close()
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# seed_suggestions — strat SILVER #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
def test_seed_suggestions_inserteaza(conn):
|
|
"""seed_suggestions insereaza un rand si returneaza 1 (numarul de randuri inserate)."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
n = seed_suggestions(conn, [
|
|
{"denumire": "Schimb ulei motor", "cod_prestatie": "OE-3", "source": "llm", "confidence": 0.9},
|
|
])
|
|
conn.commit()
|
|
|
|
assert n == 1
|
|
row = lookup_suggestion(conn, "Schimb ulei motor")
|
|
assert row is not None
|
|
assert row["cod_prestatie"] == "OE-3"
|
|
assert row["source"] == "llm"
|
|
assert abs(row["confidence"] - 0.9) < 0.001
|
|
assert row["is_nul"] == 0
|
|
|
|
|
|
def test_seed_suggestions_idempotent(conn):
|
|
"""seed_suggestions de doua ori cu acelasi item -> al doilea INSERT OR IGNORE, n=0 la re-seed."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
n1 = seed_suggestions(conn, [
|
|
{"denumire": "Verificare faruri", "cod_prestatie": "OE-2", "source": "llm", "confidence": 0.8},
|
|
])
|
|
conn.commit()
|
|
n2 = seed_suggestions(conn, [
|
|
{"denumire": "Verificare faruri", "cod_prestatie": "OE-2", "source": "llm", "confidence": 0.8},
|
|
])
|
|
conn.commit()
|
|
|
|
assert n1 == 1
|
|
assert n2 == 0 # INSERT OR IGNORE: randul deja exista
|
|
|
|
row = lookup_suggestion(conn, "Verificare faruri")
|
|
assert row is not None
|
|
assert row["cod_prestatie"] == "OE-2"
|
|
|
|
|
|
def test_seed_suggestions_nu_clobberuie_randul_existent(conn):
|
|
"""Re-seed cu cod diferit -> INSERT OR IGNORE pastreaza valoarea veche (#2)."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
seed_suggestions(conn, [
|
|
{"denumire": "Reparatie motor", "cod_prestatie": "OE-1", "source": "llm", "confidence": 0.85},
|
|
])
|
|
conn.commit()
|
|
|
|
# Al doilea seed cu alt cod: trebuie ignorat (nu suprascrie)
|
|
seed_suggestions(conn, [
|
|
{"denumire": "Reparatie motor", "cod_prestatie": "OE-2", "source": "llm", "confidence": 0.5},
|
|
])
|
|
conn.commit()
|
|
|
|
row = lookup_suggestion(conn, "Reparatie motor")
|
|
assert row is not None
|
|
assert row["cod_prestatie"] == "OE-1" # valoarea veche pastrata
|
|
|
|
|
|
def test_seed_suggestions_nul_marcat_fara_cod(conn):
|
|
"""is_nul=True -> cod_prestatie NULL, is_nul=1 in DB (supresie, #4)."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
seed_suggestions(conn, [
|
|
{"denumire": "ITP CT 12 ABC", "is_nul": True, "source": "llm", "confidence": 0.95},
|
|
])
|
|
conn.commit()
|
|
|
|
row = lookup_suggestion(conn, "ITP CT 12 ABC")
|
|
assert row is not None
|
|
assert row["is_nul"] == 1
|
|
assert row["cod_prestatie"] is None # NUL nu se promoveaza la cod (#4)
|
|
|
|
|
|
def test_seed_suggestions_nul_cu_cod_explicit_tot_nul(conn):
|
|
"""Daca is_nul=True, cod_prestatie e ignorat si stocat NULL (supresie stricta, #4)."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
seed_suggestions(conn, [
|
|
{
|
|
"denumire": "DISCOUNT MATERIALE 5%",
|
|
"cod_prestatie": "OE-1", # ignorat cand is_nul=True
|
|
"is_nul": True,
|
|
"source": "llm",
|
|
"confidence": 0.99,
|
|
},
|
|
])
|
|
conn.commit()
|
|
|
|
row = lookup_suggestion(conn, "DISCOUNT MATERIALE 5%")
|
|
assert row is not None
|
|
assert row["is_nul"] == 1
|
|
assert row["cod_prestatie"] is None # cod explicit ignorat cand is_nul
|
|
|
|
|
|
def test_seed_suggestions_cod_whitespace_devine_null(conn):
|
|
"""Rand non-NUL cu cod whitespace-only (' ') -> cod_prestatie NULL, NU '' (corectitudine)."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
seed_suggestions(conn, [
|
|
{"denumire": "OPERATIE CU COD GOL", "cod_prestatie": " ", "source": "llm", "confidence": 0.5},
|
|
])
|
|
conn.commit()
|
|
|
|
row = lookup_suggestion(conn, "OPERATIE CU COD GOL")
|
|
assert row is not None
|
|
assert row["is_nul"] == 0 # nu e marcat NUL
|
|
assert row["cod_prestatie"] is None # whitespace -> NULL, nu '' (rand non-NUL fara cod gol)
|
|
|
|
|
|
def test_seed_suggestions_normalizare_diacritice(conn):
|
|
"""Lookup pe forma cu diacritice gaseste randul seedat fara diacritice (normalize_for_match)."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
seed_suggestions(conn, [
|
|
{"denumire": "Înlocuit filtru aer", "cod_prestatie": "OE-3", "source": "llm", "confidence": 0.7},
|
|
])
|
|
conn.commit()
|
|
|
|
# Lookup cu accentele, fara accente, uppercase — trebuie sa gaseasca acelasi rand
|
|
row1 = lookup_suggestion(conn, "Înlocuit filtru aer")
|
|
row2 = lookup_suggestion(conn, "Inlocuit filtru aer")
|
|
row3 = lookup_suggestion(conn, "INLOCUIT FILTRU AER")
|
|
|
|
assert row1 is not None and row1["cod_prestatie"] == "OE-3"
|
|
assert row2 is not None and row2["cod_prestatie"] == "OE-3"
|
|
assert row3 is not None and row3["cod_prestatie"] == "OE-3"
|
|
|
|
|
|
def test_lookup_suggestion_lipseste_returneaza_none(conn):
|
|
"""lookup_suggestion pe o denumire care nu exista -> None."""
|
|
from app.shared_store import lookup_suggestion
|
|
|
|
row = lookup_suggestion(conn, "Denumire inexistenta")
|
|
assert row is None
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# record_human_validation + lookup_shared_gold — strat GOLD partajat #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
def test_record_human_validation_insert(conn):
|
|
"""Prima confirmare umana creeaza un rand nou in shared_mappings."""
|
|
from app.shared_store import record_human_validation, lookup_shared_gold
|
|
|
|
record_human_validation(
|
|
conn,
|
|
denumire="Schimb ulei",
|
|
cod_prestatie="oe-3", # se normalizeaza la OE-3
|
|
source="human",
|
|
provenance="cont_2/user@test.com",
|
|
confidence=1.0,
|
|
)
|
|
conn.commit()
|
|
|
|
row = lookup_shared_gold(conn, "Schimb ulei")
|
|
assert row is not None
|
|
assert row["cod_prestatie"] == "OE-3" # normalizat uppercase
|
|
assert row["source"] == "human"
|
|
assert row["provenance"] == "cont_2/user@test.com"
|
|
assert abs(row["confidence"] - 1.0) < 0.001
|
|
assert row["confirmations"] == 1
|
|
|
|
|
|
def test_record_human_validation_increment_confirmations(conn):
|
|
"""A doua confirmare umana pe aceeasi denumire -> confirmations += 1."""
|
|
from app.shared_store import record_human_validation, lookup_shared_gold
|
|
|
|
record_human_validation(conn, "Revizie anuala", "OE-3")
|
|
conn.commit()
|
|
record_human_validation(conn, "Revizie anuala", "OE-3")
|
|
conn.commit()
|
|
|
|
row = lookup_shared_gold(conn, "Revizie anuala")
|
|
assert row is not None
|
|
assert row["confirmations"] == 2
|
|
|
|
|
|
def test_record_human_validation_normalizare(conn):
|
|
"""Lookup pe diacritice sau uppercase gaseste acelasi rand GOLD."""
|
|
from app.shared_store import record_human_validation, lookup_shared_gold
|
|
|
|
record_human_validation(conn, "Înlocuit garnitura chiulasa", "OE-1")
|
|
conn.commit()
|
|
|
|
row1 = lookup_shared_gold(conn, "Înlocuit garnitura chiulasa")
|
|
row2 = lookup_shared_gold(conn, "Inlocuit garnitura chiulasa")
|
|
row3 = lookup_shared_gold(conn, "INLOCUIT GARNITURA CHIULASA")
|
|
|
|
assert row1 is not None and row1["cod_prestatie"] == "OE-1"
|
|
assert row2 is not None
|
|
assert row3 is not None
|
|
|
|
|
|
def test_lookup_shared_gold_lipseste_returneaza_none(conn):
|
|
"""lookup_shared_gold pe denumire inexistenta -> None."""
|
|
from app.shared_store import lookup_shared_gold
|
|
|
|
row = lookup_shared_gold(conn, "Operatie fara GOLD")
|
|
assert row is None
|
|
|
|
|
|
def test_provenance_source_confidence_pastrate(conn):
|
|
"""source, provenance, confidence sunt stocate si returnate corect (#5)."""
|
|
from app.shared_store import seed_suggestions, lookup_suggestion
|
|
|
|
seed_suggestions(conn, [
|
|
{
|
|
"denumire": "Reglat directie",
|
|
"cod_prestatie": "OE-2",
|
|
"source": "embedding",
|
|
"confidence": 0.73,
|
|
},
|
|
])
|
|
conn.commit()
|
|
|
|
row = lookup_suggestion(conn, "Reglat directie")
|
|
assert row is not None
|
|
assert row["source"] == "embedding"
|
|
assert abs(row["confidence"] - 0.73) < 0.001
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Separare structurala (#13): tabelele noi NU sunt citite de resolve_prestatii#
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
def test_mapping_suggestions_nu_e_folosita_de_resolve_prestatii():
|
|
"""resolve_prestatii NU citeste din mapping_suggestions — separare structurala (#13).
|
|
|
|
Daca un cod e in SILVER dar nu in operations_mapping, resolve_prestatii
|
|
NU il gaseste -> submission ramane needs_mapping (om in bucla).
|
|
"""
|
|
from app.mapping import resolve_prestatii
|
|
|
|
# Apelam resolve_prestatii fara niciun mapping -> operatia e nemapata
|
|
resolved, unmapped = resolve_prestatii(
|
|
[{"cod_op_service": "OP_SILVER", "denumire": "Reglat faruri"}],
|
|
{}, # operations_mapping gol
|
|
)
|
|
assert resolved[0]["cod_prestatie"] is None
|
|
assert len(unmapped) == 1
|
|
# Nu exista cale prin care SILVER sa ajunga in resolve fara wiring explicit (L14-S6)
|
|
|
|
|
|
def test_shared_mappings_nu_e_folosita_de_resolve_prestatii():
|
|
"""resolve_prestatii NU citeste din shared_mappings — separare structurala (#13).
|
|
|
|
Chiar daca GOLD partajat exista, resolve_prestatii nu il vede fara wiring explicit.
|
|
"""
|
|
from app.mapping import resolve_prestatii
|
|
|
|
resolved, unmapped = resolve_prestatii(
|
|
[{"cod_op_service": "OP_GOLD", "denumire": "Revizie periodica"}],
|
|
{}, # operations_mapping gol
|
|
)
|
|
assert resolved[0]["cod_prestatie"] is None
|
|
assert len(unmapped) == 1
|