/** * SQL constants for database schema and FTS5. * * Extracted to a standalone module (SMI-3910) so both schema.ts and * migration-runner.ts can import them without circular dependencies. */ /** * SQL statements for creating the database schema */ export declare const SCHEMA_SQL = "\n-- Enable WAL mode for better concurrent performance\nPRAGMA journal_mode = WAL;\nPRAGMA synchronous = NORMAL;\nPRAGMA cache_size = -64000; -- 64MB cache\nPRAGMA temp_store = MEMORY;\n\n-- Schema version tracking\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Skills table - main storage for discovered skills\nCREATE TABLE IF NOT EXISTS skills (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n description TEXT,\n author TEXT,\n repo_url TEXT UNIQUE,\n quality_score REAL CHECK(quality_score IS NULL OR (quality_score >= 0 AND quality_score <= 1)),\n trust_tier TEXT CHECK(trust_tier IN ('official', 'verified', 'curated', 'community', 'experimental', 'unknown', 'unverified', 'local')) DEFAULT 'unknown', -- SMI-4665: added 'local'; SMI-4917: added 'curated'; SMI-5205: added 'official', 'unverified'\n tags TEXT DEFAULT '[]', -- JSON array of tags\n risk_score INTEGER CHECK(risk_score IS NULL OR (risk_score >= 0 AND risk_score <= 100)), -- SMI-825\n security_findings_count INTEGER DEFAULT 0,\n security_scanned_at TEXT,\n security_passed INTEGER, -- boolean: 1 = passed, 0 = failed, NULL = not scanned\n compatibility TEXT DEFAULT '[]', -- SMI-2760: JSON array of IDE/LLM/platform slugs\n content_hash TEXT, -- SMI-3510: SHA-256 hash of SKILL.md for tamper detection\n source TEXT NOT NULL DEFAULT 'registry' CHECK (source IN ('registry', 'local')), -- SMI-4665: filesystem-imported rows opt out of sync overwrites\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- FTS5 virtual table for full-text search with BM25 ranking\nCREATE VIRTUAL TABLE IF NOT EXISTS skills_fts USING fts5(\n name,\n description,\n tags,\n author,\n content='skills',\n content_rowid='rowid',\n tokenize='porter unicode61'\n);\n\n-- Triggers to keep FTS index in sync with skills table\nCREATE TRIGGER IF NOT EXISTS skills_ai AFTER INSERT ON skills BEGIN\n INSERT INTO skills_fts(rowid, name, description, tags, author)\n VALUES (NEW.rowid, NEW.name, NEW.description, NEW.tags, NEW.author);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS skills_ad AFTER DELETE ON skills BEGIN\n INSERT INTO skills_fts(skills_fts, rowid, name, description, tags, author)\n VALUES ('delete', OLD.rowid, OLD.name, OLD.description, OLD.tags, OLD.author);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS skills_au AFTER UPDATE ON skills BEGIN\n INSERT INTO skills_fts(skills_fts, rowid, name, description, tags, author)\n VALUES ('delete', OLD.rowid, OLD.name, OLD.description, OLD.tags, OLD.author);\n INSERT INTO skills_fts(rowid, name, description, tags, author)\n VALUES (NEW.rowid, NEW.name, NEW.description, NEW.tags, NEW.author);\nEND;\n\n-- Sources table - tracks where skills are discovered from\nCREATE TABLE IF NOT EXISTS sources (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n type TEXT NOT NULL CHECK(type IN ('github', 'gitlab', 'local', 'registry')),\n url TEXT NOT NULL UNIQUE,\n last_sync_at TEXT,\n is_active INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Categories table - hierarchical organization of skills\nCREATE TABLE IF NOT EXISTS categories (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT,\n parent_id TEXT REFERENCES categories(id) ON DELETE SET NULL,\n skill_count INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Skill-Category junction table\nCREATE TABLE IF NOT EXISTS skill_categories (\n skill_id TEXT NOT NULL REFERENCES skills(id) ON DELETE CASCADE,\n category_id TEXT NOT NULL REFERENCES categories(id) ON DELETE CASCADE,\n PRIMARY KEY (skill_id, category_id)\n);\n\n-- Cache table for search results and API responses\nCREATE TABLE IF NOT EXISTS cache (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n expires_at INTEGER, -- Unix timestamp, NULL for no expiry\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes for common query patterns\nCREATE INDEX IF NOT EXISTS idx_skills_author ON skills(author);\nCREATE INDEX IF NOT EXISTS idx_skills_trust_tier ON skills(trust_tier);\nCREATE INDEX IF NOT EXISTS idx_skills_quality_score ON skills(quality_score);\nCREATE INDEX IF NOT EXISTS idx_skills_updated_at ON skills(updated_at);\nCREATE INDEX IF NOT EXISTS idx_skills_created_at ON skills(created_at);\nCREATE INDEX IF NOT EXISTS idx_skills_risk_score ON skills(risk_score);\nCREATE INDEX IF NOT EXISTS idx_skills_security_passed ON skills(security_passed);\nCREATE INDEX IF NOT EXISTS idx_sources_type ON sources(type);\nCREATE INDEX IF NOT EXISTS idx_sources_is_active ON sources(is_active);\nCREATE INDEX IF NOT EXISTS idx_categories_parent ON categories(parent_id);\nCREATE INDEX IF NOT EXISTS idx_cache_expires ON cache(expires_at);\n\n-- SMI-733: Audit logs table for security monitoring\n-- See: docs/security/index.md \u00A73 Audit Logging\nCREATE TABLE IF NOT EXISTS audit_logs (\n id TEXT PRIMARY KEY,\n event_type TEXT NOT NULL,\n timestamp TEXT NOT NULL DEFAULT (datetime('now')),\n actor TEXT,\n resource TEXT,\n action TEXT,\n result TEXT,\n metadata TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_audit_event_type ON audit_logs(event_type);\nCREATE INDEX IF NOT EXISTS idx_audit_timestamp ON audit_logs(timestamp);\nCREATE INDEX IF NOT EXISTS idx_audit_resource ON audit_logs(resource);\nCREATE INDEX IF NOT EXISTS idx_audit_result ON audit_logs(result);\nCREATE INDEX IF NOT EXISTS idx_audit_actor ON audit_logs(actor);\n"; /** * SMI-974: Migration SQL for adding FTS5 to existing database * Run separately as FTS5 creation can fail if table exists */ export declare const FTS5_MIGRATION_SQL = "\n-- Create FTS5 virtual table if not exists\nCREATE VIRTUAL TABLE IF NOT EXISTS skills_fts USING fts5(\n name,\n description,\n tags,\n author,\n content='skills',\n content_rowid='rowid',\n tokenize='porter unicode61'\n);\n\n-- Populate FTS from existing skills (safe to run multiple times)\nINSERT OR IGNORE INTO skills_fts(rowid, name, description, tags, author)\nSELECT rowid, name, description, tags, author FROM skills;\n"; //# sourceMappingURL=schema-sql.d.ts.map