|
|
@@ -0,0 +1,84 @@
|
|
|
+// Reseta atendimentos já avaliados (Avaliavel=true) para pendente, para que a próxima
|
|
|
+// rodada de avaliação também extraia StatusCancelamento/MotivoCancelamento (campos novos).
|
|
|
+// Não faz a reavaliação em si — só o reset. Depois de rodar com --apply, drenar a fila
|
|
|
+// com scripts/avaliarTudo.js (idempotente entre reinícios, ao contrário deste script).
|
|
|
+//
|
|
|
+// Uso: node scripts/backfillCancelamento.js [--dias 90] [--apply] [--limite N]
|
|
|
+// --dias N : só atendimentos com Abertura nos últimos N dias (omitir = todo o histórico Avaliavel=true)
|
|
|
+// --apply : executa de fato (sem essa flag, é dry-run)
|
|
|
+// --limite N : limita quantos IDs entram no backfill (teste)
|
|
|
+
|
|
|
+import fs from "node:fs";
|
|
|
+import path from "node:path";
|
|
|
+import { fileURLToPath } from "node:url";
|
|
|
+import { AtendimentoAvaliacao } from "../src/models/AtendimentoAvaliacao.model.js";
|
|
|
+import { contarPendentes } from "../src/services/atendimentoAvaliacaoService.js";
|
|
|
+
|
|
|
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
+const APLICAR = process.argv.includes("--apply");
|
|
|
+
|
|
|
+const diasIdx = process.argv.indexOf("--dias");
|
|
|
+const DIAS = diasIdx > -1 ? Number(process.argv[diasIdx + 1]) : null;
|
|
|
+
|
|
|
+const limiteIdx = process.argv.indexOf("--limite");
|
|
|
+const LIMITE = limiteIdx > -1 ? Number(process.argv[limiteIdx + 1]) : null;
|
|
|
+
|
|
|
+async function buscarCandidatos() {
|
|
|
+ const query = AtendimentoAvaliacao.query()
|
|
|
+ .where("Avaliavel", true)
|
|
|
+ .join("atendimentos as a", "a.Id", "atendimento_avaliacoes.AtendimentoId")
|
|
|
+ .select(
|
|
|
+ "atendimento_avaliacoes.AtendimentoId",
|
|
|
+ "atendimento_avaliacoes.StatusCancelamento",
|
|
|
+ "atendimento_avaliacoes.MotivoCancelamento",
|
|
|
+ "a.Abertura"
|
|
|
+ )
|
|
|
+ .orderBy("a.Abertura", "desc");
|
|
|
+
|
|
|
+ if (DIAS) {
|
|
|
+ const cutoff = new Date(Date.now() - DIAS * 24 * 60 * 60 * 1000);
|
|
|
+ query.where("a.Abertura", ">=", cutoff);
|
|
|
+ }
|
|
|
+
|
|
|
+ return query;
|
|
|
+}
|
|
|
+
|
|
|
+async function main() {
|
|
|
+ const candidatos = await buscarCandidatos();
|
|
|
+ const alvos = LIMITE ? candidatos.slice(0, LIMITE) : candidatos;
|
|
|
+
|
|
|
+ console.log(
|
|
|
+ `[backfill-cancelamento] ${candidatos.length} candidatos` +
|
|
|
+ `${DIAS ? ` (Abertura nos últimos ${DIAS} dias)` : " (todo o histórico Avaliavel=true)"}.`
|
|
|
+ );
|
|
|
+ console.log(`[backfill-cancelamento] ${alvos.length} avaliações serão resetadas para pendente${LIMITE ? ` (--limite ${LIMITE})` : ""}.`);
|
|
|
+
|
|
|
+ if (!APLICAR) {
|
|
|
+ console.log("[backfill-cancelamento] dry-run (nenhuma alteração feita). Use --apply para executar.");
|
|
|
+ process.exit(0);
|
|
|
+ }
|
|
|
+ if (alvos.length === 0) {
|
|
|
+ console.log("[backfill-cancelamento] nada para reavaliar.");
|
|
|
+ process.exit(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ const backupDir = path.resolve(__dirname, "logs");
|
|
|
+ fs.mkdirSync(backupDir, { recursive: true });
|
|
|
+ const backupPath = path.join(backupDir, `backfill-cancelamento-${new Date().toISOString().replace(/[:.]/g, "-")}.json`);
|
|
|
+ fs.writeFileSync(backupPath, JSON.stringify(alvos, null, 2));
|
|
|
+ console.log(`[backfill-cancelamento] backup dos valores antigos salvo em ${backupPath}`);
|
|
|
+
|
|
|
+ const ids = alvos.map((a) => a.AtendimentoId);
|
|
|
+ const pendentesAntes = await contarPendentes();
|
|
|
+ await AtendimentoAvaliacao.query().whereIn("AtendimentoId", ids).patch({ UltimaMensagemId: null });
|
|
|
+ const pendentesDepois = await contarPendentes();
|
|
|
+ console.log(`[backfill-cancelamento] resetados ${ids.length} — fila de pendentes ${pendentesAntes} -> ${pendentesDepois}.`);
|
|
|
+ console.log("[backfill-cancelamento] pronto. Agora rode scripts/avaliarTudo.js para drenar a fila.");
|
|
|
+
|
|
|
+ process.exit(0);
|
|
|
+}
|
|
|
+
|
|
|
+main().catch((e) => {
|
|
|
+ console.error("[backfill-cancelamento] falha:", e.message);
|
|
|
+ process.exit(1);
|
|
|
+});
|