-- OGraph v2.2 Schema
-- RFC-016 v2.2: Event, Projection, Reaction (8 tables)

-- Drop all v2.1 tables
DROP TABLE IF EXISTS projection_deps;
DROP TABLE IF EXISTS projections;
DROP TABLE IF EXISTS projection_defs;
DROP TABLE IF EXISTS event_refs;
DROP TABLE IF EXISTS events;
DROP TABLE IF EXISTS event_defs;
DROP TABLE IF EXISTS objects;
DROP TABLE IF EXISTS object_defs;
DROP TABLE IF EXISTS reactions;

-- ============================================
-- Definition Layer (3 tables)
-- ============================================

CREATE TABLE object_defs (
  name TEXT PRIMARY KEY
);

CREATE TABLE event_defs (
  name TEXT PRIMARY KEY,
  schema TEXT NOT NULL           -- JSON: { properties: { ... } }
);

CREATE TABLE projection_defs (
  name TEXT PRIMARY KEY,
  driven_by TEXT NOT NULL,       -- JSON: ["assigned", "reassigned"]
  params TEXT NOT NULL,          -- JSON: input schema, e.g. {"task": {"type": "ref"}}
  filter TEXT NOT NULL,          -- JSONata: $event 精筛
  expression TEXT NOT NULL,      -- JSONata: ($state, $events) → new_state
  initial_value TEXT             -- JSON: 初始值
);

-- ============================================
-- Instance Layer (5 tables)
-- ============================================

CREATE TABLE objects (
  id TEXT PRIMARY KEY,
  type TEXT NOT NULL REFERENCES object_defs(name),
  created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
);

CREATE TABLE events (
  id TEXT PRIMARY KEY,
  type TEXT NOT NULL REFERENCES event_defs(name),
  payload TEXT NOT NULL,         -- JSON: flat key-value
  created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
);

CREATE TABLE event_refs (
  event_id TEXT NOT NULL REFERENCES events(id),
  property TEXT NOT NULL,
  ref_id TEXT NOT NULL REFERENCES objects(id),
  PRIMARY KEY (event_id, property)
);

CREATE INDEX idx_event_refs_obj ON event_refs(ref_id);

CREATE TABLE projections (
  def TEXT NOT NULL REFERENCES projection_defs(name),
  params_hash TEXT NOT NULL,
  params TEXT NOT NULL,          -- JSON: 实际参数值
  value TEXT,                    -- JSON: 当前值
  created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),
  updated_at INTEGER,
  PRIMARY KEY (def, params_hash)
);

CREATE TABLE reactions (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  projection_def TEXT NOT NULL REFERENCES projection_defs(name),
  params_hash TEXT NOT NULL,
  params TEXT NOT NULL,          -- JSON: 监听哪个 projection 实例的参数
  webhook_url TEXT NOT NULL,
  created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)
);

CREATE INDEX idx_reactions_projection ON reactions(projection_def, params_hash);
