chore: align sqlite control plane architecture
- replace default Convex control-plane wording with Rust SQLite control-plane across architecture, AGENTS, Reasonix, and design docs - retire root Convex functions source and deploy script into recycle while keeping explicit cloud/compat/sync-replica boundaries - add control-plane migration guard/docs and keep CodeGraph refreshed after the SQLite control-plane cutover
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
-- 001-initial-schema.sql
|
||||
-- MNote control-plane v1 schema
|
||||
--
|
||||
-- All tables use TEXT for datetime columns (ISO-8601) so the database
|
||||
-- remains readable without language-specific timestamp types.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id TEXT PRIMARY KEY,
|
||||
email TEXT UNIQUE,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
display_name TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'user',
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth_identities (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
provider TEXT NOT NULL,
|
||||
provider_subject TEXT NOT NULL,
|
||||
password_hash TEXT,
|
||||
password_version INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
UNIQUE(provider, provider_subject)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth_sessions (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
token_hash TEXT NOT NULL UNIQUE,
|
||||
user_agent TEXT,
|
||||
ip_hash TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
expires_at TEXT NOT NULL,
|
||||
revoked_at TEXT,
|
||||
last_seen_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_auth_sessions_user ON auth_sessions(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_auth_sessions_token ON auth_sessions(token_hash);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspaces (
|
||||
id TEXT PRIMARY KEY,
|
||||
owner_user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
kind TEXT NOT NULL DEFAULT 'personal',
|
||||
root_uri TEXT NOT NULL UNIQUE,
|
||||
root_path TEXT NOT NULL,
|
||||
source_kind TEXT NOT NULL DEFAULT 'local_folder',
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_workspaces_owner ON workspaces(owner_user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS workspace_members (
|
||||
id TEXT PRIMARY KEY,
|
||||
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1,
|
||||
UNIQUE(workspace_id, user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS directory_grants (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
workspace_id TEXT REFERENCES workspaces(id) ON DELETE SET NULL,
|
||||
root_uri TEXT NOT NULL,
|
||||
root_path TEXT NOT NULL,
|
||||
permission TEXT NOT NULL,
|
||||
recursive INTEGER NOT NULL DEFAULT 1,
|
||||
capabilities_json TEXT NOT NULL DEFAULT '[]',
|
||||
source TEXT NOT NULL DEFAULT 'admin',
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_by TEXT REFERENCES users(id),
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_directory_grants_user ON directory_grants(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_directory_grants_root_uri ON directory_grants(root_uri);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS share_links (
|
||||
id TEXT PRIMARY KEY,
|
||||
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
||||
resource_kind TEXT NOT NULL,
|
||||
resource_id TEXT NOT NULL,
|
||||
token_hash TEXT NOT NULL UNIQUE,
|
||||
permission TEXT NOT NULL,
|
||||
created_by TEXT NOT NULL REFERENCES users(id),
|
||||
expires_at TEXT,
|
||||
revoked_at TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_share_links_resource ON share_links(workspace_id, resource_kind, resource_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sync_state (
|
||||
id TEXT PRIMARY KEY,
|
||||
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
||||
remote_kind TEXT NOT NULL,
|
||||
remote_id TEXT,
|
||||
cursor TEXT,
|
||||
last_synced_at TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'idle',
|
||||
error_json TEXT,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1,
|
||||
UNIQUE(workspace_id, remote_kind)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_policies (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
|
||||
workspace_id TEXT REFERENCES workspaces(id) ON DELETE CASCADE,
|
||||
allowed_roots_json TEXT NOT NULL DEFAULT '[]',
|
||||
model_policy_json TEXT NOT NULL DEFAULT '{}',
|
||||
quota_json TEXT NOT NULL DEFAULT '{}',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id TEXT PRIMARY KEY,
|
||||
actor_user_id TEXT REFERENCES users(id),
|
||||
action TEXT NOT NULL,
|
||||
target_kind TEXT NOT NULL,
|
||||
target_id TEXT,
|
||||
metadata_json TEXT NOT NULL DEFAULT '{}',
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_actor ON audit_log(actor_user_id, created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_target ON audit_log(target_kind, target_id, created_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS outbox_events (
|
||||
id TEXT PRIMARY KEY,
|
||||
topic TEXT NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
delivered_at TEXT,
|
||||
attempts INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_outbox_pending ON outbox_events(delivered_at, created_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS legacy_id_map (
|
||||
id TEXT PRIMARY KEY,
|
||||
legacy_system TEXT NOT NULL,
|
||||
legacy_kind TEXT NOT NULL,
|
||||
legacy_id TEXT NOT NULL,
|
||||
new_kind TEXT NOT NULL,
|
||||
new_id TEXT NOT NULL,
|
||||
metadata_json TEXT NOT NULL DEFAULT '{}',
|
||||
created_at TEXT NOT NULL,
|
||||
UNIQUE(legacy_system, legacy_kind, legacy_id)
|
||||
);
|
||||
@@ -0,0 +1,48 @@
|
||||
-- 002-ai-runtime-store.sql
|
||||
-- MNote ACP/Hermes runtime session store.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_runtime_runs (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL,
|
||||
workspace_id TEXT,
|
||||
document_id TEXT,
|
||||
session_id TEXT NOT NULL,
|
||||
run_id TEXT NOT NULL UNIQUE,
|
||||
title TEXT,
|
||||
profile TEXT NOT NULL,
|
||||
acp_runtime TEXT NOT NULL,
|
||||
trace_id TEXT,
|
||||
status TEXT NOT NULL,
|
||||
runtime_json TEXT NOT NULL DEFAULT '{}',
|
||||
payload_json TEXT NOT NULL DEFAULT '{}',
|
||||
deleted_at TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
revision INTEGER NOT NULL DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_runtime_runs_user_session
|
||||
ON ai_runtime_runs(user_id, session_id, updated_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_runtime_runs_workspace
|
||||
ON ai_runtime_runs(workspace_id, updated_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_runtime_runs_document
|
||||
ON ai_runtime_runs(document_id, updated_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_runtime_events (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL,
|
||||
workspace_id TEXT,
|
||||
document_id TEXT,
|
||||
session_id TEXT NOT NULL,
|
||||
run_id TEXT NOT NULL,
|
||||
profile TEXT NOT NULL,
|
||||
acp_runtime TEXT NOT NULL,
|
||||
event_type TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL DEFAULT '{}',
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_runtime_events_run
|
||||
ON ai_runtime_events(user_id, run_id, created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_ai_runtime_events_session
|
||||
ON ai_runtime_events(user_id, session_id, created_at);
|
||||
Reference in New Issue
Block a user