refactor(jarca-ledger): implement BAT-010 backend core layering
This commit is contained in:
+84
@@ -0,0 +1,84 @@
|
||||
# REQ-014 MCP/Streamlit adapter seam realignment and contract-preserving gateway
|
||||
|
||||
- Status: Implemented
|
||||
- Type: Interface
|
||||
- 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`은 MCP server와 Streamlit dashboard가 giant service namespace에 직접 결합돼 있어 내부 구조 개선이 곧 external contract drift로 이어질 위험이 크다고 판단했다. Phase 0~3에서는 adapter를 얇게 만들되, tool names/response envelope/dashboard 핵심 페이지를 유지하는 것이 핵심이다.
|
||||
|
||||
## 2. Intent
|
||||
|
||||
이 REQ의 목적은 MCP와 Streamlit을 제거하는 것이 아니라, backend core 위에 얹힌 thin adapter로 재정렬하는 것이다. 즉 `server.py`와 `dashboard/app.py`가 더 좁은 seam을 통해 application core를 호출하면서도 기존 사용자의 운영 경험과 계약은 유지해야 한다.
|
||||
|
||||
## 3. 범위
|
||||
|
||||
### In Scope
|
||||
- `jarca_ledger_mcp/adapters/mcp/server.py`를 도입하고 top-level `server.py`를 compatibility shim으로 유지한다.
|
||||
- `jarca_ledger_mcp/adapters/streamlit/service_gateway.py`를 도입하고 dashboard가 이 gateway를 통해 service functions를 호출하도록 정렬한다.
|
||||
- MCP tool discovery 결과(56 tools)와 success envelope contract를 유지한다.
|
||||
- Streamlit 핵심 페이지(`요약`, `자산/마감` 포함)가 synthetic fixture DB에서 렌더링돼야 한다.
|
||||
- baseline docs와 batch verification evidence에 adapter seam을 반영한다.
|
||||
|
||||
### Out of Scope
|
||||
- 신규 MCP 도구 추가나 응답 schema 변경.
|
||||
- 새로운 Streamlit IA/디자인 재구성.
|
||||
- HTTP adapter/REST route 추가.
|
||||
|
||||
## 4. Requirement
|
||||
|
||||
### FR-1. MCP adapter thinness
|
||||
- 실제 FastMCP registration은 `jarca_ledger_mcp/adapters/mcp/server.py`에 위치해야 한다.
|
||||
- top-level `jarca_ledger_mcp/server.py`는 CLI/script entrypoint 호환을 위한 shim이어야 한다.
|
||||
- MCP 도구명/설명/인자 contract는 유지돼야 한다.
|
||||
|
||||
### FR-2. Streamlit gateway seam
|
||||
- `dashboard/app.py`는 giant service implementation이 아니라 명시적 gateway module을 통해 service functions를 사용해야 한다.
|
||||
- gateway는 dashboard가 실제로 필요한 surface만 노출해야 한다.
|
||||
- dashboard 렌더 결과는 synthetic fixture DB 기준 기존 핵심 페이지를 깨지 않아야 한다.
|
||||
|
||||
### FR-3. Contract-preserving verification
|
||||
- full pytest regression과 MCP tool discovery가 PASS 해야 한다.
|
||||
- browser-level smoke는 synthetic fixture DB에서 `요약`과 구조 변경 영향 페이지(`자산/마감`)를 렌더링해야 한다.
|
||||
- 브라우저 콘솔 JS 에러가 없어야 한다.
|
||||
|
||||
### FR-4. Documentation alignment
|
||||
- `docs/project-structure.md`와 `docs/runtime-flows.md`는 adapter/gateway seam과 compatibility shim 구조를 반영해야 한다.
|
||||
- BAT verification 문서는 synthetic-only evidence와 잔여 Phase 4+ TODO를 기록해야 한다.
|
||||
|
||||
## 5. Acceptance Criteria
|
||||
|
||||
- AC-1: `jarca_ledger_mcp/adapters/mcp/server.py`와 top-level `server.py` shim이 존재하고 `hermes mcp test jarca-ledger`가 PASS 한다.
|
||||
- AC-2: `jarca_ledger_mcp/adapters/streamlit/service_gateway.py`가 도입되고 `dashboard/app.py`가 이를 사용한다.
|
||||
- AC-3: full pytest가 PASS 하고 Streamlit AppTest smoke가 계속 PASS 한다.
|
||||
- AC-4: local browser smoke에서 `요약`과 `자산/마감` 페이지가 렌더링되고 console JS errors가 없다.
|
||||
- AC-5: baseline docs와 batch evidence 문서가 새 adapter seam을 반영한다.
|
||||
|
||||
## 6. Impacted Area
|
||||
|
||||
- `jarca_ledger_mcp/server.py`
|
||||
- `jarca_ledger_mcp/adapters/mcp/server.py`
|
||||
- `jarca_ledger_mcp/adapters/streamlit/service_gateway.py`
|
||||
- `dashboard/app.py`
|
||||
- `tests/test_dashboard_app.py`
|
||||
- `tests/test_contract_regression.py`
|
||||
- `docs/project-structure.md`
|
||||
- `docs/runtime-flows.md`
|
||||
|
||||
## 7. Notes
|
||||
|
||||
- 이 REQ는 MCP/Streamlit surface와 operator-facing 호출 경계를 다루므로 `Interface` 타입으로 관리한다.
|
||||
- gateway는 현재 dashboard가 사용하는 surface만 노출하며, Phase 4+에서 더 좁은 domain-specific gateway로 재분할할 수 있다.
|
||||
|
||||
## 8. Change Log
|
||||
|
||||
- 2026-07-03 00:15 KST: dcy-010 confirmed 범위를 바탕으로 Proposed 초안을 생성.
|
||||
- 2026-07-03 00:15 KST: 사용자 승인 방향(계약 동결, adapter thinness, Phase 0~3 우선)에 따라 Approved로 전환.
|
||||
- 2026-07-03 00:18 KST: MCP adapter split, Streamlit gateway 도입, browser smoke, MCP discovery, full pytest PASS를 근거로 Implemented로 전환.
|
||||
+87
@@ -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로 전환.
|
||||
+6
-2
@@ -28,12 +28,12 @@
|
||||
| **Integration** | 외부 시스템 연동, 플러그인, 확장 | KB/토스/서울페이 import |
|
||||
| **Interface** | 사용자 상호작용 방식 | MCP tool, Streamlit UI |
|
||||
| **Migration** | 데이터 이전, 버전 업그레이드 | SQLite schema migration |
|
||||
| **Non-Functional** | 성능, 보안, 확장성, 호환성, 신뢰성 | 개인정보/금융정보 보호, UX 성능 |
|
||||
| **Non-Functional** | 성능, 보안, 확장성, 호환성, 신뢰성 | 개인정보/금융정보 보호, UX 성능, 아키텍처 유지보수성 |
|
||||
| **Testing** | 테스트 전략, QA 요구사항, 검증 방식 | parser regression, report validation |
|
||||
|
||||
## Next Requirement ID
|
||||
|
||||
- Current: `REQ-013`
|
||||
- Current: `REQ-015`
|
||||
- Rule: `Requirement Register`에 있는 가장 큰 REQ 번호보다 정확히 1 커야 한다.
|
||||
|
||||
## Requirement Register
|
||||
@@ -52,6 +52,8 @@
|
||||
| REQ-010 | Asset snapshot/net worth read MCP and dashboard alignment | Interface | Implemented | High | 렛저장인 | [req-010_asset-snapshot-net-worth-read-mcp-and-dashboard-alignment.md](Interface/req-010_asset-snapshot-net-worth-read-mcp-and-dashboard-alignment.md) |
|
||||
| REQ-011 | Manual asset CRUD / month-end snapshot write model | Data | Implemented | High | 렛저장인 | [req-011_manual-asset-crud-month-end-snapshot-write-model.md](Data/req-011_manual-asset-crud-month-end-snapshot-write-model.md) |
|
||||
| REQ-012 | Manual asset CRUD / snapshot close MCP and operator dashboard alignment | Interface | Implemented | High | 렛저장인 | [req-012_manual-asset-crud-snapshot-close-mcp-and-operator-dashboard-alignment.md](Interface/req-012_manual-asset-crud-snapshot-close-mcp-and-operator-dashboard-alignment.md) |
|
||||
| REQ-013 | Backend core layering / SQLite infrastructure split and service facade compatibility | Non-Functional | Implemented | High | 렛저장인 | [req-013_backend-core-layering-sqlite-infrastructure-service-facade-compatibility.md](Non-Functional/req-013_backend-core-layering-sqlite-infrastructure-service-facade-compatibility.md) |
|
||||
| REQ-014 | MCP/Streamlit adapter seam realignment and contract-preserving gateway | Interface | Implemented | High | 렛저장인 | [req-014_mcp-streamlit-adapter-seam-realignment-contract-preserving-gateway.md](Interface/req-014_mcp-streamlit-adapter-seam-realignment-contract-preserving-gateway.md) |
|
||||
|
||||
## Recent Change Log Summary
|
||||
|
||||
@@ -76,3 +78,5 @@
|
||||
- 2026-07-01 09:00 KST: dcy-009 confirmed 범위를 `REQ-011`(manual asset CRUD / month-end snapshot write model)과 `REQ-012`(manual asset CRUD / snapshot close MCP and operator dashboard alignment) Proposed 상태로 생성했다.
|
||||
- 2026-07-01 09:02 KST: `REQ-011`, `REQ-012`를 승인 게이트 재검토 후 Approved로 전환했다.
|
||||
- 2026-07-01 10:52 KST: BAT-009 구현·검증 evidence, full pytest PASS, MCP tool discovery, browser smoke를 근거로 `REQ-011`, `REQ-012`를 Implemented로 전환했다.
|
||||
- 2026-07-03 00:15 KST: dcy-010 confirmed 범위를 `REQ-013`, `REQ-014`로 생성하고 승인 상태를 정리했다.
|
||||
- 2026-07-03 00:18 KST: BAT-010 구현·검증 evidence, full pytest PASS, MCP tool discovery, browser smoke를 근거로 `REQ-013`, `REQ-014`를 Implemented로 전환했다.
|
||||
|
||||
Reference in New Issue
Block a user