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:
parent
08c6504589
commit
2aac10fc5d
14 changed files with 552 additions and 28 deletions
|
|
@ -332,6 +332,40 @@ describe.skipIf(!enabled)('cross-device sync against local Supabase', () => {
|
|||
vi.restoreAllMocks()
|
||||
}, 60_000)
|
||||
|
||||
it('데스크톱 전사가 폰이 그리는 구간으로 올라가고, 고친 프리셋 프롬프트가 폰 명령에 쓰인다', async () => {
|
||||
const db = testDb.db
|
||||
const meetingId = crypto.randomUUID()
|
||||
const now = Date.now()
|
||||
db.insert(meetingSessions).values({
|
||||
id: meetingId,
|
||||
title: 'segments',
|
||||
status: 'completed',
|
||||
startedAt: now,
|
||||
rawTranscript: '[00:00] one\n[00:04] two\n[00:09] three',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
}).run()
|
||||
enqueueChange('meetings', meetingId, 'upsert')
|
||||
getCustomInstructionService().update('builtin-summarize', { prompt: '두 줄로 요약' })
|
||||
enqueueChange('builtin_instructions', 'builtin-summarize', 'upsert')
|
||||
const first = await engine.flush()
|
||||
expect(first.errors).toEqual([])
|
||||
const segments = must(await mobile.from('transcripts').select('segment_index,text,edited').eq('meeting_id', meetingId).order('segment_index'))
|
||||
expect(segments.map((s) => s.text)).toEqual(['one', 'two', 'three'])
|
||||
|
||||
db.update(meetingSessions).set({ editedTranscript: '[00:00] [화자 1] one fixed', updatedAt: Date.now() }).where(eq(meetingSessions.id, meetingId)).run()
|
||||
enqueueChange('meetings', meetingId, 'upsert')
|
||||
expect((await engine.flush()).errors).toEqual([])
|
||||
const edited = must(await mobile.from('transcripts').select('text,speaker,edited').eq('meeting_id', meetingId))
|
||||
expect(edited).toEqual([{ text: 'one fixed', speaker: '화자 1', edited: true }])
|
||||
|
||||
const summarize = must(await mobile.from('custom_instructions').select('prompt').eq('user_id', userId).eq('builtin_key', 'summarize').single())
|
||||
expect(summarize.prompt).toBe('두 줄로 요약')
|
||||
// 폰은 여전히 프리셋 행을 직접 고칠 수 없다(RLS)
|
||||
const blocked = await mobile.from('custom_instructions').update({ prompt: 'hack' }).eq('user_id', userId).eq('builtin_key', 'summarize').select('id')
|
||||
expect(blocked.data ?? []).toEqual([])
|
||||
})
|
||||
|
||||
it('데스크톱이 기기 목록에 나타나고, 모바일에서 해제하면 revoked가 된다', async () => {
|
||||
const info = { deviceName: 'IT-DESKTOP', appVersion: '9.9.9', osVersion: 'test' }
|
||||
const first = await checkInDesktopDevice(desktop, userId, 'signin', info, null)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue