资讯动态

Midday 重复发票系列为什么被自动暂停?怎么排查并恢复?

发布时间:2026/9/15 11:10:31 来源:尧图企业网站定制
Midday 重复发票系列为什么被自动暂停怎么排查并恢复【免费下载链接】middayInvoicing, Time tracking, File reconciliation, Storage, Financial Overview your own Assistant made for Freelancers项目地址: https://gitcode.com/GitHub_Trending/mi/middayMidday 的重复发票recurring invoice系列在自动暂停后仪表盘里会看到该系列状态从active变为paused团队会收到一条 Recurring series paused 通知。这篇文章针对这个现象说明三件事自动暂停为什么触发、如何根据错误码定位失败原因、以及如何通过resume流程恢复系列并确认它重新进入调度。依据是 docs/invoice-recurring.md 与 Worker/API 层的实际实现。触发机制连续 3 次失败后自动暂停重复发票系列由调度器每 2 小时扫描一次BullMQ 定时任务处理所有满足statusactive AND next_scheduled_at now的系列。系列状态机只有四种取值active、paused、completed、canceled其中active → paused有两条路径用户手动暂停或者连续失败达到阈值。自动暂停的计数逻辑在 recordInvoiceGenerationFailure() 中const MAX_CONSECUTIVE_FAILURES 3; const newFailureCount current.consecutiveFailures 1; const shouldAutoPause newFailureCount MAX_CONSECUTIVE_FAILURES; // 更新consecutiveFailures newFailureCount, // status: shouldAutoPause ? paused : current.status关键规则invoice_recurring表的consecutive_failures字段每次失败 1累计到 3 次时状态被置为paused任一周期生成成功markInvoiceGenerated() 会把consecutive_failures重置为 0所以计数只针对连续失败第 1、2 次失败后系列保持active下一轮调度继续重试。达到 3 次失败并暂停时generate-recurring.ts 还会向notificationsQueue投递一条recurring_series_paused通知即团队收到的告警。文档解释了为什么这样设计连续失败通常意味着系统性问题客户邮箱无效、模板损坏等自动暂停可以避免失败任务在队列中堆积、避免重复的错误通知、避免浪费处理资源见 docs/invoice-recurring.md 的 Why auto-pause after 3 failures? 一节。排查第一步区分自动暂停和手动暂停两者在数据库里都是status paused区分依据是通知内容。apps/dashboard/src/locales/en.ts 中recurring_series_paused通知的文案分两种自动失败Recurring series paused for {customerName} ({failureCount} failures)—— 带失败次数的就是自动暂停无失败次数的 Recurring series paused for {customerName} 对应其他场景。该活动在应用内通知中优先级为 4高于一般事件的 3所以在通知中心里相对醒目。排查第二步按错误码定位失败原因Worker 在每次生成失败时会记录结构化日志字段包括recurringId、errorCode、error和requiresUserAction见 generate-recurring.ts 的this.logger.error(Failed to generate recurring invoice, ...)。错误码定义在 apps/worker/src/errors/invoice-errors.ts共 7 种错误码含义requiresUserActionisRecoverableCUSTOMER_NO_EMAIL关联客户没有邮箱是否CUSTOMER_NOT_FOUND客户记录找不到可能已被删除是否CUSTOMER_DELETED客户被删除需重新指派客户或取消系列是否TEMPLATE_INVALID发票模板数据无效或损坏是否INVOICE_EXISTS该周期发票已存在跳过重复生成否否DATABASE_ERROR数据库错误系统会自动重试否是GENERATION_FAILED发票生成失败系统会自动重试否是判断逻辑requiresUserAction true前四种是自动暂停的常见根因客户邮箱缺失、客户被删、模板损坏这类问题不会自愈重试多少次都会失败必须人工修正后再恢复isRecoverable true后两种属于瞬时错误正常情况下会自动重试只有连续 3 个调度周期都失败才会暂停。对应的排查动作也写在这些错误码的用户提示里CUSTOMER_NO_EMAIL提示更新客户资料CUSTOMER_DELETED提示重新指派客户或取消系列TEMPLATE_INVALID提示重建系列原文The invoice template data is invalid or corrupted. Please recreate the recurring invoice series.。此外还有一个需要排除的情况环境变量DISABLE_RECURRING_INVOICEStrue会让调度器直接跳过所有处理generate-recurring.ts 会输出 warning 日志 Recurring invoice scheduler disabled via DISABLE_RECURRING_INVOICES。它不会把系列置为paused但会让整个调度停摆——如果一批系列同时停止出票且没有暂停通知先查这个开关。恢复系列调用 resume修好根因后通过 tRPC 路由invoiceRecurring.resume恢复入参只需要系列id。实现在 apps/api/src/trpc/routers/invoice-recurring.ts底层是 resumeInvoiceRecurring()。恢复时发生三件事校验当前状态status必须为paused否则返回nullAPI 层抛NOT_FOUND提示 Recurring invoice series not found or not paused重置失败计数consecutive_failures置 0状态回到active从当前时间重算下一次出票日期nextScheduledAt calculateNextScheduledDate(params, now)。注意这里不补发暂停期间的发票——文档明确说明这是为了避免 catch-up 发票洪峰恢复后的计费周期从现在重新起算。恢复流程里还有一个分支如果暂停期间结束条件已经满足on_date的endDate已过或after_count的endCount已达成resume不会恢复而是直接把系列标记为completed并清空nextScheduledAt见 resumeInvoiceRecurring() 中的shouldMarkCompleted检查。所以如果恢复操作返回的状态是completed而不是active说明该系列本来就该结束了不是故障。手动暂停pausemutation除了改状态外还会把该系列下所有scheduled状态的发票回退为draft并移除对应的 BullMQ 定时任务pause mutation确保暂停期间不会发出任何发票。验证恢复是否成功按以下顺序确认resume调用返回成功返回值中的status应为active若为completed参照上一节的结束条件分支判断。若抛出 series not found or not paused说明系列不在paused状态需先用getById查询实际状态检查返回的nextScheduledAt它应该是由当前时间按频率推算出的下一个未来日期而不是暂停前遗留的旧日期等待下一个 2 小时调度周期调度器会重新捞起该系列。生成成功后consecutive_failures保持为 0、invoices_generated加 1、last_generated_at更新并且团队会收到invoice_recurring_generated相关通知。限制与边界暂停期间nextScheduledAt被保留状态机标注 nextScheduledAt preserved但恢复时以当前时间重新计算期间错过的周期不会补开批量限额单次调度最多生成 50 张发票超过部分留到下一轮hasMore: true这与暂停无关但影响恢复后多久能看到发票的预期如果根因是TEMPLATE_INVALID文档给出的处理是重建系列recreate the recurring invoice series而不是恢复后继续重试completed与canceled是终态无法恢复。【免费下载链接】middayInvoicing, Time tracking, File reconciliation, Storage, Financial Overview your own Assistant made for Freelancers项目地址: https://gitcode.com/GitHub_Trending/mi/midday创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价