docs: bind settlement requirement to PR #19

This commit is contained in:
gitea-impl-agent
2026-10-13 05:08:07 +00:00
parent dd35e0785f
commit 616bb7a744
3 changed files with 5 additions and 5 deletions
@@ -9,7 +9,7 @@
"applies_to": ["ledger", "dashboard", "mcp"], "applies_to": ["ledger", "dashboard", "mcp"],
"language": "ko", "language": "ko",
"issue": "#18", "issue": "#18",
"implementation_pr": "미정" "implementation_pr": "https://gitea.jsfamily.quest/jsfamily/jarca-ledger-mcp/pulls/19"
} }
--- ---
@@ -868,7 +868,7 @@ REQ-001의 auth gate·cookie/cleanup/logout, REQ-002의 메뉴 10개와 order(`
- 관련 설계 문서: `docs/data-model.md`, `docs/interface-contract.md`, `docs/project-structure.md`, `docs/runtime-flow.md` - 관련 설계 문서: `docs/data-model.md`, `docs/interface-contract.md`, `docs/project-structure.md`, `docs/runtime-flow.md`
- 관련 요구사항: `REQ-001`, `REQ-002` - 관련 요구사항: `REQ-001`, `REQ-002`
### Issue #18 종합 정산 확장 (revision 1.2; 구현 PR 미정) ### Issue #18 종합 정산 확장 (revision 1.2; 구현 PR #19)
기존 요구사항·AC 식별자 및 공통 섹션은 유지하고 REQ-003.11만 확장한다. 월 수입·지출은 활성 거래의 [월초, 다음 월초) 범위, 자산·부채는 기존 월말 기준이다. 초안 정책은 `draft.cashflow_policy`에 저장하며 savings는 사용자가 명시한 category/subcategory pair만 인정한다. 생활비·선택 savings·`debt_payment`은 expense; 일반 transfer와 voucher top-up 제외가 우선하고 `investment` 전체 포함은 금지한다. Refund는 환급월 원래 지출 분류에 signed negative expense로 기록하며 과거 run을 수정하지 않는다. Unresolved unknown은 승인 blocker이며 asset conditional flag로 우회할 수 없고, 확정 제외는 blocker가 아니다. KRW only, no FX. 기존 요구사항·AC 식별자 및 공통 섹션은 유지하고 REQ-003.11만 확장한다. 월 수입·지출은 활성 거래의 [월초, 다음 월초) 범위, 자산·부채는 기존 월말 기준이다. 초안 정책은 `draft.cashflow_policy`에 저장하며 savings는 사용자가 명시한 category/subcategory pair만 인정한다. 생활비·선택 savings·`debt_payment`은 expense; 일반 transfer와 voucher top-up 제외가 우선하고 `investment` 전체 포함은 금지한다. Refund는 환급월 원래 지출 분류에 signed negative expense로 기록하며 과거 run을 수정하지 않는다. Unresolved unknown은 승인 blocker이며 asset conditional flag로 우회할 수 없고, 확정 제외는 blocker가 아니다. KRW only, no FX.
+2 -2
View File
@@ -17,7 +17,7 @@ def test_requirement_docs_are_canonical_and_traceable() -> None:
text = REQ.read_text(encoding="utf-8") text = REQ.read_text(encoding="utf-8")
_, raw, body = text.split("---", 2) _, raw, body = text.split("---", 2)
metadata = json.loads(raw) metadata = json.loads(raw)
assert metadata["implementation_pr"] == "미정" or re.fullmatch(r"https://gitea\.jsfamily\.quest/jsfamily/jarca-ledger-mcp/pulls/\d+|#\d+", metadata["implementation_pr"]) assert metadata["implementation_pr"] == "https://gitea.jsfamily.quest/jsfamily/jarca-ledger-mcp/pulls/19"
assert metadata == { assert metadata == {
"schema": "gitea-agent.requirement/v1", "schema": "gitea-agent.requirement/v1",
"id": "REQ-003", "id": "REQ-003",
@@ -28,7 +28,7 @@ def test_requirement_docs_are_canonical_and_traceable() -> None:
"applies_to": ["ledger", "dashboard", "mcp"], "applies_to": ["ledger", "dashboard", "mcp"],
"language": "ko", "language": "ko",
"issue": "#18", "issue": "#18",
"implementation_pr": metadata["implementation_pr"], "implementation_pr": "https://gitea.jsfamily.quest/jsfamily/jarca-ledger-mcp/pulls/19",
} }
assert re.search(r"^# REQ-003 — ", body, re.M) assert re.search(r"^# REQ-003 — ", body, re.M)
assert "${" not in text assert "${" not in text
+1 -1
View File
@@ -21,7 +21,7 @@ def test_settlement_requirement_revision_is_additive_and_traceable() -> None:
assert metadata["id"] == "REQ-003" assert metadata["id"] == "REQ-003"
assert metadata["revision"] == "1.2" assert metadata["revision"] == "1.2"
assert metadata["issue"] == "#18" assert metadata["issue"] == "#18"
assert metadata["implementation_pr"] == "미정" or re.fullmatch(r"https://gitea\.jsfamily\.quest/jsfamily/jarca-ledger-mcp/pulls/\d+|#\d+", metadata["implementation_pr"]) assert metadata["implementation_pr"] == "https://gitea.jsfamily.quest/jsfamily/jarca-ledger-mcp/pulls/19"
assert "#12" in body and "#13" in body assert "#12" in body and "#13" in body
assert re.findall(r"^### REQ-003\.(\d+) —", body, re.M) == [f"{i:02d}" for i in range(1, 12)] assert re.findall(r"^### REQ-003\.(\d+) —", body, re.M) == [f"{i:02d}" for i in range(1, 12)]
assert re.findall(r"^## (\d+)\. ", body, re.M) == [str(i) for i in range(1, 12)] assert re.findall(r"^## (\d+)\. ", body, re.M) == [str(i) for i in range(1, 12)]