fix: type diagnosis record mapping
- Replace `function toReview(row: any)` with typed ReviewRow interface - Reconstruct DiseaseCatalogItem explicitly from selected fields instead of casting - Replace `.filter(Boolean)` with typed isDiagnosisRecord predicate - Add proper type narrowing for verdict and correctedDiseaseSlug in toReview Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
2e692a4b8c
commit
afa2e4999b
@@ -10,26 +10,47 @@ import { classifyImage } from '../lib/image-model';
|
|||||||
import { uploadImageToStorage } from '../lib/uploader-client';
|
import { uploadImageToStorage } from '../lib/uploader-client';
|
||||||
import { env } from '../config/env';
|
import { env } from '../config/env';
|
||||||
|
|
||||||
function toReview(row: any): ExpertReviewRecord | null {
|
interface ReviewRow {
|
||||||
|
reviewId: string | null;
|
||||||
|
reviewDiagnosisId: string | null;
|
||||||
|
reviewExpertId: string | null;
|
||||||
|
reviewVerdict: string | null;
|
||||||
|
reviewCorrectedDiseaseSlug: string | null;
|
||||||
|
reviewNotes: string | null;
|
||||||
|
reviewCreatedAt: Date | null;
|
||||||
|
expertId: string | null;
|
||||||
|
expertEmail: string | null;
|
||||||
|
expertName: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toReview(row: ReviewRow): ExpertReviewRecord | null {
|
||||||
if (!row.reviewId) return null;
|
if (!row.reviewId) return null;
|
||||||
|
|
||||||
|
const verdict = row.reviewVerdict as 'verified' | 'corrected';
|
||||||
|
const correctedDiseaseSlug = row.reviewCorrectedDiseaseSlug && isDiseaseSlug(row.reviewCorrectedDiseaseSlug) ? row.reviewCorrectedDiseaseSlug : null;
|
||||||
|
const notes = row.reviewNotes || '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: row.reviewId,
|
id: row.reviewId,
|
||||||
diagnosisId: row.reviewDiagnosisId,
|
diagnosisId: row.reviewDiagnosisId!,
|
||||||
expertId: row.reviewExpertId,
|
expertId: row.reviewExpertId!,
|
||||||
verdict: row.reviewVerdict,
|
verdict,
|
||||||
correctedDiseaseSlug: row.reviewCorrectedDiseaseSlug,
|
correctedDiseaseSlug,
|
||||||
notes: row.reviewNotes,
|
notes,
|
||||||
createdAt: row.reviewCreatedAt.toISOString(),
|
createdAt: row.reviewCreatedAt!.toISOString(),
|
||||||
expert: {
|
expert: {
|
||||||
id: row.expertId,
|
id: row.expertId!,
|
||||||
email: row.expertEmail,
|
email: row.expertEmail!,
|
||||||
name: row.expertName,
|
name: row.expertName!,
|
||||||
role: 'expert',
|
role: 'expert',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDiagnosisRecord(record: DiagnosisRecord | null): record is DiagnosisRecord {
|
||||||
|
return record !== null;
|
||||||
|
}
|
||||||
|
|
||||||
async function loadDiagnosisRecord(id: string, userId: string | null, expertAccess: boolean): Promise<DiagnosisRecord | null> {
|
async function loadDiagnosisRecord(id: string, userId: string | null, expertAccess: boolean): Promise<DiagnosisRecord | null> {
|
||||||
const db = createDbClient();
|
const db = createDbClient();
|
||||||
const filters = [eq(diagnoses.id, id)];
|
const filters = [eq(diagnoses.id, id)];
|
||||||
@@ -101,7 +122,20 @@ async function loadDiagnosisRecord(id: string, userId: string | null, expertAcce
|
|||||||
|
|
||||||
const predictedDiseaseSlug = row.predictedDiseaseSlug && isDiseaseSlug(row.predictedDiseaseSlug) ? row.predictedDiseaseSlug : null;
|
const predictedDiseaseSlug = row.predictedDiseaseSlug && isDiseaseSlug(row.predictedDiseaseSlug) ? row.predictedDiseaseSlug : null;
|
||||||
const status = row.status as DiagnosisStatus;
|
const status = row.status as DiagnosisStatus;
|
||||||
const disease = row.disease && row.disease.slug ? (row.disease as DiseaseCatalogItem) : null;
|
const disease = row.disease && row.disease.slug && isDiseaseSlug(row.disease.slug)
|
||||||
|
? ({
|
||||||
|
slug: row.disease.slug,
|
||||||
|
label: row.disease.label,
|
||||||
|
commonName: row.disease.commonName,
|
||||||
|
summary: row.disease.summary,
|
||||||
|
description: row.disease.description,
|
||||||
|
symptoms: row.disease.symptoms,
|
||||||
|
recommendations: row.disease.recommendations,
|
||||||
|
riskLevel: row.disease.riskLevel,
|
||||||
|
accentColor: row.disease.accentColor,
|
||||||
|
displayOrder: row.disease.displayOrder,
|
||||||
|
} as DiseaseCatalogItem)
|
||||||
|
: null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: row.id,
|
id: row.id,
|
||||||
@@ -223,7 +257,7 @@ export const diagnosisRoutes = new Elysia({ prefix: '/api/v1' })
|
|||||||
.limit(30);
|
.limit(30);
|
||||||
|
|
||||||
const records = await Promise.all(rows.map((row) => loadDiagnosisRecord(row.id, user.id, false)));
|
const records = await Promise.all(rows.map((row) => loadDiagnosisRecord(row.id, user.id, false)));
|
||||||
return records.filter(Boolean);
|
return records.filter(isDiagnosisRecord);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return serviceUnavailable('Database unavailable');
|
return serviceUnavailable('Database unavailable');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user