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
@@ -0,0 +1,37 @@
# BAT-011 Design
## Architecture summary
- Introduce dedicated write-oriented application modules under `jarca_ledger_mcp/application/` for accounts, transactions, budgets, and category rules/categories.
- Keep broad modules (`system_services.py`, `asset_account_services.py`, `transaction_report_services.py`, `categorization_services.py`) as compatibility aggregation layers for read/report/mixed responsibilities that are not yet in scope.
- Preserve `service.py` as a thin re-export facade and avoid MCP/Streamlit/dashboard call-site churn.
## Changed areas
- `jarca_ledger_mcp/application/accounts_write_services.py`
- `jarca_ledger_mcp/application/transactions_write_services.py`
- `jarca_ledger_mcp/application/budgets_write_services.py`
- `jarca_ledger_mcp/application/category_rules_write_services.py`
- Existing application modules that previously held these implementations
- `jarca_ledger_mcp/application/__init__.py`
- `jarca_ledger_mcp/service.py`
## Key decisions
- Move only mutation implementations in BAT-011; read/report/import/advanced workflow logic stays in place.
- Favor direct function relocation plus compatibility re-export over new abstraction layers to minimize contract risk.
- Keep shared helpers in `application/shared.py`; do not introduce storage-layer refactors in this batch.
## Edge cases
- `create_ledger_account` remains paired with `update_ledger_account` even though the old implementations lived in different modules.
- Category rule preview/apply remains out of BAT-011 scope if moving it would force read/workbench coupling; mutation extraction takes precedence.
- Any dashboard/MCP references must continue resolving through `service.py` without signature changes.
## Architecture Impact
- none
## Reference Doc Update Plan
- No baseline doc rewrite in BAT-011 unless the final module tree differs materially from the existing dcy-011/REQ-015 description.
@@ -0,0 +1,51 @@
# BAT-011 Implementation
## Plan summary
BAT-011 implements the first dcy-011 delivery slice by extracting transactional write paths into narrower application modules while preserving the top-level `service.py` facade, MCP tool contracts, and Streamlit/dashboard call signatures.
## Changed files
- `jarca_ledger_mcp/application/accounts_write_services.py`
- `jarca_ledger_mcp/application/transactions_write_services.py`
- `jarca_ledger_mcp/application/budgets_write_services.py`
- `jarca_ledger_mcp/application/category_rules_write_services.py`
- `jarca_ledger_mcp/application/__init__.py`
- `jarca_ledger_mcp/application/system_services.py`
- `jarca_ledger_mcp/application/asset_account_services.py`
- `jarca_ledger_mcp/application/transaction_report_services.py`
- `jarca_ledger_mcp/application/categorization_services.py`
- `jarca_ledger_mcp/service.py`
- `docs/discovery/dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing.md`
- `docs/srs/index.md`
- `docs/srs/Non-Functional/req-015_transactional-write-service-split-compatibility.md`
- `docs/batches/index.md`
- `docs/batches/bat-011_20260703_transactional-write-service-split/index.md`
- `docs/batches/bat-011_20260703_transactional-write-service-split/planning.md`
- `docs/batches/bat-011_20260703_transactional-write-service-split/design.md`
- `docs/batches/bat-011_20260703_transactional-write-service-split/implementation.md`
- `docs/batches/bat-011_20260703_transactional-write-service-split/verification.md`
## Execution log
- 2026-07-03 07:29 KST: dcy-011에서 REQ-015를 생성하고 source Discovery 역참조/SRS index를 갱신했다.
- 2026-07-03 07:30 KST: REQ-015를 Approved로 전환하고 BAT-011 standard batch scaffold(index/planning/design/implementation/verification)를 생성했다.
- 2026-07-03 07:34 KST: `accounts_write_services.py`, `transactions_write_services.py`, `budgets_write_services.py`, `category_rules_write_services.py`를 추가하고 account/transaction/budget/category rule-category mutation 구현을 새 모듈로 이동했다.
- 2026-07-03 07:35 KST: 기존 broad modules(`system_services.py`, `asset_account_services.py`, `transaction_report_services.py`, `categorization_services.py`)를 compatibility re-export/delegation 레이어로 축소했다.
- 2026-07-03 07:35 KST: `service.py` proxy module set에 새 write modules를 추가해 helper monkeypatch/export propagation이 계속 동작하도록 정렬했다.
- 2026-07-03 07:36 KST: category create path에서 빠진 `infer_cashflow_kind` 정책을 `category_rules_write_services.py`에 보강해 category mutation 회귀를 복구했다.
- 2026-07-03 07:39 KST: targeted regression, full pytest, MCP discovery, service export provenance 검증이 모두 PASS하여 REQ-015를 Implemented로 승격했다.
## Validation
- `python3 -m py_compile jarca_ledger_mcp/application/*.py jarca_ledger_mcp/service.py` → PASS
- `pytest -q tests/test_service.py tests/test_category_rule_filters.py tests/test_ledger_categories.py tests/test_contract_regression.py` → PASS (`19 passed`)
- `pytest -q` → PASS (`42 passed, 4 skipped`)
- `hermes mcp test jarca-ledger` → PASS (`Connected`, `Tools discovered: 56`)
- `python3` provenance check → PASS (`service.create_ledger_account.__module__ == jarca_ledger_mcp.application.accounts_write_services`, transaction/budget/category mutation exports도 각각 새 write module을 가리킴)
## Remaining risks / follow-up notes
- `preview_categorization`, `apply_categorization_rules`, uncategorized workbench/read-side helper는 아직 `categorization_services.py`에 남아 있어 Phase 4 후속 또는 Phase 7 adapter narrowing에서 추가 분리가 가능하다.
- import preview/import/rollback 및 cross-transfer/reconciliation/advanced workflow 분리는 BAT-011 범위 밖이며 dcy-011 후속 REQ/BAT로 이어져야 한다.
- 이번 배치는 contract-preserving extraction이 목적이므로 data model semantics와 response envelope은 의도적으로 변경하지 않았다.
@@ -0,0 +1,33 @@
# BAT-011 Transactional write service split
- Profile: standard
- Status: release-candidate
- Included REQ: REQ-015
- Discovery: dcy-011
- Owner: 렛저장인
- Date (KST): 2026-07-03
## 목표
REQ-015에 따라 account / transaction / budget / category rule-category mutation 경로를 더 좁은 write-oriented application service로 분리한다. 기존 `service.py`, MCP adapter, Streamlit gateway, dashboard 호출부와 response contract는 유지한 채 Phase 4 첫 구현 슬라이스를 실제 코드와 검증 evidence로 마무리한다.
## 산출물
- `jarca_ledger_mcp/application/` write-oriented service modules
- 기존 broad application modules의 compatibility re-export / delegation 정리
- full pytest 및 contract-sensitive regression evidence
- BAT-011 planning/design/implementation/verification documents
## 범위 제한
- import preview/import/rollback split
- advanced workflow(cross-transfer/reconciliation/assets/workbench) 분리
- HTTP adapter 추가
- destructive migration
## 문서
- `planning.md`: Phase 4 첫 delivery plan, risks, validation gate
- `design.md`: write service boundary / delegation design
- `implementation.md`: changed files, execution log, validation commands
- `verification.md`: AC mapping, PASS/FAIL, REQ Implemented decision
@@ -0,0 +1,32 @@
# BAT-011 Planning
## Scope
- Implement REQ-015: transactional write path(account / transaction / budget / category rule-category mutation)를 더 좁은 write-oriented application module로 분리한다.
- Preserve top-level service facade, MCP adapter, Streamlit gateway, dashboard call signatures and response envelope contracts.
- Leave import/advanced workflow split for follow-up REQ/BAT under dcy-011.
## Dependencies
- dcy-011 confirmed Discovery and Approved REQ-015.
- BAT-010 application/adapters baseline.
- Existing pytest regression and contract-sensitive tests.
## Work plan
1. Create write-oriented application modules for accounts / transactions / budgets / category rules.
2. Move concrete mutation implementations into those modules and keep existing broad modules as compatibility delegation layers where needed.
3. Update `application/__init__.py` and `service.py` import surface to re-export the new modules without changing public API.
4. Run focused syntax + regression validation, then full pytest if focused checks remain green.
5. Update batch implementation/verification evidence and promote REQ/BAT state if ACs are satisfied.
## Design Gate
- Result: standard batch 유지.
- Reason: package boundary 변경, compatibility delegation, category/account/transaction write contract preservation, regression evidence 정리가 함께 필요하므로 planning/design/verification depth가 필요하다.
## Risks and mitigations
- Hidden import coupling after write extraction: mitigate by preserving re-export layers and running full pytest.
- Envelope drift on mutation responses: mitigate by preserving existing function signatures and contract-sensitive tests.
- Category rule/category mutation helpers may still share read-side helpers: mitigate by extracting only write-focused logic first and leaving broad read/report paths untouched in this batch.
@@ -0,0 +1,43 @@
# BAT-011 Verification
## Verification summary
Status: PASS
Evidence was collected against synthetic/temp data only. No production ledger DB mutation or real financial files were used.
## Acceptance criteria mapping
### REQ-015
- AC-1: PASS — `jarca_ledger_mcp/application/` 아래에 `accounts_write_services.py`, `transactions_write_services.py`, `budgets_write_services.py`, `category_rules_write_services.py`가 생성됐고 account/transaction/budget/category rule-category mutation 구현이 그쪽으로 이동했다.
- AC-2: PASS — top-level `service.py` public API, MCP tools, Streamlit/dashboard call signatures and mutation envelope contracts are preserved. MCP discovery still reports 56 tools, and export provenance shows the write APIs now resolve to the new modules.
- AC-3: PASS — targeted regression (`tests/test_service.py`, `tests/test_category_rule_filters.py`, `tests/test_ledger_categories.py`, `tests/test_contract_regression.py`) PASS, plus full `pytest -q` PASS (`42 passed, 4 skipped`).
- AC-4: PASS — BAT-011 implementation/verification docs now record actual changed files, commands, and outcomes.
## Requirement state decision
- REQ-015: Implemented.
## Validation evidence
- `python3 -m py_compile jarca_ledger_mcp/application/*.py jarca_ledger_mcp/service.py` → PASS
- `pytest -q tests/test_service.py tests/test_category_rule_filters.py tests/test_ledger_categories.py tests/test_contract_regression.py` → PASS (`19 passed`)
- `pytest -q` → PASS (`42 passed, 4 skipped`)
- `hermes mcp test jarca-ledger` → PASS (`Connected`, `Tools discovered: 56`)
- Python provenance check on exported write APIs → PASS
- `create_ledger_account`, `update_ledger_account` → `accounts_write_services`
- `create/update/delete_ledger_transaction` → `transactions_write_services`
- `create_ledger_budget` → `budgets_write_services`
- `create/update/delete_category_rule`, `create/delete_ledger_category` → `category_rules_write_services`
## Remaining issues
### Hard blockers
- None.
### Non-blocking follow-up
- categorization preview/apply/workbench read-side extraction
- import pipeline split
- advanced finance workflow split
- narrower adapter surfaces under later dcy-011 batches
+1
View File
@@ -18,3 +18,4 @@
| BAT-008 | standard | release-candidate | REQ-009, REQ-010 | dcy-008 | [bat-008_20260630_asset-snapshots-manual-assets-read-mcp](bat-008_20260630_asset-snapshots-manual-assets-read-mcp/) |
| BAT-009 | standard | release-candidate | REQ-011, REQ-012 | dcy-009 | [bat-009_20260701_manual-asset-crud-snapshot-close](bat-009_20260701_manual-asset-crud-snapshot-close/) |
| BAT-010 | standard | release-candidate | REQ-013, REQ-014 | dcy-010 | [bat-010_20260703_backend-core-layering-phase-0-3](bat-010_20260703_backend-core-layering-phase-0-3/) |
| BAT-011 | standard | release-candidate | REQ-015 | dcy-011 | [bat-011_20260703_transactional-write-service-split](bat-011_20260703_transactional-write-service-split/) |