inngest-brownfield-audit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Inngest Brownfield Audit

Inngest遗留代码库审计

Use this skill when asked to inspect an existing codebase, add Inngest "where it makes sense", migrate fragile background work, or find durability gaps before making changes.
This is an agent-first workflow. Do the audit from evidence in the repo, name the specific files and call sites that drove each conclusion, and make small integration moves that preserve current behavior.
当需要检查现有代码库、在“合理位置”添加Inngest、迁移脆弱的后台工作,或在修改前找出耐久性缺口时,使用此技能。
这是一个以Agent为核心的工作流。需基于仓库中的证据开展审计,指出得出每个结论的具体文件和调用位置,并通过微小的集成操作保留当前行为。

When to Trigger

触发时机

Use this skill for requests like:
  • "Audit this repo for Inngest opportunities"
  • "Add Inngest to this codebase"
  • "Make our webhooks / cron jobs / background tasks reliable"
  • "Find places where work can be lost on deploy or process crash"
  • "Replace fragile polling, delayed jobs, or fire-and-forget promises"
  • "Make this AI workflow / agent durable"
If the user is starting from scratch instead of a brownfield repo, use
inngest-setup
,
inngest-durable-functions
,
inngest-events
,
inngest-steps
, and, for AI workflows, the agent patterns in this skill. Use
inngest-agent-evals
when the request includes scoring, sessions, experiments, deferred scorers, Insights, or outcome-based evaluation.
在以下类请求中使用此技能:
  • “审计此仓库以寻找Inngest的应用机会”
  • “为该代码库添加Inngest”
  • “让我们的Webhook/定时任务/后台任务更可靠”
  • “找出部署或进程崩溃时可能丢失工作的位置”
  • “替换脆弱的轮询、延迟任务或即发即弃的Promise”
  • “让此AI工作流/Agent具备耐久性”
如果用户是从零开始而非处理遗留代码库,请使用
inngest-setup
inngest-durable-functions
inngest-events
inngest-steps
,对于AI工作流,可使用本技能中的Agent模式。当请求包含评分、会话、实验、延迟评分器、Insights或基于结果的评估时,使用
inngest-agent-evals

Audit Loop

