Feature Owner: scorevi (Sean Patrick Caintic)
Module: Review Workflow
Priority: P1
Sprint #12: Fully Implemented & Deployed
Date: 2026-06-29
EXECUTIVE SUMMARY
What is this feature?
End-to-end content review pipeline. Creators submit quests for review. Reviewers claim them, review on a read-only canvas, then approve-and-publish or reject-and-return-to-draft. Layout guard: app/reviewer/layout.tsx — authenticateAnyRole(['REVIEWER','ADMIN','CREATOR','AGENCY']).
Why does it matter?
Quality assurance for learner-facing content requires a formal review process. Without it, draft content could be published without review. The pipeline ensures every published quest has been vetted.
What's the MVP scope?
Fully deployed. Submission pipeline (draft → submitted → in_review → approved/changes_requested). Reviewer claim and lockout (one reviewer per quest). Read-only canvas review. Approve/reject with content validation. Guest SME invites.
1. USER PAIN POINT & SOLUTION
Current State (Without Feature)
Creators publish directly without review. No QA gate. Learners may encounter low-quality or broken content.
Pain Point
Emotional: "I have no way to get feedback on my quest before learners see it."
Functional: No approval workflow.
Business Impact: Quality control risk; learner churn from bad content experiences.
Future State (With Feature)
Creator submits quest → reviewer claims it → reviewer adds comments on specific canvas nodes → reviewer approves and publishes or rejects with changes requested. Full audit trail.
Marketing Hook
"Every quest, reviewed. Every node, commented. Only approved content reaches learners."
2. 4D FRAMEWORK MAPPING
Diagnose
Reviewers diagnose content issues through node-level comments and canvas inspection.
Design
Review workflow is part of the content design feedback loop.
Develop
Changes requested → creator revises → resubmits.
Deliver
Approved content is published for learners.
3. USER FLOWS
Entry Point
Creator clicks "Submit for Review" on a quest. Reviewer sees it in their queue.
Success Criteria
Quest approved and published. Or rejected with clear feedback for revision.
Main Flow (Happy Path)
Creator builds quest → submits for review
publishing_status = "submitted",reviewer_id = NULL
Reviewer visits
/reviewer/queue(app/reviewer/queue/page.tsx, 226 lines)SSR fetches unclaimed + claimed quests
Reviewer dashboard shows metrics (
app/reviewer/dashboard/page.tsx, 135 lines)Reviewer claims quest (
POST /api/reviewer/claim-quest)Auth:
["REVIEWER","ADMIN","AGENCY"]— CREATOR EXCLUDEDChecks
.is("reviewer_id", null)— prevents duplicate claimsSets
reviewer_id+status = "in_review"If already claimed: returns success with null (0 rows updated — silent no-op). NO 409 response.
Reviewer opens quest in read-only canvas
GET /api/reviewer/get-canvas/route.ts— bypasses creator ownership
Reviewer submits review:
"Approve & Publish" → validates canvas content → status =
"approved""Reject & Return to Draft" → status =
"changes_requested"
Creator notified
Edge Cases
No data: Empty queue → "No quests awaiting review" state.
API error: Canvas validation fails on approve → "Fix issues before approving" error.
Permission denied: Non-reviewer claiming → 403.
Already claimed: Returns success with null (silent no-op, NOT 409).
Decision Points
IF quest has unresolved comments → approval BLOCKED (blocker gate).
IF canvas content invalid → approval BLOCKED (content validation gate).
4. INFORMATION ARCHITECTURE
Primary Information (Always visible)
Queue: Table with quest title, creator, submission date, AI score, status.
Dashboard: Metrics cards: pending, active, changes, approved.
Secondary Information
Quest overview modal with description and metadata.
AI validator score for submitted quests.
Actions
Primary CTA: "Claim Quest", "Submit Review".
Secondary Actions: "View Canvas", "Invite Guest Reviewer".
5. WIREFRAMES
Excluded — UI is fully developed (app/reviewer/queue/page.tsx 226 lines, app/reviewer/dashboard/page.tsx 135 lines).
6. WIREFLOWS
Excluded.
7. PROTOTYPE
Excluded — production deployed.
8. BACKEND SCHEMA
Database Extensions
-- Extended publishing_status CHECK constraintpublishing_status IN ('published','draft','archived','submitted','in_review','changes_requested','approved') -- Reviewer assignment columnALTER TABLE quests ADD COLUMN reviewer_id TEXT; -- Clerk user ID, NULL = unclaimed -- REVIEWER role added to app_users.role CHECK (migration 20260219000000)role IN ('ADMIN','AGENCY','CREATOR','LEARNER','REVIEWER')
Key Components
QueueClient.tsx,QuestOverviewModal.tsx,SubmitReviewModal.tsxReviewerPersonalMetrics.tsx,ReviewerAnalyticsCard.tsxGuestInviteModal.tsx,GuestCanvas.tsxReviewLockOverlay.tsx— locks creator out during review
9. API ENDPOINTS
POST /api/reviewer/claim-quest (auth: REVIEWER,ADMIN,AGENCY — CREATOR excluded. Checks reviewer_id IS NULL. Sets reviewer_id + in_review. Returns success null if already claimed.)PATCH /api/reviewer/update-quest-status (approve/changes_requested with content validation — 149 lines)GET /api/reviewer/get-canvas (bypasses creator ownership for read-only access)POST /api/reviewer/invites (create guest SME invite)GET /api/reviewer/invites/[inviteId] (view invite status)PATCH /api/reviewer/invites/[inviteId] (revoke invite)DELETE /api/reviewer/invites/[inviteId] (delete invite)GET /api/reviewer/analytics/personal (current user metrics)GET /api/reviewer/analytics/resolution (resolution rate)GET /api/reviewer/analytics/node-feedback (per-node heatmap)GET /api/reviewer/analytics/activity (per-reviewer activity)
10. DATA REQUIREMENTS
Frontend Needs
Real-time queue with unclaimed + claimed quests (SSR).
AI score integration.
Reviewer's personal metrics for dashboard.
Caching Strategy
Queue fetched server-side for SSR (no stale cache).
11. PERFORMANCE CONSIDERATIONS
Database Optimization
Index on
quests.publishing_statusfor filtering submitted/in_review quests.Index on
quests.reviewer_idfor claimed quest lookup.
API Response Time
Target: <500ms for queue fetch.
Who can access this feature?
Layout: REVIEWER, ADMIN, CREATOR, AGENCY (via
authenticateAnyRole).Claim: REVIEWER, ADMIN, AGENCY only (CREATOR excluded).
Canvas: bypasses creator ownership for read-only access.
Claim route: .is("reviewer_id", null) prevents duplicate claims (lockout enforcement).
KNOWN SECURITY GAP
/api/reviewer/update-quest-status/route.ts (149 lines) does NOT verify the caller is the quest's reviewer_id. Any REVIEWER/ADMIN/AGENCY can update any quest status, not just their own claimed quests.
13. ERROR HANDLING
Error | Response |
|---|---|
Quest already claimed | Returns success with null data (0 rows updated — silent no-op). NO 409. |
Unresolved comments on approve | 422: "Resolve all comments before approving" |
Invalid canvas content | 422: Validation details per node |
Canvas validation failure | "Fix the highlighted issues before publishing" |
14. TESTING CHECKLIST
Happy Path
□ Submit quest → appears in queue
□ Reviewer claims → status = in_review → creator locked (ReviewLockOverlay)
□ Approve with resolved comments → published
□ Reject → changes_requested → creator unlocked
Edge Cases
□ Two reviewers try to claim same quest → second gets success null (0 rows updated)
□ Approve with unresolved comments → blocked
□ Non-reviewer accessing queue → redirected
□ CREATOR tries to claim quest → excluded from claim auth
15. OPEN QUESTIONS
Security gap:
update-quest-statusshould verifyreviewer_idmatches the caller to prevent unauthorized status changes.Claim route should return a proper 409/conflict response instead of silent success null.
16. OUT OF SCOPE (v1.1+)
Round-robin reviewer assignment.
Review SLA tracking.
Automated review reminders.
17. SUCCESS METRICS
Average review time <24 hours.
100% of published quests pass through review pipeline.
18. DEPENDENCIES
This feature depends on:
[7.1] Reviewers' Commenting System.
[7.2] Guest Access & Invitations.
[0.1] Secure Login + [6.1.1] RBAC.
[W1.5] Canvas Schema — read-only canvas + node-level comments.
These features depend on this:
Content publishing flow (only published quests reach learners).
19. TIMELINE & OWNERSHIP
Sprint #12: Already deployed.
Backend: scorevi
Frontend: scorevi
Estimated Completion: Complete.
Document Version
1.0 - Initial version - 2026-06-29 08:21 UTC
1.1 - Added Document Version section and update author to have full name - 2026-06-29 08:47 UTC