90 lines
3.4 KiB
Python
Executable File
90 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""List/revert risky fiscal suggestions auto-applied from domain-only matches."""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
|
|
from sqlalchemy import text
|
|
|
|
from app.db import engine
|
|
|
|
DOMAIN_MATCHES = (
|
|
"email_principal_dominio",
|
|
"email_dominio_empresa_associada",
|
|
"contacto_email_dominio",
|
|
"dominio",
|
|
"email_dominio",
|
|
"website_dominio",
|
|
)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--apply", action="store_true", help="revert accepted domain-only suggestions and unlink matching opportunity customer")
|
|
args = parser.parse_args()
|
|
|
|
with engine.begin() as conn:
|
|
rows = conn.execute(text("""
|
|
SELECT
|
|
s.id::text,
|
|
s.opportunity_id::text,
|
|
s.suggested_customer_id::text,
|
|
s.suggested_name,
|
|
s.suggested_nif,
|
|
s.match_type,
|
|
s.confidence,
|
|
o.customer_name,
|
|
o.customer_email,
|
|
o.local_customer_id::text AS current_customer_id
|
|
FROM fiscal_customer_suggestions s
|
|
JOIN opportunities o ON o.id = s.opportunity_id
|
|
WHERE s.status = 'accepted'
|
|
AND s.auto_applied = TRUE
|
|
AND s.match_type = ANY(:matches)
|
|
ORDER BY s.updated_at DESC
|
|
"""), {"matches": list(DOMAIN_MATCHES)}).mappings().all()
|
|
|
|
print(f"Sugestões por domínio auto-aplicadas: {len(rows)}")
|
|
for r in rows:
|
|
print(f"- {r['customer_name']} <{r['customer_email']}> -> {r['suggested_name']} / {r['suggested_nif']} | {r['match_type']} | {r['confidence']} | opp={r['opportunity_id']}")
|
|
|
|
if not args.apply:
|
|
print("Dry-run. Para reverter: repetir com --apply")
|
|
return
|
|
|
|
updated = 0
|
|
with engine.begin() as conn:
|
|
for r in rows:
|
|
# Only unlink if the opportunity is still linked to the same customer suggested by this risky suggestion.
|
|
if r["suggested_customer_id"] and r["current_customer_id"] == r["suggested_customer_id"]:
|
|
conn.execute(text("""
|
|
UPDATE opportunities
|
|
SET local_customer_id = NULL,
|
|
metadata = COALESCE(metadata, '{}'::jsonb) || jsonb_build_object(
|
|
'domain_match_auto_apply_reverted', true,
|
|
'domain_match_reverted_suggestion_id', :suggestion_id,
|
|
'domain_match_reverted_customer_name', :customer_name,
|
|
'domain_match_reverted_at', now()
|
|
),
|
|
updated_at = now()
|
|
WHERE id = CAST(:opportunity_id AS UUID)
|
|
"""), {
|
|
"opportunity_id": r["opportunity_id"],
|
|
"suggestion_id": r["id"],
|
|
"customer_name": r["suggested_name"],
|
|
})
|
|
conn.execute(text("""
|
|
UPDATE fiscal_customer_suggestions
|
|
SET status = 'rejected', auto_applied = FALSE, resolved_by = 'domain_match_safety_review',
|
|
resolved_at = now(), reason = COALESCE(reason, '') || ' | reverted: domain-only auto-apply is unsafe',
|
|
updated_at = now()
|
|
WHERE id = CAST(:id AS UUID)
|
|
"""), {"id": r["id"]})
|
|
updated += 1
|
|
print(f"Revertidas: {updated}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|