mirror of
https://github.com/Tony0410/nextstep.git
synced 2026-05-25 13:51:40 +08:00
feat: implement all 8 new health management features
This commit implements all features specified in the eight-features design doc: Features Added: - Temperature Log: Track body temperature with fever alerts and trend charts - Contact Directory: Manage healthcare contacts with categories and roles - Weight Log: Monitor weight changes with BMI calculation and alerts - Treatment Timeline: Track treatment milestones and visualize progress - Caregiver Tasks: Manage delegated care tasks with completion tracking - Lab Results: Record lab tests with reference ranges and trend analysis - Medical Documents: Upload and organize medical documents - Drug Interactions: Check for interactions between medications Technical Changes: - Added 8 new Prisma models (TemperatureLog, Contact, WeightLog, TreatmentMilestone, CaregiverTask, LabResult, MedicalDocument, DrugInteraction) - Created 56 new components across 8 feature domains - Implemented 23 new API routes with full CRUD operations - Added comprehensive Zod schemas for type validation - Extended Dexie DB (v3) for offline-first sync support - Created lab panel templates (CBC, CMP, Liver, Tumor Markers) with flag computation - Built drug interaction checker with curated interaction database - Added 76 new tests (99 total) covering all new functionality Bug Fixes: - Fixed operator precedence bug in interaction checker - Fixed timezone handling in calculator tests - Aligned test expectations with grace window behavior All 99 tests pass and build completes successfully.
This commit is contained in:
66
src/app/api/workspaces/[id]/lab-results/trends/route.ts
Normal file
66
src/app/api/workspaces/[id]/lab-results/trends/route.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import { prisma } from '@/lib/db/prisma'
|
||||
import { checkWorkspaceAccess } from '@/lib/db/workspace-access'
|
||||
import { withAuth, type AuthenticatedRequest } from '@/lib/auth'
|
||||
|
||||
interface StoredMarker {
|
||||
marker: string
|
||||
value: number
|
||||
unit: string
|
||||
refMin: number | null
|
||||
refMax: number | null
|
||||
flag: string | null
|
||||
}
|
||||
|
||||
export const GET = withAuth(async (
|
||||
req: AuthenticatedRequest,
|
||||
{ params }: { params: Promise<Record<string, string>> }
|
||||
) => {
|
||||
try {
|
||||
const { id: workspaceId } = await params
|
||||
const access = await checkWorkspaceAccess(workspaceId, req.session.user.id)
|
||||
if (!access) return NextResponse.json({ error: 'Access denied' }, { status: 403 })
|
||||
|
||||
const { searchParams } = new URL(req.url)
|
||||
const markerName = searchParams.get('marker')
|
||||
if (!markerName) return NextResponse.json({ error: 'marker query param required' }, { status: 400 })
|
||||
|
||||
// Fetch all lab results with this marker
|
||||
const labResults = await prisma.labResult.findMany({
|
||||
where: { workspaceId, deletedAt: null },
|
||||
orderBy: { testDate: 'asc' },
|
||||
select: { testDate: true, results: true },
|
||||
})
|
||||
|
||||
// Extract the specific marker from each result
|
||||
const trendData: Array<{
|
||||
date: string
|
||||
value: number
|
||||
unit: string
|
||||
refMin: number | null
|
||||
refMax: number | null
|
||||
}> = []
|
||||
|
||||
for (const lr of labResults) {
|
||||
const markers = lr.results as unknown as StoredMarker[]
|
||||
if (!Array.isArray(markers)) continue
|
||||
const found = markers.find(
|
||||
(m) => m.marker.toLowerCase() === markerName.toLowerCase()
|
||||
)
|
||||
if (found) {
|
||||
trendData.push({
|
||||
date: lr.testDate.toISOString(),
|
||||
value: found.value,
|
||||
unit: found.unit,
|
||||
refMin: found.refMin ?? null,
|
||||
refMax: found.refMax ?? null,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({ marker: markerName, trendData })
|
||||
} catch (error) {
|
||||
console.error('Lab result trends error:', error)
|
||||
return NextResponse.json({ error: 'Failed to fetch trends' }, { status: 500 })
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user