import { MessageDirection, MessageStatus } from "@prisma/client"; import { createBindUrl, getCaregiverDashboard } from "@/lib/monitor-data"; import { prisma } from "@/lib/prisma"; const deviceSummarySelect = { id: true, deviceUuid: true, displayName: true, appVersion: true, lastSeenAt: true, } as const; export async function getCaregiverOverview(caregiverId: string) { const dashboard = await getCaregiverDashboard(caregiverId); const [recentIncomingMessages, recentOutgoingMessages] = await prisma.$transaction([ prisma.familyMessage.findMany({ where: { direction: MessageDirection.ELDER_TO_FAMILY, elderDevice: { bindings: { some: { caregiverId }, }, }, }, include: { elderDevice: { select: deviceSummarySelect, }, }, orderBy: { createdAt: "desc" }, take: 4, }), prisma.familyMessage.findMany({ where: { direction: MessageDirection.FAMILY_TO_ELDER, caregiverId, }, include: { elderDevice: { select: deviceSummarySelect, }, }, orderBy: { createdAt: "desc" }, take: 4, }), ]); return { dashboard, recentIncomingMessages, recentOutgoingMessages, }; } export async function getCaregiverMessages(caregiverId: string) { const [messages, unreadIncomingCount, unreadOutgoingCount] = await prisma.$transaction([ prisma.familyMessage.findMany({ where: { elderDevice: { bindings: { some: { caregiverId }, }, }, }, include: { elderDevice: { select: deviceSummarySelect, }, }, orderBy: [{ createdAt: "desc" }, { publicId: "desc" }], take: 120, }), prisma.familyMessage.count({ where: { direction: MessageDirection.ELDER_TO_FAMILY, elderDevice: { bindings: { some: { caregiverId }, }, }, readAt: null, }, }), prisma.familyMessage.count({ where: { direction: MessageDirection.FAMILY_TO_ELDER, caregiverId, readAt: null, }, }), ]); return { messages, unreadIncomingCount, unreadOutgoingCount, }; } export async function getCaregiverMessageDetail( caregiverId: string, publicId: number, ) { let message = await prisma.familyMessage.findFirst({ where: { publicId, elderDevice: { bindings: { some: { caregiverId }, }, }, }, include: { elderDevice: { select: deviceSummarySelect, }, }, }); if (!message) { return null; } if (message.direction === MessageDirection.ELDER_TO_FAMILY && !message.readAt) { const now = new Date(); message = await prisma.familyMessage.update({ where: { id: message.id }, data: { readAt: now, deliveredAt: message.deliveredAt ?? now, status: MessageStatus.READ, }, include: { elderDevice: { select: deviceSummarySelect, }, }, }); } return message; } export async function getCaregiverDevices(caregiverId: string) { const dashboard = await getCaregiverDashboard(caregiverId); return dashboard.devices; } export async function getCaregiverDeviceDetail( caregiverId: string, deviceUuid: string, ) { const binding = await prisma.deviceBinding.findFirst({ where: { caregiverId, elderDevice: { deviceUuid, }, }, include: { elderDevice: { include: { messages: { orderBy: [{ createdAt: "desc" }, { publicId: "desc" }], take: 14, }, usageEvents: { orderBy: { createdAt: "desc" }, take: 10, }, conversationTurns: { orderBy: { createdAt: "desc" }, take: 12, }, toolCalls: { orderBy: { createdAt: "desc" }, take: 8, }, _count: { select: { messages: true, usageEvents: true, conversationTurns: true, toolCalls: true, }, }, }, }, }, }); if (!binding) { return null; } const [familyUnreadCount, elderUnreadCount] = await prisma.$transaction([ prisma.familyMessage.count({ where: { elderDeviceId: binding.elderDeviceId, direction: MessageDirection.FAMILY_TO_ELDER, readAt: null, }, }), prisma.familyMessage.count({ where: { elderDeviceId: binding.elderDeviceId, direction: MessageDirection.ELDER_TO_FAMILY, readAt: null, }, }), ]); return { ...binding, bindUrl: createBindUrl(binding.elderDevice.deviceUuid), familyUnreadCount, elderUnreadCount, }; } export async function getCaregiverActivity(caregiverId: string) { const deviceBindings = await prisma.deviceBinding.findMany({ where: { caregiverId }, select: { elderDeviceId: true, }, }); const elderDeviceIds = deviceBindings.map((binding) => binding.elderDeviceId); if (elderDeviceIds.length === 0) { return { usageEvents: [], conversationTurns: [], toolCalls: [], }; } const [usageEvents, conversationTurns, toolCalls] = await prisma.$transaction([ prisma.usageEvent.findMany({ where: { elderDeviceId: { in: elderDeviceIds }, }, include: { elderDevice: { select: deviceSummarySelect, }, }, orderBy: { createdAt: "desc" }, take: 24, }), prisma.conversationTurn.findMany({ where: { elderDeviceId: { in: elderDeviceIds }, }, include: { elderDevice: { select: deviceSummarySelect, }, }, orderBy: { createdAt: "desc" }, take: 24, }), prisma.toolCallLog.findMany({ where: { elderDeviceId: { in: elderDeviceIds }, }, include: { elderDevice: { select: deviceSummarySelect, }, }, orderBy: { createdAt: "desc" }, take: 24, }), ]); return { usageEvents, conversationTurns, toolCalls, }; } export async function getCaregiverSettingsOverview(caregiverId: string) { const [deviceCount, pushSubscriptionCount] = await prisma.$transaction([ prisma.deviceBinding.count({ where: { caregiverId }, }), prisma.pushSubscription.count({ where: { caregiverId }, }), ]); return { deviceCount, pushSubscriptionCount, }; }