from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def read(path: str) -> str: return (ROOT / path).read_text(encoding="utf-8") def test_v491_reconciliation_service_adds_staging_schema_and_payment_proofs(): service = read("app/reconciliation_service.py") db = read("app/db.py") assert "CREATE TABLE IF NOT EXISTS reconciliation_items" in service assert "CREATE TABLE IF NOT EXISTS payment_proofs" in service assert "source_system TEXT NOT NULL" in service assert "external_type TEXT NOT NULL" in service assert "ux_reconciliation_items_source_external" in service assert "ensure_reconciliation_schema" in db def test_v491_reconciliation_page_and_navigation_exist(): page = read("app/admin_ui/pages/reconciliation.py") router = read("app/admin_ui/router.py") nav = read("app/admin_ui/navigation.py") assert '@router.get("/reconciliation"' in page assert '@router.get("/reconciliacao"' in page assert "Registar pedido externo" in page assert "Adicionar comprovativo" in page assert "Criar oportunidade" in page assert "Reconciliação" in nav assert "router.include_router(reconciliation.router)" in router def test_v491_external_intake_creates_opportunity_without_fake_chatwoot_ids(): service = read("app/reconciliation_service.py") assert "def create_external_request" in service assert "manual_external_intake" in service assert "source_channel" in service assert "WhatsApp" in read("app/admin_ui/pages/reconciliation.py") assert "conversation_id" not in service.split("def create_external_request", 1)[1].split("def create_payment_proof", 1)[0] def test_v491_payment_proof_never_confirms_payment_automatically(): service = read("app/reconciliation_service.py") page = read("app/admin_ui/pages/reconciliation.py") doc = read("docs/CLIENTFLOW_V491_OPERATIONAL_RECONCILIATION.md") assert "pending_validation" in service assert "Comprovativo recebido não confirma pagamento" in page assert "CONFIRM_PAYMENT" in service assert "não confirma pagamento" in doc assert "payment_confirmed" not in service def test_v491_sync_script_creates_reconciliation_candidates_idempotently(): script = read("scripts/sync_reconciliation_candidates.py") service = read("app/reconciliation_service.py") assert "sync_local_documents_without_opportunity" in script assert "commercial_documents" in service assert "opportunity_id IS NULL" in service assert "reconcile:commercial_document" in service assert "created_or_updated" in script def test_v491_documentation_describes_operator_confirmation_model(): doc = read("docs/CLIENTFLOW_V491_OPERATIONAL_RECONCILIATION.md") assert "Operational Reconciliation" in doc assert "Operador confirma" in doc assert "Não confirma pagamentos automaticamente" in doc assert "Não usa LLM" in doc