diff --git a/apps/desktop/src/main/services/RAGService.ts b/apps/desktop/src/main/services/RAGService.ts index 41fa603..65f2463 100644 --- a/apps/desktop/src/main/services/RAGService.ts +++ b/apps/desktop/src/main/services/RAGService.ts @@ -292,13 +292,27 @@ ${context}` await new Promise((r) => setTimeout(r, 10)) } + this._state = 'idle' + + // 한 청크도 임베딩하지 못했으면(임베딩 서버 없음 등) 색인됐다고 표시하지 않는다. + // indexed=true + 0 chunks 로 두면 문서가 검색 가능한 것처럼 보이지만 질의에 걸리지 않는다. + if (successCount === 0) { + db.update(ragDocuments) + .set({ indexed: false, indexedAt: null }) + .where(eq(ragDocuments.id, docId)) + .run() + throw new D3ROError( + ErrorCode.RAGEmbeddingFailed, + `No chunk of ${fileName} could be embedded (${chunks.length} attempted)`, + ) + } + // 인덱싱 완료 표시 db.update(ragDocuments) .set({ indexed: true, indexedAt: Date.now(), chunkCount: successCount }) .where(eq(ragDocuments.id, docId)) .run() - this._state = 'idle' this._sendToRenderer(IPC_CHANNELS.RAG.INDEX_COMPLETE, { documentId: docId, fileName }) logger.info(`RAG indexing complete: ${fileName} (${successCount}/${chunks.length} chunks embedded)`) } diff --git a/apps/desktop/tests/main/services/windows-child-process-hide.test.ts b/apps/desktop/tests/main/services/windows-child-process-hide.test.ts index bb95efa..c3af191 100644 --- a/apps/desktop/tests/main/services/windows-child-process-hide.test.ts +++ b/apps/desktop/tests/main/services/windows-child-process-hide.test.ts @@ -128,7 +128,8 @@ describe('Windows child process visibility', () => { expectWindowsHideOnAllCalls(childProcess.exec) }) - it('hides Windows device discovery and active-window PowerShell calls', async () => { + // 장치 목록·활성 창 조회는 win32 분기에서만 PowerShell 을 부른다. + it.skipIf(process.platform !== 'win32')('hides Windows device discovery and active-window PowerShell calls', async () => { const audioModule = await import('../../../src/main/services/AudioCaptureService') const audioService = audioModule.getAudioCaptureService() as unknown as { _getDevicesWindows(): Promise diff --git a/apps/desktop/tests/main/utils/paths.test.ts b/apps/desktop/tests/main/utils/paths.test.ts index 80b7488..46be323 100644 --- a/apps/desktop/tests/main/utils/paths.test.ts +++ b/apps/desktop/tests/main/utils/paths.test.ts @@ -37,13 +37,15 @@ describe('paths (dev)', () => { expect(getAppRoot()).toBe(desktopDir) }) - it('prefers the bundled SoX binary over the system PATH', () => { + // resources/sox 에는 Windows용 sox.exe 만 커밋돼 있다(앱은 Windows 배포). 다른 OS에서는 PATH 의 sox 를 쓴다. + it.skipIf(process.platform !== 'win32')('prefers the bundled SoX binary over the system PATH', () => { expect(getSoxPath()).toContain(path.join('resources', 'sox', 'sox')) expect(existsSync(getSoxPath())).toBe(true) expect(getSoxPath()).not.toBe('sox') }) - it('uses the sidecar virtualenv python when it exists', () => { + // 로컬 개발 환경에만 있는 sidecar/.venv 가 있을 때의 동작이다. CI 에는 venv 가 없다. + it.skipIf(!existsSync(path.join(desktopDir, 'sidecar', '.venv')))('uses the sidecar virtualenv python when it exists', () => { const launch = getSidecarCommand() expect(launch.source).toBe('venv')