# 财富自由指南灯 · 使用指南

> 一份给你的「人生剩余日」可视化记账系统。
> 每一笔收入点亮一颗星辰，每一笔支出投下一道阴影。
> 全部点亮 = 走完财富自由之旅。

---

## 0. 这是什么 / 为什么用它

普通记账 App 回答**「我今天花了多少」**。
本系统回答一个更本质的问题：

> 如果维持我**过往平均**的生活成本，我现在的财富能支撑我**自由地活多少天**？

- **每一笔收入** → 给自己买到 N 天自由 → **点亮 N 个人生方格**
- **每一笔支出** → 抬高平均日花销 → **熄灭已点亮的方格**
- 所有「剩余日方格」被点亮 = **财富自由达成 · 仪式动画庆祝**

不是预算工具，是**一面财富自由的进度灯**。

核心公式：

```
avg_daily_expense    = total_expense / tracking_days
net_savings          = total_income - total_expense
freedom_days_bought  = floor(net_savings / avg_daily_expense)
                     + floor(initial_assets / avg_daily_expense)   （可选）
```

---

## 1. 系统要求

- macOS / Linux（Windows 用 WSL 或 Git Bash 同样可行）
- **Python 3.9+**（自带 sqlite3 模块）
- 浏览器：Chrome / Safari / Firefox 任意现代版本
- 无需联网，无需账号注册，所有数据本地存储

---

## 2. 一键启动

解压压缩包后进入项目目录：

```bash
cd 财富自由指南灯
chmod +x run.sh         # 仅首次需要赋予执行权限
./run.sh
```

`run.sh` 会自动完成：

1. 创建 `.venv` 虚拟环境（仅首次）
2. 安装依赖：fastapi / uvicorn / pydantic
3. 启动后端服务 → 监听 `http://127.0.0.1:8766`
4. 自动打开浏览器

如自动打开失败，手动访问 → **http://127.0.0.1:8766**

停止服务：终端按 `Ctrl + C`。

---

## 3. 首次使用 · 三步走

### 步骤 ① 设置个人参数

首次进入会弹出引导对话框，依次填写：

| 字段 | 说明 | 示例 |
|------|------|------|
| **出生日期** | 用于计算剩余生命方格 | YYYY-MM-DD |
| **目标年龄** | 你希望活到的年龄（决定方格总数） | 80 |
| **显示过去** | 是否把出生至今的日子也画成方格 | 关闭 = 第一格是今天 |
| **纳入起始资产** | 是否把已有积蓄折算成自由 | 打开后填入金额 |
| **记账起始时资产** | 仅纳入起始资产打开时显示 | ¥100,000 |
| **记账天数（手动覆盖）** | 0 = 自动从交易记录派生 | 60（强制 60 天） |
| **日均花销（手动覆盖）** | 0 = 自动派生 | 150（强制 ¥150/天） |

> **手动覆盖说明**：默认两项填 0 即可，让系统从你的真实交易数据派生。
> 仅在想做「如果我每天只花 ¥X，我能买到多少自由」的假设模拟时填具体值。

### 步骤 ② 记一笔账

主界面下方的输入区：

1. 选择类型：**收入** 或 **支出**
2. 输入金额（必须 > 0）
3. 选择日期（默认今天）
4. 备注（可选，如「午餐」「项目尾款」）
5. 点击大按钮：「点亮人生」（收入）/「记下花销」（支出）

提交后立即触发：

- **数据落盘**（SQLite，本地 `data/ledger.db`）
- **方格变化动画**：收入 → 新方格点亮（光晕扩散 + 钟磬音）；支出 → 已点亮方格熄灭（灰烬飘散）
- **统计卡片实时更新**：总收入 / 总支出 / 日均花销 / 记账天数

### 步骤 ③ 浏览人生方格

页面中央是 **Canvas 人生方格图**：

- 每个方格 = 你生命中的一天
- **金黄色** = 已被收入点亮（自由日）
- **深灰色** = 未点亮（还要继续努力的日）
- **超额星光** = 收入买的自由超过了剩余寿命（达成财富自由 · 触发彩蛋动画）

