feat(V2-5차): pgvector 시맨틱 검색 + chat 스트리밍 + doc 편집 + VoiceAction + Realtime + storage + 메모

묶음 Q — pgvector + 시맨틱 검색:
- migrations/20260410000004_pgvector_knowledge.sql
  - vector extension, embedding vector(1536) 컬럼
  - ivfflat cosine 인덱스
  - match_knowledge_chunks(query_embedding, match_count, similarity_threshold) RPC
  - RLS: user_id 또는 소속 팀 기준
- functions/embed-chunks: 문서 소유권 확인 후 OpenAI text-embedding-3-small 배치 호출 → knowledge_chunks.embedding 업데이트
- functions/search-knowledge: 쿼리 텍스트 → OpenAI 임베딩 → user 권한 RPC 호출 → 상위 청크 반환
- config.toml에 embed-chunks/search-knowledge 등록
- components/knowledge/knowledge-search.tsx: 검색창 + 결과 카드(유사도 %)
- /knowledge 페이지에 검색 UI 추가

묶음 R — /chat SSE 스트리밍:
- functions/llm-proxy: Anthropic Messages API stream 지원
  - ANTHROPIC_API_KEY 없으면 SSE placeholder 스트림
  - stream=true일 때 response.body 그대로 프록시 (text/event-stream)
  - stream=false는 JSON 응답
- components/chat/chat-panel.tsx:
  - stream=true로 요청
  - ReadableStream 파싱 (SSE: data: {type:content_block_delta, delta:{text_delta}})
  - assistantId 메시지를 progressive 업데이트, scrollToBottom
  - 불필요한 LlmResponse 인터페이스 제거

묶음 S — DocumentEditor:
- components/meetings/document-editor.tsx
  - 문서 박스 클릭 → MUI Dialog (fullWidth, maxWidth md)
  - TextField multiline 20~40 rows, monospace
  - 제목 편집 + 저장/삭제 버튼
- meetings/[id] 페이지 Documents 섹션을 DocumentEditor로 교체 (+ typoSx 미사용 import 제거)

묶음 T — /actions (VoiceAction 이식):
- components/actions/action-runner.tsx
  - SYSTEM_PROMPT로 JSON 스키마 강제 (create_meeting/search_knowledge/create_memo/send_team_invite/unknown)
  - LLM 응답에서 JSON 추출 → 파싱 → 확인 후 실행
  - 각 type별 실행 로직 (meetings/memos INSERT, 검색은 안내만)
- app/(app)/actions/page.tsx + Sidebar Actions 메뉴 + AutoAwesomeIcon

묶음 U — Realtime + Storage + 메모 UI:
- CloudSyncService:
  - RealtimeChannel import 추가
  - startRealtime(): meetings/history/dictionary 변경 구독, debounce 후 pullAll 자동 트리거
  - stopRealtime(), signIn 직후/세션 복원 시 자동 시작, signOut 시 종료
- apps/web/components/meetings/memo-form.tsx
  - TextField + 저장 버튼, 회의 시작 기준 경과 ms 자동 계산
  - Realtime 구독자에게 자동 전파
- meetings/[id] MEMOS 섹션에 MemoForm 렌더
- apps/web/components/record/mic-recorder.tsx
  - STT 성공 후 Supabase Storage 'audio' 버킷에 {user_id}/{ts}.webm 업로드
  - meetings 테이블에 INSERT (raw_transcript, audio_storage_key, duration_ms, ended_at)
  - Storage/meetings 실패는 전사 결과는 유지하며 경고

묶음 V — 11개 locale nav 키:
- en/ja/zh/zh-TW/es/fr/de/pt/ru/vi/th 에 nav.chat/nav.knowledge/nav.actions 추가
- ko.json에 nav.actions 추가
- Sidebar에 Actions 메뉴(AutoAwesomeIcon) 등록

검증:
- desktop typecheck + build OK
- web typecheck + build OK (15 라우트: 기존 14 + /actions)
- api-client test 19 passed
- 회귀 없음

통계:
- 총 Edge Functions 12개 (embed-chunks/search-knowledge 추가)
- 총 SQL 마이그레이션 8개
- 웹 라우트 15개 (accept-invite/actions/billing/chat/dashboard/knowledge/login/meetings/meetings[id]/record/teams/teams[id]/auth-callback/root/_not-found)
This commit is contained in:
yunchan8804 2026-04-10 09:30:41 +09:00
parent 1fa24ce3c9
commit b386733d1e
29 changed files with 1363 additions and 81 deletions

View file

@ -8,6 +8,9 @@
"nav.settings": "Einstellungen",
"nav.meetings": "Meetings",
"nav.record": "Aufnehmen",
"nav.chat": "Chat",
"nav.knowledge": "Wissen",
"nav.actions": "Aktionen",
"nav.teams": "Teams",
"nav.billing": "Abrechnung",
"nav.logout": "Abmelden",

