mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-03 10:51:35 +00:00
* refactor(transcripts): move meeting transcripts to sqlite * perf(transcripts): batch legacy utterance staging * fix(transcripts): report recovery moves on migration failure * fix(transcripts): refresh archive membership after recovery * fix(transcripts): omit failed summary export paths * fix(transcripts): type restore metadata tuple * fix(transcripts): align migration contract gates * fix(transcripts): verify case-aliased export ownership * fix(transcripts): allowlist doctor verifier sqlite query * fix(transcripts): preflight partial artifact recovery * fix(transcripts): stabilize exports and legacy path checks * fix(transcripts): resolve case-renamed doctor ownership * fix(transcripts): harden canonical export recovery * fix(transcripts): preserve pending import boundaries * refactor(transcripts): split migration insert transaction * perf(transcripts): query selected summary existence
85 lines
3.0 KiB
TypeScript
85 lines
3.0 KiB
TypeScript
// 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<DatabaseSync>();
|
|
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);
|
|
}
|