feat: implement project bus MVP
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
PRAGMA foreign_keys = ON;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version INTEGER PRIMARY KEY,
|
||||
applied_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE projects (
|
||||
project_id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE actors (
|
||||
actor_id TEXT PRIMARY KEY,
|
||||
auth_subject TEXT NOT NULL UNIQUE,
|
||||
display_name TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE project_memberships (
|
||||
project_id TEXT NOT NULL REFERENCES projects(project_id),
|
||||
actor_id TEXT NOT NULL REFERENCES actors(actor_id),
|
||||
role TEXT NOT NULL CHECK (role IN (
|
||||
'SYSTEM','PO','PM','PA','ARCHITECT','LEAD_ENGINEER',
|
||||
'IMPLEMENTER','REVIEWER','SECURITY_REVIEWER','OBSERVER'
|
||||
)),
|
||||
active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0, 1)),
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (project_id, actor_id)
|
||||
);
|
||||
|
||||
CREATE TABLE work_packages (
|
||||
project_id TEXT NOT NULL REFERENCES projects(project_id),
|
||||
work_package_id TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
acceptance_criteria_json TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN (
|
||||
'OPEN','CLAIMED','RESULT_SUBMITTED','IN_REVIEW','REVIEWED',
|
||||
'ACCEPTED','REJECTED','CANCELLED'
|
||||
)),
|
||||
issued_by TEXT NOT NULL REFERENCES actors(actor_id),
|
||||
claimed_by TEXT REFERENCES actors(actor_id),
|
||||
result_submitted_by TEXT REFERENCES actors(actor_id),
|
||||
result_json TEXT,
|
||||
accepted_by TEXT REFERENCES actors(actor_id),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
PRIMARY KEY (project_id, work_package_id)
|
||||
);
|
||||
CREATE INDEX work_packages_project_status
|
||||
ON work_packages(project_id, status, updated_at);
|
||||
|
||||
CREATE TABLE review_requests (
|
||||
project_id TEXT NOT NULL REFERENCES projects(project_id),
|
||||
review_id TEXT NOT NULL,
|
||||
work_package_id TEXT NOT NULL,
|
||||
requested_by TEXT NOT NULL REFERENCES actors(actor_id),
|
||||
reviewer_id TEXT NOT NULL REFERENCES actors(actor_id),
|
||||
review_type TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('OPEN','SUBMITTED')),
|
||||
verdict TEXT CHECK (verdict IN ('APPROVE','CHANGES_REQUESTED','REJECT')),
|
||||
findings_json TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
submitted_at TEXT,
|
||||
PRIMARY KEY (project_id, review_id),
|
||||
FOREIGN KEY (project_id, work_package_id)
|
||||
REFERENCES work_packages(project_id, work_package_id)
|
||||
);
|
||||
CREATE INDEX review_requests_project_status
|
||||
ON review_requests(project_id, status, reviewer_id);
|
||||
|
||||
CREATE TABLE decisions (
|
||||
project_id TEXT NOT NULL REFERENCES projects(project_id),
|
||||
decision_id TEXT NOT NULL,
|
||||
kind TEXT NOT NULL CHECK (kind IN ('PRODUCT','ARCHITECTURE','OPERATIONAL','GATE')),
|
||||
title TEXT NOT NULL,
|
||||
decision TEXT NOT NULL,
|
||||
rationale TEXT NOT NULL,
|
||||
decided_by TEXT NOT NULL REFERENCES actors(actor_id),
|
||||
work_package_id TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (project_id, decision_id),
|
||||
FOREIGN KEY (project_id, work_package_id)
|
||||
REFERENCES work_packages(project_id, work_package_id)
|
||||
);
|
||||
|
||||
CREATE TABLE escalations (
|
||||
project_id TEXT NOT NULL REFERENCES projects(project_id),
|
||||
escalation_id TEXT NOT NULL,
|
||||
raised_by TEXT NOT NULL REFERENCES actors(actor_id),
|
||||
severity TEXT NOT NULL CHECK (severity IN ('LOW','MEDIUM','HIGH','CRITICAL')),
|
||||
title TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('OPEN','RESOLVED')),
|
||||
target_role TEXT,
|
||||
resolution TEXT,
|
||||
resolved_by TEXT REFERENCES actors(actor_id),
|
||||
created_at TEXT NOT NULL,
|
||||
resolved_at TEXT,
|
||||
PRIMARY KEY (project_id, escalation_id)
|
||||
);
|
||||
|
||||
CREATE TABLE event_log (
|
||||
cursor INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
event_id TEXT NOT NULL UNIQUE,
|
||||
project_id TEXT NOT NULL REFERENCES projects(project_id),
|
||||
event_type TEXT NOT NULL,
|
||||
actor_id TEXT NOT NULL REFERENCES actors(actor_id),
|
||||
actor_role TEXT NOT NULL,
|
||||
aggregate_type TEXT NOT NULL,
|
||||
aggregate_id TEXT NOT NULL,
|
||||
correlation_id TEXT,
|
||||
causation_event_id TEXT,
|
||||
payload_json TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX event_log_project_cursor ON event_log(project_id, cursor);
|
||||
CREATE INDEX event_log_aggregate ON event_log(project_id, aggregate_type, aggregate_id, cursor);
|
||||
|
||||
CREATE TRIGGER event_log_no_update
|
||||
BEFORE UPDATE ON event_log
|
||||
BEGIN
|
||||
SELECT RAISE(ABORT, 'event_log is append-only');
|
||||
END;
|
||||
|
||||
CREATE TRIGGER event_log_no_delete
|
||||
BEFORE DELETE ON event_log
|
||||
BEGIN
|
||||
SELECT RAISE(ABORT, 'event_log is append-only');
|
||||
END;
|
||||
|
||||
CREATE TABLE idempotency_records (
|
||||
project_id TEXT NOT NULL,
|
||||
actor_id TEXT NOT NULL,
|
||||
idempotency_key TEXT NOT NULL,
|
||||
operation TEXT NOT NULL,
|
||||
request_hash TEXT NOT NULL,
|
||||
response_json TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (project_id, actor_id, idempotency_key)
|
||||
);
|
||||
Reference in New Issue
Block a user