CREATE TABLE IF NOT EXISTS room_resource_events ( sequence BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, event_id TEXT NOT NULL UNIQUE, scope_type SMALLINT NOT NULL, room_id BIGINT, user_id BIGINT, aggregate_type TEXT NOT NULL, aggregate_id TEXT NOT NULL, resource_type TEXT NOT NULL, resource_id TEXT NOT NULL, event_type TEXT NOT NULL, event_version BIGINT NOT NULL DEFAULT 1, aggregate_version BIGINT, actor_user_id BIGINT, payload JSONB, summary JSONB NOT NULL, occurred_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CHECK (event_version >= 1), CHECK (jsonb_typeof(summary) = 'object'), CHECK (payload IS NULL OR jsonb_typeof(payload) = 'object') ); CREATE INDEX IF NOT EXISTS idx_room_resource_events_room_sequence ON room_resource_events(room_id, sequence) WHERE room_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_room_resource_events_room_resource_sequence ON room_resource_events(room_id, resource_type, sequence) WHERE room_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_room_resource_events_user_sequence ON room_resource_events(user_id, sequence) WHERE user_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_room_resource_events_aggregate_sequence ON room_resource_events(aggregate_type, aggregate_id, sequence); CREATE INDEX IF NOT EXISTS idx_room_resource_events_resource_sequence ON room_resource_events(resource_type, resource_id, sequence); CREATE INDEX IF NOT EXISTS idx_room_resource_events_created_at ON room_resource_events(created_at, sequence);