Initial curated projectbrain source from 8a7b1e0651dbdab97d744cbd2e653ab3970ac6c5
This commit is contained in:
commit
5aa3e8d685
700 files changed
+132801
No files matched your search
@@ -0,0 +1,617 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ProjectStatus" AS ENUM ('active', 'archived', 'paused');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "FeatureStatus" AS ENUM ('todo', 'in_progress', 'done');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "FeatureLifecycle" AS ENUM ('feature_candidate', 'planned', 'active', 'implemented', 'verified', 'production_proven', 'deprecated', 'archived');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ApprovalState" AS ENUM ('pending', 'approved', 'rejected', 'blocked');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EvidenceStrength" AS ENUM ('weak', 'medium', 'strong', 'verified');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "VerificationState" AS ENUM ('unverified', 'needs_evidence', 'verified', 'blocked');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ReviewStatus" AS ENUM ('pending', 'accepted', 'rejected', 'merged', 'converted');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EntityType" AS ENUM ('project', 'project_dna', 'workspace_state', 'feature_group', 'feature', 'evidence', 'context_pack', 'context_pack_section', 'memory_rule', 'knowledge_item', 'review_queue_item', 'idempotency_record', 'entity_relation', 'activity_event');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Project" (
|
||||
"id" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"readableId" TEXT,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"domain" TEXT NOT NULL,
|
||||
"status" "ProjectStatus" NOT NULL DEFAULT 'active',
|
||||
"health" INTEGER NOT NULL DEFAULT 0,
|
||||
"healthStatus" TEXT NOT NULL,
|
||||
"activeContextPackId" TEXT,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ProjectDNA" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"vision" TEXT NOT NULL,
|
||||
"goalsJson" JSONB NOT NULL,
|
||||
"nonGoalsJson" JSONB NOT NULL,
|
||||
"targetAudience" TEXT NOT NULL,
|
||||
"principlesJson" JSONB NOT NULL,
|
||||
"metricsJson" JSONB NOT NULL,
|
||||
"maturityStage" TEXT NOT NULL,
|
||||
"revision" INTEGER NOT NULL DEFAULT 1,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ProjectDNA_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "WorkspaceState" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"activeContextPackId" TEXT,
|
||||
"primaryObjective" TEXT NOT NULL,
|
||||
"activeSection" TEXT NOT NULL,
|
||||
"notesJson" JSONB NOT NULL,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "WorkspaceState_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "FeatureGroup" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"focusArea" TEXT,
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "FeatureGroup_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Feature" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"featureGroupId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"status" "FeatureStatus" NOT NULL DEFAULT 'todo',
|
||||
"lifecycle" "FeatureLifecycle" NOT NULL DEFAULT 'feature_candidate',
|
||||
"intent" TEXT,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"health" INTEGER NOT NULL DEFAULT 0,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"evidenceStrength" "EvidenceStrength",
|
||||
"verificationState" "VerificationState",
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"verifiedBy" TEXT,
|
||||
"trustJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Feature_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Evidence" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"type" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"evidenceStrength" "EvidenceStrength" NOT NULL DEFAULT 'weak',
|
||||
"verificationState" "VerificationState",
|
||||
"reason" TEXT NOT NULL,
|
||||
"trustJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"metadataJson" JSONB,
|
||||
"lastSeen" TIMESTAMP(3) NOT NULL,
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"verifiedBy" TEXT,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Evidence_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ContextPack" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"generatedBy" TEXT NOT NULL,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"qualityJson" JSONB,
|
||||
"trustJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"metadataJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ContextPack_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ContextPackSection" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"contextPackId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"sectionType" TEXT NOT NULL,
|
||||
"orderIndex" INTEGER NOT NULL,
|
||||
"contentJson" JSONB NOT NULL,
|
||||
"metadataJson" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ContextPackSection_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MemoryRule" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"rule" TEXT NOT NULL,
|
||||
"scope" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"severity" TEXT NOT NULL,
|
||||
"includeInContextPacks" BOOLEAN NOT NULL DEFAULT false,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"evidenceStrength" "EvidenceStrength",
|
||||
"verificationState" "VerificationState",
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"verifiedBy" TEXT,
|
||||
"trustJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "MemoryRule_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "KnowledgeItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"includeInContextPacks" BOOLEAN NOT NULL DEFAULT false,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"evidenceStrength" "EvidenceStrength",
|
||||
"verificationState" "VerificationState",
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"verifiedBy" TEXT,
|
||||
"trustJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"metadataJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "KnowledgeItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ReviewQueueItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"type" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"priority" TEXT NOT NULL,
|
||||
"status" "ReviewStatus" NOT NULL DEFAULT 'pending',
|
||||
"source" TEXT NOT NULL,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"evidenceStrength" "EvidenceStrength" NOT NULL DEFAULT 'weak',
|
||||
"verificationState" "VerificationState" NOT NULL DEFAULT 'unverified',
|
||||
"suggestedAction" TEXT NOT NULL,
|
||||
"notes" TEXT,
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdEntityType" "EntityType",
|
||||
"createdEntityId" TEXT,
|
||||
"targetEntityType" "EntityType",
|
||||
"targetEntityId" TEXT,
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"verifiedBy" TEXT,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ReviewQueueItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "IdempotencyRecord" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT,
|
||||
"method" TEXT NOT NULL,
|
||||
"path" TEXT NOT NULL,
|
||||
"key" TEXT NOT NULL,
|
||||
"requestHash" TEXT NOT NULL,
|
||||
"statusCode" INTEGER NOT NULL,
|
||||
"responseJson" JSONB NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "IdempotencyRecord_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "EntityRelation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"sourceEntityType" "EntityType" NOT NULL,
|
||||
"sourceEntityId" TEXT NOT NULL,
|
||||
"targetEntityType" "EntityType" NOT NULL,
|
||||
"targetEntityId" TEXT NOT NULL,
|
||||
"relationshipType" TEXT NOT NULL,
|
||||
"metadataJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "EntityRelation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ActivityEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"entityType" "EntityType" NOT NULL,
|
||||
"entityId" TEXT NOT NULL,
|
||||
"eventType" TEXT NOT NULL,
|
||||
"actor" TEXT NOT NULL,
|
||||
"payloadJson" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "ActivityEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Project_slug_key" ON "Project"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Project_status_idx" ON "Project"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Project_activeContextPackId_idx" ON "Project"("activeContextPackId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Project_deletedAt_idx" ON "Project"("deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Project_updatedAt_idx" ON "Project"("updatedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ProjectDNA_projectId_key" ON "ProjectDNA"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "WorkspaceState_projectId_key" ON "WorkspaceState"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "WorkspaceState_projectId_activeContextPackId_idx" ON "WorkspaceState"("projectId", "activeContextPackId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "FeatureGroup_projectId_idx" ON "FeatureGroup"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "FeatureGroup_projectId_deletedAt_idx" ON "FeatureGroup"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "FeatureGroup_projectId_slug_key" ON "FeatureGroup"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "FeatureGroup_projectId_readableId_key" ON "FeatureGroup"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Feature_projectId_idx" ON "Feature"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Feature_projectId_status_idx" ON "Feature"("projectId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Feature_projectId_lifecycle_idx" ON "Feature"("projectId", "lifecycle");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Feature_projectId_featureGroupId_idx" ON "Feature"("projectId", "featureGroupId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Feature_projectId_name_idx" ON "Feature"("projectId", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Feature_projectId_deletedAt_idx" ON "Feature"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Feature_projectId_slug_key" ON "Feature"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Feature_projectId_readableId_key" ON "Feature"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evidence_projectId_idx" ON "Evidence"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evidence_projectId_type_idx" ON "Evidence"("projectId", "type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evidence_projectId_approvalState_idx" ON "Evidence"("projectId", "approvalState");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evidence_projectId_evidenceStrength_idx" ON "Evidence"("projectId", "evidenceStrength");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evidence_projectId_lastSeen_idx" ON "Evidence"("projectId", "lastSeen");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Evidence_projectId_deletedAt_idx" ON "Evidence"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Evidence_projectId_slug_key" ON "Evidence"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Evidence_projectId_readableId_key" ON "Evidence"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPack_projectId_idx" ON "ContextPack"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPack_projectId_category_idx" ON "ContextPack"("projectId", "category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPack_projectId_generatedBy_idx" ON "ContextPack"("projectId", "generatedBy");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPack_projectId_createdAt_idx" ON "ContextPack"("projectId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPack_projectId_deletedAt_idx" ON "ContextPack"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ContextPack_projectId_slug_key" ON "ContextPack"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ContextPack_projectId_readableId_key" ON "ContextPack"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPackSection_projectId_idx" ON "ContextPackSection"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPackSection_contextPackId_orderIndex_idx" ON "ContextPackSection"("contextPackId", "orderIndex");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ContextPackSection_projectId_sectionType_idx" ON "ContextPackSection"("projectId", "sectionType");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ContextPackSection_contextPackId_slug_key" ON "ContextPackSection"("contextPackId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MemoryRule_projectId_idx" ON "MemoryRule"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MemoryRule_projectId_scope_idx" ON "MemoryRule"("projectId", "scope");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MemoryRule_projectId_category_idx" ON "MemoryRule"("projectId", "category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MemoryRule_projectId_severity_idx" ON "MemoryRule"("projectId", "severity");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MemoryRule_projectId_includeInContextPacks_idx" ON "MemoryRule"("projectId", "includeInContextPacks");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MemoryRule_projectId_deletedAt_idx" ON "MemoryRule"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MemoryRule_projectId_slug_key" ON "MemoryRule"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MemoryRule_projectId_readableId_key" ON "MemoryRule"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "KnowledgeItem_projectId_idx" ON "KnowledgeItem"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "KnowledgeItem_projectId_category_idx" ON "KnowledgeItem"("projectId", "category");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "KnowledgeItem_projectId_source_idx" ON "KnowledgeItem"("projectId", "source");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "KnowledgeItem_projectId_createdAt_idx" ON "KnowledgeItem"("projectId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "KnowledgeItem_projectId_deletedAt_idx" ON "KnowledgeItem"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "KnowledgeItem_projectId_slug_key" ON "KnowledgeItem"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "KnowledgeItem_projectId_readableId_key" ON "KnowledgeItem"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReviewQueueItem_projectId_idx" ON "ReviewQueueItem"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReviewQueueItem_projectId_status_idx" ON "ReviewQueueItem"("projectId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReviewQueueItem_projectId_type_idx" ON "ReviewQueueItem"("projectId", "type");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReviewQueueItem_projectId_priority_idx" ON "ReviewQueueItem"("projectId", "priority");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReviewQueueItem_projectId_createdAt_idx" ON "ReviewQueueItem"("projectId", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReviewQueueItem_projectId_deletedAt_idx" ON "ReviewQueueItem"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ReviewQueueItem_projectId_slug_key" ON "ReviewQueueItem"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ReviewQueueItem_projectId_readableId_key" ON "ReviewQueueItem"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "IdempotencyRecord_projectId_idx" ON "IdempotencyRecord"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "IdempotencyRecord_expiresAt_idx" ON "IdempotencyRecord"("expiresAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "IdempotencyRecord_method_path_key_key" ON "IdempotencyRecord"("method", "path", "key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EntityRelation_projectId_idx" ON "EntityRelation"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EntityRelation_projectId_sourceEntityType_sourceEntityId_idx" ON "EntityRelation"("projectId", "sourceEntityType", "sourceEntityId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EntityRelation_projectId_targetEntityType_targetEntityId_idx" ON "EntityRelation"("projectId", "targetEntityType", "targetEntityId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EntityRelation_projectId_relationshipType_idx" ON "EntityRelation"("projectId", "relationshipType");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EntityRelation_projectId_deletedAt_idx" ON "EntityRelation"("projectId", "deletedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ActivityEvent_projectId_idx" ON "ActivityEvent"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ActivityEvent_projectId_entityType_entityId_idx" ON "ActivityEvent"("projectId", "entityType", "entityId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ActivityEvent_projectId_eventType_idx" ON "ActivityEvent"("projectId", "eventType");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ActivityEvent_projectId_createdAt_idx" ON "ActivityEvent"("projectId", "createdAt");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ProjectDNA" ADD CONSTRAINT "ProjectDNA_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "WorkspaceState" ADD CONSTRAINT "WorkspaceState_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "FeatureGroup" ADD CONSTRAINT "FeatureGroup_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Feature" ADD CONSTRAINT "Feature_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Feature" ADD CONSTRAINT "Feature_featureGroupId_fkey" FOREIGN KEY ("featureGroupId") REFERENCES "FeatureGroup"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Evidence" ADD CONSTRAINT "Evidence_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContextPack" ADD CONSTRAINT "ContextPack_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ContextPackSection" ADD CONSTRAINT "ContextPackSection_contextPackId_fkey" FOREIGN KEY ("contextPackId") REFERENCES "ContextPack"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MemoryRule" ADD CONSTRAINT "MemoryRule_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "KnowledgeItem" ADD CONSTRAINT "KnowledgeItem_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ReviewQueueItem" ADD CONSTRAINT "ReviewQueueItem_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EntityRelation" ADD CONSTRAINT "EntityRelation_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ActivityEvent" ADD CONSTRAINT "ActivityEvent_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,40 @@
|
||||
-- P5 adds persistent capture items. ReviewQueueItem already exists in the initial schema.
|
||||
CREATE TABLE "CaptureItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"type" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"classificationType" TEXT,
|
||||
"confidence" INTEGER,
|
||||
"evidenceStrength" "EvidenceStrength",
|
||||
"suggestedAction" TEXT,
|
||||
"linkedReviewItemId" TEXT,
|
||||
"metadataJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CaptureItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "CaptureItem_projectId_slug_key" ON "CaptureItem"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX "CaptureItem_projectId_readableId_key" ON "CaptureItem"("projectId", "readableId");
|
||||
CREATE INDEX "CaptureItem_projectId_idx" ON "CaptureItem"("projectId");
|
||||
CREATE INDEX "CaptureItem_projectId_status_idx" ON "CaptureItem"("projectId", "status");
|
||||
CREATE INDEX "CaptureItem_projectId_type_idx" ON "CaptureItem"("projectId", "type");
|
||||
CREATE INDEX "CaptureItem_projectId_classificationType_idx" ON "CaptureItem"("projectId", "classificationType");
|
||||
CREATE INDEX "CaptureItem_projectId_linkedReviewItemId_idx" ON "CaptureItem"("projectId", "linkedReviewItemId");
|
||||
CREATE INDEX "CaptureItem_projectId_createdAt_idx" ON "CaptureItem"("projectId", "createdAt");
|
||||
CREATE INDEX "CaptureItem_projectId_deletedAt_idx" ON "CaptureItem"("projectId", "deletedAt");
|
||||
|
||||
ALTER TABLE "CaptureItem" ADD CONSTRAINT "CaptureItem_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
-- P6 accepted truth, project updates, and operating log persistence.
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'accepted_truth_item';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'project_update';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'operating_log_entry';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "AcceptedTruthItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"sourceReviewItemId" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'accepted',
|
||||
"source" TEXT NOT NULL,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'approved',
|
||||
"evidenceStrength" "EvidenceStrength" NOT NULL DEFAULT 'weak',
|
||||
"verificationState" "VerificationState" NOT NULL DEFAULT 'verified',
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'review_queue',
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"verifiedBy" TEXT,
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "AcceptedTruthItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "ProjectUpdate" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"sourceTruthItemId" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"targetArea" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'ready',
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"evidenceStrength" "EvidenceStrength" NOT NULL DEFAULT 'weak',
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'accepted_truth',
|
||||
"appliedAt" TIMESTAMP(3),
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ProjectUpdate_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "OperatingLogEntry" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"type" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"linkedEntityIdsJson" JSONB NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"importance" TEXT NOT NULL DEFAULT 'normal',
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'runtime',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "OperatingLogEntry_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_slug_key" ON "AcceptedTruthItem"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_readableId_key" ON "AcceptedTruthItem"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_idx" ON "AcceptedTruthItem"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_sourceReviewItemId_idx" ON "AcceptedTruthItem"("projectId", "sourceReviewItemId");
|
||||
CREATE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_kind_idx" ON "AcceptedTruthItem"("projectId", "kind");
|
||||
CREATE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_status_idx" ON "AcceptedTruthItem"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_createdAt_idx" ON "AcceptedTruthItem"("projectId", "createdAt");
|
||||
CREATE INDEX IF NOT EXISTS "AcceptedTruthItem_projectId_deletedAt_idx" ON "AcceptedTruthItem"("projectId", "deletedAt");
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "ProjectUpdate_projectId_slug_key" ON "ProjectUpdate"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "ProjectUpdate_projectId_readableId_key" ON "ProjectUpdate"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "ProjectUpdate_projectId_idx" ON "ProjectUpdate"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "ProjectUpdate_projectId_sourceTruthItemId_idx" ON "ProjectUpdate"("projectId", "sourceTruthItemId");
|
||||
CREATE INDEX IF NOT EXISTS "ProjectUpdate_projectId_targetArea_idx" ON "ProjectUpdate"("projectId", "targetArea");
|
||||
CREATE INDEX IF NOT EXISTS "ProjectUpdate_projectId_status_idx" ON "ProjectUpdate"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "ProjectUpdate_projectId_createdAt_idx" ON "ProjectUpdate"("projectId", "createdAt");
|
||||
CREATE INDEX IF NOT EXISTS "ProjectUpdate_projectId_deletedAt_idx" ON "ProjectUpdate"("projectId", "deletedAt");
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "OperatingLogEntry_projectId_slug_key" ON "OperatingLogEntry"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "OperatingLogEntry_projectId_readableId_key" ON "OperatingLogEntry"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "OperatingLogEntry_projectId_idx" ON "OperatingLogEntry"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "OperatingLogEntry_projectId_type_idx" ON "OperatingLogEntry"("projectId", "type");
|
||||
CREATE INDEX IF NOT EXISTS "OperatingLogEntry_projectId_timestamp_idx" ON "OperatingLogEntry"("projectId", "timestamp");
|
||||
CREATE INDEX IF NOT EXISTS "OperatingLogEntry_projectId_deletedAt_idx" ON "OperatingLogEntry"("projectId", "deletedAt");
|
||||
|
||||
ALTER TABLE "AcceptedTruthItem" ADD CONSTRAINT "AcceptedTruthItem_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ProjectUpdate" ADD CONSTRAINT "ProjectUpdate_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "OperatingLogEntry" ADD CONSTRAINT "OperatingLogEntry_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
-- P7 current state, handoff bundle, Codex task, and Codex import persistence.
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'current_state_report';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'handoff_bundle';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'codex_task';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'codex_run_import';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "CurrentStateReport" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"generatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"existsJson" JSONB NOT NULL,
|
||||
"worksJson" JSONB NOT NULL,
|
||||
"uncertainJson" JSONB NOT NULL,
|
||||
"brokenJson" JSONB NOT NULL,
|
||||
"currentRisksJson" JSONB NOT NULL,
|
||||
"pendingReviewItemIdsJson" JSONB NOT NULL,
|
||||
"activeContextPackId" TEXT,
|
||||
"recommendedNextActionsJson" JSONB NOT NULL,
|
||||
"source" TEXT NOT NULL DEFAULT 'runtime',
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'runtime',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "CurrentStateReport_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "HandoffBundle" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"target" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"markdown" TEXT NOT NULL,
|
||||
"qualityScore" INTEGER NOT NULL DEFAULT 0,
|
||||
"sourceTruthItemIdsJson" JSONB NOT NULL,
|
||||
"sourceReviewItemIdsJson" JSONB NOT NULL,
|
||||
"sourceCaptureItemIdsJson" JSONB NOT NULL,
|
||||
"sourceProjectUpdateIdsJson" JSONB,
|
||||
"sourceOperatingLogEntryIdsJson" JSONB,
|
||||
"status" TEXT NOT NULL DEFAULT 'ready',
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'runtime',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "HandoffBundle_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "CodexTask" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"handoffBundleId" TEXT,
|
||||
"goal" TEXT NOT NULL,
|
||||
"contextPackId" TEXT,
|
||||
"constraintsJson" JSONB NOT NULL,
|
||||
"relevantFilesJson" JSONB NOT NULL,
|
||||
"doNotBreakRulesJson" JSONB NOT NULL,
|
||||
"validationCommandsJson" JSONB NOT NULL,
|
||||
"expectedReportFormat" TEXT NOT NULL,
|
||||
"outputImportInstructions" TEXT NOT NULL,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"status" TEXT NOT NULL DEFAULT 'draft',
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'handoff',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "CodexTask_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "CodexRunImport" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"codexTaskId" TEXT,
|
||||
"sourceRun" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"extractedReviewItemIdsJson" JSONB NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'imported',
|
||||
"payloadJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'codex_output',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "CodexRunImport_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "CurrentStateReport_projectId_slug_key" ON "CurrentStateReport"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "CurrentStateReport_projectId_readableId_key" ON "CurrentStateReport"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "CurrentStateReport_projectId_idx" ON "CurrentStateReport"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "CurrentStateReport_projectId_generatedAt_idx" ON "CurrentStateReport"("projectId", "generatedAt");
|
||||
CREATE INDEX IF NOT EXISTS "CurrentStateReport_projectId_approvalState_idx" ON "CurrentStateReport"("projectId", "approvalState");
|
||||
CREATE INDEX IF NOT EXISTS "CurrentStateReport_projectId_deletedAt_idx" ON "CurrentStateReport"("projectId", "deletedAt");
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "HandoffBundle_projectId_slug_key" ON "HandoffBundle"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "HandoffBundle_projectId_readableId_key" ON "HandoffBundle"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "HandoffBundle_projectId_idx" ON "HandoffBundle"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "HandoffBundle_projectId_target_idx" ON "HandoffBundle"("projectId", "target");
|
||||
CREATE INDEX IF NOT EXISTS "HandoffBundle_projectId_status_idx" ON "HandoffBundle"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "HandoffBundle_projectId_createdAt_idx" ON "HandoffBundle"("projectId", "createdAt");
|
||||
CREATE INDEX IF NOT EXISTS "HandoffBundle_projectId_deletedAt_idx" ON "HandoffBundle"("projectId", "deletedAt");
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "CodexTask_projectId_slug_key" ON "CodexTask"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "CodexTask_projectId_readableId_key" ON "CodexTask"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "CodexTask_projectId_idx" ON "CodexTask"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "CodexTask_projectId_handoffBundleId_idx" ON "CodexTask"("projectId", "handoffBundleId");
|
||||
CREATE INDEX IF NOT EXISTS "CodexTask_projectId_status_idx" ON "CodexTask"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "CodexTask_projectId_approvalState_idx" ON "CodexTask"("projectId", "approvalState");
|
||||
CREATE INDEX IF NOT EXISTS "CodexTask_projectId_deletedAt_idx" ON "CodexTask"("projectId", "deletedAt");
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "CodexRunImport_projectId_slug_key" ON "CodexRunImport"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "CodexRunImport_projectId_readableId_key" ON "CodexRunImport"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "CodexRunImport_projectId_idx" ON "CodexRunImport"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "CodexRunImport_projectId_codexTaskId_idx" ON "CodexRunImport"("projectId", "codexTaskId");
|
||||
CREATE INDEX IF NOT EXISTS "CodexRunImport_projectId_status_idx" ON "CodexRunImport"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "CodexRunImport_projectId_deletedAt_idx" ON "CodexRunImport"("projectId", "deletedAt");
|
||||
|
||||
ALTER TABLE "CurrentStateReport" ADD CONSTRAINT "CurrentStateReport_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "HandoffBundle" ADD CONSTRAINT "HandoffBundle_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "CodexTask" ADD CONSTRAINT "CodexTask_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "CodexTask" ADD CONSTRAINT "CodexTask_handoffBundleId_fkey" FOREIGN KEY ("handoffBundleId") REFERENCES "HandoffBundle"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "CodexRunImport" ADD CONSTRAINT "CodexRunImport_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,36 @@
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'documentation_item';
|
||||
|
||||
-- P8 Documentation / Knowledge / Memory persistence
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "DocumentationItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"content" TEXT,
|
||||
"metadataJson" JSONB,
|
||||
"trustJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'fixture_seed',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "DocumentationItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "DocumentationItem_projectId_slug_key" ON "DocumentationItem"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "DocumentationItem_projectId_readableId_key" ON "DocumentationItem"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "DocumentationItem_projectId_idx" ON "DocumentationItem"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "DocumentationItem_projectId_kind_idx" ON "DocumentationItem"("projectId", "kind");
|
||||
CREATE INDEX IF NOT EXISTS "DocumentationItem_projectId_status_idx" ON "DocumentationItem"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "DocumentationItem_projectId_approvalState_idx" ON "DocumentationItem"("projectId", "approvalState");
|
||||
CREATE INDEX IF NOT EXISTS "DocumentationItem_projectId_deletedAt_idx" ON "DocumentationItem"("projectId", "deletedAt");
|
||||
|
||||
ALTER TABLE "DocumentationItem" ADD CONSTRAINT "DocumentationItem_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,117 @@
|
||||
-- V52 Blueprint Engine persistence foundation
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'blueprint_graph';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'blueprint_node';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'blueprint_node_run';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "BlueprintGraph" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"archetypeId" TEXT NOT NULL,
|
||||
"archetypeLabel" TEXT NOT NULL,
|
||||
"depth" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'planned',
|
||||
"documentRoot" TEXT NOT NULL DEFAULT 'docs/',
|
||||
"intakeSummary" TEXT NOT NULL,
|
||||
"assumptionsJson" JSONB NOT NULL,
|
||||
"exportManifestJson" JSONB NOT NULL,
|
||||
"recommendedNextActionsJson" JSONB NOT NULL,
|
||||
"metadataJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'blueprint_engine',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "BlueprintGraph_pkey" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "BlueprintGraph_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "BlueprintNode" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"graphId" TEXT NOT NULL,
|
||||
"templateId" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"cluster" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'pending',
|
||||
"generationOrder" INTEGER NOT NULL,
|
||||
"requiredDepth" TEXT NOT NULL,
|
||||
"dependsOnJson" JSONB NOT NULL,
|
||||
"dependencyTitlesJson" JSONB NOT NULL,
|
||||
"blockedByJson" JSONB NOT NULL,
|
||||
"outputPath" TEXT NOT NULL,
|
||||
"purpose" TEXT NOT NULL,
|
||||
"requiredContextJson" JSONB NOT NULL,
|
||||
"qualityChecksJson" JSONB NOT NULL,
|
||||
"producesJson" JSONB NOT NULL,
|
||||
"promptPreview" TEXT NOT NULL,
|
||||
"contextSelectionJson" JSONB NOT NULL,
|
||||
"documentationItemId" TEXT,
|
||||
"reviewItemId" TEXT,
|
||||
"latestRunId" TEXT,
|
||||
"staleReason" TEXT,
|
||||
"metadataJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'blueprint_engine',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "BlueprintNode_pkey" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "BlueprintNode_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "BlueprintNode_graphId_fkey" FOREIGN KEY ("graphId") REFERENCES "BlueprintGraph"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "BlueprintNodeRun" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"graphId" TEXT NOT NULL,
|
||||
"nodeId" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'needs_review',
|
||||
"generatedBy" TEXT NOT NULL DEFAULT 'deterministic',
|
||||
"inputSnapshotJson" JSONB NOT NULL,
|
||||
"prompt" TEXT NOT NULL,
|
||||
"draftMarkdown" TEXT NOT NULL,
|
||||
"qualityReportJson" JSONB NOT NULL,
|
||||
"documentationItemId" TEXT,
|
||||
"reviewItemId" TEXT,
|
||||
"metadataJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'blueprint_engine',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "BlueprintNodeRun_pkey" PRIMARY KEY ("id"),
|
||||
CONSTRAINT "BlueprintNodeRun_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "BlueprintNodeRun_graphId_fkey" FOREIGN KEY ("graphId") REFERENCES "BlueprintGraph"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "BlueprintNodeRun_nodeId_fkey" FOREIGN KEY ("nodeId") REFERENCES "BlueprintNode"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "BlueprintGraph_projectId_slug_key" ON "BlueprintGraph"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "BlueprintGraph_projectId_readableId_key" ON "BlueprintGraph"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintGraph_projectId_idx" ON "BlueprintGraph"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintGraph_projectId_archetypeId_idx" ON "BlueprintGraph"("projectId", "archetypeId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintGraph_projectId_status_idx" ON "BlueprintGraph"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintGraph_projectId_deletedAt_idx" ON "BlueprintGraph"("projectId", "deletedAt");
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "BlueprintNode_graphId_templateId_key" ON "BlueprintNode"("graphId", "templateId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNode_projectId_idx" ON "BlueprintNode"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNode_projectId_graphId_idx" ON "BlueprintNode"("projectId", "graphId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNode_projectId_status_idx" ON "BlueprintNode"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNode_projectId_cluster_idx" ON "BlueprintNode"("projectId", "cluster");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNode_projectId_outputPath_idx" ON "BlueprintNode"("projectId", "outputPath");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNode_projectId_deletedAt_idx" ON "BlueprintNode"("projectId", "deletedAt");
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNodeRun_projectId_idx" ON "BlueprintNodeRun"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNodeRun_projectId_graphId_idx" ON "BlueprintNodeRun"("projectId", "graphId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNodeRun_projectId_nodeId_idx" ON "BlueprintNodeRun"("projectId", "nodeId");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNodeRun_projectId_status_idx" ON "BlueprintNodeRun"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNodeRun_projectId_createdAt_idx" ON "BlueprintNodeRun"("projectId", "createdAt");
|
||||
CREATE INDEX IF NOT EXISTS "BlueprintNodeRun_projectId_deletedAt_idx" ON "BlueprintNodeRun"("projectId", "deletedAt");
|
||||
@@ -0,0 +1,40 @@
|
||||
CREATE TABLE "BrainstormSession" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"prompt" TEXT NOT NULL,
|
||||
"scope" TEXT NOT NULL,
|
||||
"mode" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'exploring',
|
||||
"targetEntityId" TEXT,
|
||||
"targetEntityType" TEXT,
|
||||
"generatedBy" TEXT NOT NULL DEFAULT 'manual',
|
||||
"contextSummary" TEXT NOT NULL,
|
||||
"ideasJson" JSONB NOT NULL,
|
||||
"clustersJson" JSONB NOT NULL,
|
||||
"outcomesJson" JSONB NOT NULL,
|
||||
"selectedIdeaIdsJson" JSONB NOT NULL,
|
||||
"nextActionsJson" JSONB NOT NULL,
|
||||
"metadataJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'brainstorm_cpu',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "BrainstormSession_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "BrainstormSession_projectId_slug_key" ON "BrainstormSession"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX "BrainstormSession_projectId_readableId_key" ON "BrainstormSession"("projectId", "readableId");
|
||||
CREATE INDEX "BrainstormSession_projectId_idx" ON "BrainstormSession"("projectId");
|
||||
CREATE INDEX "BrainstormSession_projectId_scope_idx" ON "BrainstormSession"("projectId", "scope");
|
||||
CREATE INDEX "BrainstormSession_projectId_mode_idx" ON "BrainstormSession"("projectId", "mode");
|
||||
CREATE INDEX "BrainstormSession_projectId_status_idx" ON "BrainstormSession"("projectId", "status");
|
||||
CREATE INDEX "BrainstormSession_projectId_targetEntityType_targetEntityId_idx" ON "BrainstormSession"("projectId", "targetEntityType", "targetEntityId");
|
||||
CREATE INDEX "BrainstormSession_projectId_deletedAt_idx" ON "BrainstormSession"("projectId", "deletedAt");
|
||||
|
||||
ALTER TABLE "BrainstormSession" ADD CONSTRAINT "BrainstormSession_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,38 @@
|
||||
-- V72: persistent initiatives created from Brainstorm CPU roadmap outcomes.
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'initiative';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "Initiative" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"intent" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'proposed',
|
||||
"priority" TEXT NOT NULL DEFAULT 'normal',
|
||||
"featureIdsJson" JSONB NOT NULL DEFAULT '[]',
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"confidence" INTEGER NOT NULL DEFAULT 0,
|
||||
"sourceBrainstormId" TEXT,
|
||||
"reviewItemId" TEXT,
|
||||
"metadataJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'brainstorm_cpu',
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "Initiative_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Initiative_projectId_slug_key" ON "Initiative"("projectId", "slug");
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "Initiative_projectId_readableId_key" ON "Initiative"("projectId", "readableId");
|
||||
CREATE INDEX IF NOT EXISTS "Initiative_projectId_idx" ON "Initiative"("projectId");
|
||||
CREATE INDEX IF NOT EXISTS "Initiative_projectId_status_idx" ON "Initiative"("projectId", "status");
|
||||
CREATE INDEX IF NOT EXISTS "Initiative_projectId_approvalState_idx" ON "Initiative"("projectId", "approvalState");
|
||||
CREATE INDEX IF NOT EXISTS "Initiative_projectId_sourceBrainstormId_idx" ON "Initiative"("projectId", "sourceBrainstormId");
|
||||
CREATE INDEX IF NOT EXISTS "Initiative_projectId_deletedAt_idx" ON "Initiative"("projectId", "deletedAt");
|
||||
|
||||
ALTER TABLE "Initiative" ADD CONSTRAINT "Initiative_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,63 @@
|
||||
-- AlterEnum
|
||||
ALTER TYPE "EntityType" ADD VALUE 'release_evidence_record';
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ReleaseEvidenceRecord" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"slug" TEXT,
|
||||
"readableId" TEXT,
|
||||
"capturedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"kind" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'captured',
|
||||
"command" TEXT,
|
||||
"outputText" TEXT,
|
||||
"route" TEXT,
|
||||
"source" TEXT NOT NULL DEFAULT 'runtime_readiness',
|
||||
"confidence" INTEGER NOT NULL DEFAULT 100,
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'approved',
|
||||
"evidenceStrength" "EvidenceStrength" NOT NULL DEFAULT 'verified',
|
||||
"verificationState" "VerificationState" NOT NULL DEFAULT 'verified',
|
||||
"metadataJson" JSONB,
|
||||
"provenanceJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'api',
|
||||
"updatedBy" TEXT,
|
||||
"sourceType" TEXT NOT NULL DEFAULT 'release_evidence',
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"verifiedBy" TEXT,
|
||||
"archivedAt" TIMESTAMP(3),
|
||||
"deletedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ReleaseEvidenceRecord_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ReleaseEvidenceRecord_projectId_slug_key" ON "ReleaseEvidenceRecord"("projectId", "slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ReleaseEvidenceRecord_projectId_readableId_key" ON "ReleaseEvidenceRecord"("projectId", "readableId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReleaseEvidenceRecord_projectId_idx" ON "ReleaseEvidenceRecord"("projectId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReleaseEvidenceRecord_projectId_kind_idx" ON "ReleaseEvidenceRecord"("projectId", "kind");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReleaseEvidenceRecord_projectId_status_idx" ON "ReleaseEvidenceRecord"("projectId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReleaseEvidenceRecord_projectId_capturedAt_idx" ON "ReleaseEvidenceRecord"("projectId", "capturedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReleaseEvidenceRecord_projectId_verificationState_idx" ON "ReleaseEvidenceRecord"("projectId", "verificationState");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ReleaseEvidenceRecord_projectId_deletedAt_idx" ON "ReleaseEvidenceRecord"("projectId", "deletedAt");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ReleaseEvidenceRecord" ADD CONSTRAINT "ReleaseEvidenceRecord_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,49 @@
|
||||
CREATE TYPE "UserRole" AS ENUM ('owner', 'member');
|
||||
CREATE TYPE "ProjectAccessRole" AS ENUM ('owner', 'editor', 'reviewer', 'reader');
|
||||
|
||||
CREATE TABLE "User" (
|
||||
"id" TEXT NOT NULL,
|
||||
"username" TEXT NOT NULL,
|
||||
"passwordHash" TEXT NOT NULL,
|
||||
"role" "UserRole" NOT NULL DEFAULT 'owner',
|
||||
"credentialVersion" INTEGER NOT NULL DEFAULT 1,
|
||||
"disabledAt" TIMESTAMP(3),
|
||||
"lastLoginAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "AuthSession" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tokenHash" TEXT NOT NULL,
|
||||
"csrfToken" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"credentialVersion" INTEGER NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"revokedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "AuthSession_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ProjectMembership" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"role" "ProjectAccessRole" NOT NULL DEFAULT 'owner',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ProjectMembership_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
|
||||
CREATE UNIQUE INDEX "AuthSession_tokenHash_key" ON "AuthSession"("tokenHash");
|
||||
CREATE INDEX "AuthSession_userId_expiresAt_idx" ON "AuthSession"("userId", "expiresAt");
|
||||
CREATE INDEX "AuthSession_expiresAt_idx" ON "AuthSession"("expiresAt");
|
||||
CREATE UNIQUE INDEX "ProjectMembership_projectId_userId_key" ON "ProjectMembership"("projectId", "userId");
|
||||
CREATE INDEX "ProjectMembership_userId_idx" ON "ProjectMembership"("userId");
|
||||
|
||||
ALTER TABLE "AuthSession" ADD CONSTRAINT "AuthSession_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ProjectMembership" ADD CONSTRAINT "ProjectMembership_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ProjectMembership" ADD CONSTRAINT "ProjectMembership_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,42 @@
|
||||
CREATE TYPE "GiteaAccessMode" AS ENUM ('read_only', 'read_write');
|
||||
|
||||
CREATE TABLE "GiteaRepositoryLink" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"owner" TEXT NOT NULL,
|
||||
"repository" TEXT NOT NULL,
|
||||
"defaultBranch" TEXT NOT NULL,
|
||||
"accessMode" "GiteaAccessMode" NOT NULL DEFAULT 'read_write',
|
||||
"linkedBy" TEXT NOT NULL,
|
||||
"lastVerifiedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "GiteaRepositoryLink_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "McpAuditEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT,
|
||||
"operationId" TEXT NOT NULL,
|
||||
"actor" TEXT NOT NULL,
|
||||
"toolName" TEXT NOT NULL,
|
||||
"repository" TEXT,
|
||||
"branch" TEXT,
|
||||
"outcome" TEXT NOT NULL,
|
||||
"errorCode" TEXT,
|
||||
"durationMs" INTEGER NOT NULL,
|
||||
"metadataJson" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "McpAuditEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "GiteaRepositoryLink_projectId_key" ON "GiteaRepositoryLink"("projectId");
|
||||
CREATE UNIQUE INDEX "GiteaRepositoryLink_owner_repository_key" ON "GiteaRepositoryLink"("owner", "repository");
|
||||
CREATE INDEX "GiteaRepositoryLink_owner_repository_idx" ON "GiteaRepositoryLink"("owner", "repository");
|
||||
CREATE UNIQUE INDEX "McpAuditEvent_operationId_key" ON "McpAuditEvent"("operationId");
|
||||
CREATE INDEX "McpAuditEvent_projectId_createdAt_idx" ON "McpAuditEvent"("projectId", "createdAt");
|
||||
CREATE INDEX "McpAuditEvent_toolName_createdAt_idx" ON "McpAuditEvent"("toolName", "createdAt");
|
||||
CREATE INDEX "McpAuditEvent_outcome_createdAt_idx" ON "McpAuditEvent"("outcome", "createdAt");
|
||||
|
||||
ALTER TABLE "GiteaRepositoryLink" ADD CONSTRAINT "GiteaRepositoryLink_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "McpAuditEvent" ADD CONSTRAINT "McpAuditEvent_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,36 @@
|
||||
CREATE TABLE "ExternalIdentity" (
|
||||
"id" TEXT NOT NULL,
|
||||
"provider" TEXT NOT NULL,
|
||||
"tenantId" TEXT NOT NULL,
|
||||
"subject" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"displayName" TEXT,
|
||||
"preferredUsername" TEXT,
|
||||
"lastLoginAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ExternalIdentity_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "OidcLoginAttempt" (
|
||||
"id" TEXT NOT NULL,
|
||||
"stateHash" TEXT NOT NULL,
|
||||
"provider" TEXT NOT NULL,
|
||||
"purpose" TEXT NOT NULL,
|
||||
"userId" TEXT,
|
||||
"codeVerifier" TEXT NOT NULL,
|
||||
"nonce" TEXT NOT NULL,
|
||||
"returnTo" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "OidcLoginAttempt_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "ExternalIdentity_provider_tenantId_subject_key" ON "ExternalIdentity"("provider", "tenantId", "subject");
|
||||
CREATE UNIQUE INDEX "ExternalIdentity_provider_userId_key" ON "ExternalIdentity"("provider", "userId");
|
||||
CREATE INDEX "ExternalIdentity_userId_idx" ON "ExternalIdentity"("userId");
|
||||
CREATE UNIQUE INDEX "OidcLoginAttempt_stateHash_key" ON "OidcLoginAttempt"("stateHash");
|
||||
CREATE INDEX "OidcLoginAttempt_expiresAt_idx" ON "OidcLoginAttempt"("expiresAt");
|
||||
CREATE INDEX "OidcLoginAttempt_userId_idx" ON "OidcLoginAttempt"("userId");
|
||||
ALTER TABLE "ExternalIdentity" ADD CONSTRAINT "ExternalIdentity_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "OidcLoginAttempt" ADD CONSTRAINT "OidcLoginAttempt_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,220 @@
|
||||
CREATE TYPE "RepositoryRole" AS ENUM ('primary', 'frontend', 'backend', 'infra', 'docs', 'shared', 'other');
|
||||
CREATE TYPE "RepositorySyncStatus" AS ENUM ('unverified', 'ready', 'degraded', 'unavailable');
|
||||
CREATE TYPE "DeliveryStatus" AS ENUM ('draft', 'awaiting_approval', 'approved', 'executing', 'validating', 'pull_request_open', 'merged', 'verified', 'released', 'blocked', 'failed', 'cancelled', 'superseded');
|
||||
CREATE TYPE "DeliveryChangeOperation" AS ENUM ('create', 'update', 'delete', 'rename');
|
||||
CREATE TYPE "DeliveryValidationStatus" AS ENUM ('pending', 'passed', 'failed', 'skipped');
|
||||
CREATE TYPE "ExternalOperationStatus" AS ENUM ('prepared', 'executing', 'succeeded', 'failed', 'unknown');
|
||||
|
||||
DROP INDEX IF EXISTS "GiteaRepositoryLink_projectId_key";
|
||||
ALTER TABLE "GiteaRepositoryLink"
|
||||
ADD COLUMN "role" "RepositoryRole" NOT NULL DEFAULT 'primary',
|
||||
ADD COLUMN "isPrimary" BOOLEAN NOT NULL DEFAULT true,
|
||||
ADD COLUMN "syncStatus" "RepositorySyncStatus" NOT NULL DEFAULT 'unverified',
|
||||
ADD COLUMN "capabilitiesJson" JSONB,
|
||||
ADD COLUMN "lastSyncAt" TIMESTAMP(3);
|
||||
|
||||
CREATE INDEX "GiteaRepositoryLink_projectId_isPrimary_idx" ON "GiteaRepositoryLink"("projectId", "isPrimary");
|
||||
CREATE INDEX "GiteaRepositoryLink_projectId_role_idx" ON "GiteaRepositoryLink"("projectId", "role");
|
||||
|
||||
CREATE TABLE "DeliveryPlan" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"initiativeId" TEXT,
|
||||
"slug" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"intent" TEXT NOT NULL,
|
||||
"priority" TEXT NOT NULL DEFAULT 'normal',
|
||||
"problem" TEXT NOT NULL,
|
||||
"desiredOutcome" TEXT NOT NULL,
|
||||
"usersJson" JSONB NOT NULL DEFAULT '[]',
|
||||
"goalsJson" JSONB NOT NULL,
|
||||
"nonGoalsJson" JSONB NOT NULL DEFAULT '[]',
|
||||
"acceptanceCriteriaJson" JSONB NOT NULL,
|
||||
"implementationPlanJson" JSONB NOT NULL,
|
||||
"risksJson" JSONB NOT NULL DEFAULT '[]',
|
||||
"validationCommandsJson" JSONB NOT NULL,
|
||||
"status" "DeliveryStatus" NOT NULL DEFAULT 'awaiting_approval',
|
||||
"approvalState" "ApprovalState" NOT NULL DEFAULT 'pending',
|
||||
"approvedAt" TIMESTAMP(3),
|
||||
"approvedBy" TEXT,
|
||||
"version" INTEGER NOT NULL DEFAULT 1,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "DeliveryPlan_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "DeliveryRun" (
|
||||
"id" TEXT NOT NULL,
|
||||
"deliveryPlanId" TEXT NOT NULL,
|
||||
"repositoryLinkId" TEXT NOT NULL,
|
||||
"branch" TEXT NOT NULL,
|
||||
"baseBranch" TEXT NOT NULL,
|
||||
"baseCommitSha" TEXT,
|
||||
"headSha" TEXT,
|
||||
"status" "DeliveryStatus" NOT NULL DEFAULT 'executing',
|
||||
"pullRequestNumber" INTEGER,
|
||||
"pullRequestUrl" TEXT,
|
||||
"pullRequestTitle" TEXT,
|
||||
"pullRequestState" TEXT,
|
||||
"mergeCommitSha" TEXT,
|
||||
"startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"pullRequestOpenedAt" TIMESTAMP(3),
|
||||
"mergedAt" TIMESTAMP(3),
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "DeliveryRun_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "DeliveryFileChange" (
|
||||
"id" TEXT NOT NULL,
|
||||
"deliveryRunId" TEXT NOT NULL,
|
||||
"path" TEXT NOT NULL,
|
||||
"previousPath" TEXT,
|
||||
"operation" "DeliveryChangeOperation" NOT NULL,
|
||||
"beforeSha" TEXT,
|
||||
"afterSha" TEXT,
|
||||
"commitSha" TEXT,
|
||||
"actor" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "DeliveryFileChange_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "DeliveryValidation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"deliveryRunId" TEXT NOT NULL,
|
||||
"command" TEXT NOT NULL,
|
||||
"checkName" TEXT,
|
||||
"status" "DeliveryValidationStatus" NOT NULL DEFAULT 'pending',
|
||||
"provider" TEXT,
|
||||
"externalRunId" TEXT,
|
||||
"externalUrl" TEXT,
|
||||
"headSha" TEXT,
|
||||
"summary" TEXT,
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "DeliveryValidation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ExternalOperation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"operationId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"deliveryRunId" TEXT,
|
||||
"actor" TEXT NOT NULL,
|
||||
"action" TEXT NOT NULL,
|
||||
"targetJson" JSONB NOT NULL,
|
||||
"status" "ExternalOperationStatus" NOT NULL DEFAULT 'prepared',
|
||||
"resultJson" JSONB,
|
||||
"errorCode" TEXT,
|
||||
"startedAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ExternalOperation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "OutboxEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"eventId" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"aggregateType" TEXT NOT NULL,
|
||||
"aggregateId" TEXT NOT NULL,
|
||||
"eventType" TEXT NOT NULL,
|
||||
"payloadJson" JSONB NOT NULL,
|
||||
"attempts" INTEGER NOT NULL DEFAULT 0,
|
||||
"publishedAt" TIMESTAMP(3),
|
||||
"lastError" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "OutboxEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "DeliveryPlan_initiativeId_key" ON "DeliveryPlan"("initiativeId");
|
||||
CREATE UNIQUE INDEX "DeliveryPlan_projectId_slug_key" ON "DeliveryPlan"("projectId", "slug");
|
||||
CREATE INDEX "DeliveryPlan_projectId_status_idx" ON "DeliveryPlan"("projectId", "status");
|
||||
CREATE INDEX "DeliveryPlan_projectId_updatedAt_idx" ON "DeliveryPlan"("projectId", "updatedAt");
|
||||
CREATE UNIQUE INDEX "DeliveryRun_repositoryLinkId_branch_key" ON "DeliveryRun"("repositoryLinkId", "branch");
|
||||
CREATE INDEX "DeliveryRun_deliveryPlanId_status_idx" ON "DeliveryRun"("deliveryPlanId", "status");
|
||||
CREATE INDEX "DeliveryRun_pullRequestNumber_idx" ON "DeliveryRun"("pullRequestNumber");
|
||||
CREATE INDEX "DeliveryFileChange_deliveryRunId_createdAt_idx" ON "DeliveryFileChange"("deliveryRunId", "createdAt");
|
||||
CREATE INDEX "DeliveryFileChange_deliveryRunId_path_idx" ON "DeliveryFileChange"("deliveryRunId", "path");
|
||||
CREATE INDEX "DeliveryValidation_deliveryRunId_status_idx" ON "DeliveryValidation"("deliveryRunId", "status");
|
||||
CREATE INDEX "DeliveryValidation_deliveryRunId_headSha_idx" ON "DeliveryValidation"("deliveryRunId", "headSha");
|
||||
CREATE UNIQUE INDEX "ExternalOperation_operationId_key" ON "ExternalOperation"("operationId");
|
||||
CREATE INDEX "ExternalOperation_projectId_status_createdAt_idx" ON "ExternalOperation"("projectId", "status", "createdAt");
|
||||
CREATE INDEX "ExternalOperation_deliveryRunId_createdAt_idx" ON "ExternalOperation"("deliveryRunId", "createdAt");
|
||||
CREATE UNIQUE INDEX "OutboxEvent_eventId_key" ON "OutboxEvent"("eventId");
|
||||
CREATE INDEX "OutboxEvent_projectId_createdAt_idx" ON "OutboxEvent"("projectId", "createdAt");
|
||||
CREATE INDEX "OutboxEvent_publishedAt_createdAt_idx" ON "OutboxEvent"("publishedAt", "createdAt");
|
||||
|
||||
ALTER TABLE "DeliveryPlan" ADD CONSTRAINT "DeliveryPlan_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "DeliveryPlan" ADD CONSTRAINT "DeliveryPlan_initiativeId_fkey" FOREIGN KEY ("initiativeId") REFERENCES "Initiative"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "DeliveryRun" ADD CONSTRAINT "DeliveryRun_deliveryPlanId_fkey" FOREIGN KEY ("deliveryPlanId") REFERENCES "DeliveryPlan"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "DeliveryRun" ADD CONSTRAINT "DeliveryRun_repositoryLinkId_fkey" FOREIGN KEY ("repositoryLinkId") REFERENCES "GiteaRepositoryLink"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE "DeliveryFileChange" ADD CONSTRAINT "DeliveryFileChange_deliveryRunId_fkey" FOREIGN KEY ("deliveryRunId") REFERENCES "DeliveryRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "DeliveryValidation" ADD CONSTRAINT "DeliveryValidation_deliveryRunId_fkey" FOREIGN KEY ("deliveryRunId") REFERENCES "DeliveryRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ExternalOperation" ADD CONSTRAINT "ExternalOperation_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ExternalOperation" ADD CONSTRAINT "ExternalOperation_deliveryRunId_fkey" FOREIGN KEY ("deliveryRunId") REFERENCES "DeliveryRun"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "OutboxEvent" ADD CONSTRAINT "OutboxEvent_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
INSERT INTO "DeliveryPlan" (
|
||||
"id", "projectId", "initiativeId", "slug", "title", "intent", "priority", "problem", "desiredOutcome",
|
||||
"usersJson", "goalsJson", "nonGoalsJson", "acceptanceCriteriaJson", "implementationPlanJson", "risksJson",
|
||||
"validationCommandsJson", "status", "approvalState", "approvedAt", "approvedBy", "createdBy", "updatedBy", "createdAt", "updatedAt"
|
||||
)
|
||||
SELECT
|
||||
'delivery-plan-' || substr(md5(i."id"), 1, 20), i."projectId", i."id", COALESCE(i."slug", i."id"), i."title", i."intent", i."priority",
|
||||
COALESCE(i."metadataJson"->>'problem', i."intent"), COALESCE(i."metadataJson"->>'desiredOutcome', i."intent"),
|
||||
COALESCE(i."metadataJson"->'users', '[]'::jsonb), COALESCE(i."metadataJson"->'goals', '[]'::jsonb),
|
||||
COALESCE(i."metadataJson"->'nonGoals', '[]'::jsonb), COALESCE(i."metadataJson"->'acceptanceCriteria', '[]'::jsonb),
|
||||
COALESCE(i."metadataJson"->'implementationPlan', '[]'::jsonb), COALESCE(i."metadataJson"->'risks', '[]'::jsonb),
|
||||
COALESCE(i."metadataJson"->'validationCommands', '[]'::jsonb),
|
||||
CASE COALESCE(i."metadataJson"->>'status', 'draft')
|
||||
WHEN 'ready_for_approval' THEN 'awaiting_approval'::"DeliveryStatus"
|
||||
WHEN 'approved' THEN 'approved'::"DeliveryStatus"
|
||||
WHEN 'in_progress' THEN 'executing'::"DeliveryStatus"
|
||||
WHEN 'ready_for_review' THEN 'validating'::"DeliveryStatus"
|
||||
WHEN 'completed' THEN 'pull_request_open'::"DeliveryStatus"
|
||||
WHEN 'blocked' THEN 'blocked'::"DeliveryStatus"
|
||||
ELSE 'draft'::"DeliveryStatus"
|
||||
END,
|
||||
i."approvalState", CASE WHEN i."approvalState" = 'approved' THEN i."updatedAt" ELSE NULL END,
|
||||
CASE WHEN i."approvalState" = 'approved' THEN COALESCE(i."updatedBy", 'owner') ELSE NULL END,
|
||||
i."createdBy", i."updatedBy", i."createdAt", i."updatedAt"
|
||||
FROM "Initiative" i
|
||||
WHERE i."sourceType" = 'chatgpt_feature_delivery' AND i."deletedAt" IS NULL
|
||||
ON CONFLICT ("initiativeId") DO NOTHING;
|
||||
|
||||
INSERT INTO "DeliveryRun" (
|
||||
"id", "deliveryPlanId", "repositoryLinkId", "branch", "baseBranch", "headSha", "status",
|
||||
"pullRequestNumber", "pullRequestUrl", "pullRequestTitle", "pullRequestState", "startedAt", "pullRequestOpenedAt",
|
||||
"createdBy", "updatedBy", "createdAt", "updatedAt"
|
||||
)
|
||||
SELECT
|
||||
'delivery-run-' || substr(md5(dp."id" || l."id"), 1, 20), dp."id", l."id", i."metadataJson"->>'branch', l."defaultBranch", NULL,
|
||||
CASE COALESCE(i."metadataJson"->>'status', 'in_progress')
|
||||
WHEN 'ready_for_review' THEN 'validating'::"DeliveryStatus"
|
||||
WHEN 'completed' THEN 'pull_request_open'::"DeliveryStatus"
|
||||
ELSE 'executing'::"DeliveryStatus"
|
||||
END,
|
||||
CASE WHEN (i."metadataJson"->'pullRequest'->>'number') ~ '^[0-9]+$' THEN (i."metadataJson"->'pullRequest'->>'number')::integer ELSE NULL END,
|
||||
i."metadataJson"->'pullRequest'->>'url', i."metadataJson"->'pullRequest'->>'title',
|
||||
CASE WHEN i."metadataJson" ? 'pullRequest' THEN 'open' ELSE NULL END,
|
||||
i."updatedAt", CASE WHEN i."metadataJson" ? 'pullRequest' THEN i."updatedAt" ELSE NULL END,
|
||||
COALESCE(i."updatedBy", i."createdBy"), i."updatedBy", i."createdAt", i."updatedAt"
|
||||
FROM "DeliveryPlan" dp
|
||||
JOIN "Initiative" i ON i."id" = dp."initiativeId"
|
||||
JOIN LATERAL (
|
||||
SELECT gl.* FROM "GiteaRepositoryLink" gl
|
||||
WHERE gl."projectId" = dp."projectId"
|
||||
ORDER BY gl."isPrimary" DESC, gl."createdAt" ASC
|
||||
LIMIT 1
|
||||
) l ON true
|
||||
WHERE COALESCE(i."metadataJson"->>'branch', '') <> ''
|
||||
ON CONFLICT ("repositoryLinkId", "branch") DO NOTHING;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "DeliveryPlan" ADD COLUMN "reviewFeedback" TEXT;
|
||||
@@ -0,0 +1,76 @@
|
||||
CREATE TYPE "AnalysisJobKind" AS ENUM ('portfolio_health');
|
||||
CREATE TYPE "AnalysisJobStatus" AS ENUM ('queued', 'running', 'succeeded', 'failed', 'cancelled');
|
||||
CREATE TYPE "AnalysisJobItemStatus" AS ENUM ('pending', 'running', 'succeeded', 'failed', 'cancelled');
|
||||
|
||||
CREATE TABLE "AnalysisJob" (
|
||||
"id" TEXT NOT NULL,
|
||||
"kind" "AnalysisJobKind" NOT NULL DEFAULT 'portfolio_health',
|
||||
"status" "AnalysisJobStatus" NOT NULL DEFAULT 'queued',
|
||||
"actor" TEXT NOT NULL,
|
||||
"requestJson" JSONB NOT NULL,
|
||||
"requestHash" TEXT NOT NULL,
|
||||
"activeDedupeKey" TEXT,
|
||||
"progressCurrent" INTEGER NOT NULL DEFAULT 0,
|
||||
"progressTotal" INTEGER NOT NULL DEFAULT 0,
|
||||
"summaryText" TEXT,
|
||||
"summaryJson" JSONB,
|
||||
"errorCode" TEXT,
|
||||
"cancelRequestedAt" TIMESTAMP(3),
|
||||
"queuedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"startedAt" TIMESTAMP(3),
|
||||
"heartbeatAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "AnalysisJob_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "AnalysisJobItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"jobId" TEXT NOT NULL,
|
||||
"repositoryLinkId" TEXT,
|
||||
"projectId" TEXT,
|
||||
"projectSlug" TEXT,
|
||||
"projectName" TEXT,
|
||||
"owner" TEXT NOT NULL,
|
||||
"repository" TEXT NOT NULL,
|
||||
"defaultBranch" TEXT NOT NULL,
|
||||
"accessMode" "GiteaAccessMode" NOT NULL,
|
||||
"sequence" INTEGER NOT NULL,
|
||||
"status" "AnalysisJobItemStatus" NOT NULL DEFAULT 'pending',
|
||||
"summary" TEXT,
|
||||
"detailJson" JSONB,
|
||||
"findingCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"errorCode" TEXT,
|
||||
"startedAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "AnalysisJobItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "AnalysisJob_activeDedupeKey_key" ON "AnalysisJob"("activeDedupeKey");
|
||||
CREATE INDEX "AnalysisJob_status_queuedAt_idx" ON "AnalysisJob"("status", "queuedAt");
|
||||
CREATE INDEX "AnalysisJob_actor_createdAt_idx" ON "AnalysisJob"("actor", "createdAt");
|
||||
CREATE INDEX "AnalysisJob_expiresAt_idx" ON "AnalysisJob"("expiresAt");
|
||||
CREATE UNIQUE INDEX "AnalysisJobItem_jobId_owner_repository_key" ON "AnalysisJobItem"("jobId", "owner", "repository");
|
||||
CREATE INDEX "AnalysisJobItem_jobId_sequence_idx" ON "AnalysisJobItem"("jobId", "sequence");
|
||||
CREATE INDEX "AnalysisJobItem_projectId_createdAt_idx" ON "AnalysisJobItem"("projectId", "createdAt");
|
||||
CREATE INDEX "AnalysisJobItem_repositoryLinkId_createdAt_idx" ON "AnalysisJobItem"("repositoryLinkId", "createdAt");
|
||||
|
||||
ALTER TABLE "AnalysisJobItem" ADD CONSTRAINT "AnalysisJobItem_jobId_fkey" FOREIGN KEY ("jobId") REFERENCES "AnalysisJob"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "AnalysisJobItem" ADD CONSTRAINT "AnalysisJobItem_repositoryLinkId_fkey" FOREIGN KEY ("repositoryLinkId") REFERENCES "GiteaRepositoryLink"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
CREATE TABLE "AnalysisWorkerHeartbeat" (
|
||||
"id" TEXT NOT NULL,
|
||||
"instanceId" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"activeJobId" TEXT,
|
||||
"detail" TEXT,
|
||||
"startedAt" TIMESTAMP(3) NOT NULL,
|
||||
"lastSeenAt" TIMESTAMP(3) NOT NULL,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "AnalysisWorkerHeartbeat_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
CREATE INDEX "AnalysisWorkerHeartbeat_lastSeenAt_idx" ON "AnalysisWorkerHeartbeat"("lastSeenAt");
|
||||
@@ -0,0 +1,129 @@
|
||||
-- Closed-loop repository findings, Gitea issue synchronization and investigations.
|
||||
CREATE TYPE "FindingSeverity" AS ENUM ('info', 'warning', 'critical');
|
||||
CREATE TYPE "FindingStatus" AS ENUM ('new', 'triaged', 'issue_open', 'investigating', 'planned', 'fixing', 'verifying', 'resolved', 'regressed', 'suppressed');
|
||||
CREATE TYPE "InvestigationStatus" AS ENUM ('collecting', 'ready', 'concluded', 'planned', 'fixing', 'verifying', 'resolved', 'failed', 'cancelled');
|
||||
CREATE TYPE "IssueSyncMode" AS ENUM ('manual', 'review', 'automatic');
|
||||
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'repository_finding';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'finding_investigation';
|
||||
ALTER TYPE "EntityType" ADD VALUE IF NOT EXISTS 'gitea_issue';
|
||||
|
||||
CREATE TABLE "RepositoryFinding" (
|
||||
"id" TEXT NOT NULL,
|
||||
"fingerprint" TEXT NOT NULL,
|
||||
"projectId" TEXT,
|
||||
"repositoryLinkId" TEXT,
|
||||
"owner" TEXT NOT NULL,
|
||||
"repository" TEXT NOT NULL,
|
||||
"ruleCode" TEXT NOT NULL,
|
||||
"subject" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"message" TEXT NOT NULL,
|
||||
"severity" "FindingSeverity" NOT NULL,
|
||||
"confidence" INTEGER NOT NULL DEFAULT 90,
|
||||
"riskScore" INTEGER NOT NULL DEFAULT 0,
|
||||
"status" "FindingStatus" NOT NULL DEFAULT 'new',
|
||||
"occurrenceCount" INTEGER NOT NULL DEFAULT 1,
|
||||
"clearCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"firstSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"resolvedAt" TIMESTAMP(3),
|
||||
"suppressedAt" TIMESTAMP(3),
|
||||
"suppressedUntil" TIMESTAMP(3),
|
||||
"suppressionReason" TEXT,
|
||||
"lastAnalysisJobId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "RepositoryFinding_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "FindingOccurrence" (
|
||||
"id" TEXT NOT NULL,
|
||||
"findingId" TEXT NOT NULL,
|
||||
"analysisJobItemId" TEXT NOT NULL,
|
||||
"observed" BOOLEAN NOT NULL DEFAULT true,
|
||||
"detailJson" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "FindingOccurrence_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "GiteaIssueLink" (
|
||||
"id" TEXT NOT NULL,
|
||||
"findingId" TEXT NOT NULL,
|
||||
"owner" TEXT NOT NULL,
|
||||
"repository" TEXT NOT NULL,
|
||||
"issueNumber" INTEGER NOT NULL,
|
||||
"issueUrl" TEXT NOT NULL,
|
||||
"state" TEXT NOT NULL DEFAULT 'open',
|
||||
"title" TEXT NOT NULL,
|
||||
"bodyFingerprint" TEXT NOT NULL,
|
||||
"lastSyncedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"closedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "GiteaIssueLink_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "FindingInvestigation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"findingId" TEXT NOT NULL,
|
||||
"projectId" TEXT,
|
||||
"deliveryPlanId" TEXT,
|
||||
"status" "InvestigationStatus" NOT NULL DEFAULT 'collecting',
|
||||
"actor" TEXT NOT NULL,
|
||||
"contextJson" JSONB NOT NULL,
|
||||
"diagnosis" TEXT,
|
||||
"rootCause" TEXT,
|
||||
"proposedChangesJson" JSONB NOT NULL DEFAULT '[]',
|
||||
"confidence" INTEGER,
|
||||
"conclusion" TEXT,
|
||||
"startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"concludedAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "FindingInvestigation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "FindingAutomationPolicy" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"issueSyncMode" "IssueSyncMode" NOT NULL DEFAULT 'review',
|
||||
"minimumSeverity" "FindingSeverity" NOT NULL DEFAULT 'warning',
|
||||
"minimumOccurrences" INTEGER NOT NULL DEFAULT 2,
|
||||
"maxIssuesPerRun" INTEGER NOT NULL DEFAULT 5,
|
||||
"autoCloseResolved" BOOLEAN NOT NULL DEFAULT true,
|
||||
"autoReopenRegressed" BOOLEAN NOT NULL DEFAULT true,
|
||||
"scheduledAnalysis" BOOLEAN NOT NULL DEFAULT true,
|
||||
"scheduleMinutes" INTEGER NOT NULL DEFAULT 1440,
|
||||
"updatedBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "FindingAutomationPolicy_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "RepositoryFinding_fingerprint_key" ON "RepositoryFinding"("fingerprint");
|
||||
CREATE INDEX "RepositoryFinding_projectId_status_severity_idx" ON "RepositoryFinding"("projectId", "status", "severity");
|
||||
CREATE INDEX "RepositoryFinding_repositoryLinkId_status_idx" ON "RepositoryFinding"("repositoryLinkId", "status");
|
||||
CREATE INDEX "RepositoryFinding_owner_repository_status_idx" ON "RepositoryFinding"("owner", "repository", "status");
|
||||
CREATE INDEX "RepositoryFinding_lastSeenAt_idx" ON "RepositoryFinding"("lastSeenAt");
|
||||
CREATE UNIQUE INDEX "FindingOccurrence_findingId_analysisJobItemId_key" ON "FindingOccurrence"("findingId", "analysisJobItemId");
|
||||
CREATE INDEX "FindingOccurrence_analysisJobItemId_idx" ON "FindingOccurrence"("analysisJobItemId");
|
||||
CREATE UNIQUE INDEX "GiteaIssueLink_findingId_key" ON "GiteaIssueLink"("findingId");
|
||||
CREATE UNIQUE INDEX "GiteaIssueLink_owner_repository_issueNumber_key" ON "GiteaIssueLink"("owner", "repository", "issueNumber");
|
||||
CREATE INDEX "GiteaIssueLink_state_updatedAt_idx" ON "GiteaIssueLink"("state", "updatedAt");
|
||||
CREATE UNIQUE INDEX "FindingInvestigation_deliveryPlanId_key" ON "FindingInvestigation"("deliveryPlanId");
|
||||
CREATE INDEX "FindingInvestigation_findingId_createdAt_idx" ON "FindingInvestigation"("findingId", "createdAt");
|
||||
CREATE INDEX "FindingInvestigation_projectId_status_idx" ON "FindingInvestigation"("projectId", "status");
|
||||
CREATE UNIQUE INDEX "FindingAutomationPolicy_projectId_key" ON "FindingAutomationPolicy"("projectId");
|
||||
|
||||
ALTER TABLE "RepositoryFinding" ADD CONSTRAINT "RepositoryFinding_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "RepositoryFinding" ADD CONSTRAINT "RepositoryFinding_repositoryLinkId_fkey" FOREIGN KEY ("repositoryLinkId") REFERENCES "GiteaRepositoryLink"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "FindingOccurrence" ADD CONSTRAINT "FindingOccurrence_findingId_fkey" FOREIGN KEY ("findingId") REFERENCES "RepositoryFinding"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "FindingOccurrence" ADD CONSTRAINT "FindingOccurrence_analysisJobItemId_fkey" FOREIGN KEY ("analysisJobItemId") REFERENCES "AnalysisJobItem"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "GiteaIssueLink" ADD CONSTRAINT "GiteaIssueLink_findingId_fkey" FOREIGN KEY ("findingId") REFERENCES "RepositoryFinding"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "FindingInvestigation" ADD CONSTRAINT "FindingInvestigation_findingId_fkey" FOREIGN KEY ("findingId") REFERENCES "RepositoryFinding"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "FindingInvestigation" ADD CONSTRAINT "FindingInvestigation_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "FindingInvestigation" ADD CONSTRAINT "FindingInvestigation_deliveryPlanId_fkey" FOREIGN KEY ("deliveryPlanId") REFERENCES "DeliveryPlan"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "FindingAutomationPolicy" ADD CONSTRAINT "FindingAutomationPolicy_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,30 @@
|
||||
-- Durable Gitea portfolio discovery and onboarding state.
|
||||
CREATE TYPE "PortfolioRepositoryStatus" AS ENUM ('discovered', 'onboarded', 'excluded', 'unavailable');
|
||||
|
||||
CREATE TABLE "PortfolioRepository" (
|
||||
"id" TEXT NOT NULL,
|
||||
"owner" TEXT NOT NULL,
|
||||
"repository" TEXT NOT NULL,
|
||||
"projectId" TEXT,
|
||||
"description" TEXT,
|
||||
"defaultBranch" TEXT NOT NULL,
|
||||
"htmlUrl" TEXT,
|
||||
"private" BOOLEAN NOT NULL DEFAULT true,
|
||||
"archived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"canPush" BOOLEAN NOT NULL DEFAULT false,
|
||||
"status" "PortfolioRepositoryStatus" NOT NULL DEFAULT 'discovered',
|
||||
"exclusionReason" TEXT,
|
||||
"firstSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"onboardedAt" TIMESTAMP(3),
|
||||
"excludedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "PortfolioRepository_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "PortfolioRepository_owner_repository_key" ON "PortfolioRepository"("owner", "repository");
|
||||
CREATE INDEX "PortfolioRepository_status_lastSeenAt_idx" ON "PortfolioRepository"("status", "lastSeenAt");
|
||||
CREATE INDEX "PortfolioRepository_projectId_idx" ON "PortfolioRepository"("projectId");
|
||||
|
||||
ALTER TABLE "PortfolioRepository" ADD CONSTRAINT "PortfolioRepository_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TYPE "AnalysisJobStatus" ADD VALUE IF NOT EXISTS 'partial';
|
||||
@@ -0,0 +1,25 @@
|
||||
CREATE TABLE "ProjectSource" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"repositoryLinkId" TEXT,
|
||||
"title" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL DEFAULT 'document',
|
||||
"inputMode" TEXT NOT NULL DEFAULT 'git',
|
||||
"path" TEXT,
|
||||
"url" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'processed',
|
||||
"branch" TEXT,
|
||||
"contentSha" TEXT,
|
||||
"commitSha" TEXT,
|
||||
"lastSyncedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ProjectSource_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
CREATE UNIQUE INDEX "ProjectSource_repositoryLinkId_path_key" ON "ProjectSource"("repositoryLinkId", "path");
|
||||
CREATE INDEX "ProjectSource_projectId_status_idx" ON "ProjectSource"("projectId", "status");
|
||||
CREATE INDEX "ProjectSource_repositoryLinkId_lastSyncedAt_idx" ON "ProjectSource"("repositoryLinkId", "lastSyncedAt");
|
||||
ALTER TABLE "ProjectSource" ADD CONSTRAINT "ProjectSource_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ProjectSource" ADD CONSTRAINT "ProjectSource_repositoryLinkId_fkey" FOREIGN KEY ("repositoryLinkId") REFERENCES "GiteaRepositoryLink"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Historical fixture and smoke records are useful evidence, but were never
|
||||
-- real owner decisions. Close only those narrowly identified pending items.
|
||||
UPDATE "ReviewQueueItem"
|
||||
SET
|
||||
"status" = 'rejected',
|
||||
"approvalState" = 'rejected',
|
||||
"notes" = CASE
|
||||
WHEN "notes" IS NULL OR "notes" = '' THEN 'Automatically closed: synthetic seed or smoke evidence is not a human attention item.'
|
||||
ELSE "notes" || E'\nAutomatically closed: synthetic seed or smoke evidence is not a human attention item.'
|
||||
END,
|
||||
"updatedBy" = 'attention_policy_migration',
|
||||
"updatedAt" = CURRENT_TIMESTAMP
|
||||
WHERE
|
||||
"status" = 'pending'
|
||||
AND (
|
||||
"createdBy" = 'seed'
|
||||
OR LOWER("source") LIKE '%smoke%'
|
||||
OR LOWER("sourceType") LIKE '%smoke%'
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE "AutonomyExecutorHeartbeat" (
|
||||
"id" TEXT NOT NULL,
|
||||
"instanceId" TEXT NOT NULL,
|
||||
"runId" TEXT,
|
||||
"status" TEXT NOT NULL,
|
||||
"activeProjectId" TEXT,
|
||||
"detail" TEXT,
|
||||
"startedAt" TIMESTAMP(3) NOT NULL,
|
||||
"lastSeenAt" TIMESTAMP(3) NOT NULL,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "AutonomyExecutorHeartbeat_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE INDEX "AutonomyExecutorHeartbeat_lastSeenAt_idx" ON "AutonomyExecutorHeartbeat"("lastSeenAt");
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
-- Durable cross-domain work graph, completion contract, saved views and diagnostics.
|
||||
-- Existing domain records remain authoritative for their domain; these tables provide
|
||||
-- the shared operating-system projection and its durable dependency/audit edges.
|
||||
|
||||
CREATE TABLE "WorkGraphNode" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"stableKey" TEXT NOT NULL,
|
||||
"source" TEXT NOT NULL,
|
||||
"sourceId" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"canonicalLifecycle" TEXT NOT NULL DEFAULT 'ready',
|
||||
"domainLifecycle" TEXT NOT NULL DEFAULT 'pending',
|
||||
"scope" TEXT NOT NULL DEFAULT 'committed',
|
||||
"priority" INTEGER NOT NULL DEFAULT 50,
|
||||
"phase" TEXT,
|
||||
"risk" TEXT NOT NULL DEFAULT 'normal',
|
||||
"blockingStatus" TEXT NOT NULL DEFAULT 'open',
|
||||
"executionEligibility" TEXT NOT NULL DEFAULT 'blocked',
|
||||
"blockReason" TEXT,
|
||||
"owner" TEXT,
|
||||
"leaseToken" TEXT,
|
||||
"leaseExpiresAt" TIMESTAMP(3),
|
||||
"attemptCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"consecutiveFailureCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"recoveryStartedAt" TIMESTAMP(3),
|
||||
"lastMeaningfulProgressAt" TIMESTAMP(3),
|
||||
"completionEvidenceJson" JSONB,
|
||||
"metadataJson" JSONB,
|
||||
"supersededById" TEXT,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "WorkGraphNode_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "WorkGraphDependency" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"nodeId" TEXT NOT NULL,
|
||||
"dependsOnNodeId" TEXT NOT NULL,
|
||||
"dependencyType" TEXT NOT NULL DEFAULT 'blocks',
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "WorkGraphDependency_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "WorkGraphAuditEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"nodeId" TEXT,
|
||||
"eventType" TEXT NOT NULL,
|
||||
"actor" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"payloadJson" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "WorkGraphAuditEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "WorkGraphEvidence" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"nodeId" TEXT NOT NULL,
|
||||
"kind" TEXT NOT NULL,
|
||||
"referenceType" TEXT NOT NULL,
|
||||
"referenceId" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'observed',
|
||||
"summary" TEXT NOT NULL,
|
||||
"metadataJson" JSONB,
|
||||
"verifiedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "WorkGraphEvidence_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ProjectDefinitionOfDone" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"requirementsJson" JSONB NOT NULL,
|
||||
"scopePolicyJson" JSONB NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'incomplete',
|
||||
"satisfiedCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"requirementCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"lastEvaluatedAt" TIMESTAMP(3),
|
||||
"lastEvidenceAt" TIMESTAMP(3),
|
||||
"evaluationJson" JSONB,
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"updatedBy" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ProjectDefinitionOfDone_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ProjectSavedView" (
|
||||
"id" TEXT NOT NULL,
|
||||
"ownerKey" TEXT NOT NULL,
|
||||
"projectId" TEXT,
|
||||
"name" TEXT NOT NULL,
|
||||
"scope" TEXT NOT NULL DEFAULT 'portfolio',
|
||||
"filtersJson" JSONB NOT NULL,
|
||||
"isPinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ProjectSavedView_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "DiagnosticRun" (
|
||||
"id" TEXT NOT NULL,
|
||||
"projectId" TEXT,
|
||||
"scope" TEXT NOT NULL DEFAULT 'platform',
|
||||
"status" TEXT NOT NULL DEFAULT 'running',
|
||||
"summary" TEXT,
|
||||
"checksJson" JSONB NOT NULL,
|
||||
"repairPlanJson" JSONB,
|
||||
"startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"createdBy" TEXT NOT NULL DEFAULT 'system',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "DiagnosticRun_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "WorkGraphNode_projectId_stableKey_key" ON "WorkGraphNode"("projectId", "stableKey");
|
||||
CREATE UNIQUE INDEX "WorkGraphNode_projectId_source_sourceId_key" ON "WorkGraphNode"("projectId", "source", "sourceId");
|
||||
CREATE INDEX "WorkGraphNode_projectId_executionEligibility_priority_idx" ON "WorkGraphNode"("projectId", "executionEligibility", "priority");
|
||||
CREATE INDEX "WorkGraphNode_projectId_canonicalLifecycle_idx" ON "WorkGraphNode"("projectId", "canonicalLifecycle");
|
||||
CREATE INDEX "WorkGraphNode_projectId_scope_idx" ON "WorkGraphNode"("projectId", "scope");
|
||||
CREATE INDEX "WorkGraphNode_projectId_leaseExpiresAt_idx" ON "WorkGraphNode"("projectId", "leaseExpiresAt");
|
||||
CREATE INDEX "WorkGraphNode_projectId_updatedAt_idx" ON "WorkGraphNode"("projectId", "updatedAt");
|
||||
CREATE INDEX "WorkGraphNode_projectId_supersededById_idx" ON "WorkGraphNode"("projectId", "supersededById");
|
||||
|
||||
CREATE UNIQUE INDEX "WorkGraphDependency_nodeId_dependsOnNodeId_key" ON "WorkGraphDependency"("nodeId", "dependsOnNodeId");
|
||||
CREATE INDEX "WorkGraphDependency_projectId_nodeId_idx" ON "WorkGraphDependency"("projectId", "nodeId");
|
||||
CREATE INDEX "WorkGraphDependency_projectId_dependsOnNodeId_idx" ON "WorkGraphDependency"("projectId", "dependsOnNodeId");
|
||||
|
||||
CREATE INDEX "WorkGraphAuditEvent_projectId_createdAt_idx" ON "WorkGraphAuditEvent"("projectId", "createdAt");
|
||||
CREATE INDEX "WorkGraphAuditEvent_projectId_nodeId_createdAt_idx" ON "WorkGraphAuditEvent"("projectId", "nodeId", "createdAt");
|
||||
CREATE INDEX "WorkGraphAuditEvent_projectId_eventType_idx" ON "WorkGraphAuditEvent"("projectId", "eventType");
|
||||
|
||||
CREATE UNIQUE INDEX "WorkGraphEvidence_nodeId_kind_referenceType_referenceId_key" ON "WorkGraphEvidence"("nodeId", "kind", "referenceType", "referenceId");
|
||||
CREATE INDEX "WorkGraphEvidence_projectId_nodeId_idx" ON "WorkGraphEvidence"("projectId", "nodeId");
|
||||
CREATE INDEX "WorkGraphEvidence_projectId_status_idx" ON "WorkGraphEvidence"("projectId", "status");
|
||||
|
||||
CREATE UNIQUE INDEX "ProjectDefinitionOfDone_projectId_key" ON "ProjectDefinitionOfDone"("projectId");
|
||||
CREATE INDEX "ProjectDefinitionOfDone_status_lastEvaluatedAt_idx" ON "ProjectDefinitionOfDone"("status", "lastEvaluatedAt");
|
||||
|
||||
CREATE UNIQUE INDEX "ProjectSavedView_ownerKey_scope_name_key" ON "ProjectSavedView"("ownerKey", "scope", "name");
|
||||
CREATE INDEX "ProjectSavedView_ownerKey_scope_updatedAt_idx" ON "ProjectSavedView"("ownerKey", "scope", "updatedAt");
|
||||
CREATE INDEX "ProjectSavedView_projectId_updatedAt_idx" ON "ProjectSavedView"("projectId", "updatedAt");
|
||||
|
||||
CREATE INDEX "DiagnosticRun_projectId_createdAt_idx" ON "DiagnosticRun"("projectId", "createdAt");
|
||||
CREATE INDEX "DiagnosticRun_scope_status_createdAt_idx" ON "DiagnosticRun"("scope", "status", "createdAt");
|
||||
|
||||
ALTER TABLE "WorkGraphNode" ADD CONSTRAINT "WorkGraphNode_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphNode" ADD CONSTRAINT "WorkGraphNode_supersededById_fkey" FOREIGN KEY ("supersededById") REFERENCES "WorkGraphNode"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphDependency" ADD CONSTRAINT "WorkGraphDependency_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphDependency" ADD CONSTRAINT "WorkGraphDependency_nodeId_fkey" FOREIGN KEY ("nodeId") REFERENCES "WorkGraphNode"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphDependency" ADD CONSTRAINT "WorkGraphDependency_dependsOnNodeId_fkey" FOREIGN KEY ("dependsOnNodeId") REFERENCES "WorkGraphNode"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphAuditEvent" ADD CONSTRAINT "WorkGraphAuditEvent_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphAuditEvent" ADD CONSTRAINT "WorkGraphAuditEvent_nodeId_fkey" FOREIGN KEY ("nodeId") REFERENCES "WorkGraphNode"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphEvidence" ADD CONSTRAINT "WorkGraphEvidence_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "WorkGraphEvidence" ADD CONSTRAINT "WorkGraphEvidence_nodeId_fkey" FOREIGN KEY ("nodeId") REFERENCES "WorkGraphNode"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ProjectDefinitionOfDone" ADD CONSTRAINT "ProjectDefinitionOfDone_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ProjectSavedView" ADD CONSTRAINT "ProjectSavedView_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "DiagnosticRun" ADD CONSTRAINT "DiagnosticRun_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Durable per-user project pins. Saved views reference these pins rather than
|
||||
-- pretending that a view-level bookmark can identify projects on its own.
|
||||
|
||||
CREATE TABLE "ProjectPortfolioPin" (
|
||||
"id" TEXT NOT NULL,
|
||||
"ownerKey" TEXT NOT NULL,
|
||||
"projectId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "ProjectPortfolioPin_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "ProjectPortfolioPin_ownerKey_projectId_key" ON "ProjectPortfolioPin"("ownerKey", "projectId");
|
||||
CREATE INDEX "ProjectPortfolioPin_ownerKey_createdAt_idx" ON "ProjectPortfolioPin"("ownerKey", "createdAt");
|
||||
CREATE INDEX "ProjectPortfolioPin_projectId_idx" ON "ProjectPortfolioPin"("projectId");
|
||||
|
||||
ALTER TABLE "ProjectPortfolioPin" ADD CONSTRAINT "ProjectPortfolioPin_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -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"
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,828 @@
|
||||
import {
|
||||
ApprovalState,
|
||||
EvidenceStrength,
|
||||
FeatureLifecycle,
|
||||
FeatureStatus,
|
||||
ReviewStatus,
|
||||
PrismaClient,
|
||||
VerificationState,
|
||||
type Prisma,
|
||||
} from "@prisma/client";
|
||||
import {
|
||||
findProject,
|
||||
getWorkspaceRead,
|
||||
} from "../src/fixtures/projectFixtures.js";
|
||||
import { contextPackFixtures } from "../src/fixtures/contextPackFixtures.js";
|
||||
import { knowledgeFixtures } from "../src/fixtures/knowledgeFixtures.js";
|
||||
import { memoryRuleFixtures } from "../src/fixtures/memoryRuleFixtures.js";
|
||||
import { captureFixtures } from "../src/fixtures/captureFixtures.js";
|
||||
import { reviewQueueFixtures } from "../src/fixtures/reviewQueueFixtures.js";
|
||||
import {
|
||||
evidenceFixtures,
|
||||
featureFixtures,
|
||||
featureGroupFixtures,
|
||||
} from "../src/fixtures/featureFixtures.js";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
const widefrog = findProject("widefrog");
|
||||
|
||||
const toJson = (value: unknown): Prisma.InputJsonValue =>
|
||||
JSON.parse(JSON.stringify(value)) as Prisma.InputJsonValue;
|
||||
|
||||
const main = async () => {
|
||||
if (!widefrog) {
|
||||
throw new Error("WideFrog fixture is missing; cannot seed P2 database.");
|
||||
}
|
||||
|
||||
const project = await prisma.project.upsert({
|
||||
where: { slug: widefrog.id },
|
||||
create: {
|
||||
slug: widefrog.id,
|
||||
readableId: widefrog.id,
|
||||
name: widefrog.name,
|
||||
description: widefrog.description,
|
||||
domain: widefrog.domain,
|
||||
status: widefrog.status,
|
||||
health: widefrog.health,
|
||||
healthStatus: widefrog.healthStatus,
|
||||
activeContextPackId: widefrog.activeContextPackId,
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
createdAt: new Date(widefrog.createdAt),
|
||||
},
|
||||
update: {
|
||||
readableId: widefrog.id,
|
||||
name: widefrog.name,
|
||||
description: widefrog.description,
|
||||
domain: widefrog.domain,
|
||||
status: widefrog.status,
|
||||
health: widefrog.health,
|
||||
healthStatus: widefrog.healthStatus,
|
||||
activeContextPackId: widefrog.activeContextPackId,
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.projectDNA.upsert({
|
||||
where: { projectId: project.id },
|
||||
create: {
|
||||
projectId: project.id,
|
||||
vision: widefrog.dna.vision,
|
||||
goalsJson: toJson(widefrog.dna.goals),
|
||||
nonGoalsJson: toJson(widefrog.dna.nonGoals),
|
||||
targetAudience: widefrog.dna.targetAudience,
|
||||
principlesJson: toJson(widefrog.dna.principles),
|
||||
metricsJson: toJson(widefrog.dna.successMetrics),
|
||||
maturityStage: widefrog.dna.maturityStage,
|
||||
revision: widefrog.dna.revision,
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
},
|
||||
update: {
|
||||
vision: widefrog.dna.vision,
|
||||
goalsJson: toJson(widefrog.dna.goals),
|
||||
nonGoalsJson: toJson(widefrog.dna.nonGoals),
|
||||
targetAudience: widefrog.dna.targetAudience,
|
||||
principlesJson: toJson(widefrog.dna.principles),
|
||||
metricsJson: toJson(widefrog.dna.successMetrics),
|
||||
maturityStage: widefrog.dna.maturityStage,
|
||||
revision: widefrog.dna.revision,
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
},
|
||||
});
|
||||
|
||||
const workspaceRead = getWorkspaceRead(widefrog);
|
||||
const workspaceState = widefrog.workspaceState;
|
||||
|
||||
if (workspaceState) {
|
||||
await prisma.workspaceState.upsert({
|
||||
where: { projectId: project.id },
|
||||
create: {
|
||||
projectId: project.id,
|
||||
activeContextPackId: workspaceState.activeContextPackId,
|
||||
primaryObjective: workspaceState.primaryObjective,
|
||||
activeSection: workspaceState.activeSection,
|
||||
notesJson: toJson({
|
||||
workspaceState,
|
||||
focusAreas: workspaceRead.focusAreas,
|
||||
activeFocusAreaId: workspaceRead.activeFocusAreaId,
|
||||
currentStateSummary: workspaceRead.currentStateSummary,
|
||||
healthSummary: workspaceRead.healthSummary,
|
||||
}),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
},
|
||||
update: {
|
||||
activeContextPackId: workspaceState.activeContextPackId,
|
||||
primaryObjective: workspaceState.primaryObjective,
|
||||
activeSection: workspaceState.activeSection,
|
||||
notesJson: toJson({
|
||||
workspaceState,
|
||||
focusAreas: workspaceRead.focusAreas,
|
||||
activeFocusAreaId: workspaceRead.activeFocusAreaId,
|
||||
currentStateSummary: workspaceRead.currentStateSummary,
|
||||
healthSummary: workspaceRead.healthSummary,
|
||||
}),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const seededProjects = new Map([[widefrog.id, project.id]]);
|
||||
|
||||
for (const group of featureGroupFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(group.projectId)!;
|
||||
await prisma.featureGroup.upsert({
|
||||
where: {
|
||||
projectId_slug: {
|
||||
projectId,
|
||||
slug: group.id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
projectId,
|
||||
slug: group.id,
|
||||
readableId: group.id,
|
||||
name: group.name,
|
||||
description: group.description,
|
||||
focusArea: group.focusArea,
|
||||
},
|
||||
update: {
|
||||
readableId: group.id,
|
||||
name: group.name,
|
||||
description: group.description,
|
||||
focusArea: group.focusArea,
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const mapFeatureStatus = (status: string): FeatureStatus => {
|
||||
if (status === "Done") return FeatureStatus.done;
|
||||
if (status === "In Progress") return FeatureStatus.in_progress;
|
||||
return FeatureStatus.todo;
|
||||
};
|
||||
|
||||
const mapFeatureLifecycle = (feature: { lifecycle?: string; status: string }): FeatureLifecycle => {
|
||||
if (feature.lifecycle && feature.lifecycle in FeatureLifecycle) {
|
||||
return FeatureLifecycle[feature.lifecycle as keyof typeof FeatureLifecycle];
|
||||
}
|
||||
if (feature.status === "Done") return FeatureLifecycle.verified;
|
||||
if (feature.status === "In Progress") return FeatureLifecycle.active;
|
||||
return FeatureLifecycle.planned;
|
||||
};
|
||||
|
||||
const mapVerificationState = (status: string): VerificationState => {
|
||||
if (status === "Done") return VerificationState.verified;
|
||||
if (status === "In Progress") return VerificationState.needs_evidence;
|
||||
return VerificationState.unverified;
|
||||
};
|
||||
|
||||
const mapEvidenceStrength = (confidence: number): EvidenceStrength => {
|
||||
if (confidence >= 95) return EvidenceStrength.verified;
|
||||
if (confidence >= 85) return EvidenceStrength.strong;
|
||||
if (confidence >= 70) return EvidenceStrength.medium;
|
||||
return EvidenceStrength.weak;
|
||||
};
|
||||
|
||||
const mapApprovalState = (approvalState: string): ApprovalState => {
|
||||
if (approvalState === "approved") return ApprovalState.approved;
|
||||
if (approvalState === "rejected") return ApprovalState.rejected;
|
||||
if (approvalState === "blocked") return ApprovalState.blocked;
|
||||
return ApprovalState.pending;
|
||||
};
|
||||
|
||||
const mapFixtureEvidenceStrength = (strength: string | undefined, confidence: number): EvidenceStrength => {
|
||||
if (strength && strength in EvidenceStrength) {
|
||||
return EvidenceStrength[strength as keyof typeof EvidenceStrength];
|
||||
}
|
||||
return mapEvidenceStrength(confidence);
|
||||
};
|
||||
|
||||
for (const feature of featureFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(feature.projectId)!;
|
||||
const group = await prisma.featureGroup.findFirst({
|
||||
where: {
|
||||
projectId,
|
||||
slug: feature.groupId,
|
||||
deletedAt: null,
|
||||
},
|
||||
});
|
||||
|
||||
if (!group) {
|
||||
throw new Error(`Feature group '${feature.groupId}' is missing for feature '${feature.id}'.`);
|
||||
}
|
||||
|
||||
await prisma.feature.upsert({
|
||||
where: {
|
||||
projectId_slug: {
|
||||
projectId,
|
||||
slug: feature.id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
projectId,
|
||||
featureGroupId: group.id,
|
||||
slug: feature.id,
|
||||
readableId: feature.id,
|
||||
name: feature.name,
|
||||
description: feature.description,
|
||||
status: mapFeatureStatus(feature.status),
|
||||
lifecycle: mapFeatureLifecycle(feature),
|
||||
intent: feature.intent,
|
||||
confidence: feature.confidence,
|
||||
health: feature.health,
|
||||
approvalState: feature.status === "Done" ? ApprovalState.approved : ApprovalState.pending,
|
||||
evidenceStrength: mapFixtureEvidenceStrength(feature.evidenceStrength, feature.confidence),
|
||||
verificationState: mapVerificationState(feature.status),
|
||||
trustJson: toJson({
|
||||
bugCount: feature.bugCount,
|
||||
taskCount: feature.taskCount,
|
||||
decisionCount: feature.decisionCount,
|
||||
codeEvidence: feature.codeEvidence,
|
||||
aiSuggestionCount: feature.aiSuggestionCount,
|
||||
evidenceIds: feature.evidenceIds,
|
||||
initiativeId: feature.initiativeId,
|
||||
}),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/featureFixtures.ts",
|
||||
fixtureId: feature.id,
|
||||
}),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
},
|
||||
update: {
|
||||
featureGroupId: group.id,
|
||||
readableId: feature.id,
|
||||
name: feature.name,
|
||||
description: feature.description,
|
||||
status: mapFeatureStatus(feature.status),
|
||||
lifecycle: mapFeatureLifecycle(feature),
|
||||
intent: feature.intent,
|
||||
confidence: feature.confidence,
|
||||
health: feature.health,
|
||||
approvalState: feature.status === "Done" ? ApprovalState.approved : ApprovalState.pending,
|
||||
evidenceStrength: mapFixtureEvidenceStrength(feature.evidenceStrength, feature.confidence),
|
||||
verificationState: mapVerificationState(feature.status),
|
||||
trustJson: toJson({
|
||||
bugCount: feature.bugCount,
|
||||
taskCount: feature.taskCount,
|
||||
decisionCount: feature.decisionCount,
|
||||
codeEvidence: feature.codeEvidence,
|
||||
aiSuggestionCount: feature.aiSuggestionCount,
|
||||
evidenceIds: feature.evidenceIds,
|
||||
initiativeId: feature.initiativeId,
|
||||
}),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/featureFixtures.ts",
|
||||
fixtureId: feature.id,
|
||||
}),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (const evidence of evidenceFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(evidence.projectId)!;
|
||||
await prisma.evidence.upsert({
|
||||
where: {
|
||||
projectId_slug: {
|
||||
projectId,
|
||||
slug: evidence.id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
projectId,
|
||||
slug: evidence.id,
|
||||
readableId: evidence.id,
|
||||
type: evidence.type,
|
||||
source: evidence.source,
|
||||
confidence: evidence.confidence,
|
||||
approvalState: mapApprovalState(evidence.approvalState),
|
||||
evidenceStrength: mapEvidenceStrength(evidence.confidence),
|
||||
verificationState: evidence.approvalState === "approved" ? VerificationState.verified : VerificationState.unverified,
|
||||
reason: evidence.reason,
|
||||
metadataJson: toJson({
|
||||
linkedEntity: evidence.linkedEntity,
|
||||
featureIds: evidence.featureIds,
|
||||
route: evidence.route,
|
||||
}),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/featureFixtures.ts",
|
||||
fixtureId: evidence.id,
|
||||
}),
|
||||
lastSeen: new Date(evidence.lastSeen),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
},
|
||||
update: {
|
||||
readableId: evidence.id,
|
||||
type: evidence.type,
|
||||
source: evidence.source,
|
||||
confidence: evidence.confidence,
|
||||
approvalState: mapApprovalState(evidence.approvalState),
|
||||
evidenceStrength: mapEvidenceStrength(evidence.confidence),
|
||||
verificationState: evidence.approvalState === "approved" ? VerificationState.verified : VerificationState.unverified,
|
||||
reason: evidence.reason,
|
||||
metadataJson: toJson({
|
||||
linkedEntity: evidence.linkedEntity,
|
||||
featureIds: evidence.featureIds,
|
||||
route: evidence.route,
|
||||
}),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/featureFixtures.ts",
|
||||
fixtureId: evidence.id,
|
||||
}),
|
||||
lastSeen: new Date(evidence.lastSeen),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (const contextPack of contextPackFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(contextPack.projectId)!;
|
||||
await prisma.contextPack.upsert({
|
||||
where: {
|
||||
projectId_slug: {
|
||||
projectId,
|
||||
slug: contextPack.id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
projectId,
|
||||
slug: contextPack.id,
|
||||
readableId: contextPack.id,
|
||||
title: contextPack.title,
|
||||
category: contextPack.category,
|
||||
summary: contextPack.summary,
|
||||
generatedBy: contextPack.generatedBy,
|
||||
confidence: contextPack.trust.confidence,
|
||||
approvalState: mapApprovalState(contextPack.trust.approvalState),
|
||||
qualityJson: toJson(contextPack.quality ?? {}),
|
||||
trustJson: toJson(contextPack.trust),
|
||||
metadataJson: toJson({
|
||||
dna: contextPack.dna,
|
||||
assumptions: contextPack.assumptions,
|
||||
constraints: contextPack.constraints,
|
||||
evidence: contextPack.evidence,
|
||||
signals: contextPack.signals,
|
||||
featureIds: contextPack.featureIds,
|
||||
bugIds: contextPack.bugIds,
|
||||
taskIds: contextPack.taskIds,
|
||||
decisionIds: contextPack.decisionIds,
|
||||
memoryRuleIds: contextPack.memoryRuleIds,
|
||||
architectureNotes: contextPack.architectureNotes,
|
||||
regressions: contextPack.regressions,
|
||||
risks: contextPack.risks,
|
||||
currentFocus: contextPack.currentFocus,
|
||||
}),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/contextPackFixtures.ts",
|
||||
fixtureId: contextPack.id,
|
||||
}),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
createdAt: new Date(contextPack.createdAt),
|
||||
sections: {
|
||||
create: [
|
||||
{
|
||||
projectId,
|
||||
slug: "dna",
|
||||
title: "Project DNA",
|
||||
sectionType: "dna",
|
||||
orderIndex: 1,
|
||||
contentJson: toJson(contextPack.dna),
|
||||
},
|
||||
{
|
||||
projectId,
|
||||
slug: "features",
|
||||
title: "Relevant features",
|
||||
sectionType: "features",
|
||||
orderIndex: 2,
|
||||
contentJson: toJson(contextPack.featureIds ?? []),
|
||||
},
|
||||
{
|
||||
projectId,
|
||||
slug: "evidence",
|
||||
title: "Evidence references",
|
||||
sectionType: "evidence",
|
||||
orderIndex: 3,
|
||||
contentJson: toJson(contextPack.evidence),
|
||||
},
|
||||
{
|
||||
projectId,
|
||||
slug: "risks",
|
||||
title: "Risks",
|
||||
sectionType: "risks",
|
||||
orderIndex: 4,
|
||||
contentJson: toJson(contextPack.risks ?? []),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
update: {
|
||||
readableId: contextPack.id,
|
||||
title: contextPack.title,
|
||||
category: contextPack.category,
|
||||
summary: contextPack.summary,
|
||||
generatedBy: contextPack.generatedBy,
|
||||
confidence: contextPack.trust.confidence,
|
||||
approvalState: mapApprovalState(contextPack.trust.approvalState),
|
||||
qualityJson: toJson(contextPack.quality ?? {}),
|
||||
trustJson: toJson(contextPack.trust),
|
||||
metadataJson: toJson({
|
||||
dna: contextPack.dna,
|
||||
assumptions: contextPack.assumptions,
|
||||
constraints: contextPack.constraints,
|
||||
evidence: contextPack.evidence,
|
||||
signals: contextPack.signals,
|
||||
featureIds: contextPack.featureIds,
|
||||
bugIds: contextPack.bugIds,
|
||||
taskIds: contextPack.taskIds,
|
||||
decisionIds: contextPack.decisionIds,
|
||||
memoryRuleIds: contextPack.memoryRuleIds,
|
||||
architectureNotes: contextPack.architectureNotes,
|
||||
regressions: contextPack.regressions,
|
||||
risks: contextPack.risks,
|
||||
currentFocus: contextPack.currentFocus,
|
||||
}),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/contextPackFixtures.ts",
|
||||
fixtureId: contextPack.id,
|
||||
}),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
|
||||
const seededContextPack = await prisma.contextPack.findFirstOrThrow({
|
||||
where: { projectId, slug: contextPack.id },
|
||||
});
|
||||
await prisma.contextPackSection.deleteMany({ where: { contextPackId: seededContextPack.id } });
|
||||
await prisma.contextPackSection.createMany({
|
||||
data: [
|
||||
{
|
||||
projectId,
|
||||
contextPackId: seededContextPack.id,
|
||||
slug: "dna",
|
||||
title: "Project DNA",
|
||||
sectionType: "dna",
|
||||
orderIndex: 1,
|
||||
contentJson: toJson(contextPack.dna),
|
||||
},
|
||||
{
|
||||
projectId,
|
||||
contextPackId: seededContextPack.id,
|
||||
slug: "features",
|
||||
title: "Relevant features",
|
||||
sectionType: "features",
|
||||
orderIndex: 2,
|
||||
contentJson: toJson(contextPack.featureIds ?? []),
|
||||
},
|
||||
{
|
||||
projectId,
|
||||
contextPackId: seededContextPack.id,
|
||||
slug: "evidence",
|
||||
title: "Evidence references",
|
||||
sectionType: "evidence",
|
||||
orderIndex: 3,
|
||||
contentJson: toJson(contextPack.evidence),
|
||||
},
|
||||
{
|
||||
projectId,
|
||||
contextPackId: seededContextPack.id,
|
||||
slug: "risks",
|
||||
title: "Risks",
|
||||
sectionType: "risks",
|
||||
orderIndex: 4,
|
||||
contentJson: toJson(contextPack.risks ?? []),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (const capture of captureFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(capture.projectId)!;
|
||||
await prisma.captureItem.upsert({
|
||||
where: {
|
||||
projectId_slug: {
|
||||
projectId,
|
||||
slug: capture.id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
projectId,
|
||||
slug: capture.id,
|
||||
readableId: capture.id,
|
||||
type: capture.type,
|
||||
title: capture.title,
|
||||
content: capture.content,
|
||||
source: capture.source,
|
||||
status: capture.status,
|
||||
classificationType: capture.classificationType,
|
||||
confidence: capture.confidence,
|
||||
evidenceStrength: capture.evidenceStrength
|
||||
? mapFixtureEvidenceStrength(capture.evidenceStrength, capture.confidence ?? 0)
|
||||
: undefined,
|
||||
suggestedAction: capture.suggestedAction,
|
||||
linkedReviewItemId: capture.linkedReviewItemId,
|
||||
metadataJson: toJson({}),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/captureFixtures.ts",
|
||||
fixtureId: capture.id,
|
||||
}),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
createdAt: new Date(capture.createdAt),
|
||||
},
|
||||
update: {
|
||||
readableId: capture.id,
|
||||
type: capture.type,
|
||||
title: capture.title,
|
||||
content: capture.content,
|
||||
source: capture.source,
|
||||
status: capture.status,
|
||||
classificationType: capture.classificationType,
|
||||
confidence: capture.confidence,
|
||||
evidenceStrength: capture.evidenceStrength
|
||||
? mapFixtureEvidenceStrength(capture.evidenceStrength, capture.confidence ?? 0)
|
||||
: undefined,
|
||||
suggestedAction: capture.suggestedAction,
|
||||
linkedReviewItemId: capture.linkedReviewItemId,
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/captureFixtures.ts",
|
||||
fixtureId: capture.id,
|
||||
}),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const mapReviewStatus = (status: string): ReviewStatus => {
|
||||
if (status === "accepted") return ReviewStatus.accepted;
|
||||
if (status === "rejected") return ReviewStatus.rejected;
|
||||
if (status === "merged") return ReviewStatus.merged;
|
||||
if (status === "converted") return ReviewStatus.converted;
|
||||
return ReviewStatus.pending;
|
||||
};
|
||||
|
||||
const mapReviewVerificationState = (state: string): VerificationState => {
|
||||
if (state === "verified") return VerificationState.verified;
|
||||
if (state === "blocked") return VerificationState.blocked;
|
||||
if (state === "needs evidence") return VerificationState.needs_evidence;
|
||||
return VerificationState.unverified;
|
||||
};
|
||||
|
||||
for (const review of reviewQueueFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(review.projectId)!;
|
||||
await prisma.reviewQueueItem.upsert({
|
||||
where: {
|
||||
projectId_slug: {
|
||||
projectId,
|
||||
slug: review.id,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
projectId,
|
||||
slug: review.id,
|
||||
readableId: review.id,
|
||||
type: review.type,
|
||||
title: review.title,
|
||||
description: review.description,
|
||||
priority: review.priority,
|
||||
status: mapReviewStatus(review.status),
|
||||
source: review.source,
|
||||
confidence: review.confidence,
|
||||
approvalState: review.status === "accepted" || review.status === "converted" || review.status === "merged"
|
||||
? ApprovalState.approved
|
||||
: review.status === "rejected"
|
||||
? ApprovalState.rejected
|
||||
: ApprovalState.pending,
|
||||
evidenceStrength: mapFixtureEvidenceStrength(review.evidenceStrength, review.confidence),
|
||||
verificationState: mapReviewVerificationState(review.verificationState),
|
||||
suggestedAction: review.suggestedAction,
|
||||
notes: review.notes,
|
||||
targetEntityId: review.targetEntityId,
|
||||
createdEntityId: review.createdEntityId,
|
||||
payloadJson: toJson({ convertedTarget: review.convertedTarget }),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/reviewQueueFixtures.ts",
|
||||
fixtureId: review.id,
|
||||
}),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
createdAt: new Date(review.createdAt),
|
||||
},
|
||||
update: {
|
||||
readableId: review.id,
|
||||
type: review.type,
|
||||
title: review.title,
|
||||
description: review.description,
|
||||
priority: review.priority,
|
||||
status: mapReviewStatus(review.status),
|
||||
source: review.source,
|
||||
confidence: review.confidence,
|
||||
approvalState: review.status === "accepted" || review.status === "converted" || review.status === "merged"
|
||||
? ApprovalState.approved
|
||||
: review.status === "rejected"
|
||||
? ApprovalState.rejected
|
||||
: ApprovalState.pending,
|
||||
evidenceStrength: mapFixtureEvidenceStrength(review.evidenceStrength, review.confidence),
|
||||
verificationState: mapReviewVerificationState(review.verificationState),
|
||||
suggestedAction: review.suggestedAction,
|
||||
notes: review.notes,
|
||||
targetEntityId: review.targetEntityId,
|
||||
createdEntityId: review.createdEntityId,
|
||||
payloadJson: toJson({ convertedTarget: review.convertedTarget }),
|
||||
provenanceJson: toJson({
|
||||
seededFrom: "backend/src/fixtures/reviewQueueFixtures.ts",
|
||||
fixtureId: review.id,
|
||||
}),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for (const knowledge of knowledgeFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(knowledge.projectId)!;
|
||||
await prisma.knowledgeItem.upsert({
|
||||
where: { projectId_slug: { projectId, slug: knowledge.id } },
|
||||
create: {
|
||||
projectId,
|
||||
slug: knowledge.id,
|
||||
readableId: knowledge.id,
|
||||
title: knowledge.title,
|
||||
category: knowledge.category,
|
||||
content: knowledge.content,
|
||||
source: knowledge.source,
|
||||
confidence: knowledge.confidence,
|
||||
includeInContextPacks: knowledge.includeInContextPacks.length > 0,
|
||||
approvalState: mapApprovalState(knowledge.trust.approvalState),
|
||||
evidenceStrength: mapEvidenceStrength(knowledge.confidence),
|
||||
verificationState: knowledge.trust.approvalState === "approved" ? VerificationState.verified : VerificationState.unverified,
|
||||
metadataJson: toJson({ linkedFeatureIds: knowledge.linkedFeatureIds, includeInContextPacks: knowledge.includeInContextPacks }),
|
||||
trustJson: toJson(knowledge.trust),
|
||||
provenanceJson: toJson({ seededFrom: "backend/src/fixtures/knowledgeFixtures.ts", fixtureId: knowledge.id }),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
createdAt: new Date(knowledge.createdAt),
|
||||
},
|
||||
update: {
|
||||
readableId: knowledge.id,
|
||||
title: knowledge.title,
|
||||
category: knowledge.category,
|
||||
content: knowledge.content,
|
||||
source: knowledge.source,
|
||||
confidence: knowledge.confidence,
|
||||
includeInContextPacks: knowledge.includeInContextPacks.length > 0,
|
||||
approvalState: mapApprovalState(knowledge.trust.approvalState),
|
||||
evidenceStrength: mapEvidenceStrength(knowledge.confidence),
|
||||
verificationState: knowledge.trust.approvalState === "approved" ? VerificationState.verified : VerificationState.unverified,
|
||||
metadataJson: toJson({ linkedFeatureIds: knowledge.linkedFeatureIds, includeInContextPacks: knowledge.includeInContextPacks }),
|
||||
trustJson: toJson(knowledge.trust),
|
||||
provenanceJson: toJson({ seededFrom: "backend/src/fixtures/knowledgeFixtures.ts", fixtureId: knowledge.id }),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (const rule of memoryRuleFixtures.filter((item) => seededProjects.has(item.projectId))) {
|
||||
const projectId = seededProjects.get(rule.projectId)!;
|
||||
await prisma.memoryRule.upsert({
|
||||
where: { projectId_slug: { projectId, slug: rule.id } },
|
||||
create: {
|
||||
projectId,
|
||||
slug: rule.id,
|
||||
readableId: rule.id,
|
||||
title: rule.title,
|
||||
rule: rule.rule,
|
||||
scope: rule.scope,
|
||||
category: rule.category,
|
||||
severity: rule.severity,
|
||||
includeInContextPacks: rule.includeInContextPacksDefault,
|
||||
confidence: rule.trust.confidence,
|
||||
approvalState: mapApprovalState(rule.trust.approvalState),
|
||||
evidenceStrength: mapEvidenceStrength(rule.trust.confidence),
|
||||
verificationState: rule.trust.approvalState === "approved" ? VerificationState.verified : VerificationState.unverified,
|
||||
trustJson: toJson(rule.trust),
|
||||
provenanceJson: toJson({ linkedFeatureIds: rule.linkedFeatureIds, includeInContextPacks: rule.includeInContextPacks, seededFrom: "backend/src/fixtures/memoryRuleFixtures.ts", fixtureId: rule.id }),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
createdAt: new Date(rule.createdAt),
|
||||
},
|
||||
update: {
|
||||
readableId: rule.id,
|
||||
title: rule.title,
|
||||
rule: rule.rule,
|
||||
scope: rule.scope,
|
||||
category: rule.category,
|
||||
severity: rule.severity,
|
||||
includeInContextPacks: rule.includeInContextPacksDefault,
|
||||
confidence: rule.trust.confidence,
|
||||
approvalState: mapApprovalState(rule.trust.approvalState),
|
||||
evidenceStrength: mapEvidenceStrength(rule.trust.confidence),
|
||||
verificationState: rule.trust.approvalState === "approved" ? VerificationState.verified : VerificationState.unverified,
|
||||
trustJson: toJson(rule.trust),
|
||||
provenanceJson: toJson({ linkedFeatureIds: rule.linkedFeatureIds, includeInContextPacks: rule.includeInContextPacks, seededFrom: "backend/src/fixtures/memoryRuleFixtures.ts", fixtureId: rule.id }),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const documentationSeed = [
|
||||
{ id: "doc-wide-readme", title: "README summary", kind: "README summary", status: "outdated", linkedFeatureIds: [], approvalState: ApprovalState.pending, content: "Project README summary needs an approved refresh after runtime persistence work." },
|
||||
{ id: "doc-wide-operating-model", title: "ProjectBrain Operating Model", kind: "architecture docs", status: "AI-generated", linkedFeatureIds: ["f-auth-mfa", "f-auth-social"], approvalState: ApprovalState.pending, content: "Operating model generated from existing project memory and runtime workflow." },
|
||||
{ id: "doc-wide-codex", title: "Codex instructions", kind: "Codex instructions", status: "needs verification", linkedFeatureIds: [], approvalState: ApprovalState.pending, content: "Codex instructions must preserve review-before-truth boundaries." },
|
||||
{ id: "doc-wide-decision-log", title: "Decision log", kind: "decision log", status: "approved", linkedFeatureIds: ["f-auth-mfa"], approvalState: ApprovalState.approved, content: "Decision log is approved and can feed context packs." },
|
||||
];
|
||||
|
||||
for (const doc of documentationSeed) {
|
||||
await prisma.documentationItem.upsert({
|
||||
where: { projectId_slug: { projectId: project.id, slug: doc.id } },
|
||||
create: {
|
||||
projectId: project.id,
|
||||
slug: doc.id,
|
||||
readableId: doc.id,
|
||||
title: doc.title,
|
||||
kind: doc.kind,
|
||||
status: doc.status,
|
||||
approvalState: doc.approvalState,
|
||||
content: doc.content,
|
||||
metadataJson: toJson({ linkedFeatureIds: doc.linkedFeatureIds, lastUpdated: new Date().toISOString() }),
|
||||
trustJson: toJson({ source: "documentation seed", confidence: doc.approvalState === ApprovalState.approved ? 90 : 70, evidence: [], lastChecked: new Date().toISOString(), approvalState: doc.approvalState }),
|
||||
provenanceJson: toJson({ seededFrom: "backend/prisma/seed.ts", fixtureId: doc.id }),
|
||||
createdBy: "seed",
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
},
|
||||
update: {
|
||||
readableId: doc.id,
|
||||
title: doc.title,
|
||||
kind: doc.kind,
|
||||
status: doc.status,
|
||||
approvalState: doc.approvalState,
|
||||
content: doc.content,
|
||||
metadataJson: toJson({ linkedFeatureIds: doc.linkedFeatureIds, lastUpdated: new Date().toISOString() }),
|
||||
trustJson: toJson({ source: "documentation seed", confidence: doc.approvalState === ApprovalState.approved ? 90 : 70, evidence: [], lastChecked: new Date().toISOString(), approvalState: doc.approvalState }),
|
||||
provenanceJson: toJson({ seededFrom: "backend/prisma/seed.ts", fixtureId: doc.id }),
|
||||
updatedBy: "seed",
|
||||
sourceType: "fixture_seed",
|
||||
deletedAt: null,
|
||||
archivedAt: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Seeded P2-P8 ProjectBrain persistence data for ${widefrog.id}.`);
|
||||
};
|
||||
|
||||
try {
|
||||
await main();
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
Reference in new issue
Block a user