feat: implement project bus MVP

This commit is contained in:
Codex Lead Engineer
2026-07-30 02:13:26 +02:00
commit bc55924198
28 changed files with 3518 additions and 0 deletions
+144
View File
@@ -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)
);