Files
2026-08-23 14:26:55 +08:00

241 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
⚠️ 本文档已过时,仅留档备查,请勿删除。当前代码状态请看 `README.md``项目需求.md``最新进度.md``任务清单.md`
# 项目交接说明
更新时间:2026-08-06
核对基线:`main` / `b3043f9`(生成本文档前与 `origin/main` 一致)
本文档基于当前仓库代码、六个银行样本、现有测试、产品/行为规范和 Git 状态核实,不把仅存在于页面中的演示交互视为已落地的生产功能。
## 1. 项目目标和当前状态
### 项目目标
本项目用于集中管理集团内部多家公司的银行流水,并以软件核算为主、人工审核为辅,形成可追溯的公司间往来关系。核心目标包括:
- 集中保存各公司、各银行账户的原始流水,避免本地电脑故障造成数据丢失。
- 按银行表头签名识别不同 Excel 模板,不依赖固定行号、列顺序或文件名。
- 将同一经济转账的双方银行流水归并为一个规范事件,避免重复统计。
- 排除同一公司不同银行账户间的内部调拨,不计入公司间往来。
- 按公司、方向、对方公司、会计科目和原始银行证据逐层查询。
- 区分总账管理端和公司出纳端,并在服务端实施真实的数据权限边界。
- 支持起算日、期初余额、覆盖断档、人工无业务校准、月结和重开审计。
### 当前状态
当前版本是“真实银行流水解析内核 + 双端高保真交互原型”,还不是可上线的财务系统。
| 能力 | 当前状态 | 事实依据 |
|---|---|---|
| 六家银行 Excel 解析 | 已实现 | `src/bank_importer/`,六个样本和 6 项单元测试均通过 |
| 本地上传并调用解析器 | 已实现最小闭环 | `POST /api/parse` 返回银行、模板、表头行、期间和明细数 |
| 总账端/公司端页面与交互 | 高保真原型 | `web/admin.html``web/company.html``web/app.js` |
| 生产数据持久化 | 未实现 | 无数据库、对象存储或导入批次持久层 |
| 身份认证与权限隔离 | 未实现 | 登录页不校验密码;服务端仅有解析接口 |
| 双边匹配与公司间核算 | 未实现 | `pairData()` 根据公司序号生成演示数据 |
| 覆盖连续性、期初、月结 | 仅前端演示 | 操作只修改当前 DOM 或显示 Toast |
| 提醒与审核 | 部分浏览器原型 | 手工记录/账户申请用 `localStorage`;无多用户服务端状态 |
### 最近验证结果
- `python -m unittest discover -s tests -v`6 项通过。
- `python -m bank_importer.cli 流水模板`:6 个样本全部识别,合计 20 条规范化交易,余额校验无警告。
- `node --check web/app.js`:通过。
- Git:生成本文档前 `main``origin/main` 均指向 `b3043f9430a93ae98139408bd582c2db32e11143`,工作区干净。
## 2. 技术架构与主要目录
### 当前架构
```text
浏览器静态页面
├─ index.html:角色入口
├─ admin.html:总账管理端原型
└─ company.html:公司出纳端原型
│ POST /api/parsemultipart/form-data
Python 标准库 ThreadingHTTPServer
bank_importer 解析内核
├─ 读取 .xlsxopenpyxl
├─ 读取 .xlsxlrd
├─ 表头签名识别
└─ 规范化交易与余额连续性检查
```
当前没有数据库、ORM、认证服务、后台任务、对象存储、消息队列或生产部署配置。`server.py` 仅适合本地原型运行。
### 主要目录
| 路径 | 作用 | 当前成熟度 |
|---|---|---|
| `src/bank_importer/` | 银行模板、工作簿读取、表头检测、字段规范化、余额校验、CLI | 可复用内核 |
| `tests/test_parser.py` | 六个现有样本及基础表头识别回归测试 | 覆盖有限 |
| `server.py` | 静态文件服务和 `/api/parse` 最小接口 | 原型服务 |
| `web/` | 登录、总账端、公司端、样式、图标和原生 JS 交互 | 高保真原型 |
| `流水模板/` | 六家银行的 `.xls`/`.xlsx` 样本 | 已纳入 Git,需确认脱敏级别 |
| `docs/issues/` | 本次拆分的独立待办 Issue | 交接清单 |
| `PRODUCT.md` | 产品边界和核心会计模型 | 规范来源 |
| `BEHAVIOR_SPEC.md` | 导入、审核、核算、月结、提醒的行为规范 | 目标行为,非当前实现说明 |
| `AGENTS.md` | 不可破坏的业务与工程行为规则 | 开发约束 |
| `DESIGN.md` / `DESIGN-TOKENS.md` | 当前深色玻璃财务工作台设计系统 | 已落地 |
| `.impeccable/design.json` | 设计系统机器可读 sidecar | 已落地 |
### 关键代码边界
- `server.py` 目前只有 `POST /api/parse`,解析成功后取 `batches[0]` 返回摘要,不保存文件或交易。
- `src/bank_importer/models.py` 的 dataclass 是解析结果,不是持久化领域模型。
- `web/app.js` 中除上传解析外,大部分操作在 DOM 或 `localStorage` 中完成。
- `web/app.js::pairData()` 是演示算法,不可作为财务计算依据。
## 3. 已完成功能
### 真实实现
1. 支持中信银行、农业银行、工商银行、建设银行、河南农商银行、郑州银行六种样本格式。
2. 支持 `.xls``.xlsx`,扫描每个工作表前 50 行寻找表头。
3. 表头别名经过空白和全角字符规范化,列顺序变化不影响识别。
4. 规范化交易日期、收入、支出、余额、本方账户/户名、对方账户/户名/银行、摘要、用途、银行参考号、币种和源行定位。
5. 金额使用 `Decimal`,支持逗号、括号负数和人民币符号清理。
6. 对同一时间组按余额执行连续性检查,并输出警告。
7. 未识别或歧义模板拒绝猜测;服务器错误会替换临时文件名为原始上传文件名。
8. CLI 可批量解析目录并只输出批次摘要,不打印敏感逐笔内容。
9. 本地页面可上传文件并调用同一解析内核。
### 已完成的原型交互
1. 登录入口明确区分总账管理端与公司业务端。
2. 总账端包含管理总览、公司对查询、审核中心、流水管理、公司与账号、结账与期初、提醒管理。
3. 公司端包含工作台、流水导入、手工记录、流水管理、往来确认、银行账户、通知。
4. 手工记录和账户登记可在公司端提交到 `localStorage`,并在同一浏览器的总账审核中心处理。
5. 已启用的浏览器本地账户可加入上传账户选项;待复核账户不加入。
6. 流水列表可按现有静态数据筛选并导出 CSV。
7. 双端具有独立导航、首页优先级、桌面/移动布局、键盘焦点和减少动效支持。
8. 深色玻璃设计系统、四个首页统计卡和响应式动效已完成并通过视觉审查。
## 4. 尚未完成的功能
未完成事项已拆分到 `docs/issues/`,以文件编号表示推荐依赖关系:
| Issue | 未完成事项 | 优先级 |
|---|---|---|
| [001](issues/001-p0-repository-data-hygiene.md) | 仓库银行样本的数据分级、脱敏和真实上传文件隔离 | P0 |
| [002](issues/002-p0-persistence-and-immutable-imports.md) | 数据库、不可变原始文件、导入批次、哈希与去重基础 | P0 |
| [003](issues/003-p0-auth-and-tenant-isolation.md) | 正式认证、RBAC 和公司级服务端权限隔离 | P0 |
| [004](issues/004-p1-dynamic-master-data.md) | 动态公司/用户/账户/别名主数据及账户审核工作流 | P1 |
| [005](issues/005-p1-import-api-hardening.md) | 导入 API 加固、完整诊断、多工作表与接口回归测试 | P1 |
| [006](issues/006-p1-canonical-transfer-matching.md) | 规范转账事件、双边匹配、同公司调拨和个人过账映射 | P1 |
| [007](issues/007-p1-position-calculation.md) | 往来科目、余额计算、手工记录审批后入账和逐层追溯 | P1 |
| [008](issues/008-p1-calculation-window-coverage.md) | 全局起算日、覆盖区间、期初余额和无业务断档校准 | P1 |
| [009](issues/009-p1-monthly-close.md) | 月结、锁定、重开、冲销/调整和完整审计报告 | P1 |
| [010](issues/010-p2-flow-query-export.md) | 服务端流水查询、权限过滤和可追溯导出 | P2 |
| [011](issues/011-p2-reminder-engine.md) | 自动/手工站内提醒、状态流转和外部提醒扩展点 | P2 |
| [012](issues/012-p1-frontend-production-api-integration.md) | 前端接入生产 API,移除静态数据、`pairData()``localStorage` 业务状态 | P1 |
## 5. 已知问题
### 核算与数据一致性
1. `pairData()` 使用 A-F 公司序号生成模拟金额和交易,不读取解析结果、手工记录或账户主数据。
2. 管理员将手工记录审核为“已确认”后,仅更新 `localStorage` 状态,不会进入往来合计或公司对查询。
3. 公司间同一笔转账的双边流水尚未归并,无法保证“一笔经济事件只计一次”。
4. 同公司跨银行调拨、外部交易、个人过账仅有静态演示,没有服务端判定链。
### 导入与证据
1. `/api/parse` 不保存原文件、哈希、导入批次、规范化交易或异常记录;页面声称“已保留”仅是原型文案。
2. 多工作表成功解析时,接口只返回 `batches[0]`,其他批次未暴露给前端。
3. 只有单个非空单元格的候选行会被 `_header_candidate_summary()` 忽略;全空工作簿的错误缺少工作表、扫描行数和候选表头四项完整诊断。
4. 手工记录附件只保存文件名,附件内容没有上传或保留。
5. 当前 multipart 解析由 `server.py` 手写,未覆盖复杂文件名、边界和二进制尾部的接口测试。
### 权限与持久化
1. 登录不验证账号或密码,公司端固定为 A 公司。
2. 服务端没有用户、会话、权限检查或公司数据隔离。
3. 公司、账号、期初、结账、提醒、确认结果多数只存在当前 DOM;刷新即丢失。
4. `localStorage` 数据仅限同一浏览器,不支持不同出纳客户端与总账端同步。
5. 银行账号唯一性只在当前浏览器本地申请中检查,不能防止并发或跨公司冲突。
### 测试与运行
1. 现有 6 项测试只覆盖解析内核,没有 `/api/parse`、认证、导入持久化、匹配、核算、权限或端到端测试。
2. `server.py` 基于标准库开发服务器,默认绑定 `0.0.0.0`(可用 `APP_HOST` 覆盖),没有生产部署、TLS、日志、备份或监控方案。
3. `流水模板/` 已进入 Git 历史;必须确认均为合成或已脱敏数据,真实生产流水不得继续提交到仓库。
## 6. 已作出的重要技术决策及原因
| 决策 | 原因 |
|---|---|
| 以表头签名识别银行模板 | 银行模板表头稳定,而标题行位置、列顺序和明细内容会变化 |
| 未识别/歧义模板进入异常,不自动猜测 | 财务系统错误入账的代价高于人工处理少量异常 |
| 原始银行行不可修改 | 保留证据链;修正通过映射、冲销或审计调整完成 |
| 银行侧观察与经济转账分层 | A/B 双方各一条流水只能形成一个规范事件,避免双计 |
| 同公司不同账户调拨不计公司间往来 | 只影响账户现金轨迹,不改变公司间债权债务 |
| 账号优先于户名识别对方 | 户名可能缩写、别名或人工录入不一致,账号确定性更高 |
| 金额使用 `Decimal` | 避免浮点误差进入余额与核算逻辑 |
| 科目只做确定性规则,歧义进入审核 | 摘要不足以可靠区分应收/其他应收等法定科目 |
| 手工记录与银行证据分开 | 防止人工信息覆盖不可变银行事实,并保留独立审核轨迹 |
| 公司端账户登记需总账审核后启用 | 未审核账户不能参与所有权识别、上传和覆盖计算 |
| 总账端与公司端为独立页面 | 两类用户的信息优先级、权限范围和高频操作不同 |
| 前端原型使用 `localStorage`,但明确不作为生产方案 | 在无数据库阶段验证流程,同时避免误认为已具备多用户一致性 |
| 深色设计系统直接替换旧 token,不追加主题覆盖层 | 防止 CSS 权重叠加和后续新旧视觉规则混用 |
## 7. 当前正在处理的事项
当前没有功能代码正在开发。本轮已经将项目事实、风险、依赖和验收标准固化到本文档,并将生产化未完成事项拆成 12 个独立 Issue 规格。当前唯一未闭环的交接事项是把这些规格创建为远程 Gitea Issues。
Gitea SSH 推送已可用;本机没有 `tea` CLI、Gitea API Token 或已配置的 Gitea CLI 登录。`192.168.200.36:3000` 不可访问,默认 HTTP 端口是 fnOS 管理页面,因此当前只能保证 Issue 规格已进入仓库,不能在没有 API/Web 入口和认证信息的情况下伪造远程 Issue 创建成功。
## 8. 推荐的后续执行顺序
1. **先做 Issue 001**:确认仓库内 Excel 的数据级别;若包含真实信息,先脱敏并清理 Git 历史,再继续协作。
2. **并行设计 Issue 002 与 003**:确定数据库/文件存储和认证授权边界,但先落地最小数据库迁移与不可变导入模型。
3. **完成 Issue 004 与 005**:主数据和加固后的导入 API 是后续识别、覆盖和权限的基础。
4. **完成 Issue 006**:建立规范事件和双边匹配,先确保不重复计算。
5. **完成 Issue 007**:在规范事件之上实现科目和公司间余额,并补齐已确认手工记录入账。
6. **完成 Issue 008**:加入起算日、期初和覆盖连续性,明确“期间净变动”与“期末余额”。
7. **完成 Issue 009**:核算结果稳定后再实现月结、重开和调整审批。
8. **完成 Issue 010 与 011**:以已持久化的事件、异常和覆盖状态实现查询导出与提醒。
9. **贯穿各后端阶段推进 Issue 012**:按垂直切片替换静态数据,最后删除 `pairData()` 和业务 `localStorage`
10. 每个阶段都增加自动化测试、迁移回滚方案和审计字段,不要把测试集中留到最后。
## 9. 每项任务的验收标准
以下是摘要,完整范围和测试要求见对应 Issue 文件。
| Issue | 核心验收标准 |
|---|---|
| 001 | 六个样本完成数据分级;确认已脱敏或替换为合成数据;真实上传目录被 Git 忽略;如需清历史,远程仓库验证不再含敏感对象 |
| 002 | 数据库迁移可重复执行;原文件按内容哈希不可变保存;重复文件/行幂等;导入批次、源行和异常可查询;重启后数据不丢失 |
| 003 | 真实登录、密码策略和会话生效;总账/公司角色在服务端授权;公司用户无法读取、导出或修改其他公司数据;有权限回归测试 |
| 004 | 公司、用户、账户、别名和生效期均来自数据库;账户审批前不参与识别/上传/覆盖;账号唯一约束由数据库保证;审核全留痕 |
| 005 | API 返回全部工作表批次;未知模板始终含原文件名、工作表、扫描行数、候选表头;失败不建成功批次;覆盖空表、单单元格、临时文件名和 multipart 回归测试 |
| 006 | 双边流水归并为一个规范事件;反向导入和重复导入不改变结果;同公司调拨排除;未识别对方不入公司间余额;个人过账映射可审计 |
| 007 | 余额只来源于已确认规范事件和已批准手工记录;双方视角守恒;四科目可追溯到原始证据;未决金额和截止日始终显示 |
| 008 | 起算日前行保留但不计算;每账户覆盖区间正确合并并检测缺口;期初双边守恒;无业务校准需要理由且不生成银行行;无期初时标记期间净变动 |
| 009 | 结账前置条件服务端校验;结账快照不可静默改写;闭期补录进入重开异常;调整/冲销经审批;能导出完整月结审计报告 |
| 010 | 总账和公司端查询均由服务端权限过滤;筛选、分页和金额汇总一致;导出包含银行标识、批次、源行和匹配状态;大数据量测试通过 |
| 011 | 五类自动触发器可幂等生成提醒;手动提醒可指定公司/期限;未读/已读/处理中/完成状态持久化;链接回原任务;外部通道保持可插拔但默认关闭 |
| 012 | 所有页面从 API 读取真实数据;刷新和跨客户端状态一致;删除模拟 `pairData()`、静态业务行和业务 `localStorage`;保留双端独立路由、响应式和无障碍行为;关键流程端到端通过 |
## 运行与交接注意事项
```powershell
python -m pip install -r requirements.txt
$env:PYTHONPATH = "src"
python -m unittest discover -s tests -v
python -m bank_importer.cli "流水模板"
python server.py
```
本地地址:
- 登录:`http://127.0.0.1:4173/`
- 总账管理端:`http://127.0.0.1:4173/admin.html`
- 公司业务端:`http://127.0.0.1:4173/company.html`
开发时必须继续遵守 `AGENTS.md`:不修改原始银行证据、不把 UI 隐藏当作权限、不得从户名单独推断财务事实、每个新银行模板或解析边界都必须有回归测试。