← ClaudeAtlas

background-jobslisted

Model long-running or scheduled work as background jobs — never inline in a request handler. Use for batch processing, PDF generation, reminders, or payroll run processing.
rajurayhan/ai-agent-framework · ★ 0 · AI & Automation · score 68
Install: claude install-skill rajurayhan/ai-agent-framework
# Background Jobs Batch processing, PDF generation, and reminders must run as background jobs — they can exceed function time limits and request-scoped failure shouldn't leave entities half-processed. ## Pattern 1. Server handler validates input and permissions (see `add-server-action`), then **enqueues** an event — it does not perform heavy computation itself. 2. Job handler does the work, broken into `step.run(...)` steps so partial progress survives retries. 3. **Idempotency is mandatory**: key on entity ID; check/set status transactionally before work — retried/duplicate events must be safe no-ops. 4. Job drives status machine and writes audit logs — async doesn't exempt auditing. ## Rules - Never perform batch computation, PDF rendering, or bulk export inside a request handler directly - Every job that mutates money data writes audit log entries - Design every step to be safely re-runnable on retry ## Example ```typescript createFunction( { id: 'process-entity', idempotency: 'event.data.entityId' }, { event: 'entity/process.requested' }, async ({ event, step }) => { const entity = await step.run('load', () => loadEntity(event.data.entityId)); if (entity.status === 'processed') return { skipped: true }; await step.run('process', () => processEntity(entity)); await step.run('mark-done', () => markProcessed(entity)); } ); ``` Test: invoke twice, assert second is no-op. See `testing-conventions` for job testing. Full worked example: If Cursor