114 lines
5.4 KiB
SQL
114 lines
5.4 KiB
SQL
-- AI-Powered Tree-Based Reminder Sequence System
|
|
-- This migration adds the foundation for sophisticated reminder trees
|
|
|
|
-- Core Tree Definition
|
|
CREATE TABLE "ReminderTree" (
|
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
"clinicId" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"triggerType" TEXT NOT NULL, -- booking_created | no_show | completed | custom
|
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
|
"version" INTEGER NOT NULL DEFAULT 1,
|
|
"metadata" TEXT, -- JSON: A/B test groups, analytics tags, etc.
|
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" DATETIME NOT NULL,
|
|
FOREIGN KEY ("clinicId") REFERENCES "Clinic" ("id") ON DELETE CASCADE
|
|
);
|
|
|
|
-- Individual nodes in the tree
|
|
CREATE TABLE "TreeNode" (
|
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
"treeId" TEXT NOT NULL,
|
|
"parentId" TEXT, -- NULL for root node
|
|
"name" TEXT NOT NULL,
|
|
"nodeType" TEXT NOT NULL, -- wait | send_message | send_buttons | condition | action | collect_input
|
|
"content" TEXT, -- Message template or condition logic
|
|
"offsetMinutes" INTEGER DEFAULT 0, -- Delay from parent execution
|
|
"conditions" TEXT, -- JSON: Complex conditions for routing
|
|
"metadata" TEXT, -- JSON: Additional node configuration
|
|
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY ("treeId") REFERENCES "ReminderTree" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("parentId") REFERENCES "TreeNode" ("id") ON DELETE CASCADE
|
|
);
|
|
|
|
-- Track user journey through trees
|
|
CREATE TABLE "UserJourney" (
|
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
"appointmentId" TEXT NOT NULL,
|
|
"treeId" TEXT NOT NULL,
|
|
"currentNodeId" TEXT,
|
|
"status" TEXT NOT NULL DEFAULT "active", -- active | completed | paused | failed
|
|
"journeyData" TEXT, -- JSON: Collected responses, scores, etc.
|
|
"startedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"lastActiveAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"completedAt" DATETIME,
|
|
FOREIGN KEY ("appointmentId") REFERENCES "Appointment" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("treeId") REFERENCES "ReminderTree" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("currentNodeId") REFERENCES "TreeNode" ("id") ON DELETE SET NULL
|
|
);
|
|
|
|
-- Track execution of individual tree nodes
|
|
CREATE TABLE "NodeExecution" (
|
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
"journeyId" TEXT NOT NULL,
|
|
"nodeId" TEXT NOT NULL,
|
|
"status" TEXT NOT NULL DEFAULT "pending", -- pending | executed | failed | skipped
|
|
"executedAt" DATETIME,
|
|
"response" TEXT, -- User response to this node
|
|
"metadata" TEXT, -- JSON: Execution details, errors, etc.
|
|
"nextNodeId" TEXT, -- Which node was selected as next
|
|
FOREIGN KEY ("journeyId") REFERENCES "UserJourney" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("nodeId") REFERENCES "TreeNode" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("nextNodeId") REFERENCES "TreeNode" ("id") ON DELETE SET NULL
|
|
);
|
|
|
|
-- Patient behavioral scoring system
|
|
CREATE TABLE "PatientProfile" (
|
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
"leadId" TEXT NOT NULL,
|
|
"clinicId" TEXT NOT NULL,
|
|
"responseStyle" TEXT NOT NULL DEFAULT "standard", -- quick | detailed | minimal | emoji_heavy
|
|
"preferredTime" TEXT, -- JSON: Hour ranges when they respond most
|
|
"engagementScore" REAL NOT NULL DEFAULT 50.0, -- 0-100 based on interaction quality
|
|
"noShowRisk" REAL NOT NULL DEFAULT 50.0, -- 0-100 predicted likelihood
|
|
"conversationTone" TEXT NOT NULL DEFAULT "neutral", -- formal | casual | friendly | professional
|
|
"languagePreference" TEXT NOT NULL DEFAULT "auto", -- auto | english | arabic
|
|
"lastInteractionAt" DATETIME,
|
|
"profileData" TEXT, -- JSON: Detailed behavioral analytics
|
|
"updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY ("leadId") REFERENCES "Lead" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("clinicId") REFERENCES "Clinic" ("id") ON DELETE CASCADE,
|
|
UNIQUE("leadId", "clinicId")
|
|
);
|
|
|
|
-- Smart A/B testing for different tree paths
|
|
CREATE TABLE "TreeExperiment" (
|
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
"clinicId" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"controlTreeId" TEXT NOT NULL,
|
|
"variantTreeId" TEXT NOT NULL,
|
|
"trafficSplit" REAL NOT NULL DEFAULT 50.0, -- Percentage for variant
|
|
"status" TEXT NOT NULL DEFAULT "draft", -- draft | running | paused | completed
|
|
"startDate" DATETIME,
|
|
"endDate" DATETIME,
|
|
"metrics" TEXT, -- JSON: Conversion goals, success criteria
|
|
"results" TEXT, -- JSON: Experiment results
|
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY ("clinicId") REFERENCES "Clinic" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("controlTreeId") REFERENCES "ReminderTree" ("id") ON DELETE CASCADE,
|
|
FOREIGN KEY ("variantTreeId") REFERENCES "ReminderTree" ("id") ON DELETE CASCADE
|
|
);
|
|
|
|
-- Indexes for performance
|
|
CREATE INDEX "idx_reminder_tree_clinic" ON "ReminderTree"("clinicId", "isActive");
|
|
CREATE INDEX "idx_tree_node_tree" ON "TreeNode"("treeId", "sortOrder");
|
|
CREATE INDEX "idx_tree_node_parent" ON "TreeNode"("parentId");
|
|
CREATE INDEX "idx_user_journey_appointment" ON "UserJourney"("appointmentId", "status");
|
|
CREATE INDEX "idx_user_journey_current" ON "UserJourney"("currentNodeId", "lastActiveAt");
|
|
CREATE INDEX "idx_node_execution_journey" ON "NodeExecution"("journeyId", "executedAt");
|
|
CREATE INDEX "idx_patient_profile_lead" ON "PatientProfile"("leadId");
|
|
CREATE INDEX "idx_tree_experiment_clinic" ON "TreeExperiment"("clinicId", "status"); |