家庭守护圈:多人加入、角色权限、24 小时邀请链接、旧设备绑定自动兼容。
家庭动态:老人/家属发言、三种可见范围,家庭内部内容不会播给老人。 共同照护:家庭备忘录、任务创建、认领、完成与交接记录。 用药闭环:计划、未来 7 天提醒实例、确认服用、延后、异常反馈。 风险闭环:红橙黄蓝分级、30 分钟去重、推送、认领、处理与误报记录。 报平安:家属发起、老人语音回应、状态同步。 Web 导航升级为守护、家庭、照护、陪伴、我的。 设备接口已升级为设备令牌认证,UUID 不再单独承担认证。
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "FamilyRole" AS ENUM ('ADMIN', 'CAREGIVER', 'CARING');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "MembershipStatus" AS ENUM ('ACTIVE', 'REMOVED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "InvitationStatus" AS ENUM ('PENDING', 'ACCEPTED', 'EXPIRED', 'REVOKED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ContentVisibility" AS ENUM ('ELDER_ONLY', 'FAMILY_ONLY', 'FAMILY_AND_ELDER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "MemoPriority" AS ENUM ('NORMAL', 'IMPORTANT', 'PINNED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CareTaskStatus" AS ENUM ('OPEN', 'CLAIMED', 'COMPLETED', 'CANCELLED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "MedicationSource" AS ENUM ('PRESCRIPTION', 'PACKAGE_LABEL', 'FAMILY_ENTRY');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "MedicationDoseStatus" AS ENUM ('SCHEDULED', 'REMINDING', 'TAKEN', 'SNOOZED', 'SKIPPED', 'MISSED', 'NEEDS_FAMILY_CONFIRMATION');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CheckInStatus" AS ENUM ('PENDING', 'SAFE', 'NEEDS_CONTACT', 'DECLINED', 'EXPIRED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AlertLevel" AS ENUM ('RED', 'ORANGE', 'YELLOW', 'BLUE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AlertStatus" AS ENUM ('OPEN', 'ACKNOWLEDGED', 'RESOLVED', 'DISMISSED');
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "ElderDevice" ADD COLUMN "deviceTokenHash" TEXT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ElderProfile" (
|
||||
"id" TEXT NOT NULL,
|
||||
"elderDeviceId" TEXT NOT NULL,
|
||||
"preferredName" TEXT NOT NULL,
|
||||
"timezone" TEXT NOT NULL DEFAULT 'Asia/Shanghai',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ElderProfile_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FamilyCircle" (
|
||||
"id" TEXT NOT NULL,
|
||||
"elderProfileId" TEXT NOT NULL,
|
||||
"createdById" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "FamilyCircle_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FamilyInvitation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"createdById" TEXT NOT NULL,
|
||||
"tokenHash" TEXT NOT NULL,
|
||||
"role" "FamilyRole" NOT NULL DEFAULT 'CARING',
|
||||
"relationLabel" TEXT,
|
||||
"status" "InvitationStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"acceptedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "FamilyInvitation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FamilyMembership" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"caregiverId" TEXT NOT NULL,
|
||||
"role" "FamilyRole" NOT NULL DEFAULT 'CARING',
|
||||
"relationLabel" TEXT,
|
||||
"status" "MembershipStatus" NOT NULL DEFAULT 'ACTIVE',
|
||||
"emergencyPush" BOOLEAN NOT NULL DEFAULT true,
|
||||
"routinePush" BOOLEAN NOT NULL DEFAULT true,
|
||||
"dutyOrder" INTEGER,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "FamilyMembership_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FamilyPost" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"authorId" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"visibility" "ContentVisibility" NOT NULL DEFAULT 'FAMILY_AND_ELDER',
|
||||
"elderAuthored" BOOLEAN NOT NULL DEFAULT false,
|
||||
"pinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"deliveredAt" TIMESTAMP(3),
|
||||
"readAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "FamilyPost_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FamilyMemo" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"authorId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"priority" "MemoPriority" NOT NULL DEFAULT 'NORMAL',
|
||||
"visibility" "ContentVisibility" NOT NULL DEFAULT 'FAMILY_AND_ELDER',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "FamilyMemo_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CareTask" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"createdById" TEXT NOT NULL,
|
||||
"assignedToId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"dueAt" TIMESTAMP(3),
|
||||
"status" "CareTaskStatus" NOT NULL DEFAULT 'OPEN',
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"completionNote" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CareTask_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MedicationPlan" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"createdById" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"dosage" TEXT NOT NULL,
|
||||
"instructions" TEXT,
|
||||
"timesJson" TEXT NOT NULL,
|
||||
"source" "MedicationSource" NOT NULL,
|
||||
"startDate" TIMESTAMP(3) NOT NULL,
|
||||
"endDate" TIMESTAMP(3),
|
||||
"stockCount" INTEGER,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"pausedReason" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "MedicationPlan_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MedicationDose" (
|
||||
"id" TEXT NOT NULL,
|
||||
"medicationPlanId" TEXT NOT NULL,
|
||||
"scheduledFor" TIMESTAMP(3) NOT NULL,
|
||||
"status" "MedicationDoseStatus" NOT NULL DEFAULT 'SCHEDULED',
|
||||
"respondedAt" TIMESTAMP(3),
|
||||
"snoozedUntil" TIMESTAMP(3),
|
||||
"note" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "MedicationDose_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CheckInRequest" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"requestedById" TEXT NOT NULL,
|
||||
"prompt" TEXT,
|
||||
"dueAt" TIMESTAMP(3),
|
||||
"status" "CheckInStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"responseText" TEXT,
|
||||
"respondedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CheckInRequest_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "SafetySignal" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"confidence" DOUBLE PRECISION,
|
||||
"contextText" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "SafetySignal_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "SafetyAlert" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"safetySignalId" TEXT NOT NULL,
|
||||
"claimedById" TEXT,
|
||||
"level" "AlertLevel" NOT NULL,
|
||||
"status" "AlertStatus" NOT NULL DEFAULT 'OPEN',
|
||||
"title" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"resolutionNote" TEXT,
|
||||
"claimedAt" TIMESTAMP(3),
|
||||
"resolvedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "SafetyAlert_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FamilyMemory" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"story" TEXT NOT NULL,
|
||||
"mediaUrl" TEXT,
|
||||
"occurredAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "FamilyMemory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ConsentSetting" (
|
||||
"id" TEXT NOT NULL,
|
||||
"elderProfileId" TEXT NOT NULL,
|
||||
"shareTranscripts" BOOLEAN NOT NULL DEFAULT true,
|
||||
"shareRawAudio" BOOLEAN NOT NULL DEFAULT false,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ConsentSetting_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AuditLog" (
|
||||
"id" TEXT NOT NULL,
|
||||
"familyCircleId" TEXT NOT NULL,
|
||||
"actorId" TEXT,
|
||||
"action" TEXT NOT NULL,
|
||||
"entityType" TEXT NOT NULL,
|
||||
"entityId" TEXT,
|
||||
"detailJson" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ElderProfile_elderDeviceId_key" ON "ElderProfile"("elderDeviceId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "FamilyCircle_elderProfileId_key" ON "FamilyCircle"("elderProfileId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "FamilyInvitation_tokenHash_key" ON "FamilyInvitation"("tokenHash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "FamilyInvitation_familyCircleId_status_expiresAt_idx" ON "FamilyInvitation"("familyCircleId", "status", "expiresAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "FamilyMembership_caregiverId_status_idx" ON "FamilyMembership"("caregiverId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "FamilyMembership_familyCircleId_caregiverId_key" ON "FamilyMembership"("familyCircleId", "caregiverId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "FamilyPost_familyCircleId_createdAt_idx" ON "FamilyPost"("familyCircleId", "createdAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "FamilyMemo_familyCircleId_priority_updatedAt_idx" ON "FamilyMemo"("familyCircleId", "priority", "updatedAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CareTask_familyCircleId_status_dueAt_idx" ON "CareTask"("familyCircleId", "status", "dueAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MedicationPlan_familyCircleId_active_idx" ON "MedicationPlan"("familyCircleId", "active");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MedicationDose_scheduledFor_status_idx" ON "MedicationDose"("scheduledFor", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MedicationDose_medicationPlanId_scheduledFor_key" ON "MedicationDose"("medicationPlanId", "scheduledFor");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckInRequest_familyCircleId_status_createdAt_idx" ON "CheckInRequest"("familyCircleId", "status", "createdAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SafetySignal_familyCircleId_category_createdAt_idx" ON "SafetySignal"("familyCircleId", "category", "createdAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "SafetyAlert_safetySignalId_key" ON "SafetyAlert"("safetySignalId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SafetyAlert_familyCircleId_status_createdAt_idx" ON "SafetyAlert"("familyCircleId", "status", "createdAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ConsentSetting_elderProfileId_key" ON "ConsentSetting"("elderProfileId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditLog_familyCircleId_createdAt_idx" ON "AuditLog"("familyCircleId", "createdAt" DESC);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ElderProfile" ADD CONSTRAINT "ElderProfile_elderDeviceId_fkey" FOREIGN KEY ("elderDeviceId") REFERENCES "ElderDevice"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyCircle" ADD CONSTRAINT "FamilyCircle_elderProfileId_fkey" FOREIGN KEY ("elderProfileId") REFERENCES "ElderProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyCircle" ADD CONSTRAINT "FamilyCircle_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "CaregiverAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyInvitation" ADD CONSTRAINT "FamilyInvitation_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyInvitation" ADD CONSTRAINT "FamilyInvitation_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "CaregiverAccount"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyMembership" ADD CONSTRAINT "FamilyMembership_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyMembership" ADD CONSTRAINT "FamilyMembership_caregiverId_fkey" FOREIGN KEY ("caregiverId") REFERENCES "CaregiverAccount"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyPost" ADD CONSTRAINT "FamilyPost_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyPost" ADD CONSTRAINT "FamilyPost_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "CaregiverAccount"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyMemo" ADD CONSTRAINT "FamilyMemo_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyMemo" ADD CONSTRAINT "FamilyMemo_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "CaregiverAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CareTask" ADD CONSTRAINT "CareTask_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CareTask" ADD CONSTRAINT "CareTask_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "CaregiverAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CareTask" ADD CONSTRAINT "CareTask_assignedToId_fkey" FOREIGN KEY ("assignedToId") REFERENCES "CaregiverAccount"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MedicationPlan" ADD CONSTRAINT "MedicationPlan_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MedicationPlan" ADD CONSTRAINT "MedicationPlan_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "CaregiverAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MedicationDose" ADD CONSTRAINT "MedicationDose_medicationPlanId_fkey" FOREIGN KEY ("medicationPlanId") REFERENCES "MedicationPlan"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CheckInRequest" ADD CONSTRAINT "CheckInRequest_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CheckInRequest" ADD CONSTRAINT "CheckInRequest_requestedById_fkey" FOREIGN KEY ("requestedById") REFERENCES "CaregiverAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SafetySignal" ADD CONSTRAINT "SafetySignal_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SafetyAlert" ADD CONSTRAINT "SafetyAlert_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SafetyAlert" ADD CONSTRAINT "SafetyAlert_safetySignalId_fkey" FOREIGN KEY ("safetySignalId") REFERENCES "SafetySignal"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SafetyAlert" ADD CONSTRAINT "SafetyAlert_claimedById_fkey" FOREIGN KEY ("claimedById") REFERENCES "CaregiverAccount"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FamilyMemory" ADD CONSTRAINT "FamilyMemory_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ConsentSetting" ADD CONSTRAINT "ConsentSetting_elderProfileId_fkey" FOREIGN KEY ("elderProfileId") REFERENCES "ElderProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AuditLog" ADD CONSTRAINT "AuditLog_familyCircleId_fkey" FOREIGN KEY ("familyCircleId") REFERENCES "FamilyCircle"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AuditLog" ADD CONSTRAINT "AuditLog_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES "CaregiverAccount"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
+348
-11
@@ -45,17 +45,103 @@ enum ToolCallStatus {
|
||||
FAILURE
|
||||
}
|
||||
|
||||
enum FamilyRole {
|
||||
ADMIN
|
||||
CAREGIVER
|
||||
CARING
|
||||
}
|
||||
|
||||
enum MembershipStatus {
|
||||
ACTIVE
|
||||
REMOVED
|
||||
}
|
||||
|
||||
enum InvitationStatus {
|
||||
PENDING
|
||||
ACCEPTED
|
||||
EXPIRED
|
||||
REVOKED
|
||||
}
|
||||
|
||||
enum ContentVisibility {
|
||||
ELDER_ONLY
|
||||
FAMILY_ONLY
|
||||
FAMILY_AND_ELDER
|
||||
}
|
||||
|
||||
enum MemoPriority {
|
||||
NORMAL
|
||||
IMPORTANT
|
||||
PINNED
|
||||
}
|
||||
|
||||
enum CareTaskStatus {
|
||||
OPEN
|
||||
CLAIMED
|
||||
COMPLETED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum MedicationSource {
|
||||
PRESCRIPTION
|
||||
PACKAGE_LABEL
|
||||
FAMILY_ENTRY
|
||||
}
|
||||
|
||||
enum MedicationDoseStatus {
|
||||
SCHEDULED
|
||||
REMINDING
|
||||
TAKEN
|
||||
SNOOZED
|
||||
SKIPPED
|
||||
MISSED
|
||||
NEEDS_FAMILY_CONFIRMATION
|
||||
}
|
||||
|
||||
enum CheckInStatus {
|
||||
PENDING
|
||||
SAFE
|
||||
NEEDS_CONTACT
|
||||
DECLINED
|
||||
EXPIRED
|
||||
}
|
||||
|
||||
enum AlertLevel {
|
||||
RED
|
||||
ORANGE
|
||||
YELLOW
|
||||
BLUE
|
||||
}
|
||||
|
||||
enum AlertStatus {
|
||||
OPEN
|
||||
ACKNOWLEDGED
|
||||
RESOLVED
|
||||
DISMISSED
|
||||
}
|
||||
|
||||
model CaregiverAccount {
|
||||
id String @id @default(cuid())
|
||||
username String? @unique
|
||||
passwordHash String?
|
||||
nickname String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
sessions CaregiverSession[]
|
||||
bindings DeviceBinding[]
|
||||
messages FamilyMessage[]
|
||||
pushSubscriptions PushSubscription[]
|
||||
id String @id @default(cuid())
|
||||
username String? @unique
|
||||
passwordHash String?
|
||||
nickname String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
sessions CaregiverSession[]
|
||||
bindings DeviceBinding[]
|
||||
messages FamilyMessage[]
|
||||
pushSubscriptions PushSubscription[]
|
||||
createdCircles FamilyCircle[] @relation("CircleCreator")
|
||||
memberships FamilyMembership[]
|
||||
posts FamilyPost[]
|
||||
memos FamilyMemo[]
|
||||
createdTasks CareTask[] @relation("TaskCreator")
|
||||
assignedTasks CareTask[] @relation("TaskAssignee")
|
||||
medicationPlans MedicationPlan[]
|
||||
requestedCheckIns CheckInRequest[]
|
||||
claimedAlerts SafetyAlert[] @relation("AlertClaimer")
|
||||
auditLogs AuditLog[]
|
||||
createdInvitations FamilyInvitation[] @relation("InvitationCreator")
|
||||
}
|
||||
|
||||
model CaregiverSession {
|
||||
@@ -84,6 +170,257 @@ model ElderDevice {
|
||||
conversationTurns ConversationTurn[]
|
||||
usageEvents UsageEvent[]
|
||||
toolCalls ToolCallLog[]
|
||||
deviceTokenHash String?
|
||||
elderProfile ElderProfile?
|
||||
}
|
||||
|
||||
model ElderProfile {
|
||||
id String @id @default(cuid())
|
||||
elderDeviceId String @unique
|
||||
preferredName String
|
||||
timezone String @default("Asia/Shanghai")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
elderDevice ElderDevice @relation(fields: [elderDeviceId], references: [id], onDelete: Cascade)
|
||||
familyCircle FamilyCircle?
|
||||
consentSetting ConsentSetting?
|
||||
}
|
||||
|
||||
model FamilyCircle {
|
||||
id String @id @default(cuid())
|
||||
elderProfileId String @unique
|
||||
createdById String
|
||||
name String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
elderProfile ElderProfile @relation(fields: [elderProfileId], references: [id], onDelete: Cascade)
|
||||
createdBy CaregiverAccount @relation("CircleCreator", fields: [createdById], references: [id], onDelete: Restrict)
|
||||
memberships FamilyMembership[]
|
||||
posts FamilyPost[]
|
||||
memos FamilyMemo[]
|
||||
tasks CareTask[]
|
||||
medicationPlans MedicationPlan[]
|
||||
checkIns CheckInRequest[]
|
||||
safetySignals SafetySignal[]
|
||||
alerts SafetyAlert[]
|
||||
memories FamilyMemory[]
|
||||
auditLogs AuditLog[]
|
||||
invitations FamilyInvitation[]
|
||||
}
|
||||
|
||||
model FamilyInvitation {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
createdById String
|
||||
tokenHash String @unique
|
||||
role FamilyRole @default(CARING)
|
||||
relationLabel String?
|
||||
status InvitationStatus @default(PENDING)
|
||||
expiresAt DateTime
|
||||
acceptedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
createdBy CaregiverAccount @relation("InvitationCreator", fields: [createdById], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([familyCircleId, status, expiresAt])
|
||||
}
|
||||
|
||||
model FamilyMembership {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
caregiverId String
|
||||
role FamilyRole @default(CARING)
|
||||
relationLabel String?
|
||||
status MembershipStatus @default(ACTIVE)
|
||||
emergencyPush Boolean @default(true)
|
||||
routinePush Boolean @default(true)
|
||||
dutyOrder Int?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
caregiver CaregiverAccount @relation(fields: [caregiverId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([familyCircleId, caregiverId])
|
||||
@@index([caregiverId, status])
|
||||
}
|
||||
|
||||
model FamilyPost {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
authorId String?
|
||||
content String
|
||||
visibility ContentVisibility @default(FAMILY_AND_ELDER)
|
||||
elderAuthored Boolean @default(false)
|
||||
pinned Boolean @default(false)
|
||||
deliveredAt DateTime?
|
||||
readAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
author CaregiverAccount? @relation(fields: [authorId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([familyCircleId, createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
model FamilyMemo {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
authorId String
|
||||
title String
|
||||
content String
|
||||
priority MemoPriority @default(NORMAL)
|
||||
visibility ContentVisibility @default(FAMILY_AND_ELDER)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
author CaregiverAccount @relation(fields: [authorId], references: [id], onDelete: Restrict)
|
||||
|
||||
@@index([familyCircleId, priority, updatedAt(sort: Desc)])
|
||||
}
|
||||
|
||||
model CareTask {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
createdById String
|
||||
assignedToId String?
|
||||
title String
|
||||
description String?
|
||||
dueAt DateTime?
|
||||
status CareTaskStatus @default(OPEN)
|
||||
completedAt DateTime?
|
||||
completionNote String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
createdBy CaregiverAccount @relation("TaskCreator", fields: [createdById], references: [id], onDelete: Restrict)
|
||||
assignedTo CaregiverAccount? @relation("TaskAssignee", fields: [assignedToId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([familyCircleId, status, dueAt])
|
||||
}
|
||||
|
||||
model MedicationPlan {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
createdById String
|
||||
name String
|
||||
dosage String
|
||||
instructions String?
|
||||
timesJson String
|
||||
source MedicationSource
|
||||
startDate DateTime
|
||||
endDate DateTime?
|
||||
stockCount Int?
|
||||
active Boolean @default(true)
|
||||
pausedReason String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
createdBy CaregiverAccount @relation(fields: [createdById], references: [id], onDelete: Restrict)
|
||||
doses MedicationDose[]
|
||||
|
||||
@@index([familyCircleId, active])
|
||||
}
|
||||
|
||||
model MedicationDose {
|
||||
id String @id @default(cuid())
|
||||
medicationPlanId String
|
||||
scheduledFor DateTime
|
||||
status MedicationDoseStatus @default(SCHEDULED)
|
||||
respondedAt DateTime?
|
||||
snoozedUntil DateTime?
|
||||
note String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
medicationPlan MedicationPlan @relation(fields: [medicationPlanId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([medicationPlanId, scheduledFor])
|
||||
@@index([scheduledFor, status])
|
||||
}
|
||||
|
||||
model CheckInRequest {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
requestedById String
|
||||
prompt String?
|
||||
dueAt DateTime?
|
||||
status CheckInStatus @default(PENDING)
|
||||
responseText String?
|
||||
respondedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
requestedBy CaregiverAccount @relation(fields: [requestedById], references: [id], onDelete: Restrict)
|
||||
|
||||
@@index([familyCircleId, status, createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
model SafetySignal {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
category String
|
||||
summary String
|
||||
confidence Float?
|
||||
contextText String?
|
||||
createdAt DateTime @default(now())
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
alert SafetyAlert?
|
||||
|
||||
@@index([familyCircleId, category, createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
model SafetyAlert {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
safetySignalId String @unique
|
||||
claimedById String?
|
||||
level AlertLevel
|
||||
status AlertStatus @default(OPEN)
|
||||
title String
|
||||
summary String
|
||||
resolutionNote String?
|
||||
claimedAt DateTime?
|
||||
resolvedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
safetySignal SafetySignal @relation(fields: [safetySignalId], references: [id], onDelete: Cascade)
|
||||
claimedBy CaregiverAccount? @relation("AlertClaimer", fields: [claimedById], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([familyCircleId, status, createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
model FamilyMemory {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
title String
|
||||
story String
|
||||
mediaUrl String?
|
||||
occurredAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model ConsentSetting {
|
||||
id String @id @default(cuid())
|
||||
elderProfileId String @unique
|
||||
shareTranscripts Boolean @default(true)
|
||||
shareRawAudio Boolean @default(false)
|
||||
updatedAt DateTime @updatedAt
|
||||
elderProfile ElderProfile @relation(fields: [elderProfileId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model AuditLog {
|
||||
id String @id @default(cuid())
|
||||
familyCircleId String
|
||||
actorId String?
|
||||
action String
|
||||
entityType String
|
||||
entityId String?
|
||||
detailJson String?
|
||||
createdAt DateTime @default(now())
|
||||
familyCircle FamilyCircle @relation(fields: [familyCircleId], references: [id], onDelete: Cascade)
|
||||
actor CaregiverAccount? @relation(fields: [actorId], references: [id], onDelete: SetNull)
|
||||
|
||||
@@index([familyCircleId, createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
model DeviceBinding {
|
||||
@@ -175,4 +512,4 @@ model ToolCallLog {
|
||||
|
||||
@@index([elderDeviceId, createdAt(sort: Desc)])
|
||||
@@index([toolName, createdAt(sort: Desc)])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user