Goal
The worker drains processing jobs, calls the AI service, persists run, fields and evidence and moves the request to REVIEW in one transaction; failures retry with backoff and end in ERROR with a visible cause.
Acceptance criteria
Not part of this task
- Vercel triggers for
drain() (showcase epic), export
Affected areas
src/features/jobs/
src/features/extraction/
src/features/requests/
Test plan
| Criterion |
Check |
| idempotent handler |
integration test with duplicate delivery |
| retry → ERROR |
integration test with a failing AI-service stub at the HTTP boundary |
| status machine |
unit test |
Security/Privacy affected?
Job payloads carry IDs only; handlers run inside withTenant.
Epic: #2 · Architecture: docs/decisions/ADR-0001-pilot-architecture.md
Goal
The worker drains processing jobs, calls the AI service, persists run, fields and evidence and moves the request to REVIEW in one transaction; failures retry with backoff and end in ERROR with a visible cause.
Acceptance criteria
fromDrizzle),singletonKey = requestId, retry with backoff, dead-letter queuedrain({ maxMs })processes jobs until its budget; the worker loop uses itNot part of this task
drain()(showcase epic), exportAffected areas
src/features/jobs/src/features/extraction/src/features/requests/Test plan
Security/Privacy affected?
Job payloads carry IDs only; handlers run inside
withTenant.Epic: #2 · Architecture:
docs/decisions/ADR-0001-pilot-architecture.md