// Additive meeting-transcript schema used by the feature's one-time lazy ensure. import type { DatabaseSync } from "node:sqlite"; import { openOpenClawStateDatabase, runOpenClawStateWriteTransaction, type OpenClawStateDatabaseOptions, } from "../state/openclaw-state-db.js"; const ensuredDatabases = new WeakSet(); const MEETING_TRANSCRIPTS_SCHEMA_SQL = ` CREATE TABLE IF NOT EXISTS meeting_transcript_sessions ( session_id TEXT NOT NULL, started_at TEXT NOT NULL, selector TEXT NOT NULL UNIQUE, export_key TEXT NOT NULL, session_slug TEXT NOT NULL, provider_id TEXT NOT NULL, title TEXT, source_json TEXT NOT NULL, stopped_at TEXT, metadata_json TEXT, export_manifest_json TEXT NOT NULL DEFAULT '{}', export_pending_json TEXT NOT NULL DEFAULT '[]', next_utterance_seq INTEGER NOT NULL DEFAULT 0 CHECK (next_utterance_seq >= 0), created_at_ms INTEGER NOT NULL CHECK (created_at_ms >= 0), updated_at_ms INTEGER NOT NULL CHECK (updated_at_ms >= 0), PRIMARY KEY (session_id, started_at) ) STRICT; CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_started ON meeting_transcript_sessions(started_at DESC, session_id); CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_id ON meeting_transcript_sessions(session_id, started_at DESC); CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_slug ON meeting_transcript_sessions(session_slug, started_at DESC); CREATE INDEX IF NOT EXISTS idx_meeting_transcript_sessions_export_key ON meeting_transcript_sessions(export_key); CREATE TABLE IF NOT EXISTS meeting_transcript_utterances ( session_id TEXT NOT NULL, session_started_at TEXT NOT NULL, sequence INTEGER NOT NULL CHECK (sequence >= 0), utterance_id TEXT, started_at TEXT, ended_at TEXT, speaker_id TEXT, speaker_label TEXT, text TEXT NOT NULL, final INTEGER CHECK (final IN (0, 1)), metadata_json TEXT, PRIMARY KEY (session_id, session_started_at, sequence), FOREIGN KEY (session_id, session_started_at) REFERENCES meeting_transcript_sessions(session_id, started_at) ON DELETE CASCADE ) STRICT; CREATE TABLE IF NOT EXISTS meeting_transcript_summaries ( session_id TEXT NOT NULL, session_started_at TEXT NOT NULL, generated_at TEXT, summary_json TEXT, markdown TEXT, utterance_count INTEGER NOT NULL CHECK (utterance_count >= 0), PRIMARY KEY (session_id, session_started_at), FOREIGN KEY (session_id, session_started_at) REFERENCES meeting_transcript_sessions(session_id, started_at) ON DELETE CASCADE, CHECK (summary_json IS NOT NULL OR markdown IS NOT NULL) ) STRICT; `; export function ensureMeetingTranscriptsSchema(options: OpenClawStateDatabaseOptions = {}): void { const database = openOpenClawStateDatabase(options); if (ensuredDatabases.has(database.db)) { return; } runOpenClawStateWriteTransaction(({ db }) => db.exec(MEETING_TRANSCRIPTS_SCHEMA_SQL), options, { operationLabel: "meeting-transcripts.schema.ensure", }); ensuredDatabases.add(database.db); }