Release v4928.1.4.2 stable
This commit is contained in:
89
scripts/review_domain_auto_applied_suggestions.py
Executable file
89
scripts/review_domain_auto_applied_suggestions.py
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user