docs: initialize StagePilot baseline

This commit is contained in:
Jarca
2026-06-26 22:34:16 +09:00
parent d8e36f6aa8
commit 97115f6acf
9 changed files with 698 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
# Batch Index
## 목적
- 이 문서는 batch delivery 단위의 전역 인덱스다.
- 각 batch는 `docs/batches/<BAT_ID>/` 아래에서 profile(`standard` | `batch-lite`)에 맞는 산출물을 관리한다.
## Batch Register
| BAT ID | Profile | Status | Included REQ | Discovery | Folder |
| --- | --- | --- | --- | --- | --- |
+140
View File
@@ -0,0 +1,140 @@
# Jarca Ledger MCP Data Model
- Baseline Mode: observed
- Baseline Seed: `.stage-pilot/bootstrap/baseline.yaml`
- Status: draft
- Owner: Jarca / project maintainer
- Last Updated (KST): 2026-06-26 22:24
- Source Discovery / Batch: bootstrap-baseline
## Project Summary
- Jarca 가계부 전용 MCP 서버와 Streamlit 대시보드로 계좌/카드 거래, 예산, 분류 규칙, import, 현금흐름 분석을 SQLite에 저장하고 운영한다.
## Purpose
- This document captures the current data-model baseline for future Discovery, REQ, Batch, and Release work.
- It focuses on durable entities, state rules, consistency rules, and persistence boundaries rather than implementation-only details.
## Persistence Backend
- SQLite database at `~/.local/share/jarca/ledger.sqlite3` by default.
- Override path through `JARCA_LEDGER_DB_PATH`.
- Schema initialization and migrations are managed by `jarca_ledger_mcp/db.py`.
## Entity: LedgerAccount
- Source of Truth: `ledger_accounts`
- Purpose: Represents bank, card, cash, investment, or loan accounts used to attach transaction evidence and balances.
- Lifecycle: created -> updated -> inactive/archived
- Key Fields:
- `id` :: text :: stable account identifier
- `name` :: text :: operator-facing account name
- `type` :: text :: bank/card/cash/investment/loan classification
- `institution` :: text :: financial institution or source
- `account_number_masked` :: text :: masked account identifier
- `holder_name` :: text :: owner context for transfer matching
- `last_balance` :: integer :: latest known balance when available
- Relationships:
- `transactions.account_id` links rows to accounts.
- State Rules:
- `active=false` hides accounts from default lists without deleting history.
## Entity: Transaction
- Source of Truth: `transactions`
- Purpose: Represents imported or manually entered financial event evidence.
- Lifecycle: created/imported -> categorized/reconciled -> soft-deleted or retained
- Key Fields:
- `transaction_date` :: date text :: ledger date
- `posted_date` / `transaction_datetime` :: text :: source timing detail where available
- `type` :: text :: `income`, `expense`, `transfer`, `refund`, or `adjustment`
- `amount` :: integer :: positive KRW amount
- `category` / `subcategory` :: text :: household classification
- `merchant`, `counterparty`, `description`, `payment_method` :: text :: evidence and display fields
- `source`, `external_id`, `import_batch_id`, `raw_summary`, `raw_payload` :: text :: provenance and audit fields
- `memo` :: text :: operator notes and reconciliation tags
- `status` :: text :: active/deleted/review lifecycle state where used
- Relationships:
- belongs to LedgerAccount through `account_id`
- linked to ImportBatch through `import_batch_id`
- interpreted with LedgerCategory through `category`/`subcategory`
- State Rules:
- Amount is stored positive; `type` determines direction.
- Cancellation/refund rows should use `refund` type when confirmed.
- Manual link evidence should be memo-tagged rather than silently rewritten.
## Entity: LedgerCategory
- Source of Truth: `ledger_categories`
- Purpose: Defines category/subcategory labels and their cashflow semantics.
- Lifecycle: seeded/created -> updated -> inactive/deleted
- Key Fields:
- `category` :: text
- `subcategory` :: text
- `cashflow_kind` :: text :: `income`, `expense`, `transfer`, `investment`, `debt_payment`, `exclude`, `unknown`
- `sort_order`, `memo`, `active`
- Relationships:
- Referenced by Transaction classification.
- Targeted by CategoryRule results.
- State Rules:
- `cashflow_kind` controls inclusion in actual household cashflow reports.
- Transfer, investment, exclude, and unresolved kinds are not actual household spending unless a report explicitly asks for account movements.
## Entity: CategoryRule
- Source of Truth: `category_rules`
- Purpose: Automatic classification policy for transactions.
- Lifecycle: created -> previewed/applied -> updated/deactivated/deleted
- Key Fields:
- `match_field` :: text :: field to inspect
- `pattern` :: text :: match pattern
- `match_type` :: text :: contains/equals/regex
- `category` / `subcategory` :: text :: classification target
- `priority` :: integer :: deterministic ordering
- `amount_min`, `amount_max`, `day_of_month` :: integer nullable :: optional constraints
- `person`, `is_fixed`, `confidence`, `memo`, `active`
- Relationships:
- Applies to Transaction rows.
- Should target valid or intentional category/subcategory labels.
- State Rules:
- Preview should precede broad application when changing classification behavior.
- More specific/high-priority rules should avoid accidentally overriding unrelated evidence.
## Entity: ImportBatch
- Source of Truth: `import_batches`
- Purpose: Tracks grouped imports for audit and rollback.
- Lifecycle: previewed -> imported -> optionally rolled back
- Key Fields:
- `id` :: text :: import batch identifier
- `source` :: text :: source kind
- `file_path` / source metadata where stored
- `inserted_count`, `skipped_duplicate_count`, `created_at`, `rolled_back_at`
- Relationships:
- Transaction rows reference `import_batch_id`.
- State Rules:
- Rollback should soft-delete by default.
- Duplicate imports with `skip_duplicates=True` may insert zero rows; that is not automatically an error.
## Entity: Budget
- Source of Truth: budget table/service functions
- Purpose: Monthly category/subcategory/person budget target.
- Lifecycle: created/updated -> compared against actual spending
- Key Fields:
- `month`, `category`, `subcategory`, `person`, `amount`, `currency`, `memo`
- Relationships:
- Compared against Transaction aggregates by report functions.
## Consistency Rules
- Actual cashflow reports include only categories whose `cashflow_kind` represents actual income or expense according to report semantics.
- Account movement summaries should be separate from actual household income/expense summaries.
- Cross-account auto-matching requires same date, same amount, opposite direction, and compatible source/owner evidence.
- External counterparty securities transfers are review items unless matched or explicitly confirmed.
- Import evidence fields are retained for audit and future correction.
- DB corrections should be narrow and memo-tagged.
## Persistence Notes
- Schema changes should be additive/idempotent unless a destructive migration is explicitly approved and backed up.
- Passwords for encrypted imports are runtime-only inputs and are not part of the persisted model.
- Raw payloads may contain sensitive financial evidence and should not be committed to git.
## Current Gaps / Planned Changes
- Formal schema migration documentation should be added before larger DB changes.
- Some UI workflows need final E2E verification against real rows.
- Statement-unavailable account handling needs a documented manual evidence model.
## Change Log
- 2026-06-26 22:24 KST: Created by `bootstrap-baseline` from repository observation.
+8
View File
@@ -0,0 +1,8 @@
# Discovery 전체 인덱스
<!-- 아래 테이블은 /new-discovery 실행 시 자동 갱신된다. 수동 편집 금지. -->
## Discovery 목록
| ID | 날짜 | 이슈명 | 문서 | 상태 |
|---|---|---|---|---|
+101
View File
@@ -0,0 +1,101 @@
# Jarca Ledger MCP Interface Contract
- Baseline Mode: observed
- Baseline Seed: `.stage-pilot/bootstrap/baseline.yaml`
- Status: draft
- Owner: Jarca / project maintainer
- Last Updated (KST): 2026-06-26 22:24
- Source Discovery / Batch: bootstrap-baseline
## Project Summary
- Jarca 가계부 전용 MCP 서버와 Streamlit 대시보드로 계좌/카드 거래, 예산, 분류 규칙, import, 현금흐름 분석을 SQLite에 저장하고 운영한다.
## Purpose
- This document captures the current external and operator-facing interface baseline.
- It is a reference for future Discovery, REQ, Batch, and Release work that changes tool signatures, dashboard behavior, or file import contracts.
## Interface: MCP Tool Surface
- Type: internal-service
- Actors: Hermes Agent and MCP clients
- Entrypoint: `jarca-ledger-mcp` script -> `jarca_ledger_mcp.server:main`
- Stability: internal but should preserve existing success response shapes for compatibility.
### Representative Tool Groups
- Health: `ledger_health_check`
- Accounts: `create_ledger_account`, `list_ledger_accounts`
- Transactions: `create_ledger_transaction`, `list_ledger_transactions`, `update_ledger_transaction`, `delete_ledger_transaction`
- Budgets/reports: `create_ledger_budget`, `list_ledger_budgets`, monthly/category/fixed/budget/investable reports
- Imports: KB Bank PDF, Toss Bank PDF, Toss Securities PDF, SeoulPay XLSX, CSV preview/import where implemented
- Categories/rules: category CRUD, rule CRUD, categorization preview/apply, uncategorized summaries
- Reconciliation: cross-account preview/run/review queue, self-transfer candidates/linking, cancel-original candidates/linking
### Inputs
- Structured MCP tool arguments as declared in `server.py` signatures.
- File paths and optional passwords for encrypted or password-protected documents.
- Transaction/account/category identifiers for update, delete, and link operations.
### Outputs
- Python dictionary payloads containing success data, counts, records, previews, reports, or error details.
- Existing success shape compatibility is preferred; new fields should be additive where possible.
### Errors
- Validation errors for invalid parameters or missing IDs.
- Parser errors for unreadable or unsupported source files.
- Password/validation errors for encrypted import files.
- Candidate-not-found errors for link operations when the chosen pair is not in the preview set.
### Compatibility Rules
- Preserve existing success response shapes unless a migration/REQ explicitly approves a breaking change.
- Do not write secrets or raw passwords into persistent output, skill files, or committed documentation.
- Source evidence should remain auditable through raw fields and import batch records.
## Interface: Streamlit Dashboard
- Type: web-app
- Actors: Local operator
- Entrypoint: `streamlit run dashboard/app.py --server.address 0.0.0.0 --server.port 8501`
- Stability: internal operator UI
### Pages
- 요약
- 거래내역
- 확인필요 큐
- 미분류
- 분류 규칙
- 카테고리
- 계좌
- Import
### Inputs
- Local SQLite database selected by `JARCA_LEDGER_DB_PATH` or default path.
- Uploaded transaction history files.
- User edits for categories, rules, transactions, and manual links.
### Outputs
- Tables, charts, dialogs, previews, import results, and transaction/category updates.
### UI Contract Rules
- Surface `cashflow_kind` where classification affects actual cashflow interpretation.
- Keep actual income/expense separated from account movement summaries.
- Rule page should support create/edit/delete and condition fields `amount_min`, `amount_max`, `day_of_month`.
- Dialog-based triage actions should avoid losing context where possible.
## Interface: File Import Contracts
- KB Bank PDF: encrypted/password-protected PDF account history; preserve transaction datetime, counterparty, balance, branch, raw summary, and raw payload.
- Toss Bank PDF: transaction history PDF parsed into ledger transaction candidates.
- Toss Securities PDF: securities transaction history with investment movement, dividend, interest, and external transfer handling.
- SeoulPay XLSX: possibly encrypted Office XLSX/OLE file; decrypt with supplied password and import usage details as actual spending evidence.
- CSV: generic preview-first import path.
## Shared Constraints
- All import flows should support preview before mutation where implemented.
- Dedupe should use deterministic source/external IDs or same-account/date/type/amount/merchant evidence.
- Import batch metadata should support rollback and audit.
- Financial data and passwords are sensitive runtime inputs and should not be committed.
## Current Gaps / Planned Changes
- Formal versioning for MCP response contracts is not yet defined.
- Browser-level UI acceptance criteria for Streamlit flows are not yet captured as REQ documents.
- CI contract for tests/lint is not yet present.
## Change Log
- 2026-06-26 22:24 KST: Created by `bootstrap-baseline` from repository observation.
+123
View File
@@ -0,0 +1,123 @@
# Jarca Ledger MCP Project Structure
- Baseline Mode: observed
- Baseline Seed: `.stage-pilot/bootstrap/baseline.yaml`
- Status: draft
- Owner: Jarca / project maintainer
- Last Updated (KST): 2026-06-26 22:24
- Source Discovery / Batch: bootstrap-baseline
## Project Summary
- Jarca 가계부 전용 MCP 서버와 Streamlit 대시보드로 계좌/카드 거래, 예산, 분류 규칙, import, 현금흐름 분석을 SQLite에 저장하고 운영한다.
## Primary Domain
- Korean household finance ledger and transaction reconciliation
## Tech Stack
- Python >=3.11
- FastMCP / MCP server
- SQLite
- Streamlit dashboard
- pandas / plotly dashboard dependencies
- PyMuPDF, openpyxl, msoffcrypto-tool
- pytest
## Primary Runtime
- Type: mixed
- Planned Entry Points:
- `jarca-ledger-mcp` :: MCP stdio server for Hermes Agent tools.
- `dashboard/app.py` :: Streamlit dashboard for local ledger operations.
- `pytest` :: Regression test entry point.
## Purpose
- This document is the current repository and package structure baseline.
- It is a cross-cutting reference document for Discovery, REQ, Batch Design, Batch Verification, and implementation updates.
## Scope
- Covers top-level repository layout and package/module boundaries.
- Does not duplicate detailed business rules, acceptance criteria, or implementation-only function signatures.
## Top-Level Structure
```text
jarca-ledger-mcp/
├── README.md
├── pyproject.toml
├── uv.lock
├── .env.example
├── dashboard/
│ └── app.py
├── jarca_ledger_mcp/
│ ├── __init__.py
│ ├── db.py
│ ├── service.py
│ ├── server.py
│ ├── kb_bank_pdf.py
│ ├── toss_bank_pdf.py
│ ├── toss_securities_pdf.py
│ └── seoulpay_xlsx.py
├── tests/
│ ├── test_service.py
│ ├── test_categorization.py
│ ├── test_category_rule_filters.py
│ ├── test_cross_account_transfer_matching.py
│ ├── test_kb_bank_pdf.py
│ ├── test_toss_securities_pdf.py
│ ├── test_seoulpay_xlsx.py
│ └── test_ledger_categories.py
├── docs/
│ ├── discovery/
│ ├── srs/
│ ├── batches/
│ ├── releases/
│ ├── project-structure.md
│ ├── runtime-flows.md
│ ├── interface-contract.md
│ └── data-model.md
└── .stage-pilot/
└── bootstrap/baseline.yaml
```
## Package / Module Responsibilities
- `jarca_ledger_mcp/db.py`
- SQLite connection, schema initialization, migrations, row conversion, and database path resolution.
- `jarca_ledger_mcp/service.py`
- Domain service layer for accounts, transactions, categories, category rules, imports, reports, transfer matching, and manual link operations.
- `jarca_ledger_mcp/server.py`
- FastMCP tool registration layer that exposes service functions to Hermes/MCP clients.
- `jarca_ledger_mcp/kb_bank_pdf.py`
- KB 국민은행 encrypted PDF transaction parsing.
- `jarca_ledger_mcp/toss_bank_pdf.py`
- Toss Bank transaction-history PDF parsing.
- `jarca_ledger_mcp/toss_securities_pdf.py`
- Toss Securities transaction-history PDF parsing and transaction preview conversion.
- `jarca_ledger_mcp/seoulpay_xlsx.py`
- SeoulPay encrypted XLSX parsing and preview conversion.
- `dashboard/app.py`
- Streamlit operator UI for summaries, transaction filtering, uncategorized triage, rule management, review queues, categories, accounts, and import operations.
- `tests/`
- Regression tests for service behavior, parser behavior, categorization, category rules, cross-account transfer matching, and ledger category semantics.
## Dependency Rules
- `server.py` should remain a thin tool adapter and delegate business logic to `service.py`.
- Parser modules should parse source documents into structured records and avoid direct UI responsibilities.
- `dashboard/app.py` may call service functions but should not duplicate core classification/report semantics.
- DB schema migrations should be additive and idempotent by default.
## Shared Boundaries
- `cashflow_kind` is the boundary between actual household income/expense and account movement/exclusion semantics.
- Import evidence fields (`source`, `external_id`, `raw_summary`, `raw_payload`, `counterparty`, `import_batch_id`) are audit boundaries and should be preserved.
- Manual reconciliation is represented through memo tags and narrow transaction updates, not broad rewrites.
## Current Gaps / Planned Changes
- Final UX verification is still needed for 분류 규칙 삭제, 취소/환급 원거래 연결, and import E2E flows.
- CI workflow and deployment/service management are not yet defined.
- Long-term policy for accounts without downloadable statements remains partially operational/documentation work.
## Update Triggers
- Update this document when package boundaries change.
- Update this document when new top-level runtime or domain modules are added.
- Update this document when a batch changes the approved structure baseline.
## Change Log
- 2026-06-26 22:24 KST: Created by `bootstrap-baseline` from repository observation.
+10
View File
@@ -0,0 +1,10 @@
# Release Index
## 목적
- 이 문서는 release 단위의 전역 인덱스다.
- 각 release는 하나 이상의 release-candidate batch를 묶고, profile(`docs-only` | `tooling` | `app-service`)에 맞는 배포와 후속 환류를 추적한다.
## Release Register
| REL ID | Profile | Status | Included Batch | Discovery/REQ Input | Link |
| --- | --- | --- | --- | --- | --- |
+84
View File
@@ -0,0 +1,84 @@
# Jarca Ledger MCP Runtime Flows
- Baseline Mode: observed
- Baseline Seed: `.stage-pilot/bootstrap/baseline.yaml`
- Status: draft
- Owner: Jarca / project maintainer
- Last Updated (KST): 2026-06-26 22:24
- Source Discovery / Batch: bootstrap-baseline
- Primary Runtime: mixed
## Project Summary
- Jarca 가계부 전용 MCP 서버와 Streamlit 대시보드로 계좌/카드 거래, 예산, 분류 규칙, import, 현금흐름 분석을 SQLite에 저장하고 운영한다.
## Purpose
- This document is the current execution-flow baseline for the project.
- It is a cross-cutting reference document for Discovery, REQ, Batch Design, Batch Verification, and implementation updates.
## Scope
- Covers representative command, MCP, dashboard, import, and reconciliation flows.
- Does not duplicate full acceptance criteria or low-level implementation details.
## Covered Entry Points
- `jarca-ledger-mcp` :: MCP stdio server for Hermes tool calls.
- `dashboard/app.py` :: Streamlit local dashboard.
- `pytest` :: regression test runner.
## Shared Components
- SQLite database at `~/.local/share/jarca/ledger.sqlite3` by default.
- `jarca_ledger_mcp.service` as the central domain/service layer.
- Parser modules for KB/Toss/SeoulPay sources.
- Category and `cashflow_kind` semantics shared by reports and UI.
## Flow: `MCP server tool call`
1. Hermes MCP client invokes a tool exposed by `jarca_ledger_mcp.server`.
2. `server.py` forwards arguments to the matching `service.py` function.
3. `service.py` opens the SQLite database path from env/default, validates inputs, and performs the operation.
4. Service returns a dictionary payload with success data or error information.
5. Hermes surfaces the tool result to the user or uses it in a follow-up workflow.
## Flow: `Streamlit dashboard operation`
1. Operator starts `streamlit run dashboard/app.py --server.address 0.0.0.0 --server.port 8501`.
2. Dashboard reads the configured/default SQLite database.
3. User navigates to 요약, 거래내역, 확인필요 큐, 미분류, 분류 규칙, 카테고리, 계좌, or Import pages.
4. UI calls service functions for reads, updates, imports, categorization, and manual linking.
5. UI displays success/error status and refreshes visible tables.
## Flow: `Import preview and import`
1. Operator chooses or supplies a supported source file: KB Bank PDF, Toss Bank PDF, Toss Securities PDF, SeoulPay XLSX, or CSV.
2. Preview function parses the file and reports counts, sample rows, duplicate status, and classification preview.
3. On explicit import, service creates/fetches the target account, inserts non-duplicate transactions, writes raw provenance, and records an import batch.
4. Reports and dashboard views read the inserted rows using category and cashflow semantics.
5. If an import is wrong, rollback uses import batch data and soft-deletes by default.
## Flow: `Categorization rule lifecycle`
1. Operator creates or edits a category rule with match field, pattern, target category/subcategory, priority, and optional amount/day constraints.
2. Preview categorization shows candidate matches without mutating rows.
3. Apply categorization updates matching transactions and preserves audit information.
4. Category `cashflow_kind` controls actual cashflow/report inclusion.
## Flow: `Cross-account and cancel/original reconciliation`
1. Preview functions search candidate pairs by amount, date, direction, account/source compatibility, and text similarity.
2. Operator reviews candidates in the dashboard or runs the automatic matcher where confidence rules are satisfied.
3. Matched self-transfers become `이체 / 본인계좌이동`; investment movements become `이체 / 투자이동`; ambiguous rows remain `확인필요`.
4. Cancel/refund rows can be linked to original expense rows; memo tags preserve manual link evidence.
## Flow Constraints
- Preview before broad import or categorization mutation where supported.
- Do not include `transfer`, `investment`, `exclude`, or unresolved rows in actual household spending totals unless a report explicitly asks for account movement.
- Preserve raw import evidence for audit and future reclassification.
- Avoid destructive migrations without a backup/approval plan.
- Sensitive passwords are runtime inputs and must not be committed.
## Current Gaps / Planned Changes
- Need final browser-level UX verification for rule delete and cancel/original linking dialogs.
- Need CI/deployment flow if this project will be maintained beyond local operation.
- Need a documented operational process for statement-unavailable accounts.
## Update Triggers
- Update this document when a command entry point changes.
- Update this document when a runtime orchestration path changes.
- Update this document when a batch changes the approved flow baseline.
## Change Log
- 2026-06-26 22:24 KST: Created by `bootstrap-baseline` from repository observation.
+46
View File
@@ -0,0 +1,46 @@
# Software Requirement Specification Index
## 목적
- 이 문서는 프로젝트의 SRS 운영 기준과 requirement 목록을 관리하는 entry point이다.
- 개별 requirement의 상세 내용은 타입별 폴더 하위 `req-XXX_*.md` 파일에서 관리한다.
## 사용 방법
1. 새로운 requirement가 필요하면 `Next Requirement ID`를 확인하고 `docs/srs/<Type>/req-XXX_<slug>.md` 파일을 생성한다.
2. 초안 작성은 `draft-req`, 승인 전환은 `confirm-req`, 변경 대응은 `change-req`, 구현 완료 전환은 `confirm-req-implemented` skill을 기준으로 수행한다.
3. requirement 추가 또는 변경 후 `Next Requirement ID`, `Requirement Register`, `Recent Change Log Summary`를 함께 갱신한다.
## 상태 정의
- Proposed: 초안 상태이며 구현 기준으로 확정되지 않음
- Approved: 구현 기준으로 승인됨
- Implemented: 구현과 검증이 완료됨
- Deprecated: 더 이상 유지하지 않음
## Requirement 타입 분류 도표
| 타입 | 정의 | 예시 |
|------|------|------|
| **Configuration** | 설정 옵션, 커스터마이징 포인트 | 환경 변수, 옵션 항목 |
| **Data** | 데이터 구조, 저장/로드, 파일 형식, 스키마 | DB 스키마, import payload |
| **Deployment** | 배포 방식, 운영 절차, 배포 환경 | 서비스 실행, 운영 가이드 |
| **Documentation** | 문서 작성, 가이드, 매뉴얼, 안내서 | 사용자 가이드, API 문서 |
| **Exception** | 오류 처리, 예외 복구, 재시도 전략 | parser 오류, validation 실패 |
| **Installation** | 시스템 설치, 환경 구성, 초기화 절차 | venv, MCP 등록, DB 초기화 |
| **Integration** | 외부 시스템 연동, 플러그인, 확장 | KB/토스/서울페이 import |
| **Interface** | 사용자 상호작용 방식 | MCP tool, Streamlit UI |
| **Migration** | 데이터 이전, 버전 업그레이드 | SQLite schema migration |
| **Non-Functional** | 성능, 보안, 확장성, 호환성, 신뢰성 | 개인정보/금융정보 보호, UX 성능 |
| **Testing** | 테스트 전략, QA 요구사항, 검증 방식 | parser regression, report validation |
## Next Requirement ID
- Current: `REQ-001`
- Rule: `Requirement Register`에 있는 가장 큰 REQ 번호보다 정확히 1 커야 한다.
## Requirement Register
| ID | Title | Type | Status | Priority | Owner | Link |
| --- | --- | --- | --- | --- | --- | --- |
## Recent Change Log Summary
- 없음