feat(V2-1a): Monorepo 구조 전환 — apps/desktop으로 V1 이동
- npm workspaces 루트 (apps/*, packages/*) 세팅 - V1 전체를 apps/desktop/으로 git mv (src, resources, tests, sidecar, scripts, electron.vite.config.ts, electron-builder.yml, vitest.config.ts, tsconfig.node.json, tsconfig.web.json) - apps/desktop/package.json 신규 (name=@d3ro/desktop) - productName: 'd3ro-voice' 명시 — app.getName()을 고정하여 userData 경로 %APPDATA%\d3ro-voice\ 그대로 유지 (기존 DB/설정 연속성 보장) - 루트 package.json을 workspace 루트로 재구성, 공통 devDep만 유지 (typescript, eslint, prettier) - turbo.json, tsconfig.base.json 추가 (Turborepo 자체 설치는 별도 sub-phase) - memory/project_status.md 생성 (규칙 13) 검증: - npm run typecheck 통과 - npm run build 통과 (electron-vite main+preload+renderer) - npm run dev 실제 실행 → DB/핫키/Ollama 자동 실행 모두 정상
This commit is contained in:
parent
3a160b9032
commit
45a580878a
178 changed files with 214 additions and 0 deletions
|
|
@ -1,256 +0,0 @@
|
|||
// src/shared/errors.ts
|
||||
|
||||
export enum ErrorCode {
|
||||
// === Success ===
|
||||
Success = 0,
|
||||
|
||||
// === STT (100-199) ===
|
||||
STTEngineNotInstalled = 100,
|
||||
STTModelNotFound = 101,
|
||||
STTModelNotLoaded = 102,
|
||||
STTModelLoadFailed = 103,
|
||||
STTModelDownloadFailed = 104,
|
||||
STTModelDownloadCancelled = 105,
|
||||
STTTranscriptionFailed = 110,
|
||||
STTTranscriptionTimeout = 111,
|
||||
STTTranscriptionCancelled = 112,
|
||||
STTNoAudioData = 113,
|
||||
STTAudioTooShort = 114,
|
||||
STTLanguageNotSupported = 120,
|
||||
STTSidecarSpawnFailed = 130,
|
||||
STTSidecarCrashed = 131,
|
||||
STTSidecarCommunicationFailed = 132,
|
||||
STTGPUNotAvailable = 140,
|
||||
|
||||
// === TTS (200-299) ===
|
||||
TTSEngineNotInstalled = 200,
|
||||
TTSVoiceNotFound = 201,
|
||||
TTSVoiceNotLoaded = 202,
|
||||
TTSVoiceLoadFailed = 203,
|
||||
TTSVoiceDownloadFailed = 204,
|
||||
TTSSynthesisFailed = 210,
|
||||
TTSPlaybackFailed = 211,
|
||||
TTSPlaybackInterrupted = 212,
|
||||
TTSTextTooLong = 220,
|
||||
TTSTextEmpty = 221,
|
||||
|
||||
// === LLM / Ollama (300-399) ===
|
||||
LLMServerUnreachable = 300,
|
||||
LLMServerConnectionFailed = 301,
|
||||
LLMServerTimeout = 302,
|
||||
LLMModelNotFound = 310,
|
||||
LLMModelNotLoaded = 311,
|
||||
LLMModelLoadFailed = 312,
|
||||
LLMModelPullFailed = 313,
|
||||
LLMModelPullCancelled = 314,
|
||||
LLMProcessingFailed = 320,
|
||||
LLMProcessingTimeout = 321,
|
||||
LLMProcessingCancelled = 322,
|
||||
LLMResponseParseFailed = 323,
|
||||
LLMInvalidAction = 330,
|
||||
LLMPromptTooLong = 331,
|
||||
|
||||
// === Audio (400-499) ===
|
||||
AudioDeviceNotFound = 400,
|
||||
AudioDeviceAccessDenied = 401,
|
||||
AudioDeviceBusy = 402,
|
||||
AudioCaptureStartFailed = 410,
|
||||
AudioCaptureStopFailed = 411,
|
||||
AudioCaptureFailed = 412,
|
||||
AudioNoPermission = 420,
|
||||
AudioStreamError = 430,
|
||||
AudioBufferOverflow = 431,
|
||||
|
||||
// === Hotkey (500-599) ===
|
||||
HotkeyRegistrationFailed = 500,
|
||||
HotkeyConflict = 501,
|
||||
HotkeySystemReserved = 502,
|
||||
HotkeyHookInitFailed = 510,
|
||||
HotkeyHookCrashed = 511,
|
||||
|
||||
// === TextInsert (600-699) ===
|
||||
TextInsertFailed = 600,
|
||||
TextInsertClipboardSaveFailed = 601,
|
||||
TextInsertClipboardRestoreFailed = 602,
|
||||
TextInsertKeySimulationFailed = 603,
|
||||
TextInsertNoActiveWindow = 610,
|
||||
TextInsertTargetAppNotResponding = 611,
|
||||
|
||||
// === History / Dictionary / DB (700-799) ===
|
||||
DBOpenFailed = 700,
|
||||
DBMigrationFailed = 701,
|
||||
DBQueryFailed = 702,
|
||||
DBWriteFailed = 703,
|
||||
HistoryNotFound = 710,
|
||||
HistoryExportFailed = 711,
|
||||
DictionaryNotFound = 720,
|
||||
DictionaryDuplicate = 721,
|
||||
DictionaryImportFailed = 722,
|
||||
DictionaryExportFailed = 723,
|
||||
DictionaryImportInvalidFormat = 724,
|
||||
|
||||
// === Phase 10: Memo Tags (730-739) ===
|
||||
MemoTagDuplicate = 730,
|
||||
MemoTagNotFound = 731,
|
||||
MemoExportFailed = 732,
|
||||
|
||||
// === Phase 10: Voice Commands (740-749) ===
|
||||
VoiceCommandMatchFailed = 740,
|
||||
VoiceCommandNotFound = 741,
|
||||
|
||||
// === Phase 10: Screen Context (750-759) ===
|
||||
ContextCaptureFailed = 750,
|
||||
ContextSelectedTextFailed = 751,
|
||||
|
||||
// === Phase 10: LLM Chain (760-769) ===
|
||||
ChainNotFound = 760,
|
||||
ChainExecutionFailed = 761,
|
||||
ChainStepFailed = 762,
|
||||
ChainCancelled = 763,
|
||||
|
||||
// === Phase 10: Live Caption (770-779) ===
|
||||
CaptionStartFailed = 770,
|
||||
CaptionAlreadyActive = 771,
|
||||
CaptionSTTFailed = 772,
|
||||
|
||||
// === Phase 12: File Transcription (780-784) ===
|
||||
FileTranscriptionFFmpegFailed = 780,
|
||||
FileTranscriptionInvalidFormat = 781,
|
||||
FileTranscriptionChunkFailed = 782,
|
||||
FileTranscriptionCancelled = 783,
|
||||
FileTranscriptionFileTooLarge = 784,
|
||||
|
||||
// === Phase 12: Meeting Summary (785-789) ===
|
||||
MeetingSummaryGenerationFailed = 785,
|
||||
MeetingSummaryNoTranscript = 786,
|
||||
MeetingSummaryExportFailed = 787,
|
||||
|
||||
// === Phase 12: Dictation Template (790-794) ===
|
||||
TemplateNotFound = 790,
|
||||
TemplateSessionAlreadyActive = 791,
|
||||
TemplateSessionNotActive = 792,
|
||||
TemplateFieldRecordingFailed = 793,
|
||||
TemplateInvalidFormat = 794,
|
||||
|
||||
// === Phase 13: Voice Conversation (795-799) ===
|
||||
ConversationSessionAlreadyActive = 795,
|
||||
ConversationNoActiveSession = 796,
|
||||
ConversationTTSFailed = 797,
|
||||
ConversationLLMFailed = 798,
|
||||
|
||||
// === Phase 13: Local RAG (870-874) ===
|
||||
RAGDocumentNotFound = 870,
|
||||
RAGIndexingFailed = 871,
|
||||
RAGEmbeddingFailed = 872,
|
||||
RAGQueryFailed = 873,
|
||||
RAGUnsupportedFormat = 874,
|
||||
|
||||
// === Phase 13: Voice Action (875-879) ===
|
||||
VoiceActionPlanFailed = 875,
|
||||
VoiceActionExecutionFailed = 876,
|
||||
VoiceActionBlocked = 877,
|
||||
VoiceActionInvalidPlan = 878,
|
||||
|
||||
// === Phase 14: Meeting Mode (880-889) ===
|
||||
MeetingAlreadyRecording = 880,
|
||||
MeetingNotRecording = 881,
|
||||
MeetingProcessingFailed = 882,
|
||||
MeetingSessionNotFound = 883,
|
||||
MeetingExportFailed = 884,
|
||||
MeetingPdfFailed = 885,
|
||||
MeetingDocumentNotFound = 886,
|
||||
MeetingDocGenerationFailed = 887,
|
||||
MeetingDocExportFailed = 888,
|
||||
MeetingTranscriptUpdateFailed = 889,
|
||||
MeetingDocTemplateNotFound = 890,
|
||||
MeetingDocTemplateBuiltinDelete = 891,
|
||||
MeetingDocxExportFailed = 892,
|
||||
MeetingPolishFailed = 893,
|
||||
MeetingChatFailed = 894,
|
||||
DiarizationFailed = 895,
|
||||
DiarizationModelNotLoaded = 896,
|
||||
DiarizationTokenRequired = 897,
|
||||
|
||||
// === Config (800-849) ===
|
||||
ConfigReadFailed = 800,
|
||||
ConfigWriteFailed = 801,
|
||||
ConfigInvalidValue = 802,
|
||||
ConfigKeyNotFound = 803,
|
||||
ConfigResetFailed = 804,
|
||||
ConfigMigrationFailed = 810,
|
||||
|
||||
// === License (850-869) ===
|
||||
LicenseKeyInvalid = 850,
|
||||
LicenseKeyExpired = 851,
|
||||
LicenseActivationFailed = 852,
|
||||
LicenseDeactivationFailed = 853,
|
||||
LicenseMachineIdMismatch = 854,
|
||||
LicenseOfflineGraceExpired = 855,
|
||||
LicenseVerificationFailed = 856,
|
||||
FeatureNotAvailable = 860,
|
||||
QuotaExceeded = 861,
|
||||
TierRequired = 862,
|
||||
|
||||
// === System / Window (900-999) ===
|
||||
WindowCreationFailed = 900,
|
||||
WindowNotFound = 901,
|
||||
TrayCreationFailed = 910,
|
||||
NotificationFailed = 920,
|
||||
PermissionDenied = 930,
|
||||
ExternalOpenFailed = 940,
|
||||
SoundPlayFailed = 950,
|
||||
AppAlreadyRunning = 960,
|
||||
UnknownError = 999
|
||||
}
|
||||
|
||||
/**
|
||||
* D3RO-VOICE 표준 에러 객체 (Speakly NXError 패턴)
|
||||
*/
|
||||
export class D3ROError extends Error {
|
||||
readonly code: ErrorCode
|
||||
readonly details?: Record<string, unknown>
|
||||
|
||||
constructor(code: ErrorCode, message: string, details?: Record<string, unknown>) {
|
||||
super(message)
|
||||
this.name = 'D3ROError'
|
||||
this.code = code
|
||||
this.details = details
|
||||
}
|
||||
|
||||
toJSON(): D3ROErrorJSON {
|
||||
return {
|
||||
code: this.code,
|
||||
message: this.message,
|
||||
details: this.details
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON(json: D3ROErrorJSON): D3ROError {
|
||||
return new D3ROError(json.code, json.message, json.details)
|
||||
}
|
||||
}
|
||||
|
||||
export interface D3ROErrorJSON {
|
||||
code: ErrorCode
|
||||
message: string
|
||||
details?: Record<string, unknown>
|
||||
}
|
||||
|
||||
/**
|
||||
* IPC 핸들러에서 사용하는 표준 응답 래퍼.
|
||||
*/
|
||||
export type IPCResult<T> =
|
||||
| { success: true; data: T }
|
||||
| { success: false; error: D3ROErrorJSON }
|
||||
|
||||
export function ipcSuccess<T>(data: T): IPCResult<T> {
|
||||
return { success: true, data }
|
||||
}
|
||||
|
||||
export function ipcError<T>(
|
||||
code: ErrorCode,
|
||||
message: string,
|
||||
details?: Record<string, unknown>
|
||||
): IPCResult<T> {
|
||||
return { success: false, error: { code, message, details } }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue