feat(desktop+web): Phase 3.3 Auto push on write + transcript fallback + dashboard Link (빅뱅 Phase 5 Part 3)
Desktop — CloudSyncService: - pushOne(table, id) 제네릭 단건 push 신규 (history/dictionary/meetings/meeting_memos/meeting_documents) - 로그인 미상태 silent noop, 실패 시 warn만 (로컬 write 절대 차단 금지) - 5개 row→payload 매퍼(_mapHistoryPayload 외 4개) private 메서드로 추출, pushAll과 공유 (DRY) Desktop — write hook 8곳 fire-and-forget 연결: - HistoryService.create / generateTitle - MeetingSummaryService.generateSummary (summaryText 저장 후) - DictionaryService.add / update - MeetingModeService.startRecording (부모 meeting pre-push — 자식 memo/doc RLS 통과용) - MeetingModeService.addMemo / generateDocument - MeetingModeService._runPostProcessing (완료 상태 최종 저장 후) Web — meeting detail page: - transcripts 테이블이 비고 status!=recording인 경우 meeting.raw_transcript(또는 edited_transcript) 를 whiteSpace:pre-wrap으로 fallback 렌더 - 실시간 구독 경로(LiveTranscriptList)는 recording 상태 또는 transcripts 존재 시에만 마운트 Web — dashboard: - RECENT MEETINGS의 MetalCard를 next/link Link로 감싸 /meetings/[id] 이동 가능 - cursor pointer + hover lift 효과 실증: 재기동 직후 pushAll 캐치업이 이전 세션 RLS 실패 메모 2건을 재시도 → pushed=4 성공. 새 녹음 → pushOne history/... ok 실시간 발화 → 웹에서 전사/메모 렌더 확인 (사용자 "잘 전사와 메모가 올라왔어")
This commit is contained in:
parent
4e6280bc69
commit
046ac857cb
8 changed files with 344 additions and 85 deletions
|
|
@ -8,6 +8,7 @@ import fs from 'fs'
|
|||
import { eq, desc, sql } from 'drizzle-orm'
|
||||
import { getLogger } from './LoggerService'
|
||||
import { configGet, configSet } from './ConfigService'
|
||||
import { getCloudSyncService } from './CloudSyncService'
|
||||
import { getMainWindow } from '../windows/WindowManager'
|
||||
import { getDatabase } from '../db'
|
||||
import { meetingSessions, meetingMemos, meetingDocuments } from '../db/schema'
|
||||
|
|
@ -197,6 +198,11 @@ class MeetingModeService extends EventEmitter {
|
|||
logger.info(`회의 녹음 시작: sessionId=${sessionId}`)
|
||||
this._sendStateToRenderer()
|
||||
|
||||
// Phase 3.3: 부모 meeting row를 즉시 push (빈 상태로).
|
||||
// 자식 meeting_memos/meeting_documents의 RLS/FK가 부모 존재를 요구하므로,
|
||||
// 녹음 중에 들어오는 addMemo/generateDocument 푸시가 통과하려면 필수.
|
||||
void getCloudSyncService().pushOne('meetings', sessionId)
|
||||
|
||||
return { sessionId }
|
||||
}
|
||||
|
||||
|
|
@ -230,6 +236,9 @@ class MeetingModeService extends EventEmitter {
|
|||
this.emit('memo-added', memo)
|
||||
logger.debug(`메모 추가: [${formatTime(memo.timestampMs)}] ${content}`)
|
||||
|
||||
// Phase 3.3: 자동 push (fire-and-forget)
|
||||
void getCloudSyncService().pushOne('meeting_memos', memo.id)
|
||||
|
||||
return memo
|
||||
}
|
||||
|
||||
|
|
@ -311,6 +320,9 @@ class MeetingModeService extends EventEmitter {
|
|||
updatedAt: now,
|
||||
}).where(eq(meetingSessions.id, sessionId)).run()
|
||||
|
||||
// Phase 3.3: 최종 save 후 자동 push (fire-and-forget)
|
||||
void getCloudSyncService().pushOne('meetings', sessionId)
|
||||
|
||||
// Step 2.5: 오디오 WAV 파일 저장 (화자 구분용)
|
||||
if (this._audioBuffersForFile.length > 0) {
|
||||
try {
|
||||
|
|
@ -654,6 +666,9 @@ class MeetingModeService extends EventEmitter {
|
|||
sendProgress(100)
|
||||
logger.info(`문서 생성 완료: docId=${docId}, sessionId=${params.sessionId}`)
|
||||
|
||||
// Phase 3.3: 자동 push (fire-and-forget)
|
||||
void getCloudSyncService().pushOne('meeting_documents', docId)
|
||||
|
||||
return {
|
||||
id: docId,
|
||||
sessionId: params.sessionId,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue