feat(desktop): send meeting transcript segments and preset prompt edits to the phone

The phone draws a meeting from its transcript segments before the edited
transcript, so desktop edits, auto-polish and diarization never showed there.
Every desktop transcript change now rebuilds the meeting's segments from its
[MM:SS] [speaker] lines and trims the rest; the line parser moves to
@d3ro/core/meeting-transcript and the meeting view uses it too.

Prompt edits of the four desktop presets that exist on the phone update the
server preset row (a reset restores its default; {{targetLanguage}} is sent
as English, the only target on both sides), and edits made on another desktop
come back. The free-prompt preset has no phone counterpart and stays local.
This commit is contained in:
Yun Chan 2026-09-27 16:24:25 +09:00
parent 08c6504589
commit 2aac10fc5d
14 changed files with 552 additions and 28 deletions

View file

@ -18,6 +18,7 @@ import { getDictationTemplateService } from '../DictationTemplateService'
import { getMeetingDocTemplateService } from '../MeetingDocTemplateService'
import { getRAGService } from '../RAGService'
import { purgeRemoteAudio } from './audio-sync'
import { pushMeetingSegments } from './transcript-sync'
import { dropEntry } from './sync-outbox'
import {
SyncRemoteError,
@ -441,6 +442,17 @@ const meetingsAdapter: SyncAdapter = {
'meetings',
rows.map((r) => ({ id: r.id, row: meetingToRemote(r, ctx.userId) }))
)
// 회의 행이 올라간 뒤 전사 구간을 맞춘다 — 폰은 구간이 있으면 구간을 그린다.
const byId = new Map(rows.map((r) => [r.id, r]))
for (const outcome of outcomes) {
const row = byId.get(outcome.id)
if (outcome.error !== null || !row) continue
try {
await pushMeetingSegments(ctx, row)
} catch (err) {
outcome.error = toSyncRemoteError(err)
}
}
return [...outcomes, ...missingAsDone(ids, found)]
},
async pushDeletes(ctx, ids) {