内容
# 金融助手
一款自我托管的个人金融助手。 将银行/信用卡对账单放入文件夹中,应用程序会读取它们,**智能分类**交易记录,在转换过程中检测您自己的账户之间的转账,正确处理投资账户,并呈现类似Mint的HTML仪表盘,支持深入分析消费情况和待办事项工作流。本地MCP服务器将任意格式的对账单转换为应用程序可以理解的标准CSV,并在转换时为每行猜测分类。
- **技术栈:** Python 3.11, FastAPI, Jinja2, SQLAlchemy, TailwindCSS (CDN), Chart.js, HTMX
- **数据库:** 默认SQLite,兼容PostgreSQL(无SQLite特定SQL)
- **地区:** 香港 - 日期优先显示为`DD/MM/YYYY`,默认货币`HKD`
- **UI参考:** Mint / Monarch Money - 侧边栏账户/类别,仪表盘卡片 + 图表,可筛选的交易记录表
## 功能
### 仪表盘
- 总余额,本月消费/收入/净额摘要卡片。
- 按类别消费的甜点图表和6个月收入/消费趋势线。
- 最近交易记录列表,带有转账/投资标志和类别事件徽章。
- 投资卡(投资组合价值,本月购买/出售/股息/利息/费用)。
### 交易记录
- 可筛选的表格(日期范围,账户,类别,转账标志,自由文本搜索)。
- 通过**可搜索,树状结构类别选择器**进行行内类别编辑(颜色点,深度缩进,输入筛选)。
- 每行转账切换和删除。
- 每行`类别事件`徽章,显示转换器的猜测原因(`商家模式`,`农历新年`,`不确定`等)。
### 按类别消费(深入页面)
- 筛选栏(日期范围 + 账户)与实时总计。
- 消费份额甜点图表和可排序的顶级类别表格(总计,交易记录数,平均值,份额条 + 百分比)。
- **点击任意类别深入钻取**:摘要瓷砖,类别6个月趋势条形图,以及该类别的筛选交易记录列表。
### 待办事项
一个页面,集中显示需要关注的所有事项,分为三个选项卡:
- **未分类** - 没有类别的交易记录;内联分配类别。
- **不确定** - 转换器无法自信分类的交易记录(`类别事件 == "不确定"`);审查和分配。
- **跳过的行** - 导入程序无法解析的行(例如未加引号的逗号),包含源文件,行号,原因和原始行,以便您可以修复CSV。
- 内联类别编辑保存到数据库**和**写回源CSV。
- "将所有编辑保存到CSV" 将当前数据库状态同步到所有对账单文件。
### 类别和账户
- 类别树(父/子)与类别颜色。
- 账户管理与**账户类型**:`checking`,`savings`,`credit_card`,`investment` - 类型驱动交易记录在统计数据中的计算方式。
### 规则
- 用户定义的分类规则(根据描述/账户/金额,子字符串或正则表达式,优先级)。
- "应用于所有交易记录" - 规则仅在转换器未分类的行上运行,因此智能猜测始终优先。
### 智能分类(内置于对账单 → CSV)
MCP `convert_statement`工具在发出每个标准行时运行内置的3层分类器,填充`类别` + `类别事件`:
1. **商家/描述模式** - 精心策划的正则表达式列表(咖啡,餐饮,杂货,交通,旅行,公用事业,收入,费用等)。
2. **香港日历事件** - 日期窗口规则,用于`农历新年`,`圣诞节`,`万圣节`,`中秋节`,`复活节`,`发薪日`,`学校假期`(农历新年/中秋节/复活节窗口硬编码至2028年)。
3. **金额启发式** - 带有工资/存款关键词的≥ 1000的正金额 → 收入;退款 → 退款。
导入时,类别文本被映射到类别行(不区分大小写,如果缺失则自动创建)。无需单独的分类步骤。
### 转账检测
当您向信用卡付款或从银行账户资助券商时,会发出两个转账并自动配对(相反符号,等大 ±3天,不同账户,转账关键词)。配对的转账不计入消费/收入和类别甜点图表,但保留在`总余额`中。
### 投资账户处理
`investment`类型账户的交易记录按描述分类为`购买` / `出售` / `股息` / `利息` / `费用`。购买和出售被视为资产交换(不计入消费/收入);股息和利息计为收入;费用计为消费。现金充值行配对为转账。
### CSV保存
在UI中进行的编辑(类别,描述,转账标志)可以写回源`statements/*.csv`文件,以便磁盘文件与数据库保持同步。每个文件创建`.bak`备份。没有匹配交易记录的行(跳过/格式错误)原样保留。
## 快速开始
```bash
# 1. 创建虚拟环境并安装
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
pip install -e ".[dev]"
# 2. 配置(可选 - 默认配置可以直接使用)
copy .env.example .env # Windows
# cp .env.example .env # macOS/Linux
# 3. 运行应用程序
finance-assistance # 在127.0.0.1:8000启动uvicorn
# 或:python -m app.main
```
打开 <http://127.0.0.1:8000>.
## 使用方法
1. **将对账单放入** `statements/`(CSV或TXT)。
- 对于PDF或不寻常的布局,请要求IDE代理运行`convert_statement` MCP工具(参见下文)以生成标准CSV,然后将该CSV放入`statements/`。
2. 打开**导入**页面并点击**导入所有**。重复项会自动跳过(通过`sha256(date|description|amount|account)`去重)。跳过的行会被记录并在**待办事项**页面显示。
3. 查看**待办事项**页面中的未分类/不确定/跳过的行;内联分配类别(编辑会写回源CSV)。
4. 探索**消费**页面,按类别深入钻取消费情况,并查看每个类别的趋势和交易记录列表。
5. 添加**规则**(例如“描述包含`STARBUCKS` → 咖啡”),然后点击*应用于所有交易记录*,以自动分类任何剩余的行。
6. **仪表盘**显示余额,本月消费/收入/净额,类别甜点图,6个月趋势和投资摘要。
## 标准CSV模式
每个规范的对账单(内置解析器或MCP输出)都符合:
```
日期,描述,金额,货币,账户,余额后,原始行,类别,类别事件
```
- `日期` - `YYYY-MM-DD`
- `金额` - 带符号的浮点数;**负数=借记,正数=贷记**
- `货币` - ISO 4217(默认`HKD`)
- `账户`,`余额后`,`原始行` - 可选
- `类别` - 转换器的最佳猜测类别(自由文本,与应用程序的分类法匹配);如果不确定,则为`""`。导入程序将其映射到类别行。
- `类别事件` - 驱动猜测的原因:`商家模式`,`农历新年`,`圣诞节`,`万圣节`,`中秋节`,`复活节`,`发薪日`,`学校假期`,`金额启发式`,或`不确定`。
> `is_transfer`和`transfer_pair_id`由应用程序在导入后设置,而不是由转换器设置。
完整的规则,分类层和银行特有的特殊情况:
[`mcp_server/INSTRUCTIONS.md`](mcp_server/INSTRUCTIONS.md).
## 通过MCP将对账单转换为CSV
本地MCP服务器注册在[`.cursor/mcp.json`](.cursor/mcp.json)中,并公开:
- `convert_statement(input_path, output_path, format_hint=None)` - 将任何支持的对账单(CSV/TXT,或如果`pip install pypdf`则为PDF)转换为写入`output_path`的标准CSV。**在转换过程中会猜测类别。**
- `canonical_schema()` - 以JSON返回9字段模式。
代理读取`mcp_server/INSTRUCTIONS.md`以获取转换契约(包括商家模式和香港日历事件智能),然后调用工具。为测试目的,可以手动运行服务器:
```bash
python -m mcp_server.server
```
## 添加新的银行(内置解析器)
应用程序设计为可扩展的。要添加已知银行格式而无需MCP往返,请在
[`app/services/parser.py`](app/services/parser.py)中注册解析器:
```python
@register("mybank")
def parse_mybank(reader, path):
for row in reader:
yield {
"date": row.get("Txn Date"),
"description": row.get("Memo"),
"amount": row.get("Amount"),
"account": "MyBank Checking",
}
parse_mybank._detect_headers = {"txn date", "memo", "amount"}
```
命名为`mybank_*.csv`的文件将自动使用它;否则,导入程序将退回到头部检测启发式和通用解析器。
## 切换到PostgreSQL
应用程序使用SQLAlchemy,仅使用通用列类型。设置`DATABASE_URL`:
```
DATABASE_URL=postgresql+psycopg://user:pass@localhost:5432/finance
```
然后`pip install psycopg[binary]`并重启。表格将在启动时自动创建。
## 项目布局
```
app/ FastAPI应用程序(配置,模型,服务,路由,模板)
services/ 标准化,解析器,导入器,类别服务,规则引擎,
转账服务,投资服务,CSV同步
mcp_server/ MCP服务器,转换器,类别分类器,INSTRUCTIONS.md
statements/ 将原始对账单放入此处(监视文件夹)
data/ SQLite数据库(gitignored)
tests/ pytest套件(标准化/解析器/导入器/分类器/转账/投资)
.cursor/mcp.json 项目范围的MCP服务器注册
```
## 测试
```bash
pytest
```
## 路线图/超出范围(当前阶段)
- 认证/多用户
- YNAB风格的信封预算(目前仅限Mint风格的概述)
- 后台文件夹监视器(今天从UI/API触发导入)
- 可靠的PDF表格提取(仅文本层;使用MCP +手动审查)