审计循环

  1. Map the project shape.
    • Read
      package.json
      , workspace files, app/router structure, server entry points, deployment config, and test scripts.
    • Identify framework: Next.js App Router, Next.js Pages Router, Express, Hono, Fastify, Remix, SvelteKit, Astro, NestJS, worker-only service, or other.
    • Detect package manager and TypeScript conventions before adding files.
  2. Find existing Inngest usage.
    • Search for
      inngest
      ,
      createFunction
      ,
      serve(
      ,
      /api/inngest
      ,
      INNGEST_
      ,
      step.run
      ,
      step.sleep
      ,
      step.waitForEvent
      ,
      step.sendEvent
      ,
      step.invoke
      ,
      step.ai
      ,
      inngest.send
      , and
      @inngest/realtime
      .
    • If Inngest exists, inspect version, client config, serve endpoint, registered functions, event naming, env vars, and v3/v4 API shape before changing anything.
  3. Find durability gaps.
    • Search for fire-and-forget work:
      void someAsync()
      , un-awaited promises,
      .then(
      chains,
      setTimeout
      ,
      setInterval
      , detached jobs after HTTP response, and background work in route handlers.
    • Search for cron and schedulers:
      cron
      ,
      node-cron
      ,
      agenda
      ,
      bull
      ,
      bullmq
      ,
      bee-queue
      ,
      qstash
      ,
      sqs
      ,
      temporal
      ,
      trigger.dev
      , deployment cron config, and scheduled API routes.
    • Search for webhooks and at-least-once producers: Stripe, Clerk, GitHub, Slack, Shopify, HubSpot, Linear, Svix, and generic
      webhook
      .
    • Search for long-running work: PDF generation, exports, video/image processing, embeddings, bulk email, imports, ETL, sync jobs, polling loops, retries, and external API calls.
    • Search for AI agent shapes: tool loops, LLM calls, streaming tokens, human approval, multi-step reasoning, vector search, eval loops, scoring, experiment assignment, user-feedback signals, and provider calls that need rate limits or retry-safe state.
  4. Classify each candidate.
    • P0: user-visible loss, duplicate charge/email/action, timeout, missed webhook, or crash-prone workflow.
    • P1: fragile but recoverable background work, manual retry burden, noisy 429s, or poor observability.
    • P2: cleanup, ergonomics, or future migration opportunity.
    • For each candidate, record: file, current trigger, side effects, idempotency key, failure mode, recommended Inngest primitive, migration size, and confidence.
  5. Choose the smallest safe integration.
    • Prefer one vertical slice over a wide rewrite.
    • Keep existing domain functions and data models where possible.
    • Add an Inngest client and serve endpoint only once.
    • Move side effects into
      step.run
      one boundary at a time.
    • Make event IDs and database writes idempotent before adding retries.
    • Add tests around existing behavior and the new event/function boundary.
  1. 梳理项目结构
    • 读取
      package.json
      、工作区文件、应用路由结构、服务器入口点、部署配置和测试脚本。
    • 识别框架:Next.js App Router、Next.js Pages Router、Express、Hono、Fastify、Remix、SvelteKit、Astro、NestJS、仅Worker服务或其他框架。
    • 在添加文件前,检测包管理器和TypeScript约定。
  2. 查找现有Inngest使用情况
    • 搜索
      inngest
      createFunction
      serve(
      /api/inngest
      INNGEST_
      step.run
      step.sleep
      step.waitForEvent
      step.sendEvent
      step.invoke
      step.ai
      inngest.send
      @inngest/realtime
    • 如果已存在Inngest,在进行任何修改前,检查其版本、客户端配置、服务端点、已注册函数、事件命名、环境变量及v3/v4 API结构。
  3. 找出耐久性缺口
    • 搜索即发即弃的工作:
      void someAsync()
      、未等待的Promise、
      .then(
      链、
      setTimeout
      setInterval
      、HTTP响应后的分离式任务,以及路由处理程序中的后台工作。
    • 搜索定时任务和调度器:
      cron
      node-cron
      agenda
      bull
      bullmq
      bee-queue
      qstash
      sqs
      temporal
      trigger.dev
      、部署定时任务配置和定时API路由。
    • 搜索Webhook和至少一次生产者:Stripe、Clerk、GitHub、Slack、Shopify、HubSpot、Linear、Svix以及通用
      webhook
    • 搜索长时间运行的工作:PDF生成、导出、视频/图像处理、嵌入、批量邮件、导入、ETL、同步任务、轮询循环、重试和外部API调用。
    • 搜索AI Agent结构:工具循环、LLM调用、流式令牌、人工审批、多步骤推理、向量搜索、评估循环、评分、实验分配、用户反馈信号,以及需要速率限制或可重试安全状态的提供商调用。
  4. 对每个候选对象分类
    • P0:用户可见的损失、重复收费/邮件/操作、超时、丢失的Webhook或易崩溃的工作流。
    • P1:脆弱但可恢复的后台工作、手动重试负担、频繁的429错误或可观测性差。
    • P2:清理工作、优化可用性或未来迁移机会。
    • 为每个候选对象记录:文件、当前触发器、副作用、幂等键、故障模式、推荐的Inngest原语、迁移规模和置信度。
  5. 选择最小化的安全集成方案
    • 优先选择垂直切片而非大范围重写。
    • 尽可能保留现有的领域函数和数据模型。
    • 仅添加一次Inngest客户端和服务端点。
    • 逐步将副作用迁移到
      step.run
      边界内。
    • 在添加重试前,确保事件ID和数据库写入具备幂等性。
    • 围绕现有行为和新的事件/函数边界添加测试。

Useful Discovery Commands

实用的发现命令

Run commands that fit the repo. Prefer
rg
; keep output focused.
bash
rg -n "inngest|createFunction|step\\.|serve\\(|/api/inngest|INNGEST_" .
rg -n "setTimeout|setInterval|Promise\\.all|void [a-zA-Z0-9_]+\\(|\\.then\\(" .
rg -n "cron|node-cron|schedule|bull|bullmq|bee-queue|agenda|qstash|sqs" .
rg -n "webhook|stripe|svix|clerk|github|shopify|slack|hubspot|linear" .
rg -n "retry|backoff|poll|status|timeout|429|rate limit|rate-limit" .
rg -n "openai|anthropic|ai\\.|generateText|streamText|tool|agent|embedding" .
When the repo is large, narrow searches to app source directories and exclude generated/vendor folders.
运行适合仓库的命令。优先使用
rg
;保持输出聚焦。
bash
rg -n "inngest|createFunction|step\\.|serve\\(|/api/inngest|INNGEST_" .
rg -n "setTimeout|setInterval|Promise\\.all|void [a-zA-Z0-9_]+\\(|\\.then\\(" .
rg -n "cron|node-cron|schedule|bull|bullmq|bee-queue|agenda|qstash|sqs" .
rg -n "webhook|stripe|svix|clerk|github|shopify|slack|hubspot|linear" .
rg -n "retry|backoff|poll|status|timeout|429|rate limit|rate-limit" .
rg -n "openai|anthropic|ai\\.|generateText|streamText|tool|agent|embedding" .
当仓库较大时,将搜索范围缩小到应用源码目录,并排除生成/供应商文件夹。

Brownfield Decision Matrix

遗留代码库决策矩阵

Existing shapeInngest fitPrimary primitives
HTTP handler does slow side effects before respondingEmit event, return fast
inngest.send
, event trigger,
step.run
Webhook must acknowledge quickly but process reliablyVerify signature, emit idempotent eventEvent ID,
step.run
, retries
Cron job loses progress midwayCron-triggered durable functionCron trigger, page-level
step.run
, flow control
Polling loop waits for external async workDurable wait or durable poll
step.waitForEvent
,
step.sleep
,
step.run
Large fan-out exceeds request/serverless limitsSplit orchestration and item work
step.sendEvent
, per-item function, concurrency
External API hits 429sMove limits to function config
throttle
,
rateLimit
,
concurrency
Human review can take daysPersist the wait in Inngest
step.waitForEvent
, timeout, realtime
AI agent/tool loop needs retry-safe progressOne step per tool/model boundary
step.ai
,
step.run
,
step.sleep
, realtime
AI workflow needs production evalsAttach outcome signals to durable runs
meta.sessions
,
step.score
,
createScorer
,
defer
,
group.experiment
Existing queue only hides fragile workReplace queue boundary graduallyEvent trigger, idempotency, function-level retries
现有结构Inngest适配性核心原语
HTTP处理程序在响应前执行缓慢的副作用发送事件,快速返回
inngest.send
、事件触发器、
step.run
Webhook必须快速确认但需可靠处理验证签名,发送幂等事件事件ID、
step.run
、重试
定时任务中途丢失进度定时触发的持久化函数定时触发器、页面级
step.run
、流控制
轮询循环等待外部异步工作持久化等待或持久化轮询
step.waitForEvent
step.sleep
step.run
大规模扇出超出请求/无服务器限制拆分编排与项级工作
step.sendEvent
、项级函数、并发控制
外部API触发429错误将限制移至函数配置
throttle
rateLimit
concurrency
人工审核可能耗时数天在Inngest中持久化等待状态
step.waitForEvent
、超时、实时功能
AI Agent/工具循环需要可重试的安全进度每个工具/模型边界对应一个步骤
step.ai
step.run
step.sleep
、实时功能
AI工作流需要生产环境评估将结果信号附加到持久化运行
meta.sessions
step.score
createScorer
defer
group.experiment
现有队列仅隐藏脆弱工作逐步替换队列边界事件触发器、幂等性、函数级重试

Integration Plan Format

集成计划格式

Before editing, summarize findings in this compact shape:
text
Inngest audit:
- Existing Inngest: none / partial / healthy / risky
- Framework: <framework and evidence>
- Best first slice: <file + workflow>
- Why: <loss/timeout/retry/idempotency failure>
- Proposed primitives: <event, steps, flow control, waits, realtime>
- Idempotency key: <source of truth>
- Files likely touched: <short list>
- Tests/checks: <commands or focused cases>
Then implement unless the user asked for audit-only.
在编辑前,将发现结果总结为以下简洁格式:
text
Inngest审计结果:
- 现有Inngest使用情况:无/部分/健康/风险
- 框架:<框架及证据>
- 最佳首个切片:<文件 + 工作流>
- 原因:<损失/超时/重试/幂等性故障>
- 推荐原语:<事件、步骤、流控制、等待、实时功能>
- 幂等键:<数据源>
- 可能涉及的文件:<简短列表>
- 测试/检查:<命令或聚焦案例>
然后执行集成,除非用户仅要求审计。

Existing Inngest Checklist

现有Inngest检查清单

If Inngest is already present, verify:
  • A single shared client is exported from a stable module.
  • The app
    id
    is a stable slug and is not derived from deploy-specific data.
  • v4 local development uses
    INNGEST_DEV=1
    ; production uses
    INNGEST_SIGNING_KEY
    .
  • Serve endpoint path is discoverable, usually
    /api/inngest
    .
  • The serve handler registers all functions that should sync.
  • Side effects and non-deterministic work are inside steps.
  • Step IDs are stable and descriptive.
  • Event names follow
    domain/noun.verb
    .
  • Events that may be replayed use deterministic IDs.
  • Webhook handlers verify signatures before emitting events.
  • Flow control is configured where external APIs have limits.
  • Realtime uses v4 native
    inngest/realtime
    , not the v3
    @inngest/realtime
    package.
如果已存在Inngest,请验证:
  • 单个共享客户端从稳定模块导出。
  • 应用
    id
    是稳定的标识,并非从部署特定数据派生。
  • v4本地开发使用
    INNGEST_DEV=1
    ;生产环境使用
    INNGEST_SIGNING_KEY
  • 服务端点路径可被发现,通常为
    /api/inngest
  • 服务处理程序注册了所有应同步的函数。
  • 副作用和非确定性工作位于步骤内部。
  • 步骤ID稳定且具有描述性。
  • 事件名称遵循
    domain/noun.verb
    格式。
  • 可能被重放的事件使用确定性ID。
  • Webhook处理程序在发送事件前验证签名。
  • 针对外部API限制配置了流控制。
  • 实时功能使用v4原生
    inngest/realtime
    ,而非v3的
    @inngest/realtime
    包。

Durable Agent Patterns

持久化Agent模式

Use Inngest when an AI or agent workflow needs durable progress across model calls, tool calls, waits, approvals, or streaming UI updates.
Good candidates:
  • Multi-step agent that calls tools or external APIs.
  • LLM workflow that may exceed one HTTP request lifetime.
  • Human-in-the-loop review, approval, correction, or escalation.
  • Agent that must pause for an external event or scheduled follow-up.
  • Bulk AI work that needs provider-level rate limits and cost protection.
  • User-visible agent progress that should stream from durable execution.
Recommended shape:
  1. HTTP/UI request stores the user intent and emits an event with a stable
    id
    .
  2. Inngest function loads state inside
    step.run
    .
  3. Each model call, tool call, vector search, and external side effect lives in its own
    step.ai
    or
    step.run
    boundary.
  4. Human pauses use
    step.waitForEvent
    or
    step.waitForSignal
    with a timeout.
  5. Progress updates use
    step.realtime.publish
    between steps, or
    inngest.realtime.publish
    inside an existing
    step.run
    .
  6. Provider rate limits use
    concurrency
    ,
    throttle
    , or
    rateLimit
    , not ad hoc in-process throttlers.
Avoid:
  • Keeping agent state only in memory.
  • Retrying whole agent loops after a single tool failure.
  • Charging for repeated successful model calls because the result was not memoized.
  • Using
    setTimeout
    or a cron poller for follow-ups and approvals.
  • Streaming progress from a process-local WebSocket server when the workflow itself is durable elsewhere.
当AI或Agent工作流需要在模型调用、工具调用、等待、审批或流式UI更新之间保持持久化进度时,使用Inngest。
合适的场景:
  • 调用工具或外部API的多步骤Agent。
  • 可能超出单个HTTP请求生命周期的LLM工作流。
  • 人工介入的审核、批准、修正或升级流程。
  • 必须暂停以等待外部事件或计划后续操作的Agent。
  • 需要提供商级速率限制和成本保护的批量AI工作。
  • 用户可见的Agent进度,需从持久化执行中流式输出。
推荐结构:
  1. HTTP/UI请求存储用户意图,并发送带有稳定
    id
    的事件。
  2. Inngest函数在
    step.run
    内部加载状态。
  3. 每个模型调用、工具调用、向量搜索和外部副作用都位于各自的
    step.ai
    step.run
    边界内。
  4. 人工暂停使用
    step.waitForEvent
    step.waitForSignal
    并设置超时。
  5. 进度更新在步骤之间使用
    step.realtime.publish
    ,或在现有
    step.run
    内部使用
    inngest.realtime.publish
  6. 提供商速率限制使用
    concurrency
    throttle
    rateLimit
    ,而非临时的进程内节流器。
需避免:
  • 仅在内存中保存Agent状态。
  • 单个工具失败后重试整个Agent循环。
  • 因未缓存结果而重复收取成功模型调用的费用。
  • 使用
    setTimeout
    或定时轮询器处理后续操作和审批。
  • 当工作流本身在其他位置持久化时,从进程本地WebSocket服务器流式输出进度。

Implementation Guardrails

实施约束

  • Do not replace working queues, crons, or webhooks blindly. First preserve behavior with a thin Inngest slice.
  • Do not create duplicate clients or serve endpoints if the repo already has them.
  • Do not put database writes, API calls, random IDs, timestamps, or LLM calls outside steps in the new function.
  • Do not hide missing idempotency behind retries. Retries require idempotent side effects.
  • Do not hardcode secrets or dev-mode flags in source.
  • Do not leave the app unable to sync: register new functions with the serve endpoint and run available type/tests.
  • 不要盲目替换正常运行的队列、定时任务或Webhook。首先通过一个轻量的Inngest切片保留现有行为。
  • 如果仓库已存在Inngest客户端或服务端点,不要创建重复实例。
  • 不要将数据库写入、API调用、随机ID、时间戳或LLM调用放在新函数的步骤外部。
  • 不要用重试掩盖缺失的幂等性。重试需要具备幂等性的副作用。
  • 不要在源码中硬编码密钥或开发模式标志。
  • 不要让应用无法同步:将新函数注册到服务端点,并运行可用的类型检查/测试。

Verification

验证

Pick checks that prove the integration path:
  • Typecheck/build/lint the touched app.
  • Run existing tests around the migrated handler or workflow.
  • Add focused tests for "handler emits event and returns fast" and "function calls the same domain operations in step boundaries" where the repo supports it.
  • If local runtime is available, start the app and Inngest dev server, confirm the function syncs, then send a sample event.
  • If only static checks are available, explicitly state that runtime sync was not verified.
选择能证明集成路径的检查项:
  • 对修改的应用进行类型检查/构建/ lint。
  • 运行迁移处理程序或工作流周围的现有测试。
  • 在仓库支持的情况下,添加聚焦测试,如“处理程序发送事件并快速返回”和“函数在步骤边界内调用相同的领域操作”。
  • 如果本地运行时可用,启动应用和Inngest开发服务器,确认函数已同步,然后发送示例事件。
  • 如果仅支持静态检查,明确说明未验证运行时同步。