chore: import upstream snapshot with attribution
This commit is contained in:
+621
@@ -0,0 +1,621 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."RuntimeEnvironmentType" AS ENUM ('PRODUCTION', 'STAGING', 'DEVELOPMENT', 'PREVIEW');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."TaskRunStatus" AS ENUM ('DELAYED', 'PENDING', 'PENDING_VERSION', 'WAITING_FOR_DEPLOY', 'DEQUEUED', 'EXECUTING', 'WAITING_TO_RESUME', 'RETRYING_AFTER_FAILURE', 'PAUSED', 'CANCELED', 'INTERRUPTED', 'COMPLETED_SUCCESSFULLY', 'COMPLETED_WITH_ERRORS', 'SYSTEM_FAILURE', 'CRASHED', 'EXPIRED', 'TIMED_OUT');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."RunEngineVersion" AS ENUM ('V1', 'V2');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."TaskRunExecutionStatus" AS ENUM ('RUN_CREATED', 'DELAYED', 'QUEUED', 'QUEUED_EXECUTING', 'PENDING_EXECUTING', 'EXECUTING', 'EXECUTING_WITH_WAITPOINTS', 'SUSPENDED', 'PENDING_CANCEL', 'FINISHED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."TaskRunCheckpointType" AS ENUM ('DOCKER', 'KUBERNETES', 'COMPUTE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."WaitpointType" AS ENUM ('RUN', 'DATETIME', 'MANUAL', 'BATCH');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."WaitpointStatus" AS ENUM ('PENDING', 'COMPLETED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."TaskRunAttemptStatus" AS ENUM ('PENDING', 'EXECUTING', 'PAUSED', 'FAILED', 'CANCELED', 'COMPLETED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."BatchTaskRunStatus" AS ENUM ('PENDING', 'PROCESSING', 'COMPLETED', 'PARTIAL_FAILED', 'ABORTED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."BatchTaskRunItemStatus" AS ENUM ('PENDING', 'FAILED', 'CANCELED', 'COMPLETED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."CheckpointType" AS ENUM ('DOCKER', 'KUBERNETES');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "public"."CheckpointRestoreEventType" AS ENUM ('CHECKPOINT', 'RESTORE');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TaskRun" (
|
||||
"id" TEXT NOT NULL,
|
||||
"number" INTEGER NOT NULL DEFAULT 0,
|
||||
"friendlyId" TEXT NOT NULL,
|
||||
"engine" "public"."RunEngineVersion" NOT NULL DEFAULT 'V1',
|
||||
"status" "public"."TaskRunStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"statusReason" TEXT,
|
||||
"idempotencyKey" TEXT,
|
||||
"idempotencyKeyExpiresAt" TIMESTAMP(3),
|
||||
"idempotencyKeyOptions" JSONB,
|
||||
"debounce" JSONB,
|
||||
"taskIdentifier" TEXT NOT NULL,
|
||||
"isTest" BOOLEAN NOT NULL DEFAULT false,
|
||||
"payload" TEXT NOT NULL,
|
||||
"payloadType" TEXT NOT NULL DEFAULT 'application/json',
|
||||
"context" JSONB,
|
||||
"traceContext" JSONB,
|
||||
"traceId" TEXT NOT NULL,
|
||||
"spanId" TEXT NOT NULL,
|
||||
"runtimeEnvironmentId" TEXT NOT NULL,
|
||||
"environmentType" "public"."RuntimeEnvironmentType",
|
||||
"projectId" TEXT NOT NULL,
|
||||
"organizationId" TEXT,
|
||||
"queue" TEXT NOT NULL,
|
||||
"lockedQueueId" TEXT,
|
||||
"masterQueue" TEXT NOT NULL DEFAULT 'main',
|
||||
"region" TEXT,
|
||||
"secondaryMasterQueue" TEXT,
|
||||
"attemptNumber" INTEGER,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"runTags" TEXT[],
|
||||
"taskVersion" TEXT,
|
||||
"sdkVersion" TEXT,
|
||||
"cliVersion" TEXT,
|
||||
"startedAt" TIMESTAMP(3),
|
||||
"executedAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"machinePreset" TEXT,
|
||||
"usageDurationMs" INTEGER NOT NULL DEFAULT 0,
|
||||
"costInCents" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"baseCostInCents" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"lockedAt" TIMESTAMP(3),
|
||||
"lockedById" TEXT,
|
||||
"lockedToVersionId" TEXT,
|
||||
"priorityMs" INTEGER NOT NULL DEFAULT 0,
|
||||
"concurrencyKey" TEXT,
|
||||
"delayUntil" TIMESTAMP(3),
|
||||
"queuedAt" TIMESTAMP(3),
|
||||
"ttl" TEXT,
|
||||
"expiredAt" TIMESTAMP(3),
|
||||
"maxAttempts" INTEGER,
|
||||
"lockedRetryConfig" JSONB,
|
||||
"oneTimeUseToken" TEXT,
|
||||
"taskEventStore" TEXT NOT NULL DEFAULT 'taskEvent',
|
||||
"queueTimestamp" TIMESTAMP(3),
|
||||
"scheduleInstanceId" TEXT,
|
||||
"scheduleId" TEXT,
|
||||
"bulkActionGroupIds" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||
"logsDeletedAt" TIMESTAMP(3),
|
||||
"replayedFromTaskRunFriendlyId" TEXT,
|
||||
"rootTaskRunId" TEXT,
|
||||
"parentTaskRunId" TEXT,
|
||||
"parentTaskRunAttemptId" TEXT,
|
||||
"batchId" TEXT,
|
||||
"resumeParentOnCompletion" BOOLEAN NOT NULL DEFAULT false,
|
||||
"depth" INTEGER NOT NULL DEFAULT 0,
|
||||
"parentSpanId" TEXT,
|
||||
"runChainState" JSONB,
|
||||
"seedMetadata" TEXT,
|
||||
"seedMetadataType" TEXT NOT NULL DEFAULT 'application/json',
|
||||
"metadata" TEXT,
|
||||
"metadataType" TEXT NOT NULL DEFAULT 'application/json',
|
||||
"metadataVersion" INTEGER NOT NULL DEFAULT 1,
|
||||
"annotations" JSONB,
|
||||
"isWarmStart" BOOLEAN,
|
||||
"output" TEXT,
|
||||
"outputType" TEXT NOT NULL DEFAULT 'application/json',
|
||||
"error" JSONB,
|
||||
"planType" TEXT,
|
||||
"maxDurationInSeconds" INTEGER,
|
||||
"realtimeStreamsVersion" TEXT NOT NULL DEFAULT 'v1',
|
||||
"realtimeStreams" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||
"streamBasinName" TEXT,
|
||||
|
||||
CONSTRAINT "TaskRun_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TaskRunExecutionSnapshot" (
|
||||
"id" TEXT NOT NULL,
|
||||
"engine" "public"."RunEngineVersion" NOT NULL DEFAULT 'V2',
|
||||
"executionStatus" "public"."TaskRunExecutionStatus" NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"isValid" BOOLEAN NOT NULL DEFAULT true,
|
||||
"error" TEXT,
|
||||
"previousSnapshotId" TEXT,
|
||||
"runId" TEXT NOT NULL,
|
||||
"runStatus" "public"."TaskRunStatus" NOT NULL,
|
||||
"batchId" TEXT,
|
||||
"attemptNumber" INTEGER,
|
||||
"environmentId" TEXT NOT NULL,
|
||||
"environmentType" "public"."RuntimeEnvironmentType" NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"organizationId" TEXT NOT NULL,
|
||||
"completedWaitpointOrder" TEXT[],
|
||||
"checkpointId" TEXT,
|
||||
"workerId" TEXT,
|
||||
"runnerId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"lastHeartbeatAt" TIMESTAMP(3),
|
||||
"metadata" JSONB,
|
||||
|
||||
CONSTRAINT "TaskRunExecutionSnapshot_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TaskRunCheckpoint" (
|
||||
"id" TEXT NOT NULL,
|
||||
"friendlyId" TEXT NOT NULL,
|
||||
"type" "public"."TaskRunCheckpointType" NOT NULL,
|
||||
"location" TEXT NOT NULL,
|
||||
"imageRef" TEXT,
|
||||
"reason" TEXT,
|
||||
"metadata" TEXT,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"runtimeEnvironmentId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "TaskRunCheckpoint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."Waitpoint" (
|
||||
"id" TEXT NOT NULL,
|
||||
"friendlyId" TEXT NOT NULL,
|
||||
"type" "public"."WaitpointType" NOT NULL,
|
||||
"status" "public"."WaitpointStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"idempotencyKey" TEXT NOT NULL,
|
||||
"userProvidedIdempotencyKey" BOOLEAN NOT NULL,
|
||||
"idempotencyKeyExpiresAt" TIMESTAMP(3),
|
||||
"inactiveIdempotencyKey" TEXT,
|
||||
"completedByTaskRunId" TEXT,
|
||||
"completedAfter" TIMESTAMP(3),
|
||||
"completedByBatchId" TEXT,
|
||||
"output" TEXT,
|
||||
"outputType" TEXT NOT NULL DEFAULT 'application/json',
|
||||
"outputIsError" BOOLEAN NOT NULL DEFAULT false,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"environmentId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"tags" TEXT[],
|
||||
|
||||
CONSTRAINT "Waitpoint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TaskRunWaitpoint" (
|
||||
"id" TEXT NOT NULL,
|
||||
"taskRunId" TEXT NOT NULL,
|
||||
"waitpointId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"spanIdToComplete" TEXT,
|
||||
"batchId" TEXT,
|
||||
"batchIndex" INTEGER,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "TaskRunWaitpoint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."WaitpointRunConnection" (
|
||||
"id" TEXT NOT NULL,
|
||||
"taskRunId" TEXT NOT NULL,
|
||||
"waitpointId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "WaitpointRunConnection_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."CompletedWaitpoint" (
|
||||
"id" TEXT NOT NULL,
|
||||
"snapshotId" TEXT NOT NULL,
|
||||
"waitpointId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "CompletedWaitpoint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."WaitpointTag" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"environmentId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "WaitpointTag_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TaskRunTag" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"friendlyId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "TaskRunTag_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TaskRunDependency" (
|
||||
"id" TEXT NOT NULL,
|
||||
"taskRunId" TEXT NOT NULL,
|
||||
"checkpointEventId" TEXT,
|
||||
"dependentAttemptId" TEXT,
|
||||
"dependentBatchRunId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"resumedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "TaskRunDependency_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."TaskRunAttempt" (
|
||||
"id" TEXT NOT NULL,
|
||||
"number" INTEGER NOT NULL DEFAULT 0,
|
||||
"friendlyId" TEXT NOT NULL,
|
||||
"taskRunId" TEXT NOT NULL,
|
||||
"backgroundWorkerId" TEXT NOT NULL,
|
||||
"backgroundWorkerTaskId" TEXT NOT NULL,
|
||||
"runtimeEnvironmentId" TEXT NOT NULL,
|
||||
"queueId" TEXT NOT NULL,
|
||||
"status" "public"."TaskRunAttemptStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"startedAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"usageDurationMs" INTEGER NOT NULL DEFAULT 0,
|
||||
"error" JSONB,
|
||||
"output" TEXT,
|
||||
"outputType" TEXT NOT NULL DEFAULT 'application/json',
|
||||
|
||||
CONSTRAINT "TaskRunAttempt_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."BatchTaskRun" (
|
||||
"id" TEXT NOT NULL,
|
||||
"friendlyId" TEXT NOT NULL,
|
||||
"idempotencyKey" TEXT,
|
||||
"idempotencyKeyExpiresAt" TIMESTAMP(3),
|
||||
"status" "public"."BatchTaskRunStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"runtimeEnvironmentId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"runIds" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||||
"runCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"payload" TEXT,
|
||||
"payloadType" TEXT NOT NULL DEFAULT 'application/json',
|
||||
"options" JSONB,
|
||||
"batchVersion" TEXT NOT NULL DEFAULT 'v1',
|
||||
"sealed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"sealedAt" TIMESTAMP(3),
|
||||
"expectedCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"completedCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"resumedAt" TIMESTAMP(3),
|
||||
"processingJobsCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"processingJobsExpectedCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"oneTimeUseToken" TEXT,
|
||||
"processingStartedAt" TIMESTAMP(3),
|
||||
"processingCompletedAt" TIMESTAMP(3),
|
||||
"successfulRunCount" INTEGER,
|
||||
"failedRunCount" INTEGER,
|
||||
"taskIdentifier" TEXT,
|
||||
"checkpointEventId" TEXT,
|
||||
"dependentTaskAttemptId" TEXT,
|
||||
|
||||
CONSTRAINT "BatchTaskRun_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."BatchTaskRunItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"status" "public"."BatchTaskRunItemStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"batchTaskRunId" TEXT NOT NULL,
|
||||
"taskRunId" TEXT NOT NULL,
|
||||
"taskRunAttemptId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "BatchTaskRunItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."BatchTaskRunError" (
|
||||
"id" TEXT NOT NULL,
|
||||
"batchTaskRunId" TEXT NOT NULL,
|
||||
"index" INTEGER NOT NULL,
|
||||
"taskIdentifier" TEXT NOT NULL,
|
||||
"payload" TEXT,
|
||||
"options" JSONB,
|
||||
"error" TEXT NOT NULL,
|
||||
"errorCode" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "BatchTaskRunError_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."Checkpoint" (
|
||||
"id" TEXT NOT NULL,
|
||||
"friendlyId" TEXT NOT NULL,
|
||||
"type" "public"."CheckpointType" NOT NULL,
|
||||
"location" TEXT NOT NULL,
|
||||
"imageRef" TEXT NOT NULL,
|
||||
"reason" TEXT,
|
||||
"metadata" TEXT,
|
||||
"runId" TEXT NOT NULL,
|
||||
"attemptId" TEXT NOT NULL,
|
||||
"attemptNumber" INTEGER,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"runtimeEnvironmentId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Checkpoint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "public"."CheckpointRestoreEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"type" "public"."CheckpointRestoreEventType" NOT NULL,
|
||||
"reason" TEXT,
|
||||
"metadata" TEXT,
|
||||
"checkpointId" TEXT NOT NULL,
|
||||
"runId" TEXT NOT NULL,
|
||||
"attemptId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"runtimeEnvironmentId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CheckpointRestoreEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRun_friendlyId_key" ON "public"."TaskRun"("friendlyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRun_parentTaskRunId_idx" ON "public"."TaskRun"("parentTaskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRun_spanId_idx" ON "public"."TaskRun"("spanId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRun_parentSpanId_idx" ON "public"."TaskRun"("parentSpanId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRun_runTags_idx" ON "public"."TaskRun" USING GIN ("runTags" array_ops);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRun_runtimeEnvironmentId_batchId_idx" ON "public"."TaskRun"("runtimeEnvironmentId", "batchId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRun_runtimeEnvironmentId_createdAt_idx" ON "public"."TaskRun"("runtimeEnvironmentId", "createdAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRun_createdAt_idx" ON "public"."TaskRun" USING BRIN ("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRun_oneTimeUseToken_key" ON "public"."TaskRun"("oneTimeUseToken");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRun_runtimeEnvironmentId_taskIdentifier_idempotencyKey_key" ON "public"."TaskRun"("runtimeEnvironmentId", "taskIdentifier", "idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRunExecutionSnapshot_runId_isValid_createdAt_idx" ON "public"."TaskRunExecutionSnapshot"("runId", "isValid", "createdAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunCheckpoint_friendlyId_key" ON "public"."TaskRunCheckpoint"("friendlyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Waitpoint_friendlyId_key" ON "public"."Waitpoint"("friendlyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Waitpoint_completedByTaskRunId_key" ON "public"."Waitpoint"("completedByTaskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Waitpoint_completedByBatchId_idx" ON "public"."Waitpoint"("completedByBatchId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Waitpoint_environmentId_type_createdAt_idx" ON "public"."Waitpoint"("environmentId", "type", "createdAt" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Waitpoint_environmentId_type_status_idx" ON "public"."Waitpoint"("environmentId", "type", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Waitpoint_environmentId_type_id_idx" ON "public"."Waitpoint"("environmentId", "type", "id" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Waitpoint_environmentId_idempotencyKey_key" ON "public"."Waitpoint"("environmentId", "idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRunWaitpoint_taskRunId_idx" ON "public"."TaskRunWaitpoint"("taskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRunWaitpoint_waitpointId_idx" ON "public"."TaskRunWaitpoint"("waitpointId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunWaitpoint_taskRunId_waitpointId_batchIndex_key" ON "public"."TaskRunWaitpoint"("taskRunId", "waitpointId", "batchIndex");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "WaitpointRunConnection_taskRunId_idx" ON "public"."WaitpointRunConnection"("taskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "WaitpointRunConnection_waitpointId_idx" ON "public"."WaitpointRunConnection"("waitpointId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "WaitpointRunConnection_taskRunId_waitpointId_key" ON "public"."WaitpointRunConnection"("taskRunId", "waitpointId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CompletedWaitpoint_snapshotId_idx" ON "public"."CompletedWaitpoint"("snapshotId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CompletedWaitpoint_waitpointId_idx" ON "public"."CompletedWaitpoint"("waitpointId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "CompletedWaitpoint_snapshotId_waitpointId_key" ON "public"."CompletedWaitpoint"("snapshotId", "waitpointId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "WaitpointTag_environmentId_name_key" ON "public"."WaitpointTag"("environmentId", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunTag_friendlyId_key" ON "public"."TaskRunTag"("friendlyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRunTag_name_id_idx" ON "public"."TaskRunTag"("name", "id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunTag_projectId_name_key" ON "public"."TaskRunTag"("projectId", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunDependency_taskRunId_key" ON "public"."TaskRunDependency"("taskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunDependency_checkpointEventId_key" ON "public"."TaskRunDependency"("checkpointEventId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRunDependency_dependentAttemptId_idx" ON "public"."TaskRunDependency"("dependentAttemptId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRunDependency_dependentBatchRunId_idx" ON "public"."TaskRunDependency"("dependentBatchRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunAttempt_friendlyId_key" ON "public"."TaskRunAttempt"("friendlyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskRunAttempt_taskRunId_idx" ON "public"."TaskRunAttempt"("taskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskRunAttempt_taskRunId_number_key" ON "public"."TaskRunAttempt"("taskRunId", "number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BatchTaskRun_friendlyId_key" ON "public"."BatchTaskRun"("friendlyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BatchTaskRun_checkpointEventId_key" ON "public"."BatchTaskRun"("checkpointEventId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "BatchTaskRun_dependentTaskAttemptId_idx" ON "public"."BatchTaskRun"("dependentTaskAttemptId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "BatchTaskRun_runtimeEnvironmentId_id_idx" ON "public"."BatchTaskRun"("runtimeEnvironmentId", "id" DESC);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BatchTaskRun_oneTimeUseToken_key" ON "public"."BatchTaskRun"("oneTimeUseToken");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BatchTaskRun_runtimeEnvironmentId_idempotencyKey_key" ON "public"."BatchTaskRun"("runtimeEnvironmentId", "idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_batchtaskrunitem_taskrunattempt" ON "public"."BatchTaskRunItem"("taskRunAttemptId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "idx_batchtaskrunitem_taskrun" ON "public"."BatchTaskRunItem"("taskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BatchTaskRunItem_batchTaskRunId_taskRunId_key" ON "public"."BatchTaskRunItem"("batchTaskRunId", "taskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "BatchTaskRunError_batchTaskRunId_idx" ON "public"."BatchTaskRunError"("batchTaskRunId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BatchTaskRunError_batchTaskRunId_index_key" ON "public"."BatchTaskRunError"("batchTaskRunId", "index");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Checkpoint_friendlyId_key" ON "public"."Checkpoint"("friendlyId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Checkpoint_attemptId_idx" ON "public"."Checkpoint"("attemptId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Checkpoint_runId_idx" ON "public"."Checkpoint"("runId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckpointRestoreEvent_checkpointId_idx" ON "public"."CheckpointRestoreEvent"("checkpointId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckpointRestoreEvent_runId_idx" ON "public"."CheckpointRestoreEvent"("runId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRun" ADD CONSTRAINT "TaskRun_rootTaskRunId_fkey" FOREIGN KEY ("rootTaskRunId") REFERENCES "public"."TaskRun"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRun" ADD CONSTRAINT "TaskRun_parentTaskRunId_fkey" FOREIGN KEY ("parentTaskRunId") REFERENCES "public"."TaskRun"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRun" ADD CONSTRAINT "TaskRun_parentTaskRunAttemptId_fkey" FOREIGN KEY ("parentTaskRunAttemptId") REFERENCES "public"."TaskRunAttempt"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRun" ADD CONSTRAINT "TaskRun_batchId_fkey" FOREIGN KEY ("batchId") REFERENCES "public"."BatchTaskRun"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRunExecutionSnapshot" ADD CONSTRAINT "TaskRunExecutionSnapshot_runId_fkey" FOREIGN KEY ("runId") REFERENCES "public"."TaskRun"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRunExecutionSnapshot" ADD CONSTRAINT "TaskRunExecutionSnapshot_checkpointId_fkey" FOREIGN KEY ("checkpointId") REFERENCES "public"."TaskRunCheckpoint"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRunDependency" ADD CONSTRAINT "TaskRunDependency_taskRunId_fkey" FOREIGN KEY ("taskRunId") REFERENCES "public"."TaskRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRunDependency" ADD CONSTRAINT "TaskRunDependency_checkpointEventId_fkey" FOREIGN KEY ("checkpointEventId") REFERENCES "public"."CheckpointRestoreEvent"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRunDependency" ADD CONSTRAINT "TaskRunDependency_dependentAttemptId_fkey" FOREIGN KEY ("dependentAttemptId") REFERENCES "public"."TaskRunAttempt"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRunDependency" ADD CONSTRAINT "TaskRunDependency_dependentBatchRunId_fkey" FOREIGN KEY ("dependentBatchRunId") REFERENCES "public"."BatchTaskRun"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."TaskRunAttempt" ADD CONSTRAINT "TaskRunAttempt_taskRunId_fkey" FOREIGN KEY ("taskRunId") REFERENCES "public"."TaskRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."BatchTaskRun" ADD CONSTRAINT "BatchTaskRun_checkpointEventId_fkey" FOREIGN KEY ("checkpointEventId") REFERENCES "public"."CheckpointRestoreEvent"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."BatchTaskRun" ADD CONSTRAINT "BatchTaskRun_dependentTaskAttemptId_fkey" FOREIGN KEY ("dependentTaskAttemptId") REFERENCES "public"."TaskRunAttempt"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."BatchTaskRunItem" ADD CONSTRAINT "BatchTaskRunItem_batchTaskRunId_fkey" FOREIGN KEY ("batchTaskRunId") REFERENCES "public"."BatchTaskRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."BatchTaskRunItem" ADD CONSTRAINT "BatchTaskRunItem_taskRunId_fkey" FOREIGN KEY ("taskRunId") REFERENCES "public"."TaskRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."BatchTaskRunItem" ADD CONSTRAINT "BatchTaskRunItem_taskRunAttemptId_fkey" FOREIGN KEY ("taskRunAttemptId") REFERENCES "public"."TaskRunAttempt"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."BatchTaskRunError" ADD CONSTRAINT "BatchTaskRunError_batchTaskRunId_fkey" FOREIGN KEY ("batchTaskRunId") REFERENCES "public"."BatchTaskRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."Checkpoint" ADD CONSTRAINT "Checkpoint_runId_fkey" FOREIGN KEY ("runId") REFERENCES "public"."TaskRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."Checkpoint" ADD CONSTRAINT "Checkpoint_attemptId_fkey" FOREIGN KEY ("attemptId") REFERENCES "public"."TaskRunAttempt"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."CheckpointRestoreEvent" ADD CONSTRAINT "CheckpointRestoreEvent_checkpointId_fkey" FOREIGN KEY ("checkpointId") REFERENCES "public"."Checkpoint"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."CheckpointRestoreEvent" ADD CONSTRAINT "CheckpointRestoreEvent_runId_fkey" FOREIGN KEY ("runId") REFERENCES "public"."TaskRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "public"."CheckpointRestoreEvent" ADD CONSTRAINT "CheckpointRestoreEvent_attemptId_fkey" FOREIGN KEY ("attemptId") REFERENCES "public"."TaskRunAttempt"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
-- Partial unique index (Prisma cannot express the WHERE clause, so it is SQL-only). Mirrors the
|
||||
-- control-plane `TaskRunWaitpoint_taskRunId_waitpointId_batchIndex_null_key`: without it the
|
||||
-- composite (taskRunId, waitpointId, batchIndex) index treats NULL batchIndex rows as distinct, so
|
||||
-- blockRunWithWaitpointEdges' ON CONFLICT DO NOTHING cannot dedupe a re-blocked NULL-batchIndex edge.
|
||||
CREATE UNIQUE INDEX "TaskRunWaitpoint_taskRunId_waitpointId_batchIndex_null_key" ON "public"."TaskRunWaitpoint"("taskRunId", "waitpointId") WHERE "batchIndex" IS NULL;
|
||||
@@ -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"
|
||||
@@ -0,0 +1,264 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
// Parses both the control-plane schema (`@trigger.dev/database`) and this
|
||||
// dedicated run-ops schema, then diffs every SCALAR field of each run-subgraph
|
||||
// model BIDIRECTIONALLY: a field present in either schema must exist in the
|
||||
// other with matching type/nullability/array-ness/`@default`, since a run row
|
||||
// must be writable to either physical database.
|
||||
//
|
||||
// Relation fields are excluded by design: the dedicated schema drops
|
||||
// control-plane `@relation`s to control-plane-owned models and replaces the
|
||||
// implicit many-to-many waitpoint relations with explicit FK-free join models
|
||||
// (`TaskRunWaitpoint`, `WaitpointRunConnection`, `CompletedWaitpoint`). Only
|
||||
// the scalar FK columns backing those relations (e.g. `projectId`) are
|
||||
// compared; the relation object fields (e.g. `project`) are skipped.
|
||||
|
||||
const CONTROL_PLANE_SCHEMA_PATH = "../../database/prisma/schema.prisma";
|
||||
const DEDICATED_SCHEMA_PATH = "./schema.prisma";
|
||||
|
||||
// Must never appear as a relation target in the dedicated schema.
|
||||
const CONTROL_PLANE_ONLY_MODELS = [
|
||||
"Organization",
|
||||
"OrgMember",
|
||||
"Project",
|
||||
"RuntimeEnvironment",
|
||||
"User",
|
||||
"TaskSchedule",
|
||||
"BackgroundWorker",
|
||||
"BackgroundWorkerTask",
|
||||
"WorkerDeployment",
|
||||
"TaskQueue",
|
||||
];
|
||||
|
||||
// Must have every scalar column reproduced in the dedicated schema.
|
||||
const RUN_SUBGRAPH_MODELS = [
|
||||
"TaskRun",
|
||||
"TaskRunAttempt",
|
||||
"TaskRunExecutionSnapshot",
|
||||
"TaskRunWaitpoint",
|
||||
"TaskRunCheckpoint",
|
||||
"CheckpointRestoreEvent",
|
||||
"TaskRunTag",
|
||||
"Waitpoint",
|
||||
"WaitpointTag",
|
||||
"BatchTaskRun",
|
||||
"TaskRunDependency",
|
||||
"BatchTaskRunItem",
|
||||
"BatchTaskRunError",
|
||||
"Checkpoint",
|
||||
];
|
||||
|
||||
function readSchema(rel: string): string {
|
||||
return readFileSync(resolve(__dirname, rel), "utf8");
|
||||
}
|
||||
|
||||
// Strips `/* */` block comments and `//`/`///` line comments so prose mentioning
|
||||
// model names can't false-match below. (Neither schema has `/*` inside a string.)
|
||||
function stripComments(schema: string): string {
|
||||
return schema.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
|
||||
}
|
||||
|
||||
type FieldInfo = {
|
||||
type: string;
|
||||
optional: boolean;
|
||||
array: boolean;
|
||||
default: string | null;
|
||||
};
|
||||
|
||||
type ModelFields = Map<string, FieldInfo>;
|
||||
|
||||
// Prisma model blocks don't nest, so a lazy match to the next `}`-only line suffices.
|
||||
function extractModelBlocks(schema: string): Map<string, string> {
|
||||
const blocks = new Map<string, string>();
|
||||
const re = /^model\s+(\w+)\s*\{([\s\S]*?)\n\}/gm;
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = re.exec(schema))) {
|
||||
blocks.set(match[1], match[2]);
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
// Raw argument of `@default(...)`, honoring nested parens (`@default(cuid())`). Null if absent.
|
||||
function extractDefault(attrs: string): string | null {
|
||||
const marker = "@default(";
|
||||
const idx = attrs.indexOf(marker);
|
||||
if (idx === -1) return null;
|
||||
const start = idx + marker.length;
|
||||
let depth = 0;
|
||||
for (let i = start; i < attrs.length; i++) {
|
||||
if (attrs[i] === "(") {
|
||||
depth++;
|
||||
} else if (attrs[i] === ")") {
|
||||
if (depth === 0) return attrs.slice(start, i);
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
return attrs.slice(start);
|
||||
}
|
||||
|
||||
// Excludes relation fields: anything carrying `@relation`, plus back-relation fields
|
||||
// (e.g. `checkpoints Checkpoint[]`) identified by their type being another model name.
|
||||
// `unparsed` collects any content line the field regex fails to match, so a future
|
||||
// multi-line field can never silently vanish from the diff.
|
||||
function parseScalarFields(
|
||||
body: string,
|
||||
modelNames: Set<string>
|
||||
): { fields: ModelFields; unparsed: string[] } {
|
||||
const fields: ModelFields = new Map();
|
||||
const unparsed: string[] = [];
|
||||
for (const rawLine of body.split("\n")) {
|
||||
const line = rawLine.trim();
|
||||
if (!line || line.startsWith("@@")) continue;
|
||||
const match = line.match(/^(\w+)\s+([A-Za-z_]\w*)(\[\])?(\?)?\s*(.*)$/);
|
||||
if (!match) {
|
||||
unparsed.push(line);
|
||||
continue;
|
||||
}
|
||||
const [, name, type, arrayMark, optionalMark, rest] = match;
|
||||
if (rest.includes("@relation")) continue;
|
||||
if (modelNames.has(type)) continue;
|
||||
fields.set(name, {
|
||||
type,
|
||||
array: arrayMark === "[]",
|
||||
optional: optionalMark === "?",
|
||||
default: extractDefault(rest),
|
||||
});
|
||||
}
|
||||
return { fields, unparsed };
|
||||
}
|
||||
|
||||
function parseSchema(schema: string) {
|
||||
const stripped = stripComments(schema);
|
||||
const modelBlocks = extractModelBlocks(stripped);
|
||||
const modelNames = new Set(modelBlocks.keys());
|
||||
const models = new Map<string, ModelFields>();
|
||||
const unparsed: string[] = [];
|
||||
for (const [name, body] of modelBlocks) {
|
||||
const parsed = parseScalarFields(body, modelNames);
|
||||
models.set(name, parsed.fields);
|
||||
for (const line of parsed.unparsed) {
|
||||
unparsed.push(`${name}: ${line}`);
|
||||
}
|
||||
}
|
||||
return { models, modelNames, unparsed };
|
||||
}
|
||||
|
||||
function describeField(field: FieldInfo | undefined): string {
|
||||
if (!field) return "<missing>";
|
||||
const array = field.array ? "[]" : "";
|
||||
const optional = field.optional ? "?" : "";
|
||||
const withDefault = field.default !== null ? ` @default(${field.default})` : "";
|
||||
return `${field.type}${array}${optional}${withDefault}`;
|
||||
}
|
||||
|
||||
const controlPlane = parseSchema(readSchema(CONTROL_PLANE_SCHEMA_PATH));
|
||||
const dedicated = parseSchema(readSchema(DEDICATED_SCHEMA_PATH));
|
||||
|
||||
describe("dedicated run-ops schema parity", () => {
|
||||
it("includes all 14 run-subgraph models in both schemas", () => {
|
||||
for (const model of RUN_SUBGRAPH_MODELS) {
|
||||
expect(Array.from(dedicated.modelNames)).toContain(model);
|
||||
expect(Array.from(controlPlane.modelNames)).toContain(model);
|
||||
}
|
||||
});
|
||||
|
||||
it("fails on any content line the field parser doesn't recognise (no silent skips)", () => {
|
||||
// Scope the control-plane check to run-subgraph models so an unrelated control-plane schema
|
||||
// edit can't break this run-ops test; the dedicated schema contains only run-ops models.
|
||||
const inRunSubgraph = (entry: string) =>
|
||||
RUN_SUBGRAPH_MODELS.some((model) => entry.startsWith(`${model}: `));
|
||||
expect(controlPlane.unparsed.filter(inRunSubgraph)).toEqual([]);
|
||||
expect(dedicated.unparsed).toEqual([]);
|
||||
});
|
||||
|
||||
it("reproduces every scalar column of each run-subgraph model bidirectionally with matching type/nullability/array/default", () => {
|
||||
const mismatches: string[] = [];
|
||||
|
||||
for (const modelName of RUN_SUBGRAPH_MODELS) {
|
||||
const controlFields = controlPlane.models.get(modelName);
|
||||
const dedicatedFields = dedicated.models.get(modelName);
|
||||
if (!controlFields || !dedicatedFields) {
|
||||
mismatches.push(`${modelName}: model not found in one of the two schemas`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const fieldNames = new Set([...controlFields.keys(), ...dedicatedFields.keys()]);
|
||||
for (const fieldName of fieldNames) {
|
||||
const controlField = controlFields.get(fieldName);
|
||||
const dedicatedField = dedicatedFields.get(fieldName);
|
||||
|
||||
if (!controlField) {
|
||||
mismatches.push(
|
||||
`${modelName}.${fieldName}: dedicated has ${describeField(
|
||||
dedicatedField
|
||||
)} but the control-plane schema has no such scalar field`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (!dedicatedField) {
|
||||
mismatches.push(
|
||||
`${modelName}.${fieldName}: control-plane has ${describeField(
|
||||
controlField
|
||||
)} but the dedicated schema has no such scalar field`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const matches =
|
||||
dedicatedField.type === controlField.type &&
|
||||
dedicatedField.array === controlField.array &&
|
||||
dedicatedField.optional === controlField.optional &&
|
||||
dedicatedField.default === controlField.default;
|
||||
|
||||
if (!matches) {
|
||||
mismatches.push(
|
||||
`${modelName}.${fieldName}: control-plane=${describeField(
|
||||
controlField
|
||||
)} dedicated=${describeField(dedicatedField)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect(mismatches).toEqual([]);
|
||||
});
|
||||
|
||||
it("references no control-plane model as a relation target", () => {
|
||||
const dedicatedText = stripComments(readSchema(DEDICATED_SCHEMA_PATH));
|
||||
for (const model of CONTROL_PLANE_ONLY_MODELS) {
|
||||
// A relation target appears as ` fieldName Model @relation(...)`. A bare
|
||||
// scalar column like `projectId String` is fine; the model TYPE must be absent.
|
||||
const relationTarget = new RegExp(
|
||||
`@relation[^\\n]*\\b${model}\\b|\\b${model}\\b[^\\n]*@relation`
|
||||
);
|
||||
expect(dedicatedText).not.toMatch(relationTarget);
|
||||
expect(dedicatedText).not.toMatch(new RegExp(`\\s${model}(\\?|\\[\\])?\\s`));
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the group-(A) waitpoint-block references FK-FREE (scalar columns / explicit FK-free join models)", () => {
|
||||
const dedicatedText = stripComments(readSchema(DEDICATED_SCHEMA_PATH));
|
||||
// TaskRunWaitpoint must NOT carry a `@relation` to Waitpoint/TaskRun/BatchTaskRun.
|
||||
const trw = dedicatedText.match(/model TaskRunWaitpoint \{[\s\S]*?\n\}/)![0];
|
||||
expect(trw).not.toMatch(/@relation/);
|
||||
expect(trw).toMatch(/waitpointId\s+String/);
|
||||
expect(trw).toMatch(/taskRunId\s+String/);
|
||||
// The two implicit M2M sets are replaced by explicit FK-free join models.
|
||||
expect(dedicatedText).toMatch(/model WaitpointRunConnection \{/);
|
||||
expect(dedicatedText).toMatch(/model CompletedWaitpoint \{/);
|
||||
const wrc = dedicatedText.match(/model WaitpointRunConnection \{[\s\S]*?\n\}/)![0];
|
||||
expect(wrc).not.toMatch(/@relation/);
|
||||
// Waitpoint completion back-refs are scalar, not relations.
|
||||
const wp = dedicatedText.match(/model Waitpoint \{[\s\S]*?\n\}/)![0];
|
||||
expect(wp).not.toMatch(/completedByTaskRun\s+TaskRun\s*\?\s*@relation/);
|
||||
});
|
||||
|
||||
it("keeps the group-(B) co-resident references as real FKs (e.g. TaskRunAttempt.taskRun)", () => {
|
||||
const dedicatedText = stripComments(readSchema(DEDICATED_SCHEMA_PATH));
|
||||
const attempt = dedicatedText.match(/model TaskRunAttempt \{[\s\S]*?\n\}/)![0];
|
||||
// The attempt->run relation stays a real FK (always co-resident).
|
||||
expect(attempt).toMatch(/taskRun\s+TaskRun\s+@relation/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,981 @@
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("RUN_OPS_DATABASE_URL")
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
output = "../generated/run-ops"
|
||||
binaryTargets = ["native", "debian-openssl-1.1.x"]
|
||||
previewFeatures = ["metrics"]
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Dedicated run-ops database schema.
|
||||
//
|
||||
// This schema holds the subset of the control-plane `@trigger.dev/database`
|
||||
// models that describe a run's lifecycle. Each model reproduces its
|
||||
// control-plane counterpart column-for-column; the only differences are in how
|
||||
// relations are handled, according to three rules:
|
||||
//
|
||||
// 1. Relations that point at control-plane-owned models (organization,
|
||||
// project, environment, background worker, queue, and the like) are not
|
||||
// reproduced. Their foreign-key columns are kept as plain scalars, with no
|
||||
// `@relation` and no database foreign key, because the referenced rows live
|
||||
// in the control-plane database.
|
||||
//
|
||||
// 2. Waitpoint block and completion relations are foreign-key-free. A block or
|
||||
// completion edge can connect a run and a waitpoint that live in different
|
||||
// databases, so it must never be enforced by a foreign key here. These
|
||||
// relations are represented by scalar columns plus the explicit join models
|
||||
// `TaskRunWaitpoint`, `WaitpointRunConnection`, and `CompletedWaitpoint`.
|
||||
// The join models replace implicit many-to-many relations that exist in the
|
||||
// control-plane schema.
|
||||
//
|
||||
// 3. Relations that stay entirely within this database (run to root/parent
|
||||
// run, run to attempt, run to batch, checkpoints, dependencies, and so on)
|
||||
// are kept as real foreign keys, exactly as in the control plane.
|
||||
//
|
||||
// Relation-only back-references to models outside this subset are dropped; the
|
||||
// per-model notes below call out where that happens.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
enum RuntimeEnvironmentType {
|
||||
PRODUCTION
|
||||
STAGING
|
||||
DEVELOPMENT
|
||||
PREVIEW
|
||||
}
|
||||
|
||||
/// Same columns and indexes as the control-plane `TaskRun`. The environment,
|
||||
/// project, `lockedBy`, and `lockedToVersion` relations are scalar-only foreign
|
||||
/// keys here. The waitpoint completion/block relations
|
||||
/// (`associatedWaitpoint`, `blockedByWaitpoints`, `connectedWaitpoints`) are
|
||||
/// foreign-key-free: completion lives on `Waitpoint.completedByTaskRunId`, block
|
||||
/// edges are rows of `TaskRunWaitpoint`, and connections are rows of
|
||||
/// `WaitpointRunConnection`. The root/parent-run, parent-attempt, and batch
|
||||
/// relations are kept as real foreign keys. Control-plane back-references to
|
||||
/// tags, alerts, bulk-action items, and playground conversations are dropped.
|
||||
model TaskRun {
|
||||
id String @id @default(cuid())
|
||||
|
||||
number Int @default(0)
|
||||
friendlyId String @unique
|
||||
|
||||
engine RunEngineVersion @default(V1)
|
||||
|
||||
status TaskRunStatus @default(PENDING)
|
||||
statusReason String?
|
||||
|
||||
idempotencyKey String?
|
||||
idempotencyKeyExpiresAt DateTime?
|
||||
/// Stores the user-provided key and scope: { key: string, scope: "run" | "attempt" | "global" }
|
||||
idempotencyKeyOptions Json?
|
||||
|
||||
/// Debounce options: { key: string, delay: string, createdAt: Date }
|
||||
debounce Json?
|
||||
|
||||
taskIdentifier String
|
||||
|
||||
isTest Boolean @default(false)
|
||||
|
||||
payload String
|
||||
payloadType String @default("application/json")
|
||||
context Json?
|
||||
traceContext Json?
|
||||
|
||||
traceId String
|
||||
spanId String
|
||||
|
||||
/// scalar FK (control-plane `runtimeEnvironment` relation)
|
||||
runtimeEnvironmentId String
|
||||
|
||||
environmentType RuntimeEnvironmentType?
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
organizationId String?
|
||||
|
||||
// The specific queue this run is in
|
||||
queue String
|
||||
// The queueId is set when the run is locked to a specific queue
|
||||
lockedQueueId String?
|
||||
|
||||
/// The main queue that this run is part of
|
||||
workerQueue String @default("main") @map("masterQueue")
|
||||
|
||||
/// User-facing geo region, stamped at trigger; workerQueue is where it actually ran.
|
||||
region String?
|
||||
|
||||
/// @deprecated
|
||||
secondaryMasterQueue String?
|
||||
|
||||
/// From engine v2+ this will be defined after a run has been dequeued (starting at 1)
|
||||
attemptNumber Int?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
attempts TaskRunAttempt[] @relation("attempts")
|
||||
|
||||
/// Denormized column that holds the raw tags
|
||||
runTags String[]
|
||||
|
||||
/// Denormalized version of the background worker task
|
||||
taskVersion String?
|
||||
sdkVersion String?
|
||||
cliVersion String?
|
||||
|
||||
checkpoints Checkpoint[]
|
||||
|
||||
/// startedAt marks the point at which a run is dequeued from MarQS
|
||||
startedAt DateTime?
|
||||
/// executedAt is set when the first attempt is about to execute
|
||||
executedAt DateTime?
|
||||
completedAt DateTime?
|
||||
machinePreset String?
|
||||
|
||||
usageDurationMs Int @default(0)
|
||||
costInCents Float @default(0)
|
||||
baseCostInCents Float @default(0)
|
||||
|
||||
lockedAt DateTime?
|
||||
/// scalar FK (control-plane `lockedBy` relation)
|
||||
lockedById String?
|
||||
|
||||
/// scalar FK (control-plane `lockedToVersion` relation)
|
||||
lockedToVersionId String?
|
||||
|
||||
/// The "priority" of the run. This is just a negative offset in ms for the queue timestamp
|
||||
/// E.g. a value of 60_000 would put the run into the queue 60s ago.
|
||||
priorityMs Int @default(0)
|
||||
|
||||
concurrencyKey String?
|
||||
|
||||
delayUntil DateTime?
|
||||
queuedAt DateTime?
|
||||
ttl String?
|
||||
expiredAt DateTime?
|
||||
maxAttempts Int?
|
||||
lockedRetryConfig Json?
|
||||
|
||||
/// optional token that can be used to authenticate the task run
|
||||
oneTimeUseToken String?
|
||||
|
||||
// The control-plane waitpoint relations (associatedWaitpoint, blockedByWaitpoints,
|
||||
// connectedWaitpoints) are foreign-key-free here: completion is stored on
|
||||
// Waitpoint.completedByTaskRunId, block edges are rows of TaskRunWaitpoint, and
|
||||
// connections are rows of WaitpointRunConnection.
|
||||
|
||||
/// Where the logs are stored
|
||||
taskEventStore String @default("taskEvent")
|
||||
|
||||
queueTimestamp DateTime?
|
||||
|
||||
batchItems BatchTaskRunItem[]
|
||||
dependency TaskRunDependency?
|
||||
CheckpointRestoreEvent CheckpointRestoreEvent[]
|
||||
executionSnapshots TaskRunExecutionSnapshot[]
|
||||
|
||||
scheduleInstanceId String?
|
||||
scheduleId String?
|
||||
|
||||
bulkActionGroupIds String[] @default([])
|
||||
|
||||
logsDeletedAt DateTime?
|
||||
|
||||
replayedFromTaskRunFriendlyId String?
|
||||
|
||||
/// This represents the original task that was triggered outside of a Trigger.dev task
|
||||
rootTaskRun TaskRun? @relation("TaskRootRun", fields: [rootTaskRunId], references: [id], onDelete: SetNull, onUpdate: NoAction)
|
||||
rootTaskRunId String?
|
||||
|
||||
/// The root run will have a list of all the descendant runs, children, grand children, etc.
|
||||
descendantRuns TaskRun[] @relation("TaskRootRun")
|
||||
|
||||
/// The immediate parent run of this task run
|
||||
parentTaskRun TaskRun? @relation("TaskParentRun", fields: [parentTaskRunId], references: [id], onDelete: SetNull, onUpdate: NoAction)
|
||||
parentTaskRunId String?
|
||||
|
||||
/// The immediate child runs of this task run
|
||||
childRuns TaskRun[] @relation("TaskParentRun")
|
||||
|
||||
/// The immediate parent attempt of this task run
|
||||
parentTaskRunAttempt TaskRunAttempt? @relation("TaskParentRunAttempt", fields: [parentTaskRunAttemptId], references: [id], onDelete: SetNull, onUpdate: NoAction)
|
||||
parentTaskRunAttemptId String?
|
||||
|
||||
/// The batch run that this task run is a part of
|
||||
batch BatchTaskRun? @relation(fields: [batchId], references: [id], onDelete: SetNull, onUpdate: NoAction)
|
||||
batchId String?
|
||||
|
||||
/// whether or not the task run was created because of a triggerAndWait for batchTriggerAndWait
|
||||
resumeParentOnCompletion Boolean @default(false)
|
||||
|
||||
/// The depth of this task run in the task run hierarchy
|
||||
depth Int @default(0)
|
||||
|
||||
/// The span ID of the "trigger" span in the parent task run
|
||||
parentSpanId String?
|
||||
|
||||
/// Holds the state of the run chain for deadlock detection
|
||||
runChainState Json?
|
||||
|
||||
/// seed run metadata
|
||||
seedMetadata String?
|
||||
seedMetadataType String @default("application/json")
|
||||
|
||||
/// Run metadata
|
||||
metadata String?
|
||||
metadataType String @default("application/json")
|
||||
metadataVersion Int @default(1)
|
||||
|
||||
/// Structured annotations: triggerSource, triggerAction, rootTriggerSource, rootScheduleId
|
||||
annotations Json?
|
||||
|
||||
/// Whether the latest attempt was a warm start. Null until first attempt starts.
|
||||
isWarmStart Boolean?
|
||||
|
||||
/// Run output
|
||||
output String?
|
||||
outputType String @default("application/json")
|
||||
|
||||
/// Run error
|
||||
error Json?
|
||||
|
||||
/// Organization's billing plan type (cached for fallback when billing API fails)
|
||||
planType String?
|
||||
|
||||
maxDurationInSeconds Int?
|
||||
|
||||
/// The version of the realtime streams implementation used by the run
|
||||
realtimeStreamsVersion String @default("v1")
|
||||
/// Store the stream keys that are being used by the run
|
||||
realtimeStreams String[] @default([])
|
||||
/// S2 basin where this run's realtime streams live. Stamped at create
|
||||
/// time from `Organization.streamBasinName` so reads can resolve the
|
||||
/// basin without joining org. Null when the org has no per-org basin
|
||||
/// (OSS, or pre-backfill); reads fall back to the global basin.
|
||||
streamBasinName String?
|
||||
|
||||
@@unique([oneTimeUseToken])
|
||||
@@unique([runtimeEnvironmentId, taskIdentifier, idempotencyKey])
|
||||
// Finding child runs
|
||||
@@index([parentTaskRunId])
|
||||
// Run page inspector
|
||||
@@index([spanId])
|
||||
@@index([parentSpanId])
|
||||
// Finding runs in a batch
|
||||
@@index([runTags(ops: ArrayOps)], type: Gin)
|
||||
@@index([runtimeEnvironmentId, batchId])
|
||||
@@index([runtimeEnvironmentId, createdAt(sort: Desc)])
|
||||
@@index([createdAt], type: Brin)
|
||||
}
|
||||
|
||||
enum TaskRunStatus {
|
||||
///
|
||||
/// NON-FINAL STATUSES
|
||||
///
|
||||
|
||||
/// Task has been scheduled to run in the future
|
||||
DELAYED
|
||||
/// Task is waiting to be executed by a worker
|
||||
PENDING
|
||||
|
||||
/// The run is pending a version update because it cannot execute without additional information (task, queue, etc.). Replaces WAITING_FOR_DEPLOY
|
||||
PENDING_VERSION
|
||||
|
||||
/// Task hasn't been deployed yet but is waiting to be executed. Deprecated in favor of PENDING_VERSION
|
||||
WAITING_FOR_DEPLOY
|
||||
|
||||
/// Task has been dequeued from the queue but is not yet executing
|
||||
DEQUEUED
|
||||
|
||||
/// Task is currently being executed by a worker
|
||||
EXECUTING
|
||||
|
||||
/// Task has been paused by the system, and will be resumed by the system
|
||||
WAITING_TO_RESUME
|
||||
|
||||
/// Task has failed and is waiting to be retried
|
||||
RETRYING_AFTER_FAILURE
|
||||
|
||||
/// Task has been paused by the user, and can be resumed by the user
|
||||
PAUSED
|
||||
|
||||
///
|
||||
/// FINAL STATUSES
|
||||
///
|
||||
|
||||
/// Task has been canceled by the user
|
||||
CANCELED
|
||||
|
||||
/// Task was interrupted during execution, mostly this happens in development environments
|
||||
INTERRUPTED
|
||||
|
||||
/// Task has been completed successfully
|
||||
COMPLETED_SUCCESSFULLY
|
||||
|
||||
/// Task has been completed with errors
|
||||
COMPLETED_WITH_ERRORS
|
||||
|
||||
/// Task has failed to complete, due to an error in the system
|
||||
SYSTEM_FAILURE
|
||||
|
||||
/// Task has crashed and won't be retried, most likely the worker ran out of resources, e.g. memory or storage
|
||||
CRASHED
|
||||
|
||||
/// Task reached the ttl without being executed
|
||||
EXPIRED
|
||||
|
||||
/// Task has been timed out when using maxDuration
|
||||
TIMED_OUT
|
||||
}
|
||||
|
||||
enum RunEngineVersion {
|
||||
/// The original version that uses marqs v1 and Graphile
|
||||
V1
|
||||
V2
|
||||
}
|
||||
|
||||
/// Used by the RunEngine during TaskRun execution
|
||||
/// It has the required information to transactionally progress a run through states,
|
||||
/// and prevent side effects like heartbeats failing a run that has progressed.
|
||||
/// It is optimised for performance and is designed to be cleared at some point,
|
||||
/// so there are no cascading relationships to other models.
|
||||
///
|
||||
/// Same columns and indexes as the control-plane version. The `run` and
|
||||
/// `checkpoint` relations are kept as real foreign keys. The `completedWaitpoints`
|
||||
/// relation is foreign-key-free: it is represented by rows of the `CompletedWaitpoint`
|
||||
/// join model instead.
|
||||
model TaskRunExecutionSnapshot {
|
||||
id String @id @default(cuid())
|
||||
|
||||
/// This should always be 2+ (V1 didn't use the run engine or snapshots)
|
||||
engine RunEngineVersion @default(V2)
|
||||
|
||||
/// The execution status
|
||||
executionStatus TaskRunExecutionStatus
|
||||
/// For debugging
|
||||
description String
|
||||
|
||||
/// We store invalid snapshots as a record of the run state when we tried to move
|
||||
isValid Boolean @default(true)
|
||||
error String?
|
||||
|
||||
/// The previous snapshot ID
|
||||
previousSnapshotId String?
|
||||
|
||||
/// Run
|
||||
runId String
|
||||
run TaskRun @relation(fields: [runId], references: [id])
|
||||
runStatus TaskRunStatus
|
||||
|
||||
// Batch
|
||||
batchId String?
|
||||
|
||||
/// This is the current run attempt number. Users can define how many attempts they want for a run.
|
||||
attemptNumber Int?
|
||||
|
||||
/// Environment
|
||||
environmentId String
|
||||
environmentType RuntimeEnvironmentType
|
||||
projectId String
|
||||
organizationId String
|
||||
|
||||
// The control-plane `completedWaitpoints` relation (waitpoints completed for this
|
||||
// execution) is foreign-key-free here, stored as rows of CompletedWaitpoint.
|
||||
|
||||
/// An array of waitpoint IDs in the correct order, used for batches
|
||||
completedWaitpointOrder String[]
|
||||
|
||||
/// Checkpoint
|
||||
checkpointId String?
|
||||
checkpoint TaskRunCheckpoint? @relation(fields: [checkpointId], references: [id])
|
||||
|
||||
/// Worker
|
||||
workerId String?
|
||||
runnerId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
lastHeartbeatAt DateTime?
|
||||
|
||||
/// Metadata used by various systems in the run engine
|
||||
metadata Json?
|
||||
|
||||
/// Used to get the latest valid snapshot quickly
|
||||
@@index([runId, isValid, createdAt(sort: Desc)])
|
||||
}
|
||||
|
||||
enum TaskRunExecutionStatus {
|
||||
/// Run has been created
|
||||
RUN_CREATED
|
||||
/// Run is delayed, waiting to be enqueued
|
||||
DELAYED
|
||||
/// Run is in the RunQueue
|
||||
QUEUED
|
||||
/// Run is in the RunQueue, and is also executing. This happens when a run is continued cannot reacquire concurrency
|
||||
QUEUED_EXECUTING
|
||||
/// Run has been pulled from the queue, but isn't executing yet
|
||||
PENDING_EXECUTING
|
||||
/// Run is executing on a worker
|
||||
EXECUTING
|
||||
/// Run is executing on a worker but is waiting for waitpoints to complete
|
||||
EXECUTING_WITH_WAITPOINTS
|
||||
/// Run has been suspended and may be waiting for waitpoints to complete before resuming
|
||||
SUSPENDED
|
||||
/// Run has been scheduled for cancellation
|
||||
PENDING_CANCEL
|
||||
/// Run is finished (success of failure)
|
||||
FINISHED
|
||||
}
|
||||
|
||||
/// Same columns as the control-plane version, with the project and environment
|
||||
/// relations kept as scalar-only foreign keys.
|
||||
model TaskRunCheckpoint {
|
||||
id String @id @default(cuid())
|
||||
|
||||
friendlyId String @unique
|
||||
|
||||
type TaskRunCheckpointType
|
||||
location String
|
||||
imageRef String?
|
||||
reason String?
|
||||
metadata String?
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
/// scalar FK (control-plane `runtimeEnvironment` relation)
|
||||
runtimeEnvironmentId String
|
||||
|
||||
executionSnapshot TaskRunExecutionSnapshot[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
enum TaskRunCheckpointType {
|
||||
DOCKER
|
||||
KUBERNETES
|
||||
COMPUTE
|
||||
}
|
||||
|
||||
/// A Waitpoint blocks a run from continuing until it's completed
|
||||
/// If there's a waitpoint blocking a run, it shouldn't be in the queue
|
||||
///
|
||||
/// Same columns and indexes as the control-plane version. Every relation is
|
||||
/// foreign-key-free, because a waitpoint and the run or batch it references may
|
||||
/// live in different databases: `completedByTaskRunId` and `completedByBatchId`
|
||||
/// are scalar-only, and the `blockingTaskRuns`, `connectedRuns`, and
|
||||
/// `completedExecutionSnapshots` back-references are represented by the
|
||||
/// `TaskRunWaitpoint`, `WaitpointRunConnection`, and `CompletedWaitpoint` join
|
||||
/// models. The project and environment relations are scalar-only foreign keys.
|
||||
model Waitpoint {
|
||||
id String @id @default(cuid())
|
||||
|
||||
friendlyId String @unique
|
||||
|
||||
type WaitpointType
|
||||
status WaitpointStatus @default(PENDING)
|
||||
|
||||
completedAt DateTime?
|
||||
|
||||
/// If it's an Event type waitpoint, this is the event. It can also be provided for the DATETIME type
|
||||
idempotencyKey String
|
||||
/// If this is true then we can show it in the dashboard/return it from the SDK
|
||||
userProvidedIdempotencyKey Boolean
|
||||
|
||||
/// If there's a user provided idempotency key, this is the time it expires at
|
||||
idempotencyKeyExpiresAt DateTime?
|
||||
|
||||
/// If an idempotencyKey is no longer active, we store it here and generate a new one for the idempotencyKey field.
|
||||
/// Clearing an idempotencyKey is useful for debounce or cancelling child runs.
|
||||
/// This is a workaround because Prisma doesn't support partial indexes.
|
||||
inactiveIdempotencyKey String?
|
||||
|
||||
/// If it's a RUN type waitpoint, this is the associated run.
|
||||
/// scalar FK (control-plane `completedByTaskRun` relation)
|
||||
completedByTaskRunId String? @unique
|
||||
|
||||
/// If it's a DATETIME type waitpoint, this is the date.
|
||||
/// If it's a MANUAL waitpoint, this can be set as the `timeout`.
|
||||
completedAfter DateTime?
|
||||
|
||||
/// If it's a BATCH type waitpoint, this is the associated batch.
|
||||
/// scalar FK (control-plane `completedByBatch` relation)
|
||||
completedByBatchId String?
|
||||
|
||||
/// When completed, an output can be stored here
|
||||
output String?
|
||||
outputType String @default("application/json")
|
||||
outputIsError Boolean @default(false)
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
/// scalar FK (control-plane `environment` relation)
|
||||
environmentId String
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
/// Denormized column that holds the raw tags
|
||||
/// Denormalized column that holds the raw tags
|
||||
tags String[]
|
||||
|
||||
/// Quickly find an idempotent waitpoint
|
||||
@@unique([environmentId, idempotencyKey])
|
||||
/// Quickly find a batch waitpoint
|
||||
@@index([completedByBatchId])
|
||||
/// Used on the Waitpoint dashboard pages
|
||||
/// Time period filtering
|
||||
@@index([environmentId, type, createdAt(sort: Desc)])
|
||||
/// Status filtering
|
||||
@@index([environmentId, type, status])
|
||||
/// For the waitpoint token dashboard page
|
||||
@@index([environmentId, type, id(sort: Desc)])
|
||||
}
|
||||
|
||||
enum WaitpointType {
|
||||
RUN
|
||||
DATETIME
|
||||
MANUAL
|
||||
BATCH
|
||||
}
|
||||
|
||||
enum WaitpointStatus {
|
||||
PENDING
|
||||
COMPLETED
|
||||
}
|
||||
|
||||
/// The block edge between a run and a waitpoint. Same columns and indexes as the
|
||||
/// control-plane version, but the run, waitpoint, project, and batch relations
|
||||
/// are all scalar-only foreign keys: a block edge can connect a run and a
|
||||
/// waitpoint that live in different databases, so it is never enforced by a
|
||||
/// foreign key here.
|
||||
model TaskRunWaitpoint {
|
||||
id String @id @default(cuid())
|
||||
|
||||
/// scalar FK (control-plane `taskRun` relation)
|
||||
taskRunId String
|
||||
|
||||
/// scalar FK (control-plane `waitpoint` relation)
|
||||
waitpointId String
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
/// This span id is completed when the waitpoint is completed. This is used with cached runs (idempotent)
|
||||
spanIdToComplete String?
|
||||
|
||||
/// scalar FK (control-plane `batch` relation)
|
||||
batchId String?
|
||||
//if there's an associated batch and this isn't set it's for the entire batch
|
||||
//if it is set, it's a specific run in the batch
|
||||
batchIndex Int?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
/// There are two constraints, the one below and also one that Prisma doesn't support
|
||||
/// The second one implemented in SQL only prevents a TaskRun + Waitpoint with a null batchIndex
|
||||
@@unique([taskRunId, waitpointId, batchIndex])
|
||||
@@index([taskRunId])
|
||||
@@index([waitpointId])
|
||||
}
|
||||
|
||||
/// Explicit join model for the connection between a run and every waitpoint that
|
||||
/// blocked it (kept for display). This has no control-plane counterpart table: it
|
||||
/// replaces the implicit many-to-many relation between `TaskRun.connectedWaitpoints`
|
||||
/// and `Waitpoint.connectedRuns`. Scalar columns only, no foreign keys, so a
|
||||
/// connection can span both databases.
|
||||
model WaitpointRunConnection {
|
||||
id String @id @default(cuid())
|
||||
|
||||
taskRunId String
|
||||
waitpointId String
|
||||
|
||||
@@unique([taskRunId, waitpointId])
|
||||
@@index([taskRunId])
|
||||
@@index([waitpointId])
|
||||
}
|
||||
|
||||
/// Explicit join model recording which waitpoints an execution snapshot completed.
|
||||
/// This has no control-plane counterpart table: it replaces the implicit
|
||||
/// many-to-many relation between `TaskRunExecutionSnapshot.completedWaitpoints`
|
||||
/// and `Waitpoint`. Scalar columns only, no foreign keys, so a snapshot may record
|
||||
/// a waitpoint that lives in the other database.
|
||||
model CompletedWaitpoint {
|
||||
id String @id @default(cuid())
|
||||
|
||||
snapshotId String
|
||||
waitpointId String
|
||||
|
||||
@@unique([snapshotId, waitpointId])
|
||||
@@index([snapshotId])
|
||||
@@index([waitpointId])
|
||||
}
|
||||
|
||||
/// Same columns and indexes as the control-plane version, with the environment
|
||||
/// and project relations kept as scalar-only foreign keys.
|
||||
model WaitpointTag {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
|
||||
/// scalar FK (control-plane `environment` relation)
|
||||
environmentId String
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([environmentId, name])
|
||||
}
|
||||
|
||||
/// Same columns and indexes as the control-plane version, with the project
|
||||
/// relation kept as a scalar-only foreign key. The control-plane `runs` back-
|
||||
/// reference (the tag-to-run many-to-many) is dropped.
|
||||
model TaskRunTag {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
|
||||
friendlyId String @unique
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([projectId, name])
|
||||
//Makes run filtering by tag faster
|
||||
@@index([name, id])
|
||||
}
|
||||
|
||||
/// This is used for triggerAndWait and batchTriggerAndWait. The taskRun is the child task, it points at a parent attempt or a batch
|
||||
///
|
||||
/// Identical to the control-plane version: every relation stays within this
|
||||
/// database and is kept as a real foreign key.
|
||||
model TaskRunDependency {
|
||||
id String @id @default(cuid())
|
||||
|
||||
/// The child run
|
||||
taskRun TaskRun @relation(fields: [taskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
taskRunId String @unique
|
||||
|
||||
checkpointEvent CheckpointRestoreEvent? @relation(fields: [checkpointEventId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
checkpointEventId String? @unique
|
||||
|
||||
/// An attempt that is dependent on this task run.
|
||||
dependentAttempt TaskRunAttempt? @relation(fields: [dependentAttemptId], references: [id])
|
||||
dependentAttemptId String?
|
||||
|
||||
/// A batch run that is dependent on this task run
|
||||
dependentBatchRun BatchTaskRun? @relation("dependentBatchRun", fields: [dependentBatchRunId], references: [id])
|
||||
dependentBatchRunId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
resumedAt DateTime?
|
||||
|
||||
@@index([dependentAttemptId])
|
||||
@@index([dependentBatchRunId])
|
||||
}
|
||||
|
||||
/// Same columns and indexes as the control-plane version. The owning-run relation
|
||||
/// is kept as a real foreign key. The background-worker, background-worker-task,
|
||||
/// environment, and queue relations are scalar-only foreign keys. The control-
|
||||
/// plane `alerts` back-reference is dropped.
|
||||
model TaskRunAttempt {
|
||||
id String @id @default(cuid())
|
||||
number Int @default(0)
|
||||
|
||||
friendlyId String @unique
|
||||
|
||||
/// The owning run
|
||||
taskRun TaskRun @relation("attempts", fields: [taskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
taskRunId String
|
||||
|
||||
/// scalar FK (control-plane `backgroundWorker` relation)
|
||||
backgroundWorkerId String
|
||||
|
||||
/// scalar FK (control-plane `backgroundWorkerTask` relation)
|
||||
backgroundWorkerTaskId String
|
||||
|
||||
/// scalar FK (control-plane `runtimeEnvironment` relation)
|
||||
runtimeEnvironmentId String
|
||||
|
||||
/// scalar FK (control-plane `queue` relation)
|
||||
queueId String
|
||||
|
||||
status TaskRunAttemptStatus @default(PENDING)
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
startedAt DateTime?
|
||||
completedAt DateTime?
|
||||
|
||||
usageDurationMs Int @default(0)
|
||||
|
||||
error Json?
|
||||
output String?
|
||||
outputType String @default("application/json")
|
||||
|
||||
dependencies TaskRunDependency[]
|
||||
batchDependencies BatchTaskRun[]
|
||||
|
||||
checkpoints Checkpoint[]
|
||||
batchTaskRunItems BatchTaskRunItem[]
|
||||
CheckpointRestoreEvent CheckpointRestoreEvent[]
|
||||
childRuns TaskRun[] @relation("TaskParentRunAttempt")
|
||||
|
||||
@@unique([taskRunId, number])
|
||||
@@index([taskRunId])
|
||||
}
|
||||
|
||||
enum TaskRunAttemptStatus {
|
||||
/// NON-FINAL
|
||||
PENDING
|
||||
EXECUTING
|
||||
PAUSED
|
||||
/// FINAL
|
||||
FAILED
|
||||
CANCELED
|
||||
COMPLETED
|
||||
}
|
||||
|
||||
/// Same columns and indexes as the control-plane version. The environment
|
||||
/// relation is a scalar-only foreign key. The `runsBlocked` and `waitpoints`
|
||||
/// back-references are foreign-key-free: block edges are rows of
|
||||
/// `TaskRunWaitpoint`, and batch-completed waitpoints are found via
|
||||
/// `Waitpoint.completedByBatchId`. The `runs`, `errors`, `items`,
|
||||
/// `checkpointEvent`, `dependentTaskAttempt`, and `runDependencies` relations
|
||||
/// stay within this database and are kept as real foreign keys.
|
||||
model BatchTaskRun {
|
||||
id String @id @default(cuid())
|
||||
friendlyId String @unique
|
||||
idempotencyKey String?
|
||||
idempotencyKeyExpiresAt DateTime?
|
||||
status BatchTaskRunStatus @default(PENDING)
|
||||
/// scalar FK (control-plane `runtimeEnvironment` relation)
|
||||
runtimeEnvironmentId String
|
||||
/// This only includes new runs, not idempotent runs.
|
||||
runs TaskRun[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
// new columns
|
||||
/// Friendly IDs
|
||||
runIds String[] @default([])
|
||||
runCount Int @default(0)
|
||||
payload String?
|
||||
payloadType String @default("application/json")
|
||||
options Json?
|
||||
batchVersion String @default("v1")
|
||||
|
||||
//engine v2
|
||||
// The control-plane `runsBlocked` and `waitpoints` back-references are foreign-
|
||||
// key-free here: block edges are rows of TaskRunWaitpoint keyed by batchId, and
|
||||
// batch-completed waitpoints are found via Waitpoint.completedByBatchId.
|
||||
|
||||
// This is for v3 batches
|
||||
/// sealed is set to true once no more items can be added to the batch
|
||||
sealed Boolean @default(false)
|
||||
sealedAt DateTime?
|
||||
/// this is the expected number of items in the batch
|
||||
expectedCount Int @default(0)
|
||||
/// this is the completed number of items in the batch. once this reaches expectedCount, and the batch is sealed, the batch is considered completed
|
||||
completedCount Int @default(0)
|
||||
completedAt DateTime?
|
||||
resumedAt DateTime?
|
||||
|
||||
/// this is used to be able to "seal" this BatchTaskRun when all of the runs have been triggered asynchronously, and using the "parallel" processing strategy
|
||||
processingJobsCount Int @default(0)
|
||||
processingJobsExpectedCount Int @default(0)
|
||||
|
||||
/// optional token that can be used to authenticate the task run
|
||||
oneTimeUseToken String?
|
||||
|
||||
// Run Engine v2 batch queue fields
|
||||
/// When processing started (status changed to PROCESSING)
|
||||
processingStartedAt DateTime?
|
||||
/// When processing completed (all items processed)
|
||||
processingCompletedAt DateTime?
|
||||
/// Count of successfully created runs
|
||||
successfulRunCount Int?
|
||||
/// Count of failed run creations
|
||||
failedRunCount Int?
|
||||
/// Detailed failure records
|
||||
errors BatchTaskRunError[]
|
||||
|
||||
///all the below properties are engine v1 only
|
||||
items BatchTaskRunItem[]
|
||||
taskIdentifier String?
|
||||
checkpointEvent CheckpointRestoreEvent? @relation(fields: [checkpointEventId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
checkpointEventId String? @unique
|
||||
dependentTaskAttempt TaskRunAttempt? @relation(fields: [dependentTaskAttemptId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
dependentTaskAttemptId String?
|
||||
runDependencies TaskRunDependency[] @relation("dependentBatchRun")
|
||||
|
||||
@@unique([oneTimeUseToken])
|
||||
///this is used for all engine versions
|
||||
@@unique([runtimeEnvironmentId, idempotencyKey])
|
||||
@@index([dependentTaskAttemptId])
|
||||
// This is for the batch list dashboard page
|
||||
@@index([runtimeEnvironmentId, id(sort: Desc)])
|
||||
}
|
||||
|
||||
enum BatchTaskRunStatus {
|
||||
PENDING
|
||||
PROCESSING
|
||||
COMPLETED
|
||||
PARTIAL_FAILED
|
||||
ABORTED
|
||||
}
|
||||
|
||||
///Used in engine V1 only
|
||||
///
|
||||
/// Identical to the control-plane version: every relation stays within this
|
||||
/// database and is kept as a real foreign key.
|
||||
model BatchTaskRunItem {
|
||||
id String @id @default(cuid())
|
||||
|
||||
status BatchTaskRunItemStatus @default(PENDING)
|
||||
|
||||
batchTaskRun BatchTaskRun @relation(fields: [batchTaskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
batchTaskRunId String
|
||||
|
||||
taskRun TaskRun @relation(fields: [taskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
taskRunId String
|
||||
|
||||
taskRunAttempt TaskRunAttempt? @relation(fields: [taskRunAttemptId], references: [id], onDelete: SetNull, onUpdate: Cascade)
|
||||
taskRunAttemptId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
completedAt DateTime?
|
||||
|
||||
@@unique([batchTaskRunId, taskRunId])
|
||||
@@index([taskRunAttemptId], map: "idx_batchtaskrunitem_taskrunattempt")
|
||||
@@index([taskRunId], map: "idx_batchtaskrunitem_taskrun")
|
||||
}
|
||||
|
||||
enum BatchTaskRunItemStatus {
|
||||
PENDING
|
||||
FAILED
|
||||
CANCELED
|
||||
COMPLETED
|
||||
}
|
||||
|
||||
/// Track individual run creation failures in batch processing (Run Engine v2)
|
||||
///
|
||||
/// Identical to the control-plane version: the batch relation stays within this
|
||||
/// database and is kept as a real foreign key.
|
||||
model BatchTaskRunError {
|
||||
id String @id @default(cuid())
|
||||
batchTaskRun BatchTaskRun @relation(fields: [batchTaskRunId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
batchTaskRunId String
|
||||
|
||||
/// Which item in the batch (0-based index)
|
||||
index Int
|
||||
/// The task identifier that was being triggered
|
||||
taskIdentifier String
|
||||
/// The payload that failed (JSON, may be truncated)
|
||||
payload String?
|
||||
/// The options that were used
|
||||
options Json?
|
||||
/// Error message
|
||||
error String
|
||||
/// Error code if available
|
||||
errorCode String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([batchTaskRunId, index])
|
||||
@@index([batchTaskRunId])
|
||||
}
|
||||
|
||||
/// Same columns and indexes as the control-plane version. The run and attempt
|
||||
/// relations are kept as real foreign keys; the project and environment relations
|
||||
/// are scalar-only foreign keys.
|
||||
model Checkpoint {
|
||||
id String @id @default(cuid())
|
||||
|
||||
friendlyId String @unique
|
||||
|
||||
type CheckpointType
|
||||
location String
|
||||
imageRef String
|
||||
reason String?
|
||||
metadata String?
|
||||
|
||||
events CheckpointRestoreEvent[]
|
||||
|
||||
run TaskRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
runId String
|
||||
|
||||
attempt TaskRunAttempt @relation(fields: [attemptId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
attemptId String
|
||||
attemptNumber Int?
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
/// scalar FK (control-plane `runtimeEnvironment` relation)
|
||||
runtimeEnvironmentId String
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([attemptId])
|
||||
@@index([runId])
|
||||
}
|
||||
|
||||
enum CheckpointType {
|
||||
DOCKER
|
||||
KUBERNETES
|
||||
}
|
||||
|
||||
/// Same columns and indexes as the control-plane version. The checkpoint, run,
|
||||
/// and attempt relations are kept as real foreign keys; the project and
|
||||
/// environment relations are scalar-only foreign keys.
|
||||
model CheckpointRestoreEvent {
|
||||
id String @id @default(cuid())
|
||||
|
||||
type CheckpointRestoreEventType
|
||||
reason String?
|
||||
metadata String?
|
||||
|
||||
checkpoint Checkpoint @relation(fields: [checkpointId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
checkpointId String
|
||||
|
||||
run TaskRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
runId String
|
||||
|
||||
attempt TaskRunAttempt @relation(fields: [attemptId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
attemptId String
|
||||
|
||||
/// scalar FK (control-plane `project` relation)
|
||||
projectId String
|
||||
|
||||
/// scalar FK (control-plane `runtimeEnvironment` relation)
|
||||
runtimeEnvironmentId String
|
||||
|
||||
taskRunDependency TaskRunDependency?
|
||||
batchTaskRunDependency BatchTaskRun?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([checkpointId])
|
||||
@@index([runId])
|
||||
}
|
||||
|
||||
enum CheckpointRestoreEventType {
|
||||
CHECKPOINT
|
||||
RESTORE
|
||||
}
|
||||
Reference in New Issue
Block a user