first commit

This commit is contained in:
2026-03-26 08:14:56 +03:30
commit 3561c09e2d
128 changed files with 16084 additions and 0 deletions

View File

@@ -0,0 +1,225 @@
-- CreateEnum
CREATE TYPE "UserRoles" AS ENUM ('DOCTOR', 'TEAM');
-- CreateEnum
CREATE TYPE "PatientStatus" AS ENUM ('PENDING', 'ACCEPTED', 'REJECTED');
-- CreateEnum
CREATE TYPE "PageType" AS ENUM ('STATIC', 'SERVICE', 'PACKAGE', 'FORM_PAGE', 'CONTACT');
-- CreateEnum
CREATE TYPE "PageStatus" AS ENUM ('DRAFT', 'PUBLISHED');
-- CreateEnum
CREATE TYPE "BlockType" AS ENUM ('TEXT', 'TEAM', 'CONTACT_INFO', 'MAP', 'PACKAGE_LIST', 'ACCORDION', 'FORM', 'GALLERY');
-- CreateEnum
CREATE TYPE "UploadedBy" AS ENUM ('PATIENT', 'STAFF');
-- CreateEnum
CREATE TYPE "FormStatus" AS ENUM ('PENDING', 'REVIEWED', 'REJECTED', 'APPROVED');
-- CreateTable
CREATE TABLE "Users" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"role" TEXT NOT NULL,
"bio" TEXT,
"position" TEXT,
"expertise" TEXT,
"phone_number" TEXT,
"email" TEXT,
"image" TEXT,
"socials" JSONB,
"profile_photo_id" INTEGER,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Users_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Patient" (
"id" SERIAL NOT NULL,
"first_name" TEXT NOT NULL,
"last_name" TEXT NOT NULL,
"dob" TIMESTAMP(3) NOT NULL,
"email" TEXT,
"phone_number" TEXT,
"country_name" TEXT,
"country_code" TEXT,
"status" "PatientStatus" NOT NULL DEFAULT 'PENDING',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Patient_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Service" (
"id" SERIAL NOT NULL,
"title" TEXT NOT NULL,
"slug" TEXT NOT NULL,
"intro" JSONB,
"image" TEXT,
"description" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Service_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Page" (
"id" SERIAL NOT NULL,
"type" "PageType" NOT NULL,
"featured_image" TEXT,
"status" "PageStatus" NOT NULL DEFAULT 'PUBLISHED',
CONSTRAINT "Page_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PageBlock" (
"id" SERIAL NOT NULL,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"blockType" "BlockType" NOT NULL,
"data" JSONB NOT NULL,
"pageId" INTEGER NOT NULL,
CONSTRAINT "PageBlock_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Package" (
"id" SERIAL NOT NULL,
"service_id" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"price" DOUBLE PRECISION,
"image" TEXT,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Package_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PackageItem" (
"id" SERIAL NOT NULL,
"package_id" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"content" JSONB,
"sortOrder" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "PackageItem_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "MedicalDocument" (
"id" SERIAL NOT NULL,
"patient_id" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"uploadedBy" "UploadedBy" NOT NULL DEFAULT 'PATIENT',
"uploadedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "MedicalDocument_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Language" (
"id" SERIAL NOT NULL,
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
CONSTRAINT "Language_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Image" (
"id" SERIAL NOT NULL,
"code" TEXT,
"url" TEXT NOT NULL,
"name" TEXT NOT NULL,
"mimeType" TEXT NOT NULL,
"size" INTEGER NOT NULL,
CONSTRAINT "Image_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "File" (
"id" SERIAL NOT NULL,
"code" TEXT,
"url" TEXT NOT NULL,
"name" TEXT NOT NULL,
"mimeType" TEXT NOT NULL,
"size" INTEGER NOT NULL,
"uploadedBy" "UploadedBy" NOT NULL DEFAULT 'PATIENT',
"uploadedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"documentId" INTEGER,
CONSTRAINT "File_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "DefaultInfo" (
"id" SERIAL NOT NULL,
"address" TEXT,
"phone_number" TEXT,
"email" TEXT,
"mapEmbed" JSONB,
"ipd_technician_phone" TEXT NOT NULL,
"ipd_email" TEXT,
"instagram_link" TEXT,
"linkedin_link" TEXT,
"under_logo_description" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "DefaultInfo_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "AdmissionForm" (
"id" SERIAL NOT NULL,
"patient_id" INTEGER NOT NULL,
"data" JSONB NOT NULL,
"submittedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"status" "FormStatus" NOT NULL DEFAULT 'PENDING',
CONSTRAINT "AdmissionForm_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Patient_email_key" ON "Patient"("email");
-- CreateIndex
CREATE UNIQUE INDEX "Service_slug_key" ON "Service"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "Language_code_key" ON "Language"("code");
-- AddForeignKey
ALTER TABLE "Users" ADD CONSTRAINT "Users_profile_photo_id_fkey" FOREIGN KEY ("profile_photo_id") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PageBlock" ADD CONSTRAINT "PageBlock_pageId_fkey" FOREIGN KEY ("pageId") REFERENCES "Page"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Package" ADD CONSTRAINT "Package_service_id_fkey" FOREIGN KEY ("service_id") REFERENCES "Service"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PackageItem" ADD CONSTRAINT "PackageItem_package_id_fkey" FOREIGN KEY ("package_id") REFERENCES "Package"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MedicalDocument" ADD CONSTRAINT "MedicalDocument_patient_id_fkey" FOREIGN KEY ("patient_id") REFERENCES "Patient"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "File" ADD CONSTRAINT "File_documentId_fkey" FOREIGN KEY ("documentId") REFERENCES "MedicalDocument"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "AdmissionForm" ADD CONSTRAINT "AdmissionForm_patient_id_fkey" FOREIGN KEY ("patient_id") REFERENCES "Patient"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,284 @@
/*
Warnings:
- You are about to drop the column `code` on the `Image` table. All the data in the column will be lost.
- You are about to drop the column `name` on the `Image` table. All the data in the column will be lost.
- You are about to drop the column `url` on the `Image` table. All the data in the column will be lost.
- The primary key for the `Patient` table will be changed. If it partially fails, the table could be left without primary key constraint.
- You are about to drop the column `country_code` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `country_name` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `dob` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `first_name` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `last_name` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `phone_number` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `status` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `bio` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `createdAt` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `image` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `name` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `phone_number` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `profile_photo_id` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `role` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `socials` on the `Users` table. All the data in the column will be lost.
- You are about to drop the `AdmissionForm` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `DefaultInfo` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `File` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Language` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `MedicalDocument` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Package` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `PackageItem` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Page` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `PageBlock` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Service` table. If the table is not empty, all the data it contains will be lost.
- Added the required column `firstName` to the `Patient` table without a default value. This is not possible if the table is not empty.
- Added the required column `lastName` to the `Patient` table without a default value. This is not possible if the table is not empty.
- Added the required column `firstName` to the `Users` table without a default value. This is not possible if the table is not empty.
- Added the required column `lastName` to the `Users` table without a default value. This is not possible if the table is not empty.
- Made the column `position` on table `Users` required. This step will fail if there are existing NULL values in that column.
*/
-- CreateEnum
CREATE TYPE "CaseStatus" AS ENUM ('NEW', 'CONTACTED', 'DOCS_PENDING', 'REVIEWING', 'PRE_APPROVED', 'REJECTED', 'CLOSED', 'CONVERTED_TO_HIS');
-- CreateEnum
CREATE TYPE "DocumentType" AS ENUM ('PASSPORT', 'MEDICAL_RECORD', 'IMAGING', 'LAB_RESULT', 'OTHER');
-- CreateEnum
CREATE TYPE "InteractionType" AS ENUM ('PHONE', 'WHATSAPP', 'EMAIL', 'SYSTEM');
-- CreateEnum
CREATE TYPE "UsersType" AS ENUM ('DOCTOR', 'TRANSFER_TEAM', 'DEPARTMENT');
-- DropForeignKey
ALTER TABLE "AdmissionForm" DROP CONSTRAINT "AdmissionForm_patient_id_fkey";
-- DropForeignKey
ALTER TABLE "File" DROP CONSTRAINT "File_documentId_fkey";
-- DropForeignKey
ALTER TABLE "MedicalDocument" DROP CONSTRAINT "MedicalDocument_patient_id_fkey";
-- DropForeignKey
ALTER TABLE "Package" DROP CONSTRAINT "Package_service_id_fkey";
-- DropForeignKey
ALTER TABLE "PackageItem" DROP CONSTRAINT "PackageItem_package_id_fkey";
-- DropForeignKey
ALTER TABLE "PageBlock" DROP CONSTRAINT "PageBlock_pageId_fkey";
-- DropForeignKey
ALTER TABLE "Users" DROP CONSTRAINT "Users_profile_photo_id_fkey";
-- DropIndex
DROP INDEX "Patient_email_key";
-- AlterTable
ALTER TABLE "Image" DROP COLUMN "code",
DROP COLUMN "name",
DROP COLUMN "url",
ADD COLUMN "filename" TEXT,
ALTER COLUMN "mimeType" DROP NOT NULL,
ALTER COLUMN "size" DROP NOT NULL;
-- AlterTable
ALTER TABLE "Patient" DROP CONSTRAINT "Patient_pkey",
DROP COLUMN "country_code",
DROP COLUMN "country_name",
DROP COLUMN "dob",
DROP COLUMN "first_name",
DROP COLUMN "last_name",
DROP COLUMN "phone_number",
DROP COLUMN "status",
ADD COLUMN "age" INTEGER,
ADD COLUMN "countryCode" TEXT,
ADD COLUMN "firstName" TEXT NOT NULL,
ADD COLUMN "lastName" TEXT NOT NULL,
ADD COLUMN "nationality" TEXT,
ADD COLUMN "phone" TEXT,
ADD COLUMN "preferredLanguage" TEXT,
ALTER COLUMN "id" DROP DEFAULT,
ALTER COLUMN "id" SET DATA TYPE TEXT,
ADD CONSTRAINT "Patient_pkey" PRIMARY KEY ("id");
DROP SEQUENCE "Patient_id_seq";
-- AlterTable
ALTER TABLE "Users" DROP COLUMN "bio",
DROP COLUMN "createdAt",
DROP COLUMN "image",
DROP COLUMN "name",
DROP COLUMN "phone_number",
DROP COLUMN "profile_photo_id",
DROP COLUMN "role",
DROP COLUMN "socials",
ADD COLUMN "firstName" TEXT NOT NULL,
ADD COLUMN "imageId" INTEGER,
ADD COLUMN "lastName" TEXT NOT NULL,
ADD COLUMN "phone" TEXT,
ADD COLUMN "type" "UsersType" NOT NULL DEFAULT 'DOCTOR',
ALTER COLUMN "position" SET NOT NULL;
-- DropTable
DROP TABLE "AdmissionForm";
-- DropTable
DROP TABLE "DefaultInfo";
-- DropTable
DROP TABLE "File";
-- DropTable
DROP TABLE "Language";
-- DropTable
DROP TABLE "MedicalDocument";
-- DropTable
DROP TABLE "Package";
-- DropTable
DROP TABLE "PackageItem";
-- DropTable
DROP TABLE "Page";
-- DropTable
DROP TABLE "PageBlock";
-- DropTable
DROP TABLE "Service";
-- DropEnum
DROP TYPE "BlockType";
-- DropEnum
DROP TYPE "FormStatus";
-- DropEnum
DROP TYPE "PageStatus";
-- DropEnum
DROP TYPE "PageType";
-- DropEnum
DROP TYPE "PatientStatus";
-- DropEnum
DROP TYPE "UploadedBy";
-- DropEnum
DROP TYPE "UserRoles";
-- CreateTable
CREATE TABLE "OnlineCase" (
"id" TEXT NOT NULL,
"patientId" TEXT NOT NULL,
"trackingCode" TEXT NOT NULL,
"message" TEXT,
"specialty" TEXT,
"formData" JSONB,
"status" "CaseStatus" NOT NULL DEFAULT 'NEW',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "OnlineCase_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Document" (
"id" TEXT NOT NULL,
"caseId" TEXT,
"patientId" TEXT,
"uploadedById" TEXT,
"type" "DocumentType" NOT NULL,
"fileKey" TEXT NOT NULL,
"filename" TEXT,
"mimeType" TEXT,
"size" INTEGER,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Document_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Interaction" (
"id" TEXT NOT NULL,
"caseId" TEXT NOT NULL,
"staffId" TEXT,
"type" "InteractionType" NOT NULL,
"message" TEXT,
"direction" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Interaction_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Review" (
"id" TEXT NOT NULL,
"caseId" TEXT NOT NULL,
"doctorId" TEXT,
"note" TEXT,
"result" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Review_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CaseStatusHistory" (
"id" TEXT NOT NULL,
"caseId" TEXT NOT NULL,
"from" "CaseStatus",
"to" "CaseStatus" NOT NULL,
"changedBy" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "CaseStatusHistory_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Staff" (
"id" TEXT NOT NULL,
"username" TEXT NOT NULL,
"role" TEXT NOT NULL,
"email" TEXT NOT NULL,
CONSTRAINT "Staff_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "OnlineCase_trackingCode_key" ON "OnlineCase"("trackingCode");
-- CreateIndex
CREATE UNIQUE INDEX "Staff_email_key" ON "Staff"("email");
-- AddForeignKey
ALTER TABLE "OnlineCase" ADD CONSTRAINT "OnlineCase_patientId_fkey" FOREIGN KEY ("patientId") REFERENCES "Patient"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Document" ADD CONSTRAINT "Document_caseId_fkey" FOREIGN KEY ("caseId") REFERENCES "OnlineCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Document" ADD CONSTRAINT "Document_patientId_fkey" FOREIGN KEY ("patientId") REFERENCES "Patient"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Document" ADD CONSTRAINT "Document_uploadedById_fkey" FOREIGN KEY ("uploadedById") REFERENCES "Staff"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Interaction" ADD CONSTRAINT "Interaction_caseId_fkey" FOREIGN KEY ("caseId") REFERENCES "OnlineCase"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Interaction" ADD CONSTRAINT "Interaction_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "Staff"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Review" ADD CONSTRAINT "Review_caseId_fkey" FOREIGN KEY ("caseId") REFERENCES "OnlineCase"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Review" ADD CONSTRAINT "Review_doctorId_fkey" FOREIGN KEY ("doctorId") REFERENCES "Staff"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CaseStatusHistory" ADD CONSTRAINT "CaseStatusHistory_caseId_fkey" FOREIGN KEY ("caseId") REFERENCES "OnlineCase"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Users" ADD CONSTRAINT "Users_imageId_fkey" FOREIGN KEY ("imageId") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -0,0 +1,17 @@
/*
Warnings:
- You are about to drop the column `email` on the `Staff` table. All the data in the column will be lost.
- A unique constraint covering the columns `[username]` on the table `Staff` will be added. If there are existing duplicate values, this will fail.
- Added the required column `password` to the `Staff` table without a default value. This is not possible if the table is not empty.
*/
-- DropIndex
DROP INDEX "Staff_email_key";
-- AlterTable
ALTER TABLE "Staff" DROP COLUMN "email",
ADD COLUMN "password" TEXT NOT NULL;
-- CreateIndex
CREATE UNIQUE INDEX "Staff_username_key" ON "Staff"("username");

View File

@@ -0,0 +1,711 @@
/*
Warnings:
- The values [MEDICAL_RECORD,IMAGING] on the enum `DocumentType` will be removed. If these variants are still used in the database, this will fail.
- You are about to drop the column `countryCode` on the `Patient` table. All the data in the column will be lost.
- You are about to drop the column `nationality` on the `Patient` table. All the data in the column will be lost.
- You are about to alter the column `email` on the `Patient` table. The data in that column could be lost. The data in that column will be cast from `Text` to `VarChar(255)`.
- You are about to alter the column `firstName` on the `Patient` table. The data in that column could be lost. The data in that column will be cast from `Text` to `VarChar(100)`.
- You are about to alter the column `lastName` on the `Patient` table. The data in that column could be lost. The data in that column will be cast from `Text` to `VarChar(100)`.
- You are about to alter the column `phone` on the `Patient` table. The data in that column could be lost. The data in that column will be cast from `Text` to `VarChar(20)`.
- You are about to alter the column `preferredLanguage` on the `Patient` table. The data in that column could be lost. The data in that column will be cast from `Text` to `VarChar(10)`.
- You are about to drop the column `note` on the `Review` table. All the data in the column will be lost.
- You are about to drop the column `result` on the `Review` table. All the data in the column will be lost.
- You are about to drop the column `expertise` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `firstName` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `lastName` on the `Users` table. All the data in the column will be lost.
- You are about to drop the column `position` on the `Users` table. All the data in the column will be lost.
- You are about to drop the `Interaction` table. If the table is not empty, all the data it contains will be lost.
- A unique constraint covering the columns `[pid]` on the table `Patient` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[nationalityCode]` on the table `Patient` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[passportCode,nationalityId]` on the table `Patient` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[phone]` on the table `Patient` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[email]` on the table `Patient` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[firstName,lastName,birthDate]` on the table `Patient` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[email]` on the table `Staff` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[slug]` on the table `Users` will be added. If there are existing duplicate values, this will fail.
- Added the required column `fileUrl` to the `Document` table without a default value. This is not possible if the table is not empty.
- Made the column `filename` on table `Document` required. This step will fail if there are existing NULL values in that column.
- Added the required column `fileKey` to the `Image` table without a default value. This is not possible if the table is not empty.
- Added the required column `pid` to the `Patient` table without a default value. This is not possible if the table is not empty.
- Changed the type of `role` on the `Staff` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
- Added the required column `slug` to the `Users` table without a default value. This is not possible if the table is not empty.
*/
-- CreateEnum
CREATE TYPE "DocStatus" AS ENUM ('NEW', 'PENDING_SCAN', 'SAFE', 'INFECTED', 'INVALID');
-- CreateEnum
CREATE TYPE "Sex" AS ENUM ('male', 'female', 'other');
-- CreateEnum
CREATE TYPE "UploadStatus" AS ENUM ('PENDING', 'UPLOADING', 'UPLOADED', 'VERIFIED', 'FAILED', 'EXPIRED');
-- CreateEnum
CREATE TYPE "StaffRoles" AS ENUM ('developer', 'admin', 'doctor', 'coordinator');
-- CreateEnum
CREATE TYPE "StaffStatus" AS ENUM ('ACTIVE', 'WARNED', 'RESTRICTED', 'BANNED');
-- CreateEnum
CREATE TYPE "ViolationType" AS ENUM ('SPAM', 'RATE_LIMIT', 'CONTENT', 'ABUSE');
-- CreateEnum
CREATE TYPE "RestrictionType" AS ENUM ('TEMP', 'SHADOW', 'PERMANENT');
-- CreateEnum
CREATE TYPE "ConfigType" AS ENUM ('BOOLEAN', 'NUMBER', 'STRING', 'JSON', 'STRING_ARRAY');
-- CreateEnum
CREATE TYPE "AuditAction" AS ENUM ('CREATE', 'UPDATE', 'DELETE', 'READ');
-- AlterEnum
BEGIN;
CREATE TYPE "DocumentType_new" AS ENUM ('MEDICAL_IMAGE', 'LAB_RESULT', 'PRESCRIPTION', 'PASSPORT', 'NATIONAL_ID', 'OTHER', 'OTHER_FILE');
ALTER TABLE "Document" ALTER COLUMN "type" TYPE "DocumentType_new" USING ("type"::text::"DocumentType_new");
ALTER TYPE "DocumentType" RENAME TO "DocumentType_old";
ALTER TYPE "DocumentType_new" RENAME TO "DocumentType";
DROP TYPE "public"."DocumentType_old";
COMMIT;
-- DropForeignKey
ALTER TABLE "Interaction" DROP CONSTRAINT "Interaction_caseId_fkey";
-- DropForeignKey
ALTER TABLE "Interaction" DROP CONSTRAINT "Interaction_staffId_fkey";
-- AlterTable
ALTER TABLE "CaseStatusHistory" ALTER COLUMN "to" DROP NOT NULL;
-- AlterTable
ALTER TABLE "Document" ADD COLUMN "checksum" TEXT,
ADD COLUMN "fileUrl" TEXT NOT NULL,
ADD COLUMN "is_deleted" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "status" "DocStatus" NOT NULL DEFAULT 'NEW',
ALTER COLUMN "filename" SET NOT NULL;
-- AlterTable
ALTER TABLE "Image" ADD COLUMN "fileKey" TEXT NOT NULL,
ADD COLUMN "fileUrl" TEXT;
-- AlterTable
ALTER TABLE "Patient" DROP COLUMN "countryCode",
DROP COLUMN "nationality",
ADD COLUMN "address" VARCHAR(500),
ADD COLUMN "birthDate" TIMESTAMP(3),
ADD COLUMN "deletedAt" TIMESTAMP(3),
ADD COLUMN "nationalityCode" CHAR(3),
ADD COLUMN "nationalityId" INTEGER,
ADD COLUMN "passportCode" VARCHAR(20),
ADD COLUMN "pid" VARCHAR(10) NOT NULL,
ADD COLUMN "postalCode" VARCHAR(20),
ADD COLUMN "sex" "Sex",
ALTER COLUMN "email" SET DATA TYPE VARCHAR(255),
ALTER COLUMN "firstName" SET DATA TYPE VARCHAR(100),
ALTER COLUMN "lastName" SET DATA TYPE VARCHAR(100),
ALTER COLUMN "phone" SET DATA TYPE VARCHAR(20),
ALTER COLUMN "preferredLanguage" SET DATA TYPE VARCHAR(10);
-- AlterTable
ALTER TABLE "Review" DROP COLUMN "note",
DROP COLUMN "result",
ADD COLUMN "deletedAt" TIMESTAMP(3);
-- AlterTable
ALTER TABLE "Staff" ADD COLUMN "email" TEXT,
ADD COLUMN "is_verified" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "resetPasswordExpires" TIMESTAMP(3),
ADD COLUMN "resetPasswordToken" TEXT,
ADD COLUMN "send_notif_with_email" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "status" "StaffStatus" NOT NULL DEFAULT 'ACTIVE',
ADD COLUMN "strikes" INTEGER NOT NULL DEFAULT 0,
ADD COLUMN "trustScore" INTEGER NOT NULL DEFAULT 100,
DROP COLUMN "role",
ADD COLUMN "role" "StaffRoles" NOT NULL;
-- AlterTable
ALTER TABLE "Users" DROP COLUMN "expertise",
DROP COLUMN "firstName",
DROP COLUMN "lastName",
DROP COLUMN "position",
ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "expertiseId" INTEGER,
ADD COLUMN "medicalNumber" TEXT,
ADD COLUMN "slug" TEXT NOT NULL,
ADD COLUMN "teamName" TEXT;
-- DropTable
DROP TABLE "Interaction";
-- CreateTable
CREATE TABLE "ReviewTranslation" (
"id" SERIAL NOT NULL,
"reviewId" TEXT NOT NULL,
"lang_id" INTEGER,
"note" TEXT,
"result" TEXT,
CONSTRAINT "ReviewTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UploadSession" (
"id" TEXT NOT NULL,
"uploadKey" TEXT NOT NULL,
"nonce" TEXT NOT NULL,
"used" BOOLEAN NOT NULL DEFAULT false,
"createdById" TEXT,
"purpose" TEXT NOT NULL,
"allowedTypes" TEXT,
"maxSize" INTEGER,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"expiresAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "UploadSession_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Violation" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" "ViolationType" NOT NULL,
"severity" INTEGER NOT NULL,
"reason" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Violation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Restriction" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" "RestrictionType" NOT NULL,
"expiresAt" TIMESTAMP(3),
CONSTRAINT "Restriction_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "StaffTranslation" (
"id" SERIAL NOT NULL,
"staffId" TEXT NOT NULL,
"lang_id" INTEGER,
"displayName" TEXT,
"position" TEXT,
"description" TEXT,
CONSTRAINT "StaffTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UserTranslation" (
"id" SERIAL NOT NULL,
"userId" INTEGER NOT NULL,
"lang_id" INTEGER,
"firstName" TEXT,
"lastName" TEXT,
"position" TEXT,
CONSTRAINT "UserTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Expertise" (
"id" SERIAL NOT NULL,
"slug" VARCHAR(100) NOT NULL,
CONSTRAINT "Expertise_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ExpertiseTranslation" (
"id" SERIAL NOT NULL,
"expertiseId" INTEGER NOT NULL,
"lang_id" INTEGER,
"displayName" TEXT,
CONSTRAINT "ExpertiseTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PanelConfig" (
"id" TEXT NOT NULL,
"key" TEXT NOT NULL,
"value" TEXT NOT NULL,
"type" "ConfigType" NOT NULL,
"description" TEXT,
"updatedAt" TIMESTAMP(3) NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "PanelConfig_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Default" (
"id" TEXT NOT NULL DEFAULT 'SITE_DEFAULTS',
"email" TEXT NOT NULL,
"hospitalPhone" TEXT NOT NULL,
"logoUrl" TEXT,
"mapAddress" TEXT NOT NULL,
"instagramLink" TEXT,
"linkedinLink" TEXT,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Default_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "DefaultTranslation" (
"id" SERIAL NOT NULL,
"defaultId" TEXT NOT NULL,
"languageId" INTEGER NOT NULL,
"address" TEXT NOT NULL,
"underLogoText" TEXT,
CONSTRAINT "DefaultTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Page" (
"id" SERIAL NOT NULL,
"slug" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Page_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PageBlock" (
"id" SERIAL NOT NULL,
"pageId" INTEGER NOT NULL,
"type" TEXT NOT NULL,
"sort" INTEGER NOT NULL,
CONSTRAINT "PageBlock_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PageBlockTranslation" (
"id" SERIAL NOT NULL,
"blockId" INTEGER NOT NULL,
"lang_id" INTEGER,
"field" TEXT NOT NULL,
"value" TEXT NOT NULL,
CONSTRAINT "PageBlockTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Language" (
"id" SERIAL NOT NULL,
"title" TEXT NOT NULL,
"slug" TEXT NOT NULL,
CONSTRAINT "Language_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "RefreshToken" (
"id" SERIAL NOT NULL,
"token" TEXT NOT NULL,
"staffId" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3) NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "RefreshToken_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Countries" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"callCode" TEXT NOT NULL,
"coverId" INTEGER,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Countries_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "AuditLog" (
"id" SERIAL NOT NULL,
"actorId" TEXT,
"actorRole" "StaffRoles",
"action" "AuditAction" NOT NULL,
"entity" TEXT NOT NULL,
"entityId" INTEGER,
"before" JSONB,
"after" JSONB,
"ip" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "AccessLog" (
"id" SERIAL NOT NULL,
"userId" TEXT NOT NULL,
"userRole" "StaffRoles" NOT NULL,
"resource" TEXT NOT NULL,
"resourceId" INTEGER,
"reason" TEXT,
"ip" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "AccessLog_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "DecisionLog" (
"id" SERIAL NOT NULL,
"decisionType" TEXT NOT NULL,
"input" JSONB NOT NULL,
"output" JSONB NOT NULL,
"algorithmVersion" TEXT NOT NULL,
"actorId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "DecisionLog_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TermsOfService" (
"id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"version" TEXT NOT NULL,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "TermsOfService_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TosAcceptanceLog" (
"id" SERIAL NOT NULL,
"userId" TEXT NOT NULL,
"policyType" TEXT NOT NULL,
"policyVersion" TEXT NOT NULL,
"acceptedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"ip" TEXT,
CONSTRAINT "TosAcceptanceLog_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PrivacyPolicy" (
"id" SERIAL NOT NULL,
"content" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "PrivacyPolicy_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "MedicalPackage" (
"id" SERIAL NOT NULL,
"thumbnail_id" INTEGER,
"icon" TEXT,
"priority" INTEGER,
"parent_id" INTEGER,
CONSTRAINT "MedicalPackage_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "MedicalPackagesTranslation" (
"id" SERIAL NOT NULL,
"title" VARCHAR(50) NOT NULL,
"content" TEXT,
"lang_id" INTEGER,
"medicalPackageId" INTEGER,
CONSTRAINT "MedicalPackagesTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TransferPackage" (
"id" SERIAL NOT NULL,
"location" TEXT NOT NULL,
"price" TEXT NOT NULL,
CONSTRAINT "TransferPackage_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TransferPackageTranslations" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"content" TEXT NOT NULL,
"lang_id" INTEGER,
"transferPackageId" INTEGER,
CONSTRAINT "TransferPackageTranslations_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TransferTeam" (
"id" SERIAL NOT NULL,
CONSTRAINT "TransferTeam_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TransferTeamTranslation" (
"id" SERIAL NOT NULL,
"lang_id" INTEGER,
"transferTeamId" INTEGER,
"name" VARCHAR(50) NOT NULL,
"introduction" TEXT NOT NULL,
"duties" TEXT NOT NULL,
"services" TEXT NOT NULL,
CONSTRAINT "TransferTeamTranslation_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "_TransferPackageLocationImages" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_TransferPackageLocationImages_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateTable
CREATE TABLE "_TransferPackageGalleryImages" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_TransferPackageGalleryImages_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateTable
CREATE TABLE "_TransferPackageToTransferTeam" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_TransferPackageToTransferTeam_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateTable
CREATE TABLE "_TransferTeamToUsers" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL,
CONSTRAINT "_TransferTeamToUsers_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateIndex
CREATE UNIQUE INDEX "ReviewTranslation_reviewId_lang_id_key" ON "ReviewTranslation"("reviewId", "lang_id");
-- CreateIndex
CREATE UNIQUE INDEX "UploadSession_uploadKey_key" ON "UploadSession"("uploadKey");
-- CreateIndex
CREATE UNIQUE INDEX "UploadSession_nonce_key" ON "UploadSession"("nonce");
-- CreateIndex
CREATE INDEX "UploadSession_createdById_idx" ON "UploadSession"("createdById");
-- CreateIndex
CREATE INDEX "UploadSession_status_idx" ON "UploadSession"("status");
-- CreateIndex
CREATE UNIQUE INDEX "StaffTranslation_staffId_lang_id_key" ON "StaffTranslation"("staffId", "lang_id");
-- CreateIndex
CREATE UNIQUE INDEX "UserTranslation_userId_lang_id_key" ON "UserTranslation"("userId", "lang_id");
-- CreateIndex
CREATE UNIQUE INDEX "ExpertiseTranslation_expertiseId_lang_id_key" ON "ExpertiseTranslation"("expertiseId", "lang_id");
-- CreateIndex
CREATE UNIQUE INDEX "PanelConfig_key_key" ON "PanelConfig"("key");
-- CreateIndex
CREATE UNIQUE INDEX "DefaultTranslation_defaultId_languageId_key" ON "DefaultTranslation"("defaultId", "languageId");
-- CreateIndex
CREATE UNIQUE INDEX "Page_slug_key" ON "Page"("slug");
-- CreateIndex
CREATE UNIQUE INDEX "Language_slug_key" ON "Language"("slug");
-- CreateIndex
CREATE INDEX "Language_id_slug_idx" ON "Language"("id", "slug");
-- CreateIndex
CREATE UNIQUE INDEX "RefreshToken_token_key" ON "RefreshToken"("token");
-- CreateIndex
CREATE INDEX "AuditLog_entity_entityId_idx" ON "AuditLog"("entity", "entityId");
-- CreateIndex
CREATE UNIQUE INDEX "TermsOfService_version_key" ON "TermsOfService"("version");
-- CreateIndex
CREATE UNIQUE INDEX "MedicalPackagesTranslation_medicalPackageId_lang_id_key" ON "MedicalPackagesTranslation"("medicalPackageId", "lang_id");
-- CreateIndex
CREATE UNIQUE INDEX "TransferPackageTranslations_transferPackageId_lang_id_key" ON "TransferPackageTranslations"("transferPackageId", "lang_id");
-- CreateIndex
CREATE UNIQUE INDEX "TransferTeamTranslation_transferTeamId_lang_id_key" ON "TransferTeamTranslation"("transferTeamId", "lang_id");
-- CreateIndex
CREATE INDEX "_TransferPackageLocationImages_B_index" ON "_TransferPackageLocationImages"("B");
-- CreateIndex
CREATE INDEX "_TransferPackageGalleryImages_B_index" ON "_TransferPackageGalleryImages"("B");
-- CreateIndex
CREATE INDEX "_TransferPackageToTransferTeam_B_index" ON "_TransferPackageToTransferTeam"("B");
-- CreateIndex
CREATE INDEX "_TransferTeamToUsers_B_index" ON "_TransferTeamToUsers"("B");
-- CreateIndex
CREATE INDEX "CaseStatusHistory_id_caseId_idx" ON "CaseStatusHistory"("id", "caseId");
-- CreateIndex
CREATE UNIQUE INDEX "Patient_pid_key" ON "Patient"("pid");
-- CreateIndex
CREATE INDEX "Patient_pid_idx" ON "Patient"("pid");
-- CreateIndex
CREATE UNIQUE INDEX "Patient_nationalityCode_key" ON "Patient"("nationalityCode");
-- CreateIndex
CREATE UNIQUE INDEX "Patient_passportCode_nationalityId_key" ON "Patient"("passportCode", "nationalityId");
-- CreateIndex
CREATE UNIQUE INDEX "Patient_phone_key" ON "Patient"("phone");
-- CreateIndex
CREATE UNIQUE INDEX "Patient_email_key" ON "Patient"("email");
-- CreateIndex
CREATE UNIQUE INDEX "Patient_firstName_lastName_birthDate_key" ON "Patient"("firstName", "lastName", "birthDate");
-- CreateIndex
CREATE UNIQUE INDEX "Staff_email_key" ON "Staff"("email");
-- CreateIndex
CREATE UNIQUE INDEX "Users_slug_key" ON "Users"("slug");
-- CreateIndex
CREATE INDEX "Users_id_slug_idx" ON "Users"("id", "slug");
-- AddForeignKey
ALTER TABLE "Patient" ADD CONSTRAINT "Patient_nationalityId_fkey" FOREIGN KEY ("nationalityId") REFERENCES "Countries"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ReviewTranslation" ADD CONSTRAINT "ReviewTranslation_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ReviewTranslation" ADD CONSTRAINT "ReviewTranslation_reviewId_fkey" FOREIGN KEY ("reviewId") REFERENCES "Review"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Violation" ADD CONSTRAINT "Violation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Staff"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Restriction" ADD CONSTRAINT "Restriction_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Staff"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "StaffTranslation" ADD CONSTRAINT "StaffTranslation_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "StaffTranslation" ADD CONSTRAINT "StaffTranslation_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "Staff"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Users" ADD CONSTRAINT "Users_expertiseId_fkey" FOREIGN KEY ("expertiseId") REFERENCES "Expertise"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserTranslation" ADD CONSTRAINT "UserTranslation_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserTranslation" ADD CONSTRAINT "UserTranslation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ExpertiseTranslation" ADD CONSTRAINT "ExpertiseTranslation_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ExpertiseTranslation" ADD CONSTRAINT "ExpertiseTranslation_expertiseId_fkey" FOREIGN KEY ("expertiseId") REFERENCES "Expertise"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "DefaultTranslation" ADD CONSTRAINT "DefaultTranslation_defaultId_fkey" FOREIGN KEY ("defaultId") REFERENCES "Default"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "DefaultTranslation" ADD CONSTRAINT "DefaultTranslation_languageId_fkey" FOREIGN KEY ("languageId") REFERENCES "Language"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PageBlock" ADD CONSTRAINT "PageBlock_pageId_fkey" FOREIGN KEY ("pageId") REFERENCES "Page"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PageBlockTranslation" ADD CONSTRAINT "PageBlockTranslation_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PageBlockTranslation" ADD CONSTRAINT "PageBlockTranslation_blockId_fkey" FOREIGN KEY ("blockId") REFERENCES "PageBlock"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RefreshToken" ADD CONSTRAINT "RefreshToken_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "Staff"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Countries" ADD CONSTRAINT "Countries_coverId_fkey" FOREIGN KEY ("coverId") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TosAcceptanceLog" ADD CONSTRAINT "TosAcceptanceLog_policyVersion_fkey" FOREIGN KEY ("policyVersion") REFERENCES "TermsOfService"("version") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MedicalPackage" ADD CONSTRAINT "MedicalPackage_thumbnail_id_fkey" FOREIGN KEY ("thumbnail_id") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MedicalPackage" ADD CONSTRAINT "MedicalPackage_parent_id_fkey" FOREIGN KEY ("parent_id") REFERENCES "MedicalPackage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MedicalPackagesTranslation" ADD CONSTRAINT "MedicalPackagesTranslation_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MedicalPackagesTranslation" ADD CONSTRAINT "MedicalPackagesTranslation_medicalPackageId_fkey" FOREIGN KEY ("medicalPackageId") REFERENCES "MedicalPackage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TransferPackageTranslations" ADD CONSTRAINT "TransferPackageTranslations_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TransferPackageTranslations" ADD CONSTRAINT "TransferPackageTranslations_transferPackageId_fkey" FOREIGN KEY ("transferPackageId") REFERENCES "TransferPackage"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TransferTeamTranslation" ADD CONSTRAINT "TransferTeamTranslation_lang_id_fkey" FOREIGN KEY ("lang_id") REFERENCES "Language"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TransferTeamTranslation" ADD CONSTRAINT "TransferTeamTranslation_transferTeamId_fkey" FOREIGN KEY ("transferTeamId") REFERENCES "TransferTeam"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferPackageLocationImages" ADD CONSTRAINT "_TransferPackageLocationImages_A_fkey" FOREIGN KEY ("A") REFERENCES "Image"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferPackageLocationImages" ADD CONSTRAINT "_TransferPackageLocationImages_B_fkey" FOREIGN KEY ("B") REFERENCES "TransferPackage"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferPackageGalleryImages" ADD CONSTRAINT "_TransferPackageGalleryImages_A_fkey" FOREIGN KEY ("A") REFERENCES "Image"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferPackageGalleryImages" ADD CONSTRAINT "_TransferPackageGalleryImages_B_fkey" FOREIGN KEY ("B") REFERENCES "TransferPackage"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferPackageToTransferTeam" ADD CONSTRAINT "_TransferPackageToTransferTeam_A_fkey" FOREIGN KEY ("A") REFERENCES "TransferPackage"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferPackageToTransferTeam" ADD CONSTRAINT "_TransferPackageToTransferTeam_B_fkey" FOREIGN KEY ("B") REFERENCES "TransferTeam"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferTeamToUsers" ADD CONSTRAINT "_TransferTeamToUsers_A_fkey" FOREIGN KEY ("A") REFERENCES "TransferTeam"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_TransferTeamToUsers" ADD CONSTRAINT "_TransferTeamToUsers_B_fkey" FOREIGN KEY ("B") REFERENCES "Users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"

682
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,682 @@
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
enum CaseStatus {
NEW
CONTACTED
DOCS_PENDING
REVIEWING
PRE_APPROVED
REJECTED
CLOSED
CONVERTED_TO_HIS
}
// enum DocumentType {
// PASSPORT
// MEDICAL_RECORD
// IMAGING
// LAB_RESULT
// OTHER
// }
enum InteractionType {
PHONE
WHATSAPP
EMAIL
SYSTEM
}
model Patient {
id String @id @default(uuid())
pid String @unique @db.VarChar(10)
// -------- Identity --------
firstName String @db.VarChar(100)
lastName String @db.VarChar(100)
birthDate DateTime?
sex Sex?
age Int?
// -------- Nationality --------
nationality Countries? @relation(fields: [nationalityId], references: [id])
nationalityId Int?
nationalityCode String? @db.Char(3)
passportCode String? @db.VarChar(20)
// -------- Contact --------
phone String? @db.VarChar(20)
email String? @db.VarChar(255)
preferredLanguage String? @db.VarChar(10)
// -------- Address --------
address String? @db.VarChar(500)
postalCode String? @db.VarChar(20)
// -------- System --------
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
// -------- Relations --------
cases OnlineCase[]
documents Document[]
// -------- Indexes & Constraints --------
@@unique([nationalityCode]) // کد ملی
@@unique([passportCode, nationalityId]) // پاسپورت
@@unique([phone])
@@unique([email])
@@unique([firstName, lastName, birthDate])
@@index([pid])
}
model Document {
id String @id @default(uuid())
caseId String?
patientId String?
uploadedById String?
type DocumentType
filename String
fileUrl String
fileKey String
mimeType String?
size Int?
checksum String?
status DocStatus @default(NEW)
is_deleted Boolean @default(false)
createdAt DateTime @default(now())
case OnlineCase? @relation(fields: [caseId], references: [id])
patient Patient? @relation(fields: [patientId], references: [id])
uploadedBy Staff? @relation(fields: [uploadedById], references: [id])
}
enum DocumentType {
MEDICAL_IMAGE
LAB_RESULT
PRESCRIPTION
PASSPORT
NATIONAL_ID
OTHER
OTHER_FILE
}
enum DocStatus {
NEW
PENDING_SCAN
SAFE
INFECTED
INVALID
}
enum Sex {
male
female
other
}
model OnlineCase {
id String @id @default(uuid())
patientId String
trackingCode String @unique
message String?
specialty String?
formData Json?
status CaseStatus @default(NEW)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
patient Patient @relation(fields: [patientId], references: [id])
documents Document[]
// interactions Interaction[]
reviews Review[]
statusHistory CaseStatusHistory[]
}
model Review {
id String @id @default(uuid())
caseId String
doctorId String?
createdAt DateTime @default(now())
deletedAt DateTime?
case OnlineCase @relation(fields: [caseId], references: [id])
doctor Staff? @relation(fields: [doctorId], references: [id])
translations ReviewTranslation[]
}
model ReviewTranslation {
id Int @id @default(autoincrement())
reviewId String
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
note String?
result String? // eligible, needs more docs, not eligible (می‌تونه ترجمه شود)
review Review @relation(fields: [reviewId], references: [id])
@@unique([reviewId, lang_id]) // هر Review در هر زبان فقط یک ترجمه دارد
}
model CaseStatusHistory {
id String @id @default(uuid())
caseId String
from CaseStatus?
to CaseStatus?
changedBy String?
createdAt DateTime @default(now())
case OnlineCase @relation(fields: [caseId], references: [id])
@@index([id, caseId])
}
model UploadSession {
id String @id @default(uuid())
uploadKey String @unique // path/key to store file on CDN (e.g. documents/{uuid}.pdf)
nonce String @unique
used Boolean @default(false)
createdById String? // user id
purpose String // "document" | "image"
allowedTypes String? // JSON string array
maxSize Int?
status String @default("PENDING")
createdAt DateTime @default(now())
expiresAt DateTime
// indexes
@@index([createdById])
@@index([status])
}
enum UploadStatus {
PENDING
UPLOADING
UPLOADED
VERIFIED
FAILED
EXPIRED
}
enum StaffRoles {
developer
admin
doctor
coordinator
}
model Staff {
id String @id @default(uuid())
username String @unique
password String
email String? @unique
role StaffRoles
is_verified Boolean @default(false)
send_notif_with_email Boolean @default(false)
resetPasswordToken String?
resetPasswordExpires DateTime?
status StaffStatus @default(ACTIVE)
trustScore Int @default(100)
strikes Int @default(0)
restrictions Restriction[]
violations Violation[]
documents Document[]
reviews Review[]
profilePicture Image? @relation(fields: [profilePictureID],references: [id])
profilePictureID Int?
translations StaffTranslation[]
tokens RefreshToken[]
}
enum StaffStatus {
ACTIVE
WARNED
RESTRICTED
BANNED
}
model Violation {
id String @id @default(uuid())
userId String
type ViolationType
severity Int
reason String
user Staff @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
}
enum ViolationType {
SPAM
RATE_LIMIT
CONTENT
ABUSE
}
model Restriction {
id String @id @default(uuid())
userId String
type RestrictionType
expiresAt DateTime?
user Staff @relation(fields: [userId], references: [id])
}
enum RestrictionType {
TEMP
SHADOW
PERMANENT
}
model StaffTranslation {
id Int @id @default(autoincrement())
staffId String
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
// فیلدهایی که نیاز به ترجمه دارند
displayName String?
position String?
description String?
staff Staff @relation(fields: [staffId], references: [id])
@@unique([staffId, lang_id]) // هر کارمند در هر زبان فقط یک ترجمه دارد
}
model Image {
id Int @id @default(autoincrement())
fileKey String
filename String?
fileUrl String?
mimeType String?
size Int?
usersProfile Users[]
countriesCover Countries[]
medicalPackagesThumbnails MedicalPackage[]
transferPackageLocationImages TransferPackage[] @relation(name: "TransferPackageLocationImages")
transferPackageGalleryImages TransferPackage[] @relation(name: "TransferPackageGalleryImages")
staffProfilePictures Staff[]
}
model Users {
id Int @id @default(autoincrement())
slug String @unique
type UsersType @default(DOCTOR)
displayInMainPage Boolean @default(false)
phone String?
email String?
teamName String?
medicalNumber String?
expertise Expertise? @relation(fields: [expertiseId], references: [id])
expertiseId Int?
image Image? @relation(fields: [imageId], references: [id])
imageId Int?
createdAt DateTime @default(now())
translations UserTranslation[]
transerTeamMembers TransferTeam[]
@@index([id, slug])
}
model UserTranslation {
id Int @id @default(autoincrement())
userId Int
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
firstName String?
lastName String?
position String?
bio String?
excerpt String?
user Users @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, lang_id]) // هر کاربر در هر زبان فقط یک ترجمه دارد
}
model Expertise {
id Int @id @default(autoincrement())
slug String @db.VarChar(100)
users Users[]
translations ExpertiseTranslation[]
}
model ExpertiseTranslation {
id Int @id @default(autoincrement())
expertiseId Int
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
displayName String?
level EducationLevel?
expertise Expertise @relation(fields: [expertiseId], references: [id])
@@unique([expertiseId, lang_id]) // هر کاربر در هر زبان فقط یک ترجمه دارد
}
enum EducationLevel {
GP
SPECIALIST
SUBSPECIALIST
FELLOWSHIP
}
enum UsersType {
DOCTOR
TRANSFER_TEAM
DEPARTMENT
}
model PanelConfig {
id String @id @default(uuid())
key String @unique
value String // مقدار خام (string)
type ConfigType // نوع داده
description String?
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
}
model Default {
id String @id @default("SITE_DEFAULTS")
email String
hospitalPhone String
logoUrl String?
mapAddress String
instagramLink String?
linkedinLink String?
ipdNumber String?
updatedAt DateTime @updatedAt
translations DefaultTranslation[]
}
model DefaultTranslation {
id Int @id @default(autoincrement())
default Default @relation(fields: [defaultId], references: [id])
defaultId String
language Language @relation(fields: [languageId], references: [id])
languageId Int
address String
underLogoText String?
aboutUsText String?
patientsRights String?
@@unique([defaultId, languageId])
}
model Statics {
id String @id @default(uuid())
key String @unique @db.VarChar(191)
group String @db.VarChar(100)
description String? @db.Text
translations StaticsTranslation[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([group])
}
model StaticsTranslation {
id String @id @default(uuid())
languageId Int
staticsKeyId String
value String @db.Text
language Language @relation(fields: [languageId], references: [id], onDelete: Cascade)
staticsKey Statics @relation(fields: [staticsKeyId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([languageId, staticsKeyId])
@@index([languageId])
@@index([staticsKeyId])
}
enum ConfigType {
BOOLEAN
NUMBER
STRING
JSON
STRING_ARRAY
}
model Page {
id Int @id @default(autoincrement())
slug String @unique
createdAt DateTime @default(now())
pageBlocks PageBlock[]
}
model PageBlock {
id Int @id @default(autoincrement())
pageId Int
type String // hero, text, image, faq, etc
sort Int
page Page @relation(fields: [pageId], references: [id])
pageBlockTranslations PageBlockTranslation[]
}
model PageBlockTranslation {
id Int @id @default(autoincrement())
blockId Int
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
field String // title, subtitle, description, button_text
value String
block PageBlock @relation(fields: [blockId], references: [id])
}
model Language {
id Int @id @default(autoincrement())
title String
slug String @unique
pageBlockTranslations PageBlockTranslation[]
// translations Translation[]
reviewTranslations ReviewTranslation[]
staffTranslations StaffTranslation[]
userTranslations UserTranslation[]
expertiseTranslations ExpertiseTranslation[]
defaultTranslations DefaultTranslation[]
medicalPackagesTranslations MedicalPackagesTranslation[]
transferPackageTranslations TransferPackageTranslations[]
transferTeamTranslations TransferTeamTranslation[]
staticsTranslations StaticsTranslation[]
@@index([id, slug])
}
model RefreshToken {
id Int @id @default(autoincrement())
token String @unique
staff Staff @relation(fields: [staffId], references: [id])
staffId String
expiresAt DateTime
createdAt DateTime @default(now())
}
model Countries {
id Int @id @default(autoincrement())
name String
callCode String
cover Image? @relation(fields: [coverId], references: [id])
coverId Int?
createdAt DateTime @default(now())
patients Patient[]
}
enum AuditAction {
CREATE
UPDATE
DELETE
READ
}
model AuditLog {
id Int @id @default(autoincrement())
actorId String?
actorRole StaffRoles?
action AuditAction
entity String
entityId Int?
before Json?
after Json?
ip String?
createdAt DateTime @default(now())
@@index([entity, entityId])
}
model AccessLog {
id Int @id @default(autoincrement())
userId String
userRole StaffRoles
resource String
resourceId Int?
reason String?
ip String?
createdAt DateTime @default(now())
}
model DecisionLog {
id Int @id @default(autoincrement())
decisionType String
input Json
output Json
algorithmVersion String
actorId String?
createdAt DateTime @default(now())
}
model TermsOfService {
id String @id @default(uuid()) // شناسه یکتا
title String // عنوان سند، مثلا "Terms of Service"
content String // متن کامل TOS (Markdown یا HTML)
version String @unique // نسخه سند، مثلا "v1.0.0"
isActive Boolean @default(true) // آیا این نسخه فعال است؟
createdAt DateTime @default(now()) // زمان ایجاد نسخه
updatedAt DateTime @updatedAt // زمان آخرین آپدیت
/// روابط اختیاری، اگر بخواهید لاگ پذیرش کاربران را نگه دارید
acceptances TosAcceptanceLog[] // ثبت کاربرانی که این نسخه را پذیرفته‌اند
}
model TosAcceptanceLog {
id Int @id @default(autoincrement())
userId String // شناسه کاربر
policyType String // نوع سند (TOS یا Privacy Policy)
policyVersion String // نسخه سند پذیرفته شده
acceptedAt DateTime @default(now()) // زمان پذیرش
ip String? // آی‌پی کاربر برای ثبت لاگ
tos TermsOfService? @relation(fields: [policyVersion], references: [version])
}
model PrivacyPolicy {
id Int @id @default(autoincrement()) // شناسه یکتا
content String // متن کامل TOS (Markdown یا HTML)
createdAt DateTime @default(now()) // زمان ایجاد نسخه
updatedAt DateTime @updatedAt // زمان آخرین آپدیت
}
model MedicalPackage {
id Int @id @default(autoincrement())
thumbnail Image? @relation(fields: [thumbnail_id], references: [id])
thumbnail_id Int?
icon String?
priority Int?
price String
parent MedicalPackage? @relation("MedicalPackageHierarchy", fields: [parent_id], references: [id], onDelete: SetNull)
parent_id Int? // برای اشاره به دسته‌بندی والد
children MedicalPackage[] @relation("MedicalPackageHierarchy")
translations MedicalPackagesTranslation[]
}
model MedicalPackagesTranslation {
id Int @id @default(autoincrement())
title String @db.VarChar(50)
content String?
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
medicalPackage MedicalPackage? @relation(fields: [medicalPackageId], references: [id])
medicalPackageId Int?
@@unique([medicalPackageId, lang_id]) // هر کاربر در هر زبان فقط یک ترجمه دارد
}
model TransferPackage {
id Int @id @default(autoincrement())
location String
price String
locationImages Image[] @relation(name: "TransferPackageLocationImages")
galleryImages Image[] @relation(name: "TransferPackageGalleryImages")
transferTeam TransferTeam[]
translations TransferPackageTranslations[]
}
model TransferPackageTranslations {
id Int @id @default(autoincrement())
name String
content String
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
transferPackage TransferPackage? @relation(fields: [transferPackageId], references: [id])
transferPackageId Int?
@@unique([transferPackageId, lang_id]) // هر کاربر در هر زبان فقط یک ترجمه دارد
}
model TransferTeam {
id Int @id @default(autoincrement())
members Users[]
packages TransferPackage[]
translations TransferTeamTranslation[]
}
model TransferTeamTranslation {
id Int @id @default(autoincrement())
lang Language? @relation(fields: [lang_id], references: [id])
lang_id Int?
transferTeam TransferTeam? @relation(fields: [transferTeamId], references: [id])
transferTeamId Int?
name String @db.VarChar(50)
introduction String
duties String
services String
@@unique([transferTeamId, lang_id]) // هر کاربر در هر زبان فقط یک ترجمه دارد
}