From d72eaffb6b7caca6e5c19a5e77beb09e13e795f6 Mon Sep 17 00:00:00 2001 From: Asep Haryana Saputra <90584806+MythEclipse@users.noreply.github.com> Date: Fri, 22 May 2026 16:30:17 +0000 Subject: [PATCH] fix: guard expert review state - Reject diagnoses not in needs_review status with badRequest - Make update conditional on both id and status needs_review using and() - Simplify isDiagnosisRecordOrNull type guard with type alias Co-Authored-By: Claude Opus 4.7 --- apps/api/src/routes/expert.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/api/src/routes/expert.ts b/apps/api/src/routes/expert.ts index fb3a467..dc1a9fb 100644 --- a/apps/api/src/routes/expert.ts +++ b/apps/api/src/routes/expert.ts @@ -1,14 +1,16 @@ import { Elysia } from 'elysia'; import type { ReviewDiagnosisRequest } from '@zeavis/shared'; import { isDiseaseSlug } from '@zeavis/shared'; -import { desc, eq } from 'drizzle-orm'; +import { and, desc, eq } from 'drizzle-orm'; import { createDbClient } from '../db/client'; import { diagnoses, expertReviews } from '../db/schema'; import { badRequest, forbidden, notFound, serviceUnavailable, unauthorized } from '../lib/http-errors'; import { getCurrentUser } from '../lib/auth'; import { loadDiagnosisRecord } from './diagnoses'; -function isDiagnosisRecordOrNull(record: unknown): record is ReturnType extends Promise ? T : never { +type DiagnosisRecord = Awaited>; + +function isDiagnosisRecordOrNull(record: unknown): record is DiagnosisRecord { return record !== null; } @@ -62,6 +64,7 @@ export const expertRoutes = new Elysia({ prefix: '/api/v1/expert' }) const diagnosis = existing[0]; if (!diagnosis) return notFound('Diagnosis not found'); + if (diagnosis.status !== 'needs_review') return badRequest('Diagnosis is not pending review'); const correctedSlug = req.verdict === 'corrected' ? req.correctedDiseaseSlug : null; @@ -80,7 +83,7 @@ export const expertRoutes = new Elysia({ prefix: '/api/v1/expert' }) predictedDiseaseSlug: req.verdict === 'corrected' ? correctedSlug : diagnosis.predictedDiseaseSlug, updatedAt: new Date(), }) - .where(eq(diagnoses.id, diagnosis.id)); + .where(and(eq(diagnoses.id, diagnosis.id), eq(diagnoses.status, 'needs_review'))); return await loadDiagnosisRecord(diagnosis.id, null, true); } catch (error) {