feat(relay): Phase1 foundation — P3 Postgres store + async capability verifier + compose
RELAY-PHASE1 Wave A (2/3) + E1 infra: - A1: createPgStores() Postgres adapter for all 9 P3 store ports + runMigrations(); writable-CTE atomic INV8 status swaps; 0002_routes.sql. 23/23 pg tests, 96.72% cov. - A3: real capability verifier delegating to relay-auth verifyCapabilityToken; sync->async seam across authz/provision/main. Full CP suite 15 files/101 pass, tsc clean. - E1: deploy/docker-compose.yml (Postgres16+Redis7, loopback-only) + .env.example. - docs: PLAN_RELAY_PHASE1.md file-level execution spec; PROGRESS_LOG RELAY-PHASE1 section.
This commit is contained in:
15
control-plane/db/migrations/0002_routes.sql
Normal file
15
control-plane/db/migrations/0002_routes.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- A1 — routes table (P3-owned). Not present in 0001_init.sql: the RouteStore port is a
|
||||
-- Redis-like live routing table (INV7 — NOT source of truth). This Postgres adapter needs a
|
||||
-- durable backing for it. Postgres has no per-key TTL, so we store an explicit `expires_at`
|
||||
-- and treat `expires_at <= now()` as ABSENT (fail-closed, INV7); expired rows are lazily
|
||||
-- DELETEd on access. This mirrors `store/memory.ts` memRouteStore() semantics exactly.
|
||||
--
|
||||
-- No FK to hosts(host_id): routes are an ephemeral location cache keyed by host_id, decoupled
|
||||
-- from the ownership source of truth (matches memory.ts, where routes live independently).
|
||||
CREATE TABLE IF NOT EXISTS routes (
|
||||
host_id uuid PRIMARY KEY,
|
||||
relay_node_id text NOT NULL,
|
||||
updated_at timestamptz NOT NULL,
|
||||
expires_at timestamptz NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS routes_node_idx ON routes(relay_node_id);
|
||||
Reference in New Issue
Block a user