# REQ-013 Backend core layering / SQLite infrastructure split and service facade compatibility - Status: Implemented - Type: Non-Functional - Priority: High - Owner: 렛저장인 - Source Discovery: `docs/discovery/dcy-010_20260702_backend-core-layering-mcp-adapter-realignment.md` - Batch: BAT-010 - Created At (KST): 2026-07-03 00:15 KST - Approved At (KST): 2026-07-03 00:15 KST - Implemented At (KST): 2026-07-03 00:18 KST ## 1. 배경 `dcy-010` confirmed Discovery는 `jarca_ledger_mcp/service.py`와 `jarca_ledger_mcp/db.py`에 과도하게 집중된 책임 때문에 MCP adapter, Streamlit dashboard, SQLite persistence가 하나의 giant module 집합에 강결합돼 있다고 판단했다. Phase 0~3 우선 범위에서는 기능 계약을 바꾸지 않고도 backend core의 최소 layering을 세워 이후 write/import/advanced workflow 분리를 안전하게 이어갈 수 있어야 한다. ## 2. Intent 이 REQ의 목적은 서비스/DB 코드를 한 번에 다시 쓰는 것이 아니라, 기존 동작을 유지한 채 `application` / `infrastructure/sqlite` / compatibility facade 경계를 도입해 코드 탐색성, 변경 안전성, 후속 분리 가능성을 확보하는 것이다. ## 3. 범위 ### In Scope - `jarca_ledger_mcp/service.py`를 compatibility facade로 축소하고 실제 구현을 application 모듈로 분리한다. - 공통 helper/정책을 `jarca_ledger_mcp/application/shared.py`로 정리한다. - SQLite connection/schema/migration 책임을 `jarca_ledger_mcp/infrastructure/sqlite/`로 이동한다. - 기존 `jarca_ledger_mcp/db.py` import surface는 compatibility shim으로 유지한다. - additive/idempotent migration discipline과 기존 테스트 contract를 유지한다. - `docs/project-structure.md`, `docs/runtime-flows.md`에 새 경계를 반영한다. ### Out of Scope - FastAPI/HTTP adapter 추가. - write/import/advanced workflow의 본격적인 Phase 4+ domain 분리. - 데이터 모델 semantics 변경, 응답 envelope 변경, destructive migration. ## 4. Requirement ### FR-1. Application service decomposition - 기존 `service.py`의 기능 구현은 최소한 `system`, `asset/account`, `transaction/report`, `import/transfer`, `categorization` 성격의 application 모듈로 분리돼야 한다. - shared helper와 공통 정책(`cashflow_kind`, KST clock, dedupe, validation helpers)은 application shared module로 이동해야 한다. - 분리 후에도 기존 `from jarca_ledger_mcp import service` 사용자는 동일 함수명을 계속 사용할 수 있어야 한다. ### FR-2. SQLite infrastructure split - 기존 `db.py`의 connection/schema/migration 책임은 `jarca_ledger_mcp/infrastructure/sqlite/`로 이동해야 한다. - top-level `db.py`는 기존 import 경로를 유지하는 compatibility shim이어야 한다. - `db()` context manager는 기존처럼 초기화/commit/rollback semantics를 유지해야 한다. - 스키마 migration은 additive/idempotent 원칙을 유지해야 한다. ### FR-3. Service facade compatibility - `jarca_ledger_mcp/service.py`는 thin facade여야 하며 구현 디테일 대신 application 모듈을 재노출해야 한다. - 기존 pytest/service call sites와 monkeypatch 관성(`_current_kst_datetime`)은 깨지지 않아야 한다. - facade 축소 결과는 더 이상 giant implementation file이 아니어야 한다. ### FR-4. Baseline documentation alignment - `docs/project-structure.md`는 새 package tree와 책임 경계를 반영해야 한다. - `docs/runtime-flows.md`는 service facade, Streamlit gateway, MCP adapter, SQLite infrastructure flow를 반영해야 한다. - 문서는 Phase 4+가 GitHub Project TODO로 남아 있음을 드러내야 한다. ## 5. Acceptance Criteria - AC-1: `jarca_ledger_mcp/application/` 아래에 phase-0~3 범위의 application service modules와 shared module이 생성된다. - AC-2: `jarca_ledger_mcp/infrastructure/sqlite/` 아래에 connection/schema/migration 분리가 생성되고 top-level `db.py` shim이 동작한다. - AC-3: `jarca_ledger_mcp/service.py`는 compatibility facade로 축소되고 600줄 이하를 유지한다. - AC-4: 전체 pytest regression이 PASS 하며 기존 service/db import surface가 유지된다. - AC-5: `docs/project-structure.md`, `docs/runtime-flows.md`가 새 계층 구조를 반영한다. ## 6. Impacted Area - `jarca_ledger_mcp/service.py` - `jarca_ledger_mcp/db.py` - `jarca_ledger_mcp/application/*` - `jarca_ledger_mcp/infrastructure/sqlite/*` - `tests/test_service.py` - `tests/test_asset_snapshots.py` - `docs/project-structure.md` - `docs/runtime-flows.md` ## 7. Notes - 이 REQ는 주로 maintainability/architecture boundary와 compatibility behavior를 다루므로 `Non-Functional`로 관리한다. - write/import/advanced workflow의 deeper split은 dcy-010에서 별도 Phase 4+ TODO로 남겼다. ## 8. Change Log - 2026-07-03 00:15 KST: dcy-010 confirmed 범위를 바탕으로 Proposed 초안을 생성. - 2026-07-03 00:15 KST: 사용자 승인 방향(Phase 0~3 우선, facade 축소, 계약 동결)에 따라 Approved로 전환. - 2026-07-03 00:18 KST: application/infrastructure split, facade/shim compatibility, full pytest PASS, MCP tool discovery, browser smoke evidence를 근거로 Implemented로 전환.