Feat v0.3.1 instance + assignment tables and store
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 5s
CI/CD / test-frontend (pull_request) Has been skipped
CI/CD / test-go-pg (pull_request) Failing after 2m32s
CI/CD / test-sqlite (pull_request) Successful in 2m58s
CI/CD / build-and-deploy (pull_request) Has been skipped

Add workflow execution layer: workflow_instances tracks running workflows
(stage, status, entry token), workflow_assignments tracks per-stage team
queue with optimistic-lock claim. 15 new store methods in PG + SQLite.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 18:41:03 +00:00
parent 965885a8f7
commit 1bf8422932
6 changed files with 667 additions and 7 deletions

View File

@@ -78,3 +78,55 @@ CREATE TABLE IF NOT EXISTS workflow_versions (
CREATE INDEX IF NOT EXISTS idx_workflow_versions_workflow
ON workflow_versions(workflow_id, version_number DESC);
-- ── Workflow Instances (v0.3.1) ──────────────
CREATE TABLE IF NOT EXISTS workflow_instances (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workflow_id UUID NOT NULL REFERENCES workflows(id) ON DELETE CASCADE,
workflow_version INTEGER NOT NULL,
current_stage TEXT NOT NULL,
stage_data JSONB NOT NULL DEFAULT '{}',
status TEXT NOT NULL DEFAULT 'active'
CHECK (status IN ('active', 'completed', 'cancelled', 'stale', 'error')),
started_by TEXT NOT NULL,
entry_token TEXT,
metadata JSONB NOT NULL DEFAULT '{}',
stage_entered_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_workflow_instances_workflow_status
ON workflow_instances(workflow_id, status);
CREATE INDEX IF NOT EXISTS idx_workflow_instances_active
ON workflow_instances(status) WHERE status = 'active';
CREATE UNIQUE INDEX IF NOT EXISTS idx_workflow_instances_token
ON workflow_instances(entry_token) WHERE entry_token IS NOT NULL;
DROP TRIGGER IF EXISTS workflow_instances_updated_at ON workflow_instances;
CREATE TRIGGER workflow_instances_updated_at BEFORE UPDATE ON workflow_instances
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- ── Workflow Assignments (v0.3.1) ────────────
CREATE TABLE IF NOT EXISTS workflow_assignments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
instance_id UUID NOT NULL REFERENCES workflow_instances(id) ON DELETE CASCADE,
stage TEXT NOT NULL,
team_id UUID NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
assigned_to UUID REFERENCES users(id) ON DELETE SET NULL,
status TEXT NOT NULL DEFAULT 'unassigned'
CHECK (status IN ('unassigned', 'claimed', 'completed', 'cancelled')),
review_data JSONB NOT NULL DEFAULT '{}',
claimed_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_workflow_assignments_instance_stage
ON workflow_assignments(instance_id, stage);
CREATE INDEX IF NOT EXISTS idx_workflow_assignments_team_status
ON workflow_assignments(team_id, status);
CREATE INDEX IF NOT EXISTS idx_workflow_assignments_assigned
ON workflow_assignments(assigned_to) WHERE assigned_to IS NOT NULL;

View File

@@ -69,3 +69,53 @@ CREATE TABLE IF NOT EXISTS workflow_versions (
CREATE INDEX IF NOT EXISTS idx_workflow_versions_workflow
ON workflow_versions(workflow_id, version_number);
-- ── Workflow Instances (v0.3.1) ──────────────
CREATE TABLE IF NOT EXISTS workflow_instances (
id TEXT PRIMARY KEY,
workflow_id TEXT NOT NULL REFERENCES workflows(id) ON DELETE CASCADE,
workflow_version INTEGER NOT NULL,
current_stage TEXT NOT NULL,
stage_data TEXT NOT NULL DEFAULT '{}',
status TEXT NOT NULL DEFAULT 'active'
CHECK (status IN ('active', 'completed', 'cancelled', 'stale', 'error')),
started_by TEXT NOT NULL,
entry_token TEXT UNIQUE,
metadata TEXT NOT NULL DEFAULT '{}',
stage_entered_at TEXT NOT NULL DEFAULT (datetime('now')),
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_workflow_instances_workflow_status
ON workflow_instances(workflow_id, status);
CREATE INDEX IF NOT EXISTS idx_workflow_instances_active
ON workflow_instances(status);
CREATE TRIGGER IF NOT EXISTS workflow_instances_updated_at AFTER UPDATE ON workflow_instances
FOR EACH ROW WHEN NEW.updated_at = OLD.updated_at
BEGIN UPDATE workflow_instances SET updated_at = datetime('now') WHERE id = NEW.id; END;
-- ── Workflow Assignments (v0.3.1) ────────────
CREATE TABLE IF NOT EXISTS workflow_assignments (
id TEXT PRIMARY KEY,
instance_id TEXT NOT NULL REFERENCES workflow_instances(id) ON DELETE CASCADE,
stage TEXT NOT NULL,
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
assigned_to TEXT REFERENCES users(id) ON DELETE SET NULL,
status TEXT NOT NULL DEFAULT 'unassigned'
CHECK (status IN ('unassigned', 'claimed', 'completed', 'cancelled')),
review_data TEXT NOT NULL DEFAULT '{}',
claimed_at TEXT,
completed_at TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_workflow_assignments_instance_stage
ON workflow_assignments(instance_id, stage);
CREATE INDEX IF NOT EXISTS idx_workflow_assignments_team_status
ON workflow_assignments(team_id, status);
CREATE INDEX IF NOT EXISTS idx_workflow_assignments_assigned
ON workflow_assignments(assigned_to);