feat(notificaciones): ejecutar todos for servicios jobs
Add POST /notifications/run-all: runs the four notification jobs (outstanding, payment confirmation, account status, trust confirmation) sequentially with one shared set of flags from "Flags del envío". Sequential rather than parallel — the jobs share the SES transport and account status can self-throttle via useEmailLimit. A job that throws is captured and the sweep continues, so one bad query cannot swallow the other three envíos; the aggregate response carries per-job results plus summed sent/skipped/failed and an errors count. Audited as a single notification.run-all.run entry so one staff click is one audit row. UI adds the button to the flags card, with a confirm when debug is off, and a per-job summary in "Última respuesta".
This commit is contained in:
@@ -12,7 +12,10 @@ import { MailService } from "../mail/mail.service";
|
||||
import { PrismaService } from "../prisma/prisma.service";
|
||||
import {
|
||||
SendAttempt,
|
||||
NotificationJobKind,
|
||||
NotificationJobResponse,
|
||||
NotificationRunAllJobResult,
|
||||
NotificationRunAllResponse,
|
||||
AttemptStatus,
|
||||
} from "./notification.types";
|
||||
import {
|
||||
@@ -649,6 +652,66 @@ export class NotificationsService {
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Ejecutar todos" — run all four jobs back to back with one set of flags.
|
||||
*
|
||||
* Sequential on purpose: the jobs share the SES transport and Job 3 can
|
||||
* self-throttle via `useEmailLimit`, so firing them in parallel would both
|
||||
* defeat that pause and interleave `email_notification_log` writes for no
|
||||
* gain. A job that throws is captured and the sweep continues — one bad
|
||||
* query must not swallow the other three envíos.
|
||||
*/
|
||||
async runAll(flags: {
|
||||
debug?: boolean;
|
||||
ignoreDayRestriction?: boolean;
|
||||
useEmailLimit?: boolean;
|
||||
}): Promise<NotificationRunAllResponse> {
|
||||
const debug = !!flags.debug;
|
||||
const steps: {
|
||||
kind: NotificationJobKind;
|
||||
run: () => Promise<NotificationJobResponse>;
|
||||
}[] = [
|
||||
{ kind: "outstanding", run: () => this.runOutstandingPayments(flags) },
|
||||
{ kind: "payment", run: () => this.runPaymentConfirmation(flags) },
|
||||
{ kind: "account", run: () => this.runAccountStatus(flags) },
|
||||
{ kind: "trust", run: () => this.runTrustConfirmation(flags) },
|
||||
];
|
||||
|
||||
const jobs: NotificationRunAllJobResult[] = [];
|
||||
let sent = 0;
|
||||
let skipped = 0;
|
||||
let failed = 0;
|
||||
let errors = 0;
|
||||
|
||||
for (const step of steps) {
|
||||
try {
|
||||
const result = await step.run();
|
||||
sent += result.sent;
|
||||
skipped += result.skipped;
|
||||
failed += result.failed;
|
||||
jobs.push({ kind: step.kind, ok: true, result });
|
||||
} catch (e) {
|
||||
errors++;
|
||||
const message = e instanceof Error ? e.message : String(e);
|
||||
this.logger.error(`run-all: job ${step.kind} failed — ${message}`);
|
||||
jobs.push({ kind: step.kind, ok: false, error: message });
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
request: "success",
|
||||
notificationType: "runAllNotifications",
|
||||
statusCode: 200,
|
||||
debug,
|
||||
sent,
|
||||
skipped,
|
||||
failed,
|
||||
errors,
|
||||
jobs,
|
||||
type: "RUN_ALL",
|
||||
};
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* Log browser — list / drill-down for the UI.
|
||||
* ========================================================================== */
|
||||
|
||||
Reference in New Issue
Block a user