#!/usr/bin/env python3 """Reabre tasks Chatwoot que foram classificadas como revisão/remoção mas ficaram skipped. Uso seguro: PYTHONPATH=. python scripts/reopen_chatwoot_review_tasks.py --dry-run PYTHONPATH=. python scripts/reopen_chatwoot_review_tasks.py --days 7 Por defeito só olha para os últimos 7 dias e não toca em spam/NO_ACTION. """ from __future__ import annotations import argparse import json from sqlalchemy import text from app.db import engine def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--days", type=int, default=7, help="Janela de dias a corrigir") parser.add_argument("--dry-run", action="store_true", help="Mostra o que faria sem alterar") args = parser.parse_args() params = {"days": int(args.days)} select_sql = text(""" SELECT id::text, created_at, action_code, route, action, status, conversation_id, contact_id FROM tasks WHERE source_system = 'chatwoot' AND status = 'skipped' AND action_code IN ('REVIEW_MANUALLY', 'REMOVE_FROM_LIST') AND created_at >= now() - (:days * interval '1 day') ORDER BY created_at DESC """) with engine.begin() as conn: rows = conn.execute(select_sql, params).mappings().all() print(f"Encontradas {len(rows)} task(s) Chatwoot a reabrir.") for row in rows[:50]: print(f"- {row['created_at']} {row['action_code']} conversa={row['conversation_id']} task={row['id']}") if args.dry_run or not rows: print("Dry-run: nenhuma alteração aplicada." if args.dry_run else "Nada para alterar.") return 0 ids = [row["id"] for row in rows] update_sql = text(""" UPDATE tasks SET status = 'pending', priority = CASE WHEN action_code = 'REVIEW_MANUALLY' THEN 'alta' ELSE COALESCE(priority, 'normal') END, route = CASE WHEN action_code = 'REMOVE_FROM_LIST' THEN 'marketing' ELSE route END, updated_at = now(), metadata = COALESCE(metadata, '{}'::jsonb) || CAST(:patch AS JSONB) WHERE id = ANY(CAST(:ids AS uuid[])) """) patch = json.dumps({ "v46_reopened": True, "v46_reason": "REVIEW_MANUALLY/REMOVE_FROM_LIST devem gerar trabalho humano pendente", }, ensure_ascii=False) with engine.begin() as conn: conn.execute(update_sql, {"ids": ids, "patch": patch}) print(f"Reabertas {len(ids)} task(s) como pending.") return 0 if __name__ == "__main__": raise SystemExit(main())