Implement BAT-011 transactional write service split

This commit is contained in:
Jarca
2026-07-03 07:42:16 +09:00
parent 7ac25a6cf7
commit ac78e94571
21 changed files with 844 additions and 228 deletions
@@ -7,7 +7,7 @@
- 작성 시각(KST): 2026-07-02 23:32
- 마지막 갱신 시각(KST): 2026-07-02 23:56
- 대체됨: 없음
- 후속 Discovery 참조: 없음
- 후속 Discovery 참조: docs/discovery/dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing.md (Phase 4~7 write/import/advanced workflow/adapter narrowing 후속 주기)
- 생성된 REQ 참조: `REQ-013`, `REQ-014`
# 1. 계획 상태 요약
@@ -0,0 +1,243 @@
# 0. 문서 상태
이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다.
- 상태: confirmed
- 문서 ID: dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing
- 이슈명: Jarca Ledger 백엔드 리팩터링 Phase 4+ 후속 주기 (write service 분리 → import pipeline 분리 → advanced finance workflow 분리 → MCP/Streamlit adapter 표면 축소)
- 작성 시각(KST): 2026-07-03 07:10
- 마지막 갱신 시각(KST): 2026-07-03 07:29
- 대체됨: 없음
- 후속 Discovery 참조: 없음
- 생성된 REQ 참조: `REQ-015`
# 1. 계획 상태 요약
현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다.
- 연계 문서 현황:
- 선행 Discovery: `docs/discovery/dcy-010_20260702_backend-core-layering-mcp-adapter-realignment.md` (Phase 0~3 foundations/persistence/read-only 추출을 확정한 confirmed Discovery, REQ-013/REQ-014 생성)
- 관련 blueprint: `.hermes/plans/2026-07-02_jarca-ledger-backend-refactor-blueprint.md` (Phase 0~8 리팩터링 청사진, 이번 Discovery는 Phase 4~8 절을 근거로 함)
- 관련 baseline 문서: `docs/project-structure.md`, `docs/runtime-flows.md`
- 관련 project board: GitHub Project 4(Jarca) Todo 항목 (Phase 4 transactional write services, Phase 5 import pipeline application/infrastructure 분리, Phase 6 advanced finance workflow services, Phase 7 MCP/Streamlit adapter surface 축소, Phase 8 optional HTTP adapter 준비)
- 해석:
- dcy-010은 blueprint Phase 0~3(behavioral baseline 고정 → skeleton/compat seam → persistence 분리 → read-only application service 추출)을 첫 배치로 확정했고, BAT-010 구현으로 `service.py`/`server.py` shim과 Streamlit gateway seam이 이미 도입되었다. 다만 Phase 4 이후의 write/import/advanced workflow 세분화와 adapter surface 추가 축소는 명시적으로 Out of Scope로 남겨 별도 후속 주기(REQ·Batch·GitHub Project TODO)로 추적하기로 했다.
- 이번 Discovery는 그 후속 주기를 독립적으로 정의한다. project board Todo와 blueprint Phase 4~8을 근거로, 우선순위를 Phase 4~7(write → import → advanced workflow → adapter narrowing)에 두되, 이미 착수된 seam을 전제로 남은 coupling을 더 좁히는 방향으로 다룬다. Phase 8(optional HTTP adapter)은 이번 주기에서는 구현하지 않고 Deferred 후보로만 남긴다. staged refactor·contract preservation·additive migration·text-first UI seam·no destructive migration 원칙은 dcy-010과 동일하게 유지한다.
# 2. 요구사항 판정 결과
이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다.
- 판정: 신규
- 근거
- dcy-010은 Phase 0~3을 In Scope로 확정하고 Phase 4+를 명시적으로 Out of Scope로 분리(`# 5. 범위 경계`)했으므로, Phase 4~7 write/import/advanced workflow/adapter narrowing은 dcy-010의 미세 조정이 아니라 문제 정의·핵심 사용자 시나리오·성공 기준이 다른 독립 후속 주기다(SKILL 규칙 2의 `새 Discovery 생성` 조건: 후속 반복을 독립 주기로 추적).
- 대상 슬라이스가 mutation-heavy(트랜잭션/계좌/규칙 CRUD, import mutation, cross-transfer/reconciliation/asset)이고 adapter 표면 축소까지 포함하므로, dcy-010의 read-only 우선 배치와 리스크 프로파일·검증 전략이 실질적으로 다르다. 같은 문서에 계속 누적하면 책임 경계가 흐려진다.
> **판정이 `완전 중복`인 경우**: 이하 섹션 작성을 중단하고 `# 9. 파일 처리 결과`에 중복 판정 사유와 참조 문서 경로를 기록한 뒤 문서를 닫는다. REQ 초안 작성으로 넘기지 않는다.
# 3. 문제점의 요약
문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.
- 현재 상태
- dcy-010/REQ-013·REQ-014와 BAT-010 구현으로 Phase 0~3 배치(behavioral baseline, skeleton/compat seam, persistence 분리, read-only application service)가 이미 반영되어 `jarca_ledger_mcp/service.py`는 40줄 compatibility facade, `jarca_ledger_mcp/server.py`는 6줄 shim, `dashboard/app.py`는 `adapters/streamlit/service_gateway`를 통하는 read gateway 형태로 정리되었다.
- 그러나 write/import/advanced workflow의 핵심 로직은 여전히 대형 application modules, broad gateway, compatibility surface 뒤에 넓게 남아 있다. 특히 `application/import_transfer_services.py`는 1,500줄대 규모로 import mutation·cross-transfer·reconciliation 일부를 함께 품고 있어 다음 단계의 세분화 대상이 명확하다.
- project board의 Phase 4~7 Todo는 BAT-010 이전 표현(예: MCP/Streamlit seam 도입)을 일부 포함하지만, 현재 저장소 기준으로는 “초기 seam 도입”이 아니라 “남은 write/import/advanced coupling과 broad adapter surface를 추가 축소”하는 후속 작업으로 재해석해야 한다.
- baseline 문서(`docs/project-structure.md`, `docs/runtime-flows.md`)는 dcy-010에서 Phase 0~3 구조까지는 반영했지만, Phase 4~7의 finer-grained write/import/advanced 서비스 경계와 추가 adapter narrowing이 반영되면 다시 갱신 갭이 발생한다.
- GitHub Project 4(Jarca) 보드 Todo에 Phase 4~8이 후속 작업으로 등록되어 있어, 이 후속 주기를 Discovery로 정식화할 필요가 있다.
- 기대 상태
- write 경로(계좌/트랜잭션/예산/카테고리·규칙 mutation)가 현재의 broad compatibility/application surface에서 더 잘게 쪼개진 `application/*_service.py`와 대응 repository 뒤로 이동해 validation·orchestration·transaction boundary·audit tagging 책임이 명시된다.
- import pipeline이 `application/imports_service.py`와 `infrastructure/parsers/*`로 더 선명하게 분리되어 parser(파싱/정규화)와 import orchestration(dedupe/분류 기본값/batch 생성/persistence/후속 reconciliation)이 독립적으로 테스트 가능해지고, import 증빙 필드가 그대로 보존된다.
- cross-transfer/reconciliation/asset/net worth/workbench 등 domain-heavy 워크플로우가 전용 application service로 추가 분리되어 import/write 서비스와 책임 경계가 겹치지 않는다.
- MCP/Streamlit seam은 이미 존재하므로, 다음 목표는 top-level shim과 broad gateway를 유지한 채 호출 표면을 더 좁혀 MCP tool registration/contract helper와 Streamlit page-domain gateway를 분리하는 것이다.
- 결과적으로 compatibility facade/shim은 계속 얇게 유지되고, HTTP 등 신규 adapter가 로직 재배치 없이 `application/*` 위에 추가 가능한 상태가 된다.
- 이해관계자
- 문서 작성자(AI agent) 및 리팩터링 실행 subagent
- 리뷰어/승인자(Hermes 및 저장소 소유자 `진환 고`)
- MCP/Streamlit 사용자(마이그레이션 전 구간에서 동작·계약 유지가 보장되어야 하는 소비자)
- 제약사항
- 마이그레이션 전 구간에서 MCP tool 이름/주요 응답 필드/카테고리·현금흐름 의미/import 증빙 필드(`raw_summary`/`counterparty`/`raw_payload`/`external_id`/`import_batch_id`)/additive-only migration/Streamlit 페이지 동작·순서가 호환 계약으로 유지되어야 한다(contract preservation).
- big-bang rewrite 금지, staged refactor로 한 번에 하나의 도메인 슬라이스만 이관한다.
- 금융 데이터 특성상 destructive migration은 승인 없이 금지하고 fixture/복사 DB만 사용한다(additive migration, no destructive migration).
- Streamlit UI seam은 text-first(좁은 gateway 호출 기반)로 유지하며 UI에 SQL/deep domain 규칙을 두지 않는다.
- Phase 4~7은 dcy-010(Phase 0~3) 산출물이 seam으로 존재함을 전제로 하므로 선행 배치 완료·부분 완료 상태에 따라 착수 시점 의존성이 있다.
## 주요 사용자 시나리오
사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.
- 개발자가 트랜잭션 생성/수정/삭제 또는 카테고리 규칙 mutation 로직을 고칠 때, 3,379줄 service.py 대신 `application/transactions_service.py`·`category_rules_service.py`와 대응 repository만 열어 변경·테스트하려는 상황.
- 운영자가 특정 은행 PDF/엑셀 import 파싱 이슈를 진단할 때, parser(`infrastructure/parsers/*`)와 import orchestration(`imports_service`)이 분리되어 있어 파싱 오류를 mutation 경로가 아닌 parser 경계로 국소화하려는 상황.
- 개발자가 cross-transfer 매칭이나 asset snapshot/net worth 계산 같은 domain-heavy 로직을 확장할 때, 전용 service에서 규칙을 이해·테스트하고 monolith 회귀 위험을 피하려는 상황.
- 향후 HTTP/FastAPI adapter를 추가하려는 개발자가 write/import/advanced 로직을 다시 이동시키지 않고 좁은 gateway와 `application/*` 위에 adapter 패키지만 얹으려는 상황.
# 4. 이번에 정의할 변경
이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다.
- Phase 4 — transactional write service 분리: 계좌/트랜잭션/예산/카테고리·규칙 mutation을 `application/{accounts,transactions,budgets,category_rules}_service.py`와 대응 repository 뒤로 이관하고, service.py는 해당 함수에 대해 delegator/facade로 남긴다.
- Phase 5 — import pipeline application/infrastructure 분리: import preview/import/rollback 및 parser orchestration을 `application/imports_service.py`와 `infrastructure/parsers/*`로 분리하고, parser는 파싱/정규화만, imports_service는 dedupe·분류 기본값·batch 생성·persistence·후속 reconciliation을 담당하며 import 증빙 필드를 보존한다.
- Phase 6 — advanced finance workflow service 분리: cross-transfer·reconciliation·asset/snapshot/net worth·uncategorized workbench 워크플로우를 `application/{cross_transfer,reconciliation,assets}_service.py`로 이관한다.
- Phase 7 — MCP/Streamlit adapter surface 추가 축소: 이미 도입된 `adapters/mcp/server.py`·`adapters/streamlit/service_gateway.py` seam을 전제로, MCP registration helper/contract helper와 Streamlit page-domain gateway를 더 잘게 분리하고 `dashboard/app.py`의 broad gateway 의존을 단계적으로 좁힌다.
- baseline 문서 갱신 요구: Phase 4~7의 새 write/import/advanced 서비스와 adapter 경계·호출 흐름을 반영해 `docs/project-structure.md`와 `docs/runtime-flows.md`를 갱신한다.
- 단계적 완료 기준 확정: Phase 4~7 완료 시 service.py/db.py가 blueprint §11 기준 호환 facade/shim(~400~600줄 이하) 수준으로 축소되는 것을 이번 주기의 Definition of Done 방향으로 둔다.
- Phase 8 취급 결정: optional HTTP adapter 준비(`adapters/http/*`)는 이번 주기 우선순위에서 제외하고 Deferred 후보로만 다룬다.
## 영향 범위
변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.
- 코드 영향:
- 신규 `jarca_ledger_mcp/application/{accounts,transactions,budgets,category_rules,imports,cross_transfer,reconciliation,assets}_service.py`
- 신규 `jarca_ledger_mcp/infrastructure/parsers/{kb_bank_pdf,toss_bank_pdf,toss_securities_pdf,seoulpay_xlsx}.py` 및 대응 repository(트랜잭션/예산/규칙/import_batches/assets/snapshots)
- 신규 `jarca_ledger_mcp/adapters/mcp/{server,tool_contracts}.py`, `jarca_ledger_mcp/adapters/streamlit/service_gateway.py`
- `jarca_ledger_mcp/service.py`·`db.py`·`server.py`의 facade/shim 축소, `dashboard/app.py`의 gateway 전환, `pyproject.toml` 패키지 discovery/entrypoint 정합성 유지
- 테스트를 repository/application-service/adapter 계층(Layer A/B/C)으로 재배치 및 신규 추가
- 문서 영향:
- `docs/project-structure.md`, `docs/runtime-flows.md` 갱신 요구
- 신규 Discovery(`dcy-011`) 및 `docs/discovery/index.md` 행 추가, dcy-010의 `후속 Discovery 참조` 갱신
- 운영 영향:
- 마이그레이션 중 MCP/Streamlit 동작·계약 유지 필요, entrypoint 호환 유지로 배포 절차 자체 변경 없음
- destructive migration 금지, DB 안전 정책(복사/fixture DB) 유지
# 5. 요구사항 목록
실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.
## 기능 요구사항
- FR-1 (Phase 4): 계좌/트랜잭션/예산/카테고리·규칙 write 함수(`create/update/delete_ledger_transaction`, `create/update_ledger_account`, `create_ledger_budget`, `create/delete_ledger_category`, `create/update/delete_category_rule`, `preview/apply_categorization*`, `preview/apply_category_rule*`)를 `application/*_service.py`와 대응 repository로 이관하고, service.py는 delegator facade로 남겨 기존 호출부와 MCP/Streamlit 계약이 깨지지 않게 한다.
- FR-2 (Phase 5): import preview/import/rollback(`preview_ledger_csv_import`, `preview/import_kb_bank_pdf`, `preview/import_seoulpay_xlsx`, `preview/import_toss_bank_pdf`, `preview/import_toss_securities_pdf`, `list_ledger_import_batches`, `rollback_ledger_import_batch`)을 `application/imports_service.py`와 `infrastructure/parsers/*`로 분리하되, parser는 파싱/정규화만 담당하고 import 증빙 필드(`raw_summary`/`counterparty`/`raw_payload`/`external_id`/`import_batch_id`)를 변경 없이 보존한다.
- FR-3 (Phase 6): cross-transfer(`preview_cross_account_transfers`, `run_cross_account_transfer_match`, `list_cross_transfer_review_queue`), reconciliation(`get_balance_reconciliation_report`), asset/net worth(`list/create/update/deactivate_manual_asset`, `preview/close/create_asset_snapshot`, `get_asset_snapshot_report`, `get_net_worth_timeseries`, `get_asset_liquidity_report`), workbench(`list_uncategorized_transactions`, `get_uncategorized_merchant_summary`, `get_uncategorized_workbench`)를 전용 application service로 이관한다.
- FR-4 (Phase 7): 이미 존재하는 `adapters/mcp/server.py`와 `adapters/streamlit/service_gateway.py`를 출발점으로 삼아 MCP registration/helper·contract helper를 adapter 내부로 더 정리하고, Streamlit이 page/domain별 좁은 gateway에만 의존하도록 `dashboard/app.py`의 broad gateway 사용을 단계적으로 축소한다.
- FR-5 (baseline): Phase 4~7의 새 계층 구조와 호출 흐름 갱신 요구를 `docs/project-structure.md`와 `docs/runtime-flows.md`에 반영한다.
## 비기능 요구사항
성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다.
- NFR-1 (contract preservation): MCP tool 이름, 주요 응답 필드(`success`, `count`, `items`, `error`, `validation`, `matched_count` 등), 카테고리·현금흐름 의미, import 증빙 필드, additive-only migration, Streamlit 페이지 동작·순서가 의도적 버전 변경·승인 없이 바뀌지 않는다.
- NFR-2 (staged safety): 각 phase는 독립적으로 검증 가능해야 하고(pytest 회귀 + py_compile), 한 번에 하나의 도메인 슬라이스만 이관해 blast radius를 최소화하며, write/import/advanced 순서로 mutation 위험이 낮은 것부터 이관한다.
- NFR-3 (DB safety / additive migration): 리팩터링 중 fixture/복사 DB만 사용하고 승인 없는 destructive migration을 수행하지 않으며, schema 변경이 필요하면 additive column 방식만 사용한다.
- NFR-4 (test layering): 이관과 함께 테스트를 Layer A(repository)/Layer B(application-service)/Layer C(adapter contract)로 이동·보강해 검증이 monolith service.py 테스트에만 의존하지 않게 한다.
## 범위 경계
이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다.
- In Scope
- blueprint Phase 4~7 우선: transactional write service 분리 → import pipeline application/infrastructure 분리 → advanced finance workflow service 분리 → MCP/Streamlit adapter surface 축소
- Phase 4~7 이관에 필요한 repository/parser/adapter 모듈과 대응 테스트(Layer A/B/C) 재배치
- baseline 문서(project-structure/runtime-flows) 갱신 요구
- staged refactor·contract preservation·additive migration·text-first UI seam·no destructive migration 원칙 유지
- Out of Scope
- Phase 8 optional HTTP adapter(`adapters/http/*`) 실제 구현 — 이번 주기 우선순위 밖이며 Deferred 후보로만 유지한다.
- 즉시 FastAPI/HTTP 전환 강제
- Postgres/원격 DB 이관
- 멀티유저/권한 체계 도입
- 원격 운영(remote ops) 재설계
- Phase 0~3 재작업(선행 dcy-010/REQ-013·REQ-014 범위이며 본 주기에서 다시 정의하지 않음)
- 이번 Discovery는 하나로 유지하되, REQ/Batch는 Phase별·도메인별로 분할한다.
# 6. 리스크/가정 목록
불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다.
## 리스크
- R-1 (High): write/import mutation 경로 이관 중 계약 drift — 트랜잭션/규칙/import 응답 형태나 증빙 필드가 조용히 바뀌면 데이터 무결성과 소비자 계약이 깨질 수 있다.
- 완화 방안: 이관 전 MCP tool contract 및 응답 shape 회귀 테스트(dcy-010 Phase 0 baseline 및 dcy-007 응답 계약)를 기준으로 두고, import 증빙 필드 보존을 명시적 테스트로 고정한 뒤 슬라이스 단위로 이관한다.
- R-2 (High): advanced workflow(cross-transfer/reconciliation/asset)의 숨은 결합 — domain-heavy 로직이 공유 helper에 의존해 이관 시 예상치 못한 호출부가 깨질 수 있다.
- 완화 방안: blueprint 실행 순서(read → write → import → advanced)를 지켜 repository/base service가 검증된 뒤에 이관하고, helper는 첫 소비자와 함께 이동하며 characterization 테스트를 선행한다.
- R-3 (Medium): Streamlit adapter 축소 시 hot-reload/직접 import 취약성 — `dashboard/app.py`의 넓은 `service.*` 의존을 좁은 gateway로 바꾸는 과정에서 페이지가 깨질 수 있다.
- 완화 방안: `service_gateway.py`를 도입해 페이지 단위로 점진 이관하고, hot-reload helper는 domain/application이 아닌 adapter-specific 코드로 이동하며 페이지/서비스 통합 테스트를 확보한다.
- R-4 (Medium): 선행 배치(dcy-010 Phase 0~3) 미완료 상태에서 Phase 4 착수 시 seam 부재로 이관 비용 증가.
- 완화 방안: Phase 4 착수 전 Phase 0~3 seam(compat facade, persistence 분리, read-only service) 완료 여부를 REQ/Batch planning의 진입 조건으로 확인한다.
## 가정
아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다.
- A-1: dcy-010/REQ-013·REQ-014로 정의된 Phase 0~3 배치가 이번 후속 주기 착수 시점까지 seam(compat facade, sqlite 분리, read-only application service)을 제공한다.
- A-2: 기존 pytest 스위트(transaction/import/rules/dashboard/asset snapshot 회귀 등)와 dcy-007 MCP 응답 계약 테스트가 동작하며 Phase 4~7 회귀 검증의 기준으로 사용할 수 있다.
- A-3: 현재 SQLite schema가 additive-oriented이므로 destructive 변경 없이 write/import/advanced 슬라이스 이관을 진행할 수 있다.
- A-4: GitHub Project 4(Jarca) 보드 Todo의 Phase 4~8 항목과 blueprint Phase 4~8 절이 동일한 후속 작업 정의를 가리킨다(요청 원문과 blueprint로 교차 확인).
## 오픈 질문
답을 아직 모르는 항목을 적는다. 추정으로 덮지 말고 REQ 초안 작성 이전에 확인할 질문으로 남긴다.
- OQ-1: Phase 4~7을 하나의 후속 REQ/Batch 주기로 묶을지, Phase별(또는 write / import / advanced+adapter) 하위 배치로 분할해 추적할지?
- 상태: Answered
- 처리 방안: 사용자 결정에 따라 Discovery는 하나로 유지하고, REQ/Batch는 Phase별·도메인별로 분할한다.
- 종료 조건: `# 5. 범위 경계`와 `# 10. 사용자 결정 필요 항목 요약`에 배치 분할 방침이 반영되었으므로 종료한다.
- OQ-2: Phase 8 optional HTTP adapter 준비를 이번 후속 주기의 Out of Scope로 완전히 제외할지, Deferred(다음 주기 예약) 후보로 명시적으로 남길지?
- 상태: Answered
- 처리 방안: 사용자 결정에 따라 이번 주기에서는 구현하지 않고 Deferred 후보로만 남긴다.
- 종료 조건: `# 1. 계획 상태 요약`, `# 4. 이번에 정의할 변경`, `# 5. 범위 경계`에 Deferred 취급이 반영되었으므로 종료한다.
### 오픈 질문 처리 기준
- `Open`: 아직 답이 없고 다음 단계 진행에 영향이 있는 상태다. 문서에 유지한다.
- `Answered`: 답이 확정된 상태다. 관련 본문/요구사항에 반영한 뒤 오픈 질문 목록에서는 제거하거나 resolved 기록으로 이동한다.
- `Deferred`: 지금 단계에서 결정하지 않고 다음 단계 또는 후속 이슈로 넘기는 상태다. 넘길 대상과 이유를 반드시 적는다.
- `Dropped`: 더 이상 유효하지 않은 질문이다. 삭제 사유를 짧게 남기고 목록에서 제거한다.
- 처리 원칙 1: 질문만 남기지 말고 반드시 `상태`, `처리 방안`, `종료 조건`을 함께 적는다.
- 처리 원칙 2: 답이 나온 질문은 본문 반영 없이 단순 삭제하지 않는다. 반영 위치를 먼저 갱신한다.
- 처리 원칙 3: High 영향 질문은 `Deferred` 처리 후 처리 방안에 REQ 인계 추적 방식을 명시한다.
# 7. 초기 성공 기준
이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다.
- S-1: Phase 4~7 전 구간에서 MCP와 Streamlit이 동작하며, 기존/대체 회귀 테스트와 MCP tool contract 테스트가 통과한다(계약 무변경).
- S-2: Phase 4~7 이관 완료 시 write/import/advanced 로직이 더 잘게 나뉜 `application/*`, `infrastructure/parsers/*`, 전용 advanced workflow services로 이동하고, compatibility facade/shim은 얇게 유지되며 broad application modules의 책임 밀도가 유의미하게 낮아진다.
- S-3: `dashboard/app.py`가 broad `service_gateway` 또는 legacy compatibility surface 대신 더 좁은 page/domain gateway에 의존하고, MCP adapter도 registration/helper·contract helper가 분리된 구조를 갖는다.
- S-4: 각 도메인 영역이 자체 application service와 persistence 경계를 갖고 `docs/project-structure.md`·`docs/runtime-flows.md`가 Phase 4~7 계층 구조를 반영하도록 갱신되어, 이후 REQ/Batch 산출물과 향후 HTTP adapter가 baseline 문서를 참조할 수 있다.
## 측정 방식 및 데이터 출처
각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다.
- S-1 측정 방식: 각 phase 종료 시 pytest 회귀 스위트 + MCP tool contract 테스트 전부 통과 확인 / 데이터 출처: `tests/` 실행 결과, `docs/discovery/dcy-007` 응답 계약, dcy-010 Phase 0 baseline
- S-2 측정 방식: 대형 application module의 라인 수/책임 축소, write/import/advanced 함수가 더 세분화된 `application/*`·`infrastructure/parsers/*`·전용 workflow services로 이동했는지 확인 / 데이터 출처: 리팩터링 후 소스 파일, blueprint §5(Phase 4~7)·§11 DoD
- S-3 측정 방식: `dashboard/app.py`의 broad gateway 직접 호출 수 감소와 page/domain gateway 사용 여부, MCP adapter 내부 helper 분리 여부 확인 / 데이터 출처: `dashboard/app.py`, `jarca_ledger_mcp/adapters/*`
- S-4 측정 방식: 도메인별 application service/repository 존재 여부 및 baseline 문서 diff 확인 / 데이터 출처: `jarca_ledger_mcp/{application,infrastructure,adapters}/*`, `docs/project-structure.md`, `docs/runtime-flows.md`
# 8. REQ로 넘기기 전 확인 체크
REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다.
- [x] 범위(In Scope/Out of Scope) 확정
- 기준: Phase 4~7 우선 In Scope, Phase 8은 Deferred 후보로만 유지, Discovery는 하나로 두되 REQ/Batch는 Phase별·도메인별로 분할한다는 방침이 문서에 반영되어 있다.
- [x] 성공 지표의 측정 방식/데이터 출처 확정
- 기준: S-2의 DoD를 broad application module 책임 축소와 compatibility facade/shim 유지로 채택하고 baseline 테스트 목록은 REQ/planning에서 계측 대상으로 명시한다.
- [ ] High 영향 리스크 우선순위 및 해소 책임자 지정
- 기준: R-1(계약 drift), R-2(advanced 결합)의 characterization/contract 테스트 선행 책임자는 REQ/Batch planning에서 지정한다. Discovery confirm의 차단 사유는 아니다.
- [x] 모든 오픈 질문(OQ) `Open` 상태 없음 확인
- 기준: OQ 목록에 `Open` 상태 항목이 0개이며, 남은 DATA 항목은 REQ/planning의 세부 실행자료로만 이관된다.
- [x] Freeze 확정 담당자(CONFIRMED_BY) 지정
- 기준: 승인자 `Justin Ko`가 Confirmed By로 기록된다.
# 9. 파일 처리 결과
이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다.
- 처리 결과: 생성
- 생성 경로: docs/discovery/dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing.md
- 참조 문서:
- docs/discovery/dcy-010_20260702_backend-core-layering-mcp-adapter-realignment.md (선행 Discovery, Phase 0~3, 본 문서가 후속 주기)
- .hermes/plans/2026-07-02_jarca-ledger-backend-refactor-blueprint.md (근거 blueprint, Phase 4~8)
- stage-pilot/templates/project-structure.md (baseline 갱신 논리 템플릿 참조)
- stage-pilot/templates/runtime-flows.md (baseline 갱신 논리 템플릿 참조)
# 10. 사용자 결정 필요 항목 요약
사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다.
## DECIDE
- 없음 — Phase 8 optional HTTP adapter 준비는 이번 주기에서 구현하지 않고 Deferred 후보로만 남긴다.
- 없음 — dcy-011 Discovery는 하나로 유지하고, 후속 REQ/Batch는 Phase별·도메인별로 분할한다.
## CONFIRM
- 없음 — Phase 4~7 이관 동안 MCP tool 이름/주요 응답 필드/import 증빙 필드/Streamlit 페이지 동작을 호환 계약으로 동결한다.
- 없음 — Phase 4 착수 전 dcy-010(Phase 0~3) seam 완료를 진입 조건으로 둔다.
## DATA
- {{DATA_BASELINE_TEST_SET}} — Phase 4~7 회귀 검증에 사용할 현재 통과 pytest 스위트 목록과 커버 대상 MCP tool 집합(REQ/planning 산출물에서 명시).
# 11. Discovery Freeze
REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다.
## 섹션 참조
- 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록)
- 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록)
- 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준)
- 인계 전 확인: [# 8. REQ로 넘기기 전 확인 체크](#8-req로-넘기기-전-확인-체크)
- 사용자 결정 필요: [# 10. 사용자 결정 필요 항목 요약](#10-사용자-결정-필요-항목-요약)
## Freeze 플래그
- Handoff Decision: 승인
- Handoff Rationale: Phase 4~7 후속 주기 Discovery가 현재 저장소 상태와 정합하도록 보정되었고, 사용자 승인에 따라 Phase 8은 Deferred 후보로만 남기며, Discovery는 하나로 유지하되 REQ/Batch는 Phase별·도메인별로 분할한다는 방침이 확정되었다. 계약 동결·additive migration·text-first UI seam·Phase 0~3 선행 seam 진입 조건도 문서에 반영되었고, 남은 `DATA_BASELINE_TEST_SET`은 REQ/planning 단계에서 계측할 비차단 운영 데이터로 정리되었다.
- Ready for REQ Drafting: true
- Confirmed By: Justin Ko
- Confirmed At (KST): 2026-07-03 07:23 KST
+1
View File
@@ -16,3 +16,4 @@
| dcy-008_20260630_asset-snapshot-manual-valuation-system | 20260630 | 자산 스냅샷/수기 자산 테이블/평가 체계 정립 | [Discovery](./dcy-008_20260630_asset-snapshot-manual-valuation-system.md) | confirmed |
| dcy-009_20260701_manual-asset-crud-month-end-snapshot-close-workflow | 20260701 | 수기 자산 CRUD + 월말 스냅샷 생성/마감 운영 워크플로우 | [Discovery](./dcy-009_20260701_manual-asset-crud-month-end-snapshot-close-workflow.md) | confirmed |
| dcy-010_20260702_backend-core-layering-mcp-adapter-realignment | 20260702 | Jarca Ledger 백엔드 코어 분리 및 layered 아키텍처 재편, MCP adapter 재정렬 | [Discovery](./dcy-010_20260702_backend-core-layering-mcp-adapter-realignment.md) | confirmed |
| dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing | 20260703 | Jarca Ledger 백엔드 리팩터링 Phase 4+ 후속 주기 (write service 분리 → import pipeline 분리 → advanced finance workflow 분리 → MCP/Streamlit adapter 표면 축소) | [Discovery](./dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing.md) | confirmed |