mirror of
https://github.com/Tony0410/nextstep.git
synced 2026-05-24 21:31:43 +08:00
- Fix argon2 native module build in Docker (add build-essential, python3) - Switch Docker base image from Alpine to Debian-slim for OpenSSL compatibility - Fix session cookies for HTTP access (COOKIE_SECURE env var) - Fix TypeScript type errors in sync routes and middleware - Fix CSS circular dependency in globals.css - Fix Map iteration in rate-limit cleanup - Add createdAt field to LocalNote interface - Configure Tailscale Funnel on port 10000 - Update NEXT_PUBLIC_APP_URL for public funnel access - Add initial Prisma migration Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
331 lines
11 KiB
SQL
331 lines
11 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "WorkspaceRole" AS ENUM ('OWNER', 'EDITOR', 'VIEWER');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "ScheduleType" AS ENUM ('FIXED_TIMES', 'INTERVAL', 'WEEKDAYS', 'PRN');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "NoteType" AS ENUM ('QUESTION', 'GENERAL');
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "User" (
|
|
"id" TEXT NOT NULL,
|
|
"email" TEXT NOT NULL,
|
|
"passwordHash" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Session" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"token" TEXT NOT NULL,
|
|
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"userAgent" TEXT,
|
|
"ipAddress" TEXT,
|
|
|
|
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "LoginAttempt" (
|
|
"id" TEXT NOT NULL,
|
|
"email" TEXT NOT NULL,
|
|
"ipAddress" TEXT,
|
|
"success" BOOLEAN NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "LoginAttempt_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Workspace" (
|
|
"id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"clinicPhone" TEXT,
|
|
"emergencyPhone" TEXT,
|
|
"quietHoursStart" TEXT,
|
|
"quietHoursEnd" TEXT,
|
|
"largeTextMode" BOOLEAN NOT NULL DEFAULT false,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Workspace_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "WorkspaceMember" (
|
|
"id" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"role" "WorkspaceRole" NOT NULL DEFAULT 'VIEWER',
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "WorkspaceMember_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "InviteToken" (
|
|
"id" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"token" TEXT NOT NULL,
|
|
"role" "WorkspaceRole" NOT NULL DEFAULT 'VIEWER',
|
|
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
"usedAt" TIMESTAMP(3),
|
|
"usedById" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "InviteToken_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Appointment" (
|
|
"id" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"title" TEXT NOT NULL,
|
|
"datetime" TIMESTAMP(3) NOT NULL,
|
|
"location" TEXT,
|
|
"mapUrl" TEXT,
|
|
"notes" TEXT,
|
|
"deletedAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
"createdById" TEXT NOT NULL,
|
|
"updatedById" TEXT NOT NULL,
|
|
"version" INTEGER NOT NULL DEFAULT 1,
|
|
"syncedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "Appointment_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Medication" (
|
|
"id" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"instructions" TEXT,
|
|
"scheduleType" "ScheduleType" NOT NULL,
|
|
"scheduleData" JSONB NOT NULL,
|
|
"startDate" TIMESTAMP(3),
|
|
"endDate" TIMESTAMP(3),
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"deletedAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
"createdById" TEXT NOT NULL,
|
|
"updatedById" TEXT NOT NULL,
|
|
"version" INTEGER NOT NULL DEFAULT 1,
|
|
"syncedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "Medication_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "DoseLog" (
|
|
"id" TEXT NOT NULL,
|
|
"medicationId" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"takenAt" TIMESTAMP(3) NOT NULL,
|
|
"loggedById" TEXT NOT NULL,
|
|
"undoneAt" TIMESTAMP(3),
|
|
"undoneById" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"syncedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "DoseLog_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Note" (
|
|
"id" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"type" "NoteType" NOT NULL,
|
|
"content" TEXT NOT NULL,
|
|
"askedAt" TIMESTAMP(3),
|
|
"deletedAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
"createdById" TEXT NOT NULL,
|
|
"updatedById" TEXT NOT NULL,
|
|
"version" INTEGER NOT NULL DEFAULT 1,
|
|
"syncedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "Note_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "AuditLog" (
|
|
"id" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"action" TEXT NOT NULL,
|
|
"entityType" TEXT NOT NULL,
|
|
"entityId" TEXT NOT NULL,
|
|
"details" JSONB,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "SyncCursor" (
|
|
"id" TEXT NOT NULL,
|
|
"workspaceId" TEXT NOT NULL,
|
|
"cursor" BIGINT NOT NULL DEFAULT 0,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "SyncCursor_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "User_email_idx" ON "User"("email");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Session_token_key" ON "Session"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Session_token_idx" ON "Session"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Session_userId_idx" ON "Session"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Session_expiresAt_idx" ON "Session"("expiresAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "LoginAttempt_email_createdAt_idx" ON "LoginAttempt"("email", "createdAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "LoginAttempt_ipAddress_createdAt_idx" ON "LoginAttempt"("ipAddress", "createdAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Workspace_name_idx" ON "Workspace"("name");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "WorkspaceMember_userId_idx" ON "WorkspaceMember"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "WorkspaceMember_workspaceId_userId_key" ON "WorkspaceMember"("workspaceId", "userId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "InviteToken_token_key" ON "InviteToken"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "InviteToken_token_idx" ON "InviteToken"("token");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "InviteToken_workspaceId_idx" ON "InviteToken"("workspaceId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Appointment_workspaceId_datetime_idx" ON "Appointment"("workspaceId", "datetime");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Appointment_workspaceId_deletedAt_idx" ON "Appointment"("workspaceId", "deletedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Appointment_syncedAt_idx" ON "Appointment"("syncedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Medication_workspaceId_active_idx" ON "Medication"("workspaceId", "active");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Medication_workspaceId_deletedAt_idx" ON "Medication"("workspaceId", "deletedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Medication_syncedAt_idx" ON "Medication"("syncedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "DoseLog_medicationId_takenAt_idx" ON "DoseLog"("medicationId", "takenAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "DoseLog_workspaceId_takenAt_idx" ON "DoseLog"("workspaceId", "takenAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "DoseLog_syncedAt_idx" ON "DoseLog"("syncedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Note_workspaceId_type_idx" ON "Note"("workspaceId", "type");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Note_workspaceId_deletedAt_idx" ON "Note"("workspaceId", "deletedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Note_syncedAt_idx" ON "Note"("syncedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AuditLog_workspaceId_createdAt_idx" ON "AuditLog"("workspaceId", "createdAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AuditLog_entityType_entityId_idx" ON "AuditLog"("entityType", "entityId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "SyncCursor_workspaceId_key" ON "SyncCursor"("workspaceId");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "WorkspaceMember" ADD CONSTRAINT "WorkspaceMember_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "WorkspaceMember" ADD CONSTRAINT "WorkspaceMember_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "InviteToken" ADD CONSTRAINT "InviteToken_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Medication" ADD CONSTRAINT "Medication_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Medication" ADD CONSTRAINT "Medication_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Medication" ADD CONSTRAINT "Medication_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "DoseLog" ADD CONSTRAINT "DoseLog_medicationId_fkey" FOREIGN KEY ("medicationId") REFERENCES "Medication"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "DoseLog" ADD CONSTRAINT "DoseLog_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "DoseLog" ADD CONSTRAINT "DoseLog_loggedById_fkey" FOREIGN KEY ("loggedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "DoseLog" ADD CONSTRAINT "DoseLog_undoneById_fkey" FOREIGN KEY ("undoneById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Note" ADD CONSTRAINT "Note_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Note" ADD CONSTRAINT "Note_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Note" ADD CONSTRAINT "Note_updatedById_fkey" FOREIGN KEY ("updatedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "AuditLog" ADD CONSTRAINT "AuditLog_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "AuditLog" ADD CONSTRAINT "AuditLog_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "SyncCursor" ADD CONSTRAINT "SyncCursor_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "Workspace"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|