页面顶部显示：进度环（已点亮百分比）/ 剩余天数 / 资产带来自由 / 收入带来自由。

---

## 4. 常用操作

### 4.1 删除一笔账

主界面右下「最近交易」列表 → 点击单笔右侧 × → 立即删除并重算。

### 4.2 修改个人设置

页面顶部齿轮图标 → 重新打开设置对话框 → 修改后点击「开始 / 保存」。

### 4.3 注入演示数据（仅供首次体验）

```bash
.venv/bin/python backend/seed_demo.py
```

默认参数：60 天 · 平均日花销 ≈ ¥70 · 平均日收入 ≈ ¥500。
**注意**：seed_demo 会**清空现有交易**，仅首次体验时使用。

### 4.4 自定义平均日花销的演示数据

编辑 `backend/seed_demo.py` 顶部：

```python
DAYS = 60                              # 跨度天数
TARGET_AVG_EXPENSE_PER_DAY = 150.0     # 改为你想要的日均
TARGET_AVG_INCOME_PER_DAY = 800.0
```

重新运行即可。

### 4.5 完全重置

```bash
rm data/ledger.db
./run.sh                # 重启会自动建空库
```

---

## 5. 文件结构

```
财富自由指南灯/
├── README.md              简介
├── 使用指南.md             本文件
├── 设计方案.md             数学模型 / API 契约 / 动画规格（开发者向）
├── run.sh                 一键启动脚本
├── backend/
│   ├── main.py            FastAPI + SQLite 后端（单文件）
│   ├── seed_demo.py       演示数据注入器
│   └── requirements.txt   Python 依赖
├── frontend/
│   ├── index.html         页面结构
│   ├── style.css          视觉设计
│   ├── app.js             状态机 / API 调用 / 仪式编排
│   └── grid.js            Canvas 方格 + 动画引擎
└── data/                  自动创建，存放 ledger.db
```

---

## 6. 隐私与数据

- **所有数据存储在本地** `data/ledger.db` 文件，**不上传任何服务器**
- 后端只监听 `127.0.0.1`（仅本机访问，局域网内不可见）
- 想换设备：直接复制整个项目目录（含 `data/ledger.db`），在新设备 `./run.sh`
- 想清空：删除 `data/ledger.db`

---

## 7. API 接口（可选 · 用于二次开发）

服务运行后访问 `http://127.0.0.1:8766/api/docs` 看 Swagger 文档。

| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/state` | GET | 获取设置 + 统计 + 最近 50 笔交易 |
| `/api/settings` | POST | 更新设置 |
| `/api/transactions` | GET | 列出交易（支持 limit / offset） |
| `/api/transactions` | POST | 新增交易 |
| `/api/transactions/{id}` | DELETE | 删除指定交易 |

---

## 8. 常见问题

**Q：启动报「Address already in use」？**
A：8766 端口被占用。运行 `lsof -i :8766` 找进程并 `kill`，或修改 `run.sh` 中的 `PORT`。

**Q：浏览器没有自动打开？**
A：手动访问 `http://127.0.0.1:8766` 即可。

**Q：第一次进入没有引导弹窗？**
A：检查 `data/ledger.db` 是否已存在历史记录。删除该文件后重启 → 重新触发引导。

**Q：方格全黑没有点亮？**
A：因为净储蓄（收入 - 支出）≤ 0。多记一笔收入即可看到方格开始点亮。

**Q：能不能两人共用一个账本？**
A：当前为单用户单库设计。多人需各自部署一份独立实例。

**Q：手动覆盖记账天数 / 日均花销有什么意义？**
A：用于模拟假设场景。例如想知道「如果我每天只花 ¥100 维持 365 天，我已有的存款能买几年自由」，把覆盖值填进去即可即时看到效果。**填 0 表示按真实数据计算**。

---

## 9. 设计哲学

> 数据是真相，动画是仪式。仪式服从真相。

- 任何视觉效果都必须由数学模型驱动，绝不为了好看而作弊
- 简洁优先：函数只做一件事，能消除分支不增加 if/else
- 无后向兼容包袱：用户的真实需求 > 历史代码的延续性

详见同目录 **设计方案.md**。

---

祝你早日点亮所有方格。
