mirror of
https://github.com/Tony0410/nextstep.git
synced 2026-05-24 21:31:43 +08:00
Add 11 major features for caregiver health management
Features added: - Emergency Info Card: Full-screen emergency view with patient info - Refill Tracker: Track pill counts with auto-decrement on dose - Activity Feed: View caregiver activity with filtering - Symptom Tracker: Log symptoms with severity and offline sync - Print Views: Daily meds, appointments, doctor visit summaries - iCal Export: Calendar subscription for appointments - PDF Export: Medical summary for doctor visits - Calendar View: Monthly calendar for appointments - Appointment Preparation: Checklist for upcoming appointments - Medication Reminders: PWA push notifications with quiet hours Bug fixes: - Fix invite workflow: Register/login now properly redirect back - Add undo for doctor questions (can unmark "asked" questions) - Fix API route type annotations for Next.js 14 compatibility - Add Suspense boundary for useSearchParams in login/register Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,7 @@ export const GET = withAuth(async (req: AuthenticatedRequest) => {
|
||||
const sinceDate = new Date(since)
|
||||
|
||||
// Fetch all changed entities
|
||||
const [appointments, medications, notes, doseLogs, workspace] = await Promise.all([
|
||||
const [appointments, medications, notes, doseLogs, symptoms, workspace] = await Promise.all([
|
||||
prisma.appointment.findMany({
|
||||
where: { workspaceId, syncedAt: { gt: sinceDate } },
|
||||
include: {
|
||||
@@ -63,6 +63,12 @@ export const GET = withAuth(async (req: AuthenticatedRequest) => {
|
||||
undoneBy: { select: { id: true, name: true } },
|
||||
},
|
||||
}),
|
||||
prisma.symptom.findMany({
|
||||
where: { workspaceId, syncedAt: { gt: sinceDate } },
|
||||
include: {
|
||||
createdBy: { select: { id: true, name: true } },
|
||||
},
|
||||
}),
|
||||
prisma.workspace.findUnique({
|
||||
where: { id: workspaceId },
|
||||
select: {
|
||||
@@ -74,13 +80,21 @@ export const GET = withAuth(async (req: AuthenticatedRequest) => {
|
||||
quietHoursEnd: true,
|
||||
largeTextMode: true,
|
||||
updatedAt: true,
|
||||
// Emergency info fields
|
||||
patientName: true,
|
||||
patientDOB: true,
|
||||
bloodType: true,
|
||||
allergies: true,
|
||||
medicalConditions: true,
|
||||
primaryPhysician: true,
|
||||
physicianPhone: true,
|
||||
},
|
||||
}),
|
||||
])
|
||||
|
||||
// Calculate new cursor (latest syncedAt timestamp)
|
||||
let cursor = since
|
||||
const allItems = [...appointments, ...medications, ...notes, ...doseLogs]
|
||||
const allItems = [...appointments, ...medications, ...notes, ...doseLogs, ...symptoms]
|
||||
for (const item of allItems) {
|
||||
const itemTime = (item as { syncedAt: Date }).syncedAt.getTime()
|
||||
if (itemTime > cursor) {
|
||||
@@ -94,6 +108,7 @@ export const GET = withAuth(async (req: AuthenticatedRequest) => {
|
||||
medications,
|
||||
notes,
|
||||
doseLogs,
|
||||
symptoms,
|
||||
cursor,
|
||||
hasConflicts: false, // For now, always false - client handles conflicts
|
||||
})
|
||||
@@ -296,6 +311,64 @@ export const POST = withAuth(async (req: AuthenticatedRequest) => {
|
||||
break
|
||||
}
|
||||
|
||||
case 'UNMARK_ASKED': {
|
||||
if (!op.entityId) {
|
||||
results.push({ opId: op.id, success: false, error: 'Missing entityId' })
|
||||
break
|
||||
}
|
||||
|
||||
await prisma.note.update({
|
||||
where: { id: op.entityId },
|
||||
data: {
|
||||
askedAt: null,
|
||||
updatedById: req.session.user.id,
|
||||
version: { increment: 1 },
|
||||
syncedAt: new Date(),
|
||||
},
|
||||
})
|
||||
results.push({ opId: op.id, success: true })
|
||||
break
|
||||
}
|
||||
|
||||
case 'LOG_SYMPTOM': {
|
||||
if (!op.data) {
|
||||
results.push({ opId: op.id, success: false, error: 'Missing symptom data' })
|
||||
break
|
||||
}
|
||||
|
||||
const symptom = await prisma.symptom.create({
|
||||
data: {
|
||||
workspaceId,
|
||||
type: op.data.type as 'FATIGUE' | 'NAUSEA' | 'PAIN' | 'APPETITE' | 'SLEEP' | 'MOOD' | 'CUSTOM',
|
||||
customName: (op.data.customName as string) || null,
|
||||
severity: op.data.severity as number,
|
||||
notes: (op.data.notes as string) || null,
|
||||
recordedAt: op.data.recordedAt ? new Date(op.data.recordedAt as string) : new Date(),
|
||||
createdById: req.session.user.id,
|
||||
},
|
||||
})
|
||||
results.push({ opId: op.id, success: true, entityId: symptom.id })
|
||||
break
|
||||
}
|
||||
|
||||
case 'DELETE_SYMPTOM': {
|
||||
if (!op.entityId) {
|
||||
results.push({ opId: op.id, success: false, error: 'Missing entityId' })
|
||||
break
|
||||
}
|
||||
|
||||
await prisma.symptom.update({
|
||||
where: { id: op.entityId },
|
||||
data: {
|
||||
deletedAt: new Date(),
|
||||
version: { increment: 1 },
|
||||
syncedAt: new Date(),
|
||||
},
|
||||
})
|
||||
results.push({ opId: op.id, success: true })
|
||||
break
|
||||
}
|
||||
|
||||
default:
|
||||
results.push({ opId: op.id, success: false, error: 'Unknown operation type' })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user