//! kei-content-store EntitySchema — declarative spec consumed by //! `kei_entity_store::Store` and its verb templates. //! //! Primary entity is the `content_units` table (assets). Prompts, //! campaigns, and `campaign_assets` ride `custom_migrations` because //! they are separate tables that keep their existing column names so //! `prompts.rs` / `campaigns.rs` compile unchanged. use kei_entity_store::schema::{EdgeKeyKind, EntitySchema, FieldDef}; static FIELDS: &[FieldDef] = &[ FieldDef::pk("id"), FieldDef::text_default("unit_type", "asset"), FieldDef::text_nn("title"), FieldDef::text("content"), FieldDef::text("media_type"), FieldDef::text("file_path"), FieldDef::text("file_hash"), FieldDef::text("provider"), FieldDef::integer("cost_cents"), FieldDef::integer("parent_id"), FieldDef::created_at(), FieldDef::updated_at(), ]; const DDL_SECONDARY: &str = r#" CREATE INDEX IF NOT EXISTS idx_cu_type ON content_units(unit_type); CREATE INDEX IF NOT EXISTS idx_cu_hash ON content_units(file_hash) WHERE file_hash != ''; CREATE TABLE IF NOT EXISTS prompts ( id INTEGER PRIMARY KEY, prompt_text TEXT NOT NULL, prompt_hash TEXT NOT NULL, prompt_type TEXT DEFAULT '', model TEXT DEFAULT '', version INTEGER DEFAULT 1, parent_id INTEGER DEFAULT 0, created_at INTEGER NOT NULL, UNIQUE(prompt_hash, model) ); CREATE TABLE IF NOT EXISTS campaigns ( id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT DEFAULT '', status TEXT DEFAULT 'draft', created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS campaign_assets ( campaign_id INTEGER NOT NULL, asset_id INTEGER NOT NULL, PRIMARY KEY(campaign_id, asset_id) ); "#; pub static CONTENT_SCHEMA: EntitySchema = EntitySchema { name: "asset", table: "content_units", fields: FIELDS, enabled_verbs: &["create", "get", "list", "search", "update", "delete"], fts_columns: Some(&["title", "content"]), edge_table: None, edge_key_kind: EdgeKeyKind::IntegerPair, archived_field: None, custom_migrations: &[DDL_SECONDARY], };