miroir/crates/miroir-core/migrations/002_feature_tables.sql
jedarden 3c06c51ce8 P3.4: Implement schema versioning system
Implement a first-class schema version system with the following components:

- schema_versions table (SQLite) tracking applied migrations
- Numbered migration files (001_initial.sql, 002_feature_tables.sql)
- MigrationRegistry for version validation and pending migration detection
- Startup: read current version → apply pending migrations → record latest
- Refuse to start if DB version > binary version (SchemaVersionAhead error)

Acceptance criteria met:
- First run creates schema at version 001
- Second run is a no-op (single SELECT for version check)
- Store version > binary version fails with SchemaVersionAhead error
- Migration metadata structure is backend-agnostic (shared by SQLite/Redis)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 00:13:19 -04:00

78 lines
2.6 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Migration 002: Feature-flagged tables 814
-- These tables are only used when their respective features are enabled
-- (canary_runner, CDC, tenant_map API key mode, ILM rollover, search UI, admin sessions)
-- Table 8: canaries (plan §13.18)
CREATE TABLE IF NOT EXISTS canaries (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
index_uid TEXT NOT NULL,
interval_s INTEGER NOT NULL,
query_json TEXT NOT NULL,
assertions_json TEXT NOT NULL,
enabled INTEGER NOT NULL,
created_at INTEGER NOT NULL
);
-- Table 9: canary_runs (plan §13.18)
-- Auto-pruned to run_history_per_canary (default 100) on insert
CREATE TABLE IF NOT EXISTS canary_runs (
canary_id TEXT NOT NULL,
ran_at INTEGER NOT NULL,
status TEXT NOT NULL,
latency_ms INTEGER NOT NULL,
failed_assertions_json TEXT,
PRIMARY KEY (canary_id, ran_at)
);
-- Table 10: cdc_cursors (plan §13.13)
-- Composite PK on (sink_name, index_uid) for update-in-place
CREATE TABLE IF NOT EXISTS cdc_cursors (
sink_name TEXT NOT NULL,
index_uid TEXT NOT NULL,
last_event_seq INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
PRIMARY KEY (sink_name, index_uid)
);
-- Table 11: tenant_map (plan §13.15)
-- api_key_hash is a 32-byte BLOB (raw sha256, never plaintext)
CREATE TABLE IF NOT EXISTS tenant_map (
api_key_hash BLOB PRIMARY KEY,
tenant_id TEXT NOT NULL,
group_id INTEGER
);
-- Table 12: rollover_policies (plan §13.17)
CREATE TABLE IF NOT EXISTS rollover_policies (
name TEXT PRIMARY KEY,
write_alias TEXT NOT NULL,
read_alias TEXT NOT NULL,
pattern TEXT NOT NULL,
triggers_json TEXT NOT NULL,
retention_json TEXT NOT NULL,
template_json TEXT NOT NULL,
enabled INTEGER NOT NULL
);
-- Table 13: search_ui_config (plan §13.21)
CREATE TABLE IF NOT EXISTS search_ui_config (
index_uid TEXT PRIMARY KEY,
config_json TEXT NOT NULL,
updated_at INTEGER NOT NULL
);
-- Table 14: admin_sessions (plan §13.19)
CREATE TABLE IF NOT EXISTS admin_sessions (
session_id TEXT PRIMARY KEY,
csrf_token TEXT NOT NULL,
admin_key_hash TEXT NOT NULL,
created_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL,
revoked INTEGER NOT NULL DEFAULT 0,
user_agent TEXT,
source_ip TEXT
);
-- Index for lazy eviction of expired admin sessions (plan §4 footnote)
CREATE INDEX IF NOT EXISTS admin_sessions_expires ON admin_sessions(expires_at);