Files
OmniRoute/docs/i18n/ko/docs/architecture/CODEBASE_DOCUMENTATION.md
Diego Rodrigues de Sa e Souza b637350680 fix(docs): re-sync the 65 documentation mirror sets; section-level docs pipeline; drift gate blocking (#13940)
1,104 mirrors rewritten over five passes of run-translation on the 22-source core set: the 14 sources edited since their translation, the 322 mirrors that were still English copies, and the frontmatter the old extractor leaked into the newer locales' bodies. The pipeline now caches per-`## `-section hashes and retranslates only changed sections, never reuses a section that is still English, rebuilds English-copy / leaked mirrors even when the source is unchanged, merges the state on save (parallel runs), and the drift gate (scoped to the core set) is blocking. Final audit: 0 stale, 0 English copies, 0 leaked frontmatter across 1,430 core mirrors.

⚠️ base-red inherited: #12732
2026-09-17 02:55:31 -03:00

80 KiB

OmniRoute Codebase Documentation (한국어)

🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW


버전: v3.8.51 최종 업데이트: 2026-06-28 대상 독자: OmniRoute에 기여하거나 이를 기반으로 통합 기능을 구축하는 엔지니어.

상위 수준의 아키텍처 다이어그램과 각 하위 시스템의 설계 근거는 ARCHITECTURE.md를 참조하세요. 개별 하위 시스템 (Auto Combo, MCP 서버, A2A 서버, Skills, Memory, Cloud Agents, Resilience, Compression 등)에 대한 심층 설명은 이 docs/ 디렉터리의 전용 파일을 참조하세요.

이 파일은 신규 엔지니어가 트리를 탐색하고, 런타임 계층 구조를 이해하며, 새로운 모듈을 만들지 않고도 코드를 추가할 위치를 파악할 수 있도록 현재 저장소에 존재하는 항목을 설명합니다.


1. 기술 스택

영역 선택
웹 프레임워크 Next.js 16 (App Router, 독립 실행형 출력, 전역 미들웨어 없음)
언어 TypeScript 6.0+ — 대상 ES2022, module: esnext, moduleResolution: bundler, strict: false
런타임 Node.js >=22.22.2 <23 또는 >=24.0.0 <27 (engines + SUPPORTED_NODE_RANGE로 강제 적용)
데이터베이스 better-sqlite3를 통한 SQLite (싱글턴, WAL 저널링)
데스크톱 Electron 41 + electron-builder 26.10 (electron/의 별도 워크스페이스)
테스트 Node 네이티브 테스트 러너 (단위/통합), Vitest (MCP, autoCombo, 캐시), Playwright (e2e + protocols-e2e)
빌드 scripts/build/build-next-isolated.mjs를 통한 Next.js 독립 실행형 빌드
린트/포맷 ESLint 플랫 구성 + Prettier (Husky 사전 커밋 훅을 통한 lint-staged)
모듈 시스템 전체에서 ESM 사용 ("type": "module")
워크스페이스 npm 워크스페이스 — open-sse가 유일한 하위 워크스페이스

경로 별칭(tsconfig.json):

  • @/*src/*
  • @omniroute/open-sseopen-sse/index.ts
  • @omniroute/open-sse/*open-sse/*

기본 HTTP 포트: 20128(API와 대시보드가 동일한 프로세스를 공유). 데이터 디렉터리는 DATA_DIR 환경 변수로 지정하며, 기본값은 ~/.omniroute/입니다.


2. 저장소 구조

OmniRoute/
├── src/                  Next.js 애플리케이션(App Router, 라이브러리, 도메인, 서버, 공유 코드)
├── open-sse/             스트리밍 엔진 워크스페이스(@omniroute/open-sse)
├── electron/             데스크톱 래퍼(Electron 41 메인 + 프리로드)
├── bin/                  CLI 진입점(omniroute, reset-password)
├── tests/                단위, 통합, e2e, protocols-e2e, 변환기, 보안, 픽스처
├── scripts/              빌드, 동기화, 검사, 마이그레이션 및 런타임 도우미 스크립트
├── docs/                 공개 문서(현재 디렉터리)
├── public/               정적 자산, PWA 매니페스트, 서비스 워커
├── config/               런타임 구성 샘플
├── images/               마케팅/스크린샷 자산
├── _ideia/, _references/, _mono_repo/, _tasks/   내부 임시 작업/계획용(배포되지 않음)
├── CLAUDE.md             Claude Code용 저장소 규칙
├── AGENTS.md             에이전트용 상세 아키텍처 참고 자료
├── package.json          v3.8.51, 워크스페이스 루트
└── tsconfig.json         경로 별칭 + 핵심 컴파일러 옵션

3. src/ — Next.js 애플리케이션

src/
├── app/                  App Router 페이지 + API 라우트
├── lib/                  핵심 라이브러리(DB, 인증, OAuth, 스킬, 메모리 등)
├── domain/               순수 도메인 계층(정책, 폴백, 비용, 잠금 등)
├── server/               서버 전용 모듈(권한 부여, CORS, 인증)
├── shared/               타입, 상수, 유효성 검사, 계약, 유틸리티(경계 간 사용 가능)
├── mitm/                 CLI 통합을 위한 중간자 프록시 헬퍼
├── models/               로컬 모델 메타데이터 / 별칭 처리
├── sse/                  아직 src/ 아래에 있는 레거시 SSE 핸들러(open-sse/ 아님)
├── store/                클라이언트 측 상태 저장소
├── middleware/           라우트 수준 미들웨어 유틸리티(Next.js 전역 미들웨어 아님)
├── scripts/              앱 코드에서 가져올 수 있는 트리 내부 스크립트
├── types/                앰비언트 및 공유 TS 타입
├── i18n/                 로케일 번들
├── instrumentation.ts    Next.js 계측 훅
├── instrumentation-node.ts
└── proxy.ts              최상위 프록시 부트스트랩 헬퍼

3.1 src/app/ — App Router

App Router는 대시보드 UI와 공개/관리 HTTP API를 모두 제공합니다. 전역 미들웨어는 없으며, 인터셉션은 라우트별로 수행됩니다.

src/app/ 아래의 최상위 세그먼트:

경로 용도
api/ 모든 HTTP API 라우트(아래 세부 내역 참조)
a2a/ A2A JSON-RPC 2.0 엔드포인트(POST /a2a)
.well-known/agent.json/ A2A Agent Card 검색 문서
(dashboard)/ 대시보드 UI(라우트 그룹, URL 접두사 없음)
auth/, login/, forgot-password/, callback/ 인증 흐름
landing/ 마케팅/랜딩 페이지
docs/ 내장 API 문서 뷰어
status/, maintenance/, offline/ 운영 페이지
privacy/, terms/ 법적 고지 페이지
400/, 401/, 403/, 408/, 429/, 500/, 502/, 503/ 정적 오류 페이지
error.tsx, global-error.tsx, not-found.tsx, forbidden/, loading.tsx 프레임워크 오류/로딩 경계
layout.tsx, page.tsx, globals.css, manifest.ts 루트 셸

3.1.1 src/app/(dashboard)/dashboard/ — UI 페이지

agents, analytics, api-manager, audit, auto-combo, batch, cache, changelog, cli-tools, cloud-agents, combos, compression, context, costs, endpoint, health, limits, logs, memory, onboarding, playground, providers, search-tools, settings, skills, system, translator, usage, webhooks 및 루트 page.tsx, HomePageClient.tsx, BootstrapBanner.tsx.

3.1.2 src/app/api/ — 최상위 API 그룹

src/app/api/
├── a2a/{status, tasks}
├── acp/
├── admin/
├── analytics/
├── assess/
├── auth/
├── batches/
├── cache/
├── cli-tools/
├── cloud/{codex-responses-ws}
├── combos/
├── compliance/
├── compression/
├── context/
├── db/, db-backups/
├── evals/
├── fallback/
├── files/
├── health/
├── init/
├── internal/{concurrency}
├── keys/
├── logs/
├── mcp/{audit, sse, status, stream, tools}
├── memory/{health, [id]/, route.ts}
├── model-combo-mappings/
├── models/
├── monitoring/
├── oauth/
├── openapi/
├── policies/
├── pricing/
├── provider-metrics/, provider-models/, provider-nodes/
├── providers/
├── rate-limit/, rate-limits/
├── resilience/
├── restart/, shutdown/
├── search/
├── sessions/
├── settings/
├── skills/{executions, [id], install, marketplace, route.ts, skillssh}
├── storage/
├── sync/, synced-available-models/
├── system/
├── tags/
├── telemetry/
├── token-health/
├── translator/
├── tunnels/
├── services/   내장 서비스 관리(9router, cliproxy) — LOCAL_ONLY
├── upstream-proxy/
├── usage/
├── v1/         OpenAI 호환 공개 API
├── v1beta/     Gemini 스타일 호환성
├── version-manager/
└── webhooks/

3.1.2a src/app/api/services/ — 내장 서비스 관리

9Router 및 CLIProxyAPI를 설치, 시작, 중지, 모니터링하기 위한 라우트입니다. 모든 경로는 npm install을 호출하고 자식 프로세스를 생성할 수 있으므로 LOCAL_ONLY(루프백 전용, 엄격 규칙 #17)로 분류됩니다.

src/app/api/services/
├── 9router/
│   ├── _lib.ts             getOrInitSupervisor() 헬퍼
│   ├── install/route.ts    POST — execFile을 통한 npm install
│   ├── start/route.ts      POST — supervisor.start()
│   ├── stop/route.ts       POST — supervisor.stop()
│   ├── restart/route.ts    POST — supervisor.restart()
│   ├── update/route.ts     POST — 최신 버전 npm install
│   ├── rotate-key/route.ts POST — 새 API 키 생성 + 재시작
│   ├── status/route.ts     GET  — 실시간 + DB 상태 + 버전 메타데이터
│   └── auto-start/route.ts POST — auto_start 플래그 전환
├── cliproxy/
│   ├── _lib.ts             getOrInitSupervisor() 헬퍼
│   ├── install/route.ts    POST — npm install
│   ├── start/route.ts      POST — supervisor.start()
│   ├── stop/route.ts       POST — supervisor.stop()
│   ├── restart/route.ts    POST — supervisor.restart()
│   ├── update/route.ts     POST — 최신 버전 npm install
│   ├── status/route.ts     GET  — 실시간 + DB 상태 + 버전 메타데이터
│   └── auto-start/route.ts POST — auto_start 플래그 전환
└── [name]/
    └── logs/route.ts       GET  — SSE 로그 테일링(모든 서비스에서 공유)

대응하는 대시보드 UI: src/app/(dashboard)/dashboard/providers/services/ — 탭 2개로 구성된 페이지(CLIProxyAPI + 9Router). 9Router 임베디드 UI용 리버스 프록시: src/app/(dashboard)/dashboard/providers/services/[name]/embed/[[...path]]/route.ts

심층 분석: docs/frameworks/EMBEDDED-SERVICES.md

3.1.3 src/app/api/v1/ — OpenAI 호환 공개 API

v1/
├── accounts/[id]/                       계정 조회
├── agents/tasks/[id]/, agents/tasks/    A2A 스타일 작업 엔드포인트
├── api/                                 v1/api 아래에 노출되는 내부 API 헬퍼
├── audio/{speech, transcriptions}/      TTS + STT
├── batches/[id]/{cancel}, batches/      OpenAI Batches API
├── chat/completions/                    Chat Completions(주요 엔드포인트)
├── completions/                         레거시 텍스트 완성
├── embeddings/                          임베딩
├── files/[id]/, files/                  Files API
├── _helpers/                            공유 라우트 헬퍼(공개 URL 없음)
├── images/{edits, generations}/         이미지 생성 + 편집
├── issues/                              트리아지 헬퍼 엔드포인트
├── management/{proxies}/                v1 내부의 관리 범위 라우트
├── messages/{count_tokens}/             Anthropic 스타일 메시지 호환성
├── models/                              모델 목록(`route.ts`, `catalog.ts`)
├── moderations/                         콘텐츠 조정
├── music/                               음악 생성
├── providers/[provider]/                공급자별 작업
├── quotas/{check}                       할당량 검사
├── registered-keys/                     등록된 키 관리
├── rerank/                              재순위화
├── responses/[...path]/                 OpenAI Responses API(포괄 라우트)
├── search/                              웹 검색
├── videos/                              동영상 생성
├── ws/                                  WebSocket 브리지
└── route.ts                             인덱스 핸들러

모든 라우트 파일은 동일한 패턴을 따릅니다.

라우트 → CORS 프리플라이트 → Zod 본문 유효성 검사 → 선택적 인증
       → API 키 정책 적용 → 핸들러 위임(open-sse)

v1beta/는 Gemini 스타일 호환 인터페이스입니다(동일한 open-sse/handlers/ 파이프라인으로 변환하는 얇은 래퍼).

3.2 src/lib/ — 핵심 라이브러리

데이터, 동기화, OAuth, 스킬, 메모리 등은 항상 이 모듈을 통해 가져오세요. 이 표는 실제 디렉터리와 주요 최상위 파일을 그룹화합니다.

모듈 목적
a2a/ A2A 프로토콜 서버: taskManager.ts, streaming.ts, taskExecution.ts, routingLogger.ts, skills/(6개 스킬: 비용 분석, 상태 보고서, 공급자 탐색, 할당량 관리, 스마트 라우팅, 기능 목록 조회)
acp/ Agent-Control-Protocol: index.ts, manager.ts, registry.ts
api/ 내부 API 헬퍼: requireManagementAuth.ts, requireCliToolsAuth.ts, errorResponse.ts
auth/ managementPassword.ts(비밀번호 재설정/해싱)
batches/ OpenAI Batches API 서비스(service.ts)
catalog/ OpenRouter 카탈로그 동기화(openrouterCatalog.ts)
cloudAgent/ 클라우드 에이전트 레지스트리: api.ts, baseAgent.ts, db.ts, index.ts, registry.ts, types.ts, agents/{codex, devin, jules}.ts
combos/ 콤보 해석 헬퍼
compliance/ 감사 및 공급자 감사: index.ts, providerAudit.ts
config/ 런타임 구성 연결부
db/ SQLite 도메인 모듈(§3.2.1 참조)
display/ API 응답에서 사용하는 UI/표시 헬퍼
embeddings/ 임베딩 서비스 레지스트리
env/ 환경 로드 및 검사
evals/ 평가 런타임
guardrails/ piiMasker.ts, promptInjection.ts, visionBridge.ts, visionBridgeHelpers.ts, registry.ts, base.ts
jobs/ 백그라운드 작업(autoUpdate.ts, …)
memory/ 영구 메모리: store.ts, cache.ts, retrieval.ts, summarization.ts, extraction.ts, injection.ts, qdrant.ts, settings.ts, verify.ts, schemas.ts, types.ts
monitoring/ observability.ts
oauth/ OAuth/공급자 가져오기 모듈(22개): agy, antigravity, claude, cline, codebuddy-cn, codex, cursor, devin-desktop, ghe-copilot, github, gitlab-duo, grok-cli-oauth, grok-cli, kilocode, kimi-coding, kiro, openference, qoder, trae, xai-oauth, zed-hosted, zed, 그리고 services/, utils/, constants/oauth.ts
plugins/ 플러그인 로더(index.ts)
promptCache/ prefixAnalyzer.ts, index.ts
providerModels/ 관리형 모델 수명 주기: modelDiscovery.ts, managedModelImport.ts, managedAvailableModels.ts, cursorAgent.ts
providers/ 공급자 헬퍼: catalog.ts, validation.ts, imageValidation.ts, claudeExtraUsage.ts, codexConnectionDefaults.ts, codexFastTier.ts, webCookieAuth.ts, managedAvailableModels.ts, requestDefaults.ts
resilience/ settings.ts — 회로 차단기, 쿨다운, 잠금 설정
runtime/ 런타임 기능 감지
search/ executeWebSearch.ts
services/ 임베디드 서비스 프레임워크: ServiceSupervisor.ts(작업 잠금, 링 버퍼, 상태 검사기를 갖춘 범용 자식 프로세스 감독자), bootstrap.ts(프로세스 수준 등록 및 자동 시작), registry.ts(도구 → 감독자 맵), apiKey.ts(AES-256-GCM 키 저장소), modelSync.ts(주기적 모델 동기화), ringBuffer.ts(5 MB 순환 로그 버퍼), healthCheck.ts(HTTP 상태 프로브), types.ts, embedWsProxy.ts(WebSocket 프록시), installers/{ninerouter,cliproxy}.ts. docs/frameworks/EMBEDDED-SERVICES.md 참조
agentSkills/ Agent Skills 카탈로그 및 생성기: catalog.ts(getCatalog/getSkillById/filterCatalog/computeCoverage), generator.ts(generateAgentSkills → skills/{id}/SKILL.md에 기록), openapiParser.ts(OpenAPI 명세에서 REST 엔드포인트 추출), cliRegistryParser.ts(bin/cli-registry에서 CLI 하위 명령 추출), schemas.ts(Zod: AgentSkillSchema, SkillCoverageSchema, ListQuerySchema, GenerateBodySchema), types.ts(AgentSkill, SkillCoverage, SkillMarkdown, GeneratorReport). REST 경로(/api/agent-skills/*), MCP 도구(omniroute_agent_skills_*), A2A 스킬 list-capabilities에서 사용됩니다. AGENT-SKILLS.md를 참조하세요.
skills/ 스킬 프레임워크: registry.ts, executor.ts, interception.ts, injection.ts, sandbox.ts, custom.ts, hybrid.ts, builtins.ts, a2a.ts, providerSettings.ts, schemas.ts, skillssh.ts, types.ts, 그리고 builtin/browser.ts
spend/ batchWriter.ts(후기입 버퍼)
sync/ bundle.ts, tokens.ts(Cloud Sync)
system/ 시스템 수준 헬퍼
translator/ 최상위 번역기 연결부(open-sse/translator/로 위임)
usage/ 사용량 계산: costCalculator.ts, tokenAccounting.ts, usageHistory.ts, aggregateHistory.ts, usageStats.ts, callLogs.ts, callLogArtifacts.ts, fetcher.ts, providerLimits.ts, migrations.ts
versionManager/ 자동 업데이트 및 버전 매니페스트
ws/ WebSocket 브리지
zed-oauth/ Zed 편집기 OAuth 흐름

src/lib/의 최상위 파일:

  • 이전 localDb.ts 배럴 파일은 제거되었습니다. 사용자는 특정 src/lib/db/* 모듈을 직접 가져옵니다.
  • proxyHealth.ts, proxyLogger.ts, tokenHealthCheck.ts, localHealthCheck.ts
  • apiBridgeServer.ts, cacheLayer.ts, semanticCache.ts, settingsCache.ts
  • cloudSync.ts, initCloudSync.ts
  • cloudflaredTunnel.ts, ngrokTunnel.ts, tailscaleTunnel.ts
  • consoleInterceptor.ts, container.ts, gracefulShutdown.ts, idempotencyLayer.ts
  • ipUtils.ts, logEnv.ts, logPayloads.ts, logRotation.ts
  • modelAliasSeed.ts, modelCapabilities.ts, modelMetadataRegistry.ts, modelsDevSync.ts
  • piiSanitizer.ts, pricingSync.ts
  • apiKeyExposure.ts, cacheControlSettings.ts, dataPaths.ts, toolPolicy.ts
  • translatorEvents.ts, usageDb.ts, usageAnalytics.ts, webhookDispatcher.ts

3.2.1 src/lib/db/

싱글턴 SQLite 데이터베이스(core.tsgetDbInstance(), WAL 저널링). 라우트나 핸들러에 원시 SQL을 절대 작성하지 마세요 — 반드시 이 모듈들을 통해 접근하세요.

데이터베이스 스키마 개요(선별된 핵심 테이블)

출처: diagrams/db-schema-overview.mmd

도메인 모듈(각각 하나 이상의 테이블을 담당): apiKeys.ts, backup.ts, batches.ts, cleanup.ts, cliToolState.ts, combos.ts, commandCodeAuth.ts, compression.ts, compressionAnalytics.ts, compressionCacheStats.ts, compressionCombos.ts, compressionScheduler.ts, contextHandoffs.ts, core.ts, creditBalance.ts, databaseSettings.ts, detailedLogs.ts, domainState.ts, encryption.ts, evals.ts, files.ts, healthCheck.ts, jsonMigration.ts, migrationRunner.ts, modelComboMappings.ts, models.ts, oneproxy.ts, prompts.ts, providers.ts, providerLimits.ts, proxies.ts, quotaSnapshots.ts, readCache.ts, reasoningCache.ts, registeredKeys.ts, secrets.ts, sessionAccountAffinity.ts, settings.ts, stateReset.ts, stats.ts, syncTokens.ts, tierConfig.ts, upstreamProxy.ts, versionManager.ts, webhooks.ts.

migrations/에는 버전이 지정된 .sql 파일 168개(멱등적이며 트랜잭션 방식)가 있으며, 부팅 시 migrationRunner.ts에 의해 실행됩니다.

마이그레이션 전반에 걸쳐 생성되는 테이블(총 123개):

a, account_key_limits, api_keys, batches, call_logs, combo_adaptation_state, combos, command_code_auth_sessions, compression_analytics, compression_cache_stats, compression_combo_assignments, compression_combos, context_handoffs, daily_usage_summary, db_meta, domain_budgets, domain_circuit_breakers, domain_cost_history, domain_fallback_chains, domain_lockout_state, eval_cases, eval_runs, eval_suites, files, hourly_usage_summary, key_value, mcp_tool_audit, memories, model_combo_mappings, provider_connections, provider_key_limits, provider_nodes, proxy_assignments, proxy_logs, proxy_registry, quota_snapshots, reasoning_cache, registered_keys, request_detail_logs, routing_decisions, semantic_cache, session_account_affinity, skill_executions, skills, sync_tokens, tier_assignments, tier_config, upstream_proxy_config, usage_history, version_manager, webhooks(메모리 검색용 FTS5 가상 테이블 포함).

3.3 src/domain/ — 도메인 계층

I/O가 없는 순수 비즈니스 로직입니다. 라우트와 핸들러에서 가져와 사용합니다.

파일 용도
policyEngine.ts 최상위 정책 해석기
fallbackPolicy.ts 폴백 결정 트리
costRules.ts 비용 계산 규칙
lockoutPolicy.ts 모델 잠금 결정
tagRouter.ts 태그 기반 라우팅
comboResolver.ts 요청 → 대상 목록으로 콤보 해석
connectionModelRules.ts 연결별 모델 필터
modelAvailability.ts 모델 가용성 확인
degradation.ts 성능 저하 모드 전환
providerExpiration.ts 만료된 계정/키 감지
quotaCache.ts 캐시된 할당량 결정
responses.ts, omnirouteResponseMeta.ts 응답 형태 헬퍼
configAudit.ts 구성 변경 감사
assessment/ 모델 평가(RFC 기준, 부분적으로 구현됨)
types.ts 공유 도메인 타입

3.4 src/server/ — 서버 전용

클라이언트 컴포넌트에서는 가져올 수 없습니다.

server/
├── auth/loginGuard.ts
├── authz/
│   ├── classify.ts        라우트를 공개 또는 관리용으로 분류
│   ├── assertAuth.ts      어설션 헬퍼
│   ├── context.ts         요청별 authz 컨텍스트
│   ├── headers.ts
│   ├── pipeline.ts        Authz 파이프라인
│   ├── policies/          구체적인 정책
│   └── types.ts
└── cors/origins.ts        CORS 오리진 허용 목록

3.5 src/shared/ — 안전하게 공유 가능

목적별 하위 디렉터리로 분할되어 있습니다:

  • constants/providers.ts(Zod로 검증된 제공자 카탈로그), models.ts, modelSpecs.ts, modelCompat.ts, pricing.ts, cliTools.ts, cliCompatProviders.ts, routingStrategies.ts, comboConfigMode.ts, headers.ts, upstreamHeaders.ts(차단 목록), mcpScopes.ts, errorCodes.ts, publicApiRoutes.ts, batch.ts, batchEndpoints.ts, bodySize.ts, colors.ts, appConfig.ts, config.ts, sidebarVisibility.ts, visionBridgeDefaults.ts.
  • validation/schemas.ts(약 80개의 Zod 스키마), compressionConfigSchemas.ts, providerSchema.ts, settingsSchemas.ts, helpers.ts.
  • contracts/ — npm에 배포되는 공개 API 계약.
  • types/ — 공유 TS 타입.
  • utils/circuitBreaker.ts, apiAuth.ts, apiKey.ts, apiKeyPolicy.ts, api.ts, classify429.ts, cliCompat.ts, clipboard.ts, cloud.ts, cn.ts, cors.ts, featureFlags.ts, fetchTimeout.ts, formatting.ts, inputSanitizer.ts, logger.ts, machine.ts, machineId.ts, maskEmail.ts, modelCatalogSearch.ts, nodeRuntimeSupport.ts, parseApiKeys.ts, providerHints.ts, providerModelAliases.ts, rateLimiter.ts, releaseNotes.ts, a11yAudit.ts, 그리고 services/, network/, middleware/, schemas/, hooks/, components/ 아래의 대시보드 훅/컴포넌트.

4. open-sse/ — 스트리밍 엔진 워크스페이스

@omniroute/open-sse로 게시되는 별도의 npm 워크스페이스입니다. 요청 처리, 실행기, 변환기, 서비스, 트랜스포머 및 MCP 서버를 담당합니다.

open-sse/
├── index.ts                공개 내보내기
├── package.json            워크스페이스 매니페스트
├── tsconfig.json
├── types.d.ts
├── config/                 제공자 레지스트리, 헤더 프로필, ID, …
├── handlers/               요청 핸들러(채팅, 임베딩, 오디오, 이미지, …)
├── executors/              제공자별 HTTP 실행기 108개
├── translator/             형식 변환(OpenAI ↔ Claude ↔ Gemini ↔ Cursor ↔ Kiro)
├── transformer/            Responses API ↔ Chat Completions 스트림 트랜스포머
├── services/               80개 이상의 서비스 모듈(조합, 폴백, 할당량, ID, …)
├── utils/                  스트리밍 헬퍼, TLS 클라이언트, AWS SigV4, 프록시 가져오기, …
└── mcp-server/             MCP 서버(전송 방식 3개, 범위 33개, 도구 110개)

4.1 open-sse/handlers/

핸들러 용도
chatCore.ts 기본 채팅 파이프라인(캐시, 속도 제한, 조합 라우팅, 실행기 디스패치)
responsesHandler.ts OpenAI Responses API 진입점
embeddings.ts 임베딩
imageGeneration.ts 이미지 생성
audioSpeech.ts 텍스트 음성 변환
audioTranscription.ts 음성 텍스트 변환
videoGeneration.ts 동영상 생성
musicGeneration.ts 음악 생성
rerank.ts 재순위화
moderations.ts 콘텐츠 조정
search.ts 웹 검색
sseParser.ts SSE 이벤트 파서
usageExtractor.ts 업스트림 스트림에서 토큰 수 추출
responseSanitizer.ts 제공자별 불필요한 데이터 제거
responseTranslator.ts 제공자 응답과 변환기 계층 사이를 연결

4.2 open-sse/executors/

108개의 제공자 실행기가 있으며, 각각 BaseExecutor(base.ts)를 확장합니다.

antigravity, azure-openai, blackbox-web, cliproxyapi, chatgpt-web-codex, cloudflare-ai, codex, commandCode, cursor, default, devin-cli, muse-spark-web, nlpcloud, opencode, perplexity-web, petals, pollinations, qoder, vertex, devin-desktop, 그리고 claudeIdentity.ts (공유 ID 헬퍼)와 index.ts(레지스트리)가 있습니다.

참고: 여기에 나열되지 않은 제공자는 범용 OpenAI 호환 실행기를 사용하는 default.ts를 통해 제공됩니다. 전체 제공자 카탈로그(355개 제공자)는 src/shared/constants/providers.ts에 있습니다.

4.3 open-sse/translator/

허브 앤드 스포크 방식의 변환 구조입니다(OpenAI가 허브).

  • 요청 변환기 9개(translator/request/): antigravity-to-openai, claude-to-gemini, claude-to-openai, gemini-to-openai, openai-responses, openai-to-claude, openai-to-cursor, openai-to-gemini, openai-to-kiro.
  • 응답 변환기 9개(translator/response/): claude-to-openai, cursor-to-openai, gemini-to-claude, gemini-to-openai, kiro-to-openai, openai-responses, openai-to-antigravity, openai-to-claude.
  • 헬퍼 9개(translator/helpers/): claudeHelper, geminiHelper, geminiToolsSanitizer, maxTokensHelper, openaiHelper, responsesApiHelper, schemaCoercion, toolCallHelper 및 헬퍼 테스트.
  • 이미지 헬퍼(translator/image/sizeMapper.ts).
  • 최상위: bootstrap.ts, formats.ts, registry.ts, index.ts.

4.4 open-sse/transformer/

  • responsesTransformer.tsTransformStream 기반 Responses API ↔ Chat Completions 변환기(responses/ 라우트의 포괄 처리에 사용).

4.5 open-sse/services/

주요 항목(전체 목록은 open-sse/services/에 있음):

관심 영역 파일
콤보 라우팅 combo.ts (19개 전략), comboConfig.ts, comboMetrics.ts, comboManifestMetrics.ts, comboAgentMiddleware.ts
Auto Combo 엔진 autoCombo/engine.ts, scoring.ts, taskFitness.ts, virtualFactory.ts, modePacks.ts, autoPrefix.ts, persistence.ts, providerDiversity.ts, providerRegistryAccessor.ts, routerStrategy.ts, selfHealing.ts, index.ts
복원력 accountFallback.ts (쿨다운 + 잠금), errorClassifier.ts, emergencyFallback.ts, rateLimitManager.ts, rateLimitSemaphore.ts, accountSemaphore.ts, accountSelector.ts
할당량 quotaMonitor.ts, quotaPreflight.ts, bailianQuotaFetcher.ts, codexQuotaFetcher.ts, deepseekQuotaFetcher.ts, openrouterQuotaFetcher.ts, openrouterFreeWindow.ts, crofUsageFetcher.ts, antigravityCredits.ts
캐싱 reasoningCache.ts, searchCache.ts, signatureCache.ts, requestDedup.ts
라우팅 인텔리전스 intentClassifier.ts, taskAwareRouter.ts, backgroundTaskDetector.ts, volumeDetector.ts, wildcardRouter.ts, workflowFSM.ts, specificityDetector.ts, specificityRules.ts, specificityTypes.ts
모델 처리 modelCapabilities.ts, modelDeprecation.ts, modelFamilyFallback.ts, modelStrip.ts, model.ts, provider.ts, providerRequestDefaults.ts, providerCostData.ts, payloadRules.ts
압축 compression/ — 전체 압축 엔진 연결
토큰 + 세션 tokenRefresh.ts, sessionManager.ts, apiKeyRotator.ts, contextManager.ts, contextHandoff.ts, systemPrompt.ts, roleNormalizer.ts, responsesInputSanitizer.ts, toolSchemaSanitizer.ts, toolLimitDetector.ts, thinkingBudget.ts
티어 / 매니페스트 tierResolver.ts, tierConfig.ts, tierDefaults.json, tierTypes.ts, manifestAdapter.ts
IP / 네트워크 ipFilter.ts, webSearchFallback.ts
배치 batchProcessor.ts
사용량 usage.ts

4.6 open-sse/mcp-server/

  • server.ts에 연결된 110개의 고유 도구(schemas/tools.ts의 표준 도구 45개 + 메모리, 스킬, GitHub 스킬, 풀, 게임화, 플러그인, Notion, Obsidian, 로컬 코퍼스 및 압축 모듈 — 합집합은 countUniqueMcpTools로 계산).
  • 3가지 전송 방식: stdio, HTTP Streamable, SSE.
  • 런타임에 적용되는 33개 스코프 — 기본 목록은 src/shared/constants/mcpScopes.ts에 있으며, 전체 집합은 각 도구 모듈에서 선언한 스코프의 합집합입니다.
  • 감사 테이블: mcp_tool_audit(audit.ts에서 데이터 입력).
  • 파일: server.ts, index.ts, httpTransport.ts, audit.ts, scopeEnforcement.ts, runtimeHeartbeat.ts, descriptionCompressor.ts, schemas/{tools, a2a, audit, index}.ts, tools/{advancedTools, compressionTools, memoryTools, skillTools}.ts, 그리고 __tests__/ 아래의 테스트.
  • 전체 도구 카탈로그는 MCP-SERVER.md를 참조하세요.

4.7 open-sse/config/

프로바이더 레지스트리(providerRegistry.ts, providerModels.ts, providerHeaderProfiles.ts), 형식별 모델 레지스트리(audioRegistry.ts, embeddingRegistry.ts, imageRegistry.ts, moderationRegistry.ts, musicRegistry.ts, rerankRegistry.ts, searchRegistry.ts, videoRegistry.ts), 아이덴티티 헬퍼(codexIdentity.ts, codexInstructions.ts, anthropicHeaders.ts, antigravityUpstream.ts, antigravityModelAliases.ts, cliFingerprints.ts, toolCloaking.ts, defaultThinkingSignature.ts), 자격 증명 헬퍼(credentialLoader.ts, codexClient.ts) 및 클라우드 어댑터(azureAi.ts, bedrock.ts, datarobot.ts, glmProvider.ts, maritalk.ts, oci.ts, petals.ts, runway.ts, sap.ts, watsonx.ts, ollamaModels.ts, errorConfig.ts, constants.ts, registryUtils.ts).

4.8 open-sse/utils/

스트리밍 프리미티브 및 공급자 헬퍼: stream.ts, streamHandler.ts, streamHelpers.ts, streamPayloadCollector.ts, streamReadiness.ts, sseHeartbeat.ts, proxyFetch.ts, proxyDispatcher.ts, tlsClient.ts, networkProxy.ts, awsSigV4.ts, cacheControlPolicy.ts, cursorChecksum.ts, cursorAgentProtobuf.ts, cursorVersionDetector.ts, comfyuiClient.ts, kieTask.ts, bypassHandler.ts, aiSdkCompat.ts, thinkTagParser.ts, urlSanitize.ts, usageTracking.ts, requestLogger.ts, progressTracker.ts, cors.ts, error.ts, logger.ts, sleep.ts, ollamaTransform.ts.


5. electron/ — 데스크톱 래퍼

electron/
├── main.js                  Electron 메인 프로세스
├── preload.js               프리로드 브리지(contextIsolation 활성화)
├── types.d.ts
├── package.json             electron-builder 구성, 버전 3.8.51
├── README.md
├── assets/                  빌드 리소스(아이콘, 권한 설정, …)
├── node_modules/            전용 node_modules(better-sqlite3, electron-updater)
└── dist-electron/           빌드 출력(커밋되지 않음)

워크스페이스 루트에는 electron:dev, electron:build, electron:build:{win,mac,linux}, electron:smoke:packaged의 5개 npm 스크립트가 있습니다. 자동 업데이트는 GitHub 릴리스 피드를 가리키는 electron-updater를 통해 수행됩니다.


6. bin/ — CLI

bin/
├── omniroute.mjs           기본 CLI 진입점(Node ESM)
├── reset-password.mjs      CLI에서 관리 비밀번호 재설정
├── mcp-server.mjs          MCP 서버 실행기(stdio)
├── nodeRuntimeSupport.mjs  Node 버전 가드
└── cli/
    ├── program.mjs         Commander 프로그램 빌더
    ├── runtime.mjs         withRuntime 헬퍼(서버 우선/DB 폴백)
    ├── output.mjs          출력 포매터(json/jsonl/table/csv)
    ├── i18n.mjs            로케일을 지원하는 t() 헬퍼
    ├── api.mjs             API fetch 헬퍼
    ├── data-dir.mjs
    ├── encryption.mjs
    ├── sqlite.mjs
    └── commands/
        ├── registry.mjs    명령 등록
        ├── setup.mjs
        ├── doctor.mjs
        ├── providers.mjs
        └── ...             (명령/그룹당 파일 하나)

package.jsonbin에는 두 개의 바이너리가 노출됩니다.

  • omniroutebin/omniroute.mjs
  • omniroute-reset-passwordbin/reset-password.mjs

7. tests/

디렉터리 유형
tests/unit/ Node 기본 테스트 러너를 통한 단위 테스트(1821개 파일 및 api/, auth/, authz/ 하위 디렉터리)
tests/integration/ 모듈 간 + DB 상태 테스트
tests/e2e/ Playwright UI 테스트
tests/e2e/protocol-clients.test.ts MCP/A2A 프로토콜 e2e
tests/translator/ 번역기 전용 테스트
tests/security/ 보안 회귀 테스트
tests/load/ 부하 / 스트레스 테스트
tests/golden-set/ 번역기 회귀 테스트용 참조 출력
tests/helpers/, tests/fixtures/, tests/manual/ 지원

자주 사용하는 명령:

명령 실행 내용
npm run test:unit Node 테스트 러너를 통해 모든 tests/unit/*.test.ts 실행(동시 실행 수 10)
npm run test:vitest Vitest 테스트 스위트(MCP, autoCombo, cache)
npm run test:e2e Playwright UI 테스트 스위트
npm run test:protocols:e2e MCP + A2A 프로토콜 e2e
npm run test:coverage 커버리지 게이트(라인/구문/함수/분기 ≥60%)
node --import tsx/esm --test tests/unit/<file>.test.ts 단일 파일 실행

8. scripts/

용도에 따라 6개의 하위 폴더로 구성됩니다.

  • scripts/build/build-next-isolated.mjs, prepublish.ts, prepare-electron-standalone.mjs, pack-artifact-policy.ts, validate-pack-artifact.ts, postinstall.mjs, postinstallSupport.mjs, uninstall.mjs, bootstrap-env.mjs, runtime-env.mjs, native-binary-compat.mjs.
  • scripts/dev/run-next.mjs, run-next-playwright.mjs, run-standalone.mjs, standalone-server-ws.mjs, responses-ws-proxy.mjs, v1-ws-bridge.mjs, smoke-electron-packaged.mjs, run-playwright-tests.mjs, run-ecosystem-tests.mjs, run-protocol-clients-tests.mjs, sync-env.mjs, healthcheck.mjs, system-info.mjs.
  • scripts/check/check-cycles.mjs, check-docs-sync.mjs, check-docs-counts-sync.mjs, check-env-doc-sync.mjs, check-deprecated-versions.mjs, check-route-validation.mjs, check-t11-any-budget.mjs, check-pr-test-policy.mjs, check-supported-node-runtime.ts, test-report-summary.mjs.
  • scripts/docs/generate-docs-index.mjs, gen-provider-reference.ts.
  • scripts/i18n/generate-multilang.mjs, run-visual-qa.mjs, generate-qa-checklist.mjs, apply-priority-overrides.mjs, validate_translation.py, check_translations.py, i18n_autotranslate.py, untranslatable-keys.json.
  • scripts/ad-hoc/cursor-tap.cjs, sync-cursor-models.mjs, migrate-env.mjs, dbsetup.js.

9. 요청 파이프라인(요약)

요청 파이프라인 (/v1/chat/completions)

출처: diagrams/request-pipeline.mmd

클라이언트 요청
  → /v1/chat/completions (route.ts)
     CORS 프리플라이트 검사
     Zod 검증(shared/validation/schemas.ts의 chatCompletionsSchema)
     인증(extractApiKey + isValidApiKey 또는 requireManagementAuth)
     정책 엔진(src/server/authz/pipeline.ts)
     가드레일(PII 마스커, 프롬프트 인젝션, 비전 브리지)
  → handleChatCore() (open-sse/handlers/chatCore.ts)
     캐시 검사(시맨틱 + 읽기 캐시)
     속도 제한(rateLimitManager, accountSemaphore)
     콤보 라우팅(모델이 콤보로 해석되는 경우)
       comboResolver → 각 대상에 대해 반복 → handleSingleModel()
     translateRequest()  (open-sse/translator/request/*)
     getExecutor(providerId).execute()  (open-sse/executors/*)
       업스트림 가져오기 → accountFallback을 통한 재시도/백오프
     translateResponse() (open-sse/translator/response/*)
     SSE 스트림 또는 JSON 응답
     Responses API인 경우: open-sse/transformer/responsesTransformer.ts를 통한 TransformStream
  → 규정 준수 감사(src/lib/compliance/)
  → 클라이언트에 응답

복원력 런타임 상태(세 가지 메커니즘)

메커니즘 범위 위치
제공자 서킷 브레이커 전체 제공자 src/shared/utils/circuitBreaker.ts, domain_circuit_breakers에 영속화
연결 쿨다운 하나의 계정/키 src/sse/services/auth.tsmarkAccountUnavailable(); accountFallback.checkFallbackError()에서 사용
모델 잠금 제공자 + 연결 + 모델 open-sse/services/accountFallback.ts, domain_lockout_state에 영속화

RESILIENCE_GUIDE.mdCLAUDE.md의 전용 섹션을 참조하세요.


10. 기여 방법

새 제공자 추가

  1. src/shared/constants/providers.ts에 등록합니다(로드 시 Zod로 검증됨).
  2. 사용자 지정 로직이 필요한 경우 open-sse/executors/에 실행기를 추가합니다 (BaseExecutor를 확장).
  3. OpenAI 형식을 사용하지 않는 경우 open-sse/translator/에 변환기를 추가합니다.
  4. OAuth 기반인 경우 src/lib/oauth/providers/src/lib/oauth/services/ 아래에 설정을 추가합니다.
  5. open-sse/config/providerRegistry.ts(또는 open-sse/config/ 아래의 형식별 레지스트리)에 모델을 등록합니다.
  6. tests/unit/ 아래에 테스트를 작성합니다.

새 API 라우트 추가

  1. src/app/api/your-route/route.ts를 생성합니다.
  2. CORS → Zod 본문 검증 → 인증 → 핸들러 위임 패턴을 따릅니다.
  3. 새로운 요청 형식인 경우 src/shared/validation/schemas.ts에 Zod 스키마를 추가합니다.
  4. 관리 전용인 경우 src/shared/constants/publicApiRoutes.ts에 경로를 추가합니다 (공개 API 범위에 대한 거부 목록).
  5. tests/unit/ 아래에 테스트를 추가합니다.
  6. docs/reference/API_REFERENCE.mddocs/openapi.yaml을 업데이트합니다.

새 DB 모듈 추가

  1. src/lib/db/yourModule.ts를 생성하고 ./core.ts에서 getDbInstance()를 가져옵니다.
  2. 도메인에 대한 CRUD 함수를 내보냅니다.
  3. 새 테이블이 있는 경우 src/lib/db/migrations/ 아래에 순차적으로 번호가 지정되고 멱등성과 트랜잭션이 보장되는 마이그레이션을 추가합니다.
  4. 가져오는 쪽에서는 @/lib/db/yourModule에서 직접 가져옵니다(배럴 사용 금지 — 기존 localDb.ts 재내보내기 계층은 제거됨).
  5. tests/unit/ 아래에 테스트를 추가합니다.

새 MCP 도구 추가

  1. open-sse/mcp-server/tools/ 아래에 도구 정의를 추가합니다(또는 open-sse/mcp-server/schemas/tools.ts를 확장).
  2. src/shared/constants/mcpScopes.ts에서 적절한 범위를 할당합니다.
  3. open-sse/mcp-server/server.ts에 도구를 등록합니다.
  4. open-sse/mcp-server/__tests__/ 아래에 테스트를 추가합니다.
  5. MCP-SERVER.md를 업데이트합니다.

새 A2A 스킬 추가

A2A-SERVER.md § 새 스킬 추가를 참조하세요. 스킬은 src/lib/a2a/skills/에 있으며 A2A 작업 관리자를 통해 등록됩니다.


11. 규칙

  • 코드 스타일: 2칸 들여쓰기, 큰따옴표, 100자 너비, 세미콜론, es5 후행 쉼표 — lint-staged를 통해 Prettier로 적용됩니다.
  • 가져오기: 외부 → 내부(@/, @omniroute/open-sse) → 상대 경로 순서입니다.
  • 명명: 파일은 camelCase 또는 kebab-case, 컴포넌트는 PascalCase, 상수는 UPPER_SNAKE를 사용합니다.
  • ESLint: 모든 곳에서 no-eval, no-implied-eval, no-new-func = error; open-sse/tests/에서는 no-explicit-any = warn, 그 외에서는 오류입니다.
  • TypeScript: strict: false(레거시 방침). 모듈 간 경계에서는 타입 추론보다 명시적 타입을 선호합니다.
  • 데이터베이스: 라우트나 핸들러에 원시 SQL을 절대 작성하지 말고, 항상 src/lib/db/ 모듈을 사용합니다. 배럴 가져오기는 절대 사용하지 말고 특정 src/lib/db/* 모듈을 직접 사용합니다.
  • DB 엔터티 타입 지정(#3512): DB 테이블의 행 형상을 쓰거나 읽는 함수는 호출 지점에서 any 또는 인라인 익명 타입을 사용하는 대신, 해당 테이블의 열과 1:1로 대응하는 명명된 TS 인터페이스를 매개변수/반환 타입으로 사용해야 합니다. 인터페이스는 함수 옆에 배치하고(예: saveRequestUsage 위의 src/lib/usage/usageHistory.ts에 있는 export interface UsageEntry), 여러 작성자가 행을 점진적으로 채우는 경우 개별 필드를 선택적/nullable로 유지하며, 호출자마다 형상이 달라지는 필드에는 any보다 unknown을 선호합니다(필드에 문서화해야 함. 예: UsageEntry.tokens는 원시 제공자 형식의 사용량과 정규화된 형식을 모두 허용). 이러한 방식으로 파일의 any 개수가 0에 도달하면 회귀하지 않도록 해당 파일을 check:any-budget:t11 허용 목록 (scripts/check/check-t11-any-budget.mjs, maxAny: 0)에 추가합니다. 이는 첫 단계 규칙이며, 더 광범위한 "익명 any 금지" 정리는 나머지 코드베이스에 걸쳐 반복적으로 진행됩니다.
  • 오류: 구체적인 오류 타입과 함께 try/catch를 사용하고 pino 컨텍스트로 기록합니다. SSE 스트림에서 오류를 절대 조용히 무시하지 말고, 정리를 위해 중단 신호를 사용합니다.
  • 보안: eval() / new Function() / 암시적 eval을 절대 사용하지 않습니다. 모든 입력을 Zod로 검증합니다. 저장된 자격 증명은 암호화합니다(AES-256-GCM). src/shared/constants/upstreamHeaders.ts의 거부 목록을 정리/검증 계층과 일치하도록 유지합니다.
  • 커밋: Conventional Commits — feat(scope): subject. 허용되는 범위: db, sse, oauth, dashboard, api, cli, docker, ci, mcp, a2a, memory, skills.
  • 브랜치: 접두사 feat/, fix/, refactor/, docs/, test/, chore/를 사용합니다. main에 직접 커밋하지 않습니다.
  • Husky: pre-commit은 lint-staged + check:docs-sync + check:any-budget:t11을 실행하고, pre-push는 check:any-budget:t11 + check:tracked-artifacts를 실행합니다(빠른 게이트이며 test:unit은 제외).

12. 엄격한 규칙 (CLAUDE.md에서 발췌)

  1. 비밀 정보나 자격 증명을 절대 커밋하지 마세요.
  2. 배럴 임포트를 절대 사용하지 말고, 특정 src/lib/db/* 모듈을 직접 사용하세요.
  3. eval() / new Function() / 암시적 eval을 절대 사용하지 마세요.
  4. main에 직접 커밋하지 마세요.
  5. 라우트에서 원시 SQL을 절대 작성하지 말고, 항상 src/lib/db/ 모듈을 통해 처리하세요.
  6. SSE 스트림에서 오류를 아무런 처리 없이 무시하지 마세요.
  7. 항상 Zod 스키마로 입력값을 검증하세요.
  8. 프로덕션 코드를 변경할 때는 항상 테스트를 포함하세요.
  9. 커버리지(구문, 라인, 함수, 분기)는 60% 이상을 유지해야 합니다.

13. 참고 자료