View file

@ -8,6 +8,8 @@
"nav.settings": "Settings",
"nav.meetings": "Meetings",
"nav.record": "Record",
"nav.chat": "Chat",
"nav.actions": "Actions",
"nav.teams": "Teams",
"nav.billing": "Billing",
"nav.logout": "Logout",

View file

@ -8,6 +8,9 @@
"nav.settings": "Ajustes",
"nav.meetings": "Reuniones",
"nav.record": "Grabar",
"nav.chat": "Chat",
"nav.knowledge": "Conocimiento",
"nav.actions": "Acciones",
"nav.teams": "Equipos",
"nav.billing": "Facturación",
"nav.logout": "Cerrar sesión",

View file

@ -8,6 +8,9 @@
"nav.settings": "Paramètres",
"nav.meetings": "Réunions",
"nav.record": "Enregistrer",
"nav.chat": "Chat",
"nav.knowledge": "Connaissance",
"nav.actions": "Actions",
"nav.teams": "Équipes",
"nav.billing": "Facturation",
"nav.logout": "Déconnexion",

View file

@ -8,6 +8,9 @@
"nav.settings": "設定",
"nav.meetings": "会議",
"nav.record": "録音",
"nav.chat": "チャット",
"nav.knowledge": "知識",
"nav.actions": "アクション",
"nav.teams": "チーム",
"nav.billing": "支払い",
"nav.logout": "ログアウト",

View file

@ -9,7 +9,8 @@
"nav.meetings": "회의",
"nav.record": "녹음",
"nav.chat": "채팅",
"nav.knowledge": "지식",
"nav.knowledge": "지식 베이스",
"nav.actions": "액션",
"nav.teams": "팀",
"nav.billing": "결제",
"nav.logout": "로그아웃",
@ -375,7 +376,6 @@
"conversation.inputPlaceholder": "메시지 입력...",
"conversation.end": "종료",
"conversation.clearHistory": "대화 초기화",
"nav.knowledge": "지식 베이스",
"rag.title": "지식 베이스",
"rag.addDocument": "문서 추가",
"rag.documents": "문서",
@ -492,4 +492,4 @@
"settings.hfTokenHint": "화자 구분을 위해 HuggingFace 토큰이 필요합니다",
"settings.diarization": "화자 구분",
"settings.diarizationHint": "녹음 종료 후 화자를 자동으로 구분합니다"
}
}

View file

@ -8,6 +8,9 @@
"nav.settings": "Configurações",
"nav.meetings": "Reuniões",
"nav.record": "Gravar",
"nav.chat": "Chat",
"nav.knowledge": "Conhecimento",
"nav.actions": "Ações",
"nav.teams": "Equipes",
"nav.billing": "Faturamento",
"nav.logout": "Sair",

View file

@ -8,6 +8,9 @@
"nav.settings": "Настройки",
"nav.meetings": "Встречи",
"nav.record": "Запись",
"nav.chat": "Чат",
"nav.knowledge": "База знаний",
"nav.actions": "Действия",
"nav.teams": "Команды",
"nav.billing": "Оплата",
"nav.logout": "Выйти",

View file

@ -8,6 +8,9 @@
"nav.settings": "การตั้งค่า",
"nav.meetings": "การประชุม",
"nav.record": "บันทึกเสียง",
"nav.chat": "แชท",
"nav.knowledge": "ความรู้",
"nav.actions": "การกระทำ",
"nav.teams": "ทีม",
"nav.billing": "การเรียกเก็บเงิน",
"nav.logout": "ออกจากระบบ",

View file

@ -8,6 +8,9 @@
"nav.settings": "Cài đặt",
"nav.meetings": "Cuộc họp",
"nav.record": "Ghi âm",
"nav.chat": "Trò chuyện",
"nav.knowledge": "Kiến thức",
"nav.actions": "Hành động",
"nav.teams": "Nhóm",
"nav.billing": "Thanh toán",
"nav.logout": "Đăng xuất",

View file

@ -8,6 +8,9 @@
"nav.settings": "設定",
"nav.meetings": "會議",
"nav.record": "錄音",
"nav.chat": "聊天",
"nav.knowledge": "知識",
"nav.actions": "動作",
"nav.teams": "團隊",
"nav.billing": "帳單",
"nav.logout": "登出",

View file

@ -8,6 +8,9 @@
"nav.settings": "设置",
"nav.meetings": "会议",
"nav.record": "录音",
"nav.chat": "聊天",
"nav.knowledge": "知识",
"nav.actions": "操作",
"nav.teams": "团队",
"nav.billing": "账单",
"nav.logout": "登出",