PR D: typed + signed event bus + events table + SSE (arch step 5) (#8)
Some checks failed
CI / Frontend Lint (push) Has been cancelled
CI / Frontend Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Frontend E2E Tests (push) Has been cancelled
CI / Orchestrator Build (push) Has been cancelled
CI / Contracts Compile (push) Has been cancelled
CI / Contracts Test (push) Has been cancelled
Security Scan / Dependency Vulnerability Scan (push) Has been cancelled
Security Scan / OWASP ZAP Scan (push) Has been cancelled
Some checks failed
CI / Frontend Lint (push) Has been cancelled
CI / Frontend Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Frontend E2E Tests (push) Has been cancelled
CI / Orchestrator Build (push) Has been cancelled
CI / Contracts Compile (push) Has been cancelled
CI / Contracts Test (push) Has been cancelled
Security Scan / Dependency Vulnerability Scan (push) Has been cancelled
Security Scan / OWASP ZAP Scan (push) Has been cancelled
This commit was merged in pull request #8.
This commit is contained in:
43
orchestrator/src/db/migrations/003_events.ts
Normal file
43
orchestrator/src/db/migrations/003_events.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { query } from "../postgres";
|
||||
|
||||
/**
|
||||
* Migration 003 — append-only events journal (arch §4.5, §5.5, §7).
|
||||
*
|
||||
* The `events` table is the system-of-record for normalised workflow
|
||||
* events (arch §7.2: `transaction.created`, `instrument.ready`,
|
||||
* `payment.settled`, `transaction.committed`, …). It is:
|
||||
*
|
||||
* - append-only (no UPDATE / DELETE)
|
||||
* - signed (HMAC of (plan_id, type, payload_hash, prev_hash))
|
||||
* - hash-chained via prev_hash for tamper-evident forensic replay
|
||||
* - indexed by plan_id so the SSE endpoint can stream efficiently
|
||||
*/
|
||||
export async function up() {
|
||||
await query(
|
||||
`CREATE TABLE IF NOT EXISTS events (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
plan_id UUID NOT NULL REFERENCES plans(plan_id) ON DELETE CASCADE,
|
||||
type VARCHAR(128) NOT NULL,
|
||||
actor VARCHAR(255),
|
||||
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
payload_hash CHAR(64) NOT NULL,
|
||||
prev_hash CHAR(64),
|
||||
signature CHAR(64) NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
);
|
||||
|
||||
await query(
|
||||
`CREATE INDEX IF NOT EXISTS idx_events_plan_id_created
|
||||
ON events(plan_id, created_at)`,
|
||||
);
|
||||
|
||||
await query(
|
||||
`CREATE INDEX IF NOT EXISTS idx_events_type
|
||||
ON events(type)`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function down() {
|
||||
await query("DROP TABLE IF EXISTS events CASCADE");
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { up as up001 } from "./001_initial_schema";
|
||||
import { up as up002 } from "./002_transaction_state";
|
||||
import { up as up003 } from "./003_events";
|
||||
|
||||
/**
|
||||
* Run all migrations
|
||||
@@ -8,6 +9,7 @@ export async function runMigration() {
|
||||
try {
|
||||
await up001();
|
||||
await up002();
|
||||
await up003();
|
||||
console.log("All migrations completed");
|
||||
} catch (error) {
|
||||
console.error("Migration failed:", error);
|
||||
|
||||
Reference in New Issue
Block a user