refactor(jarca-ledger): implement BAT-010 backend core layering

This commit is contained in:
Jarca
2026-07-03 07:03:17 +09:00
parent 02380a88ab
commit 7ac25a6cf7
36 changed files with 4892 additions and 4113 deletions
@@ -0,0 +1,87 @@
# 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로 전환.