NEEDS_REVIEW validation now creates a real human review workflow.
Validation result:
ExtractionRun.status = NEEDS_REVIEW
Then:
ReviewTask.status = PENDING
ReviewTask.priority = NORMAL
ReviewTask.reasonJson = missing fields / conflicts / warnings / required evidence
ReviewEvent.type = REVIEW_TASK_CREATED
Proof:
AI validation no longer just marks a run as NEEDS_REVIEW.
It opens a separate ReviewTask for human review.
ReviewTask backend APIs are implemented and state transitions are enforced.
Supported flow:
PENDING → IN_REVIEW
IN_REVIEW → APPROVED
IN_REVIEW → REJECTED
IN_REVIEW → NEEDS_MORE_INFO
APIs:
GET /api/review-tasks
GET /api/review-tasks/[taskId]
POST /api/review-tasks/[taskId]/start
POST /api/review-tasks/[taskId]/approve
POST /api/review-tasks/[taskId]/reject
POST /api/review-tasks/[taskId]/request-more-info
Proof:
Every human action creates ReviewEvent.
Final decisions create ReviewDecision.
Invalid transitions return 409.
Reject/request-more-info require notes.
Validation route owns AI validation.
Review APIs own human review.
Human In the loop Workflow so far

1. Update DB Schema with Review Workflow Tables

2. Upserting Review Task when validationResult.status === “NEEDS_REVIEW”

3. Adding endpoints

