// MCP Workflow Tracker - Prisma Schema (SQLite)
// Usage: Standalone MCP server without external DB dependency
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
// ============================================
// MODELS (SQLite compatible)
// Note: Enums stored as TEXT, arrays as JSON strings
// ============================================
model Workflow {
id String @id @default(cuid())
name String
description String?
plan String? // JSON string
// Mission fields (merged from Mission model)
objective String? // Measurable goal
scope String? // What's included/excluded
constraints String? // Technical limits
profile String @default("STANDARD") // WorkflowProfile: SIMPLE | STANDARD | COMPLEX
// Execution state
status String @default("PENDING") // WorkflowStatus: PENDING | IN_PROGRESS | COMPLETED | FAILED | BLOCKED
currentPhase Int @default(0)
totalPhases Int @default(1)
// Metadata
missionPath String? // .claude/missions/<name>/
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
completedAt DateTime?
// Aggregated metrics (computed on task completion)
totalDurationMs Int? // Sum of all task durations
totalTokens Int? // Sum of all tokens (input + output)
// Relations
tasks Task[]
phases Phase[]
@@index([status])
@@index([createdAt])
}
model Phase {
id String @id @default(cuid())
workflowId String
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
number Int // Phase sequence (1, 2, 3...)
name String
description String?
// Execution
status String @default("PENDING") // PhaseStatus: PENDING | IN_PROGRESS | COMPLETED | FAILED
isParallel Boolean @default(false) // Can tasks run in parallel?
// Timing
startedAt DateTime?
completedAt DateTime?
// Relations
tasks Task[]
@@unique([workflowId, number])
@@index([workflowId])
}
model Task {
id String @id @default(cuid())
workflowId String
parentTaskId String?
name String
goal String
status String @default("IN_PROGRESS") // TaskStatus enum
// Phase relation (optional for backward compat)
phaseId String?
phase Phase? @relation(fields: [phaseId], references: [id], onDelete: Cascade)
// Caller context
callerType String? // CallerType enum: ORCHESTRATOR | SUBAGENT
agentName String? // e.g., "feature-implementer"
agentPrompt String? // The prompt given to sub-agent (for replay)
// Scope (JSON array)
areas String @default("[]")
// Snapshot data (Git ou Checksum)
snapshotId String?
snapshotType String?
snapshotData String? // JSON string
// Timing
startedAt DateTime @default(now())
completedAt DateTime?
durationMs Int?
// Outcome
summary String?
achievements String @default("[]") // JSON array
limitations String @default("[]") // JSON array
manualReviewNeeded Boolean @default(false)
manualReviewReason String?
nextSteps String @default("[]") // JSON array
// Metadata
packagesAdded String @default("[]") // JSON array
packagesRemoved String @default("[]") // JSON array
commandsExecuted String @default("[]") // JSON array
testsStatus String? // TestsStatus enum
// Token metrics
tokensInput Int? // Input tokens used
tokensOutput Int? // Output tokens generated
// Files changed
filesAdded String @default("[]") // JSON array
filesModified String @default("[]") // JSON array
filesDeleted String @default("[]") // JSON array
// Verification
scopeMatch Boolean?
unexpectedFiles String @default("[]") // JSON array
warnings String @default("[]") // JSON array
// Relations
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
parentTask Task? @relation("TaskHierarchy", fields: [parentTaskId], references: [id])
subtasks Task[] @relation("TaskHierarchy")
decisions Decision[]
issues Issue[]
milestones Milestone[]
@@index([workflowId])
@@index([parentTaskId])
@@index([status])
@@index([startedAt])
@@index([phaseId])
@@index([callerType])
@@index([agentName])
}
model Decision {
id String @id @default(cuid())
taskId String
category String // DecisionCategory enum
question String
optionsConsidered String @default("[]") // JSON array
chosen String
reasoning String
tradeOffs String?
createdAt DateTime @default(now())
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
@@index([taskId])
@@index([createdAt])
}
model Issue {
id String @id @default(cuid())
taskId String
type String // IssueType enum
description String
resolution String
requiresHumanReview Boolean @default(false)
createdAt DateTime @default(now())
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
@@index([taskId])
@@index([createdAt])
}
model Milestone {
id String @id @default(cuid())
taskId String
message String
progress Int?
metadata String? // JSON string
createdAt DateTime @default(now())
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
@@index([taskId])
@@index([createdAt])
}
// ============================================
// SERVER INFO (WebSocket Port Discovery)
// ============================================
model ServerInfo {
id String @id @default("singleton") // Always "singleton" - single entry
websocketPort Int
startedAt DateTime @default(now())
lastHeartbeat DateTime @default(now())
processId Int? // PID for debugging
}