fix(desktop+supabase): 로컬 ID UUID 통일 + Realtime publication (빅뱅 Phase 5 Part 2)
SaaS [9] — 실증 A/B/C/D 전부 통과, 로컬→클라우드 push 최초 성공(pushed=1). ## Bug 4: 로컬 nanoid PK vs Supabase UUID PK 불일치 - 증상: Push history failed: invalid input syntax for type uuid: "fvy6bIzr..." - 원인: 로컬 drizzle schema는 text PK + nanoid() 생성, Supabase는 uuid PK. 빅뱅 사이클 내내 push가 한 번도 성공한 적 없었음 (지난 pushed=0은 데이터 0건이라서). - 픽스: 로컬을 UUID로 통일 (근본 해결, 땜질 금지). 14개 서비스 20곳 nanoid() → crypto.randomUUID() 일괄 교체. nanoid 의존성 + electron.vite.config exclude 제거. drizzle schema는 text PK 그대로 유지 (SQLite는 UUID 문자열 저장 가능). ## Bug 5: supabase_realtime publication 누락 - 증상: 로그인 직후 Realtime 채널 상태: TIMED_OUT - 원인: initial_schema.sql이 transcripts 테이블만 publication에 추가. 데스크톱이 구독하는 meetings/history/dictionary는 누락 → postgres_changes 흐르지 않음. - 픽스: 20260411000002_realtime_publication.sql 신규. pg_publication_tables 카탈로그 체크 + 조건부 ADD TABLE (meetings/meeting_memos/ meeting_documents/history/dictionary 5개). supabase db push 적용. ## Bug 6: persistSession:false에서 realtime.setAuth 자동 전파 안 됨 (부분 픽스) - 픽스: CloudSyncService.startRealtime()에 client.realtime.setAuth(access_token) 명시 호출 (채널 구성 이전). - ⚠️ Bug 5+6 적용 후에도 Realtime 여전히 TIMED_OUT. 후속 조사 필요. 블로커 아님 — 주기 pull + Phase 3.3 auto push로 최종 일관성 유지. ## 실증 결과 - A 세션 자동 복원: Restored session for yunchan8804@gmail.com → DB 재오픈 - B push 경로: HistoryService created 56a767ac-... → Sync complete pushed=1 errors=0 - C 로그아웃 복귀: Realtime 종료 → users/_local/d3ro.db 복귀 → local mode - D 재로그인 복원: 실증 A의 restore 경로와 동일, 같은 uuid DB 파일 보존 - E 웹 크로스 디바이스: Phase 3.3 이후로 지연 (Realtime 이슈 별건) 검증: desktop tsc --noEmit ✅, dev 재기동 ✅, push 최초 성공 ✅
This commit is contained in:
parent
c8338ec458
commit
e55687d298
19 changed files with 132 additions and 38 deletions
|
|
@ -2,7 +2,6 @@
|
|||
// Phase 10.5: 음성 단축키 — 전사 텍스트에서 키워드를 감지하여 명령어 자동 선택.
|
||||
// electron-store에 VoiceCommandRule[] 저장, 키워드 매칭 엔진 제공.
|
||||
|
||||
import { nanoid } from 'nanoid'
|
||||
import { getLogger } from './LoggerService'
|
||||
import { configGet, configSet } from './ConfigService'
|
||||
import type {
|
||||
|
|
@ -224,7 +223,7 @@ class VoiceCommandService {
|
|||
// 새 rule 생성
|
||||
const maxPriority = this.rules.reduce((max, r) => Math.max(max, r.priority), -1)
|
||||
this.rules.push({
|
||||
id: nanoid(),
|
||||
id: crypto.randomUUID(),
|
||||
instructionId,
|
||||
keywords,
|
||||
enabled: true,
|
||||
|
|
@ -260,7 +259,7 @@ class VoiceCommandService {
|
|||
|
||||
for (const entry of DEFAULT_KEYWORDS) {
|
||||
this.rules.push({
|
||||
id: nanoid(),
|
||||
id: crypto.randomUUID(),
|
||||
instructionId: entry.instructionId,
|
||||
keywords: [...entry.keywords],
|
||||
enabled: true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue