feat: simplify agent permissions and require current ZIP backups

This commit is contained in:
陈煜 committed 2026-10-04 01:46:47 +08:00
1 parent efc2c7c734
commit 91c489513a
51 files changed
+1680 -1270

No files matched your search

+2
View File
@@ -1,5 +1,7 @@
# 首版验收(2026-10-01,Asia/Hong_Kong)
> 历史验收记录:2026-10-04 起所有旧备份兼容与单文件 JSON 支持已删除,当前仅接受 ZIP v9;本文旧版本测试记录不代表现行功能。现行 MCP 权限与工具范围见 [本次更新](update-agent-backup-2026-10-04.md)。
代码位于 E:\WorthPath,远程 origin 为用户指定 GitHub 仓库,分支 main。初始目录和仓库为空;没有覆盖已有项目文件。已有其他程序占用 API 默认端口,因此本项目使用 3100,前端使用 5173。
已验证:
+2 -2
View File
@@ -1,6 +1,6 @@
# WorthPath 首版设计
2026-10-02 更新:查询、历史分页、趋势重放、借入借出联动及三语言的当前实现和实测见 [性能与联动验收](performance.md)。以下首版设计中的历史 ZIP v3/v4 说明保留作格式沿革;当前导出为 v7,兼容读取 v3/v4/v5/v6/v7 ZIP 和旧 JSON。
2026-10-04 更新:当前仅支持完整 ZIP v9 备份,不支持任何单文件 JSON 或旧 ZIP。本文旧版结构说明作为历史记录,现行权限与验证以 [本次更新](update-agent-backup-2026-10-04.md) 和 [MCP 接入](mcp.md) 为准。
本轮账户分组、定时计划、收支日历、迁移步骤与验证边界见 [更新说明](update-2026-10-02.md)。
@@ -34,7 +34,7 @@ Revision 保存按业务日期生效的绝对金额,每次金额更新新增
Icon 存储 name、ownerId、shared、SHA-256、规范静态 PNG 的 MediumBlob 和可选公开来源;Position.iconId 外键 SetNull,多个账户共享同一图片。所有图标接口使用已验证身份,读取/检索/赋值均限定 shared=true 或 ownerId=当前用户,响应不返回 ownerId。个人上传默认私有;共享发布须中文名称和明确公开确认。拒绝 SVG、动图、损坏图片、超限像素/文件,重编码移除元数据。内置图标固定 ID 追加初始化;在线请求不会发送用户财务数据。
备份逻辑增加可选 icons 数组(旧格式缺失可兼容),v4 ZIP 将图标内容放入 icons.json;内容校验和解码在导入事务前完成,图标在事务内以当前用户私有范围重建,账户关联重映射。清空删除私有图标,公开共享图标不因发布者清空而消失。用户删除时图标 ownerId SetNull,不影响他人已引用的公共图标。
当前备份要求完整 icons 数组,ZIP v9 将图标内容放入 icons.json;内容校验和解码在导入事务前完成,图标在事务内以当前用户私有范围重建,账户关联重映射。清空删除私有图标,公开共享图标不因发布者清空而消失。用户删除时图标 ownerId SetNull,不影响他人已引用的公共图标。
## 转账及显示偏好
+3 -3
View File
@@ -28,7 +28,7 @@
},
{
"TABLE_NAME": "agentpolicy",
"TABLE_COMMENT": "用户的 Agent 写入策略"
"TABLE_COMMENT": "已停用的历史 Agent 策略数据,保留原数据但不参与权限判定"
},
{
"TABLE_NAME": "exchangerate",
@@ -215,7 +215,7 @@
{
"TABLE_NAME": "agentgrant",
"COLUMN_NAME": "scopes",
"COLUMN_COMMENT": "权限列表:read、draft、write、sensitive"
"COLUMN_COMMENT": "权限列表:read、draft 或 write;隐藏账户附加权限 hidden_read、hidden_write"
},
{
"TABLE_NAME": "agentgrant",
@@ -235,7 +235,7 @@
{
"TABLE_NAME": "agentgrant",
"COLUMN_NAME": "expiresAt",
"COLUMN_COMMENT": "到期时间,UTC"
"COLUMN_COMMENT": "访问令牌到期时间,UTC;空表示可撤销的永久个人令牌"
},
{
"TABLE_NAME": "agentgrant",
+59 -57
View File
@@ -1,69 +1,71 @@
# 现有功能 → MCP 覆盖与验证矩阵
> 2026-10-04 最新边界:MCP 提供 39 个工具。用户明确要求撤下敏感操作、汇率和贵金属报价修改;备份、清空、密码与隐藏解锁流程仍在网站完成。单文件 JSON 及旧 ZIP 全部拒绝。此要求取代最初“全部业务均可由 MCP 完成”的范围。
盘点来源:App.tsx、Calendar、SchedulePanel、MetalPanel、IconLibrary、TransferForm、DebtPaymentForm、GroupOrderList 及所有 API Controller 路由。架构沿用 NestJS/Express/Prisma/MySQL/Zod,不新增消费账本或 AI 框架。
验证记号:**M** `test/mcp.test.ts` 第一组真实官方 SDK/MySQL;**C** 第二组并发/图标/密码修改;**O** 第三组 OAuth;**R** 18 组真实 REST/MySQL 回归;**U** 原单元计算/行情/ZIP 测试。均有实际业务断言。M 中公共刷新验证无需要更新资产时的真实调用;外部行情响应和失败回退由 U 验证,未声称行情供应商稳定可用。
验证记号:**M** 第一组官方 SDK 普通业务/草稿/隐藏权限;**C** 第二组幂等/并发/私有图标/回滚;**O** 第三组 OAuth;**P** 第四组期限/永久令牌/隔离/撤销;**R** 18 组真实 REST/MySQL;**U** 34 项单元计算/行情/ZIP 测试。均有真实业务断言,外部行情成功/失败路径由 U 验证。
**B**:2026-10-03 22:55(UTC+8)真实浏览器验证黄金/白银创建、可选买入价与盈亏、清空成本、估值历史及报价完成后自动同步,临时用户已清理。
普通写入需要 draft 或 write,且受用户 readonly/draft/direct 策略约束;敏感操作额外要求 sensitive 并强制网页确认。所有写入工具要求幂等键和 expectedState。每项都先检查可信用户归属;annotations 不替代权限。
当前权限为 read(只读)、read+draft(网页确认后提交)、read+write(直接普通修改)。hidden_read/hidden_write 是独立附加授权。没有网站全局写入策略。所有写入均校验可信身份、归属、幂等键和 expectedState。
| 现有页面/API 与功能 | MCP 操作路径 | 权限 | 确认方式 | 验证 |
| ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------- | -------------------------------------------- | --------------------------------------------------------- |
| 账户/独立资产/债务列表 GET positions | positions_list:kind、名称、归档、方向、币种、分组、排序、offset/limit | read | 无 | M:查询、重名、分页和外用户隔离 |
| 项目详情 GET positions/:id | position_get | read | 隐藏项目须连接独立网页解锁 | M:当前余额、隐藏/外用户拒绝 |
| 创建项目 POST positions | position_create,保留账户/资产/债务初始绝对余额语义 | draft/write | 策略决定草稿或直接 | M/C:3 类对象、重复调用、无效金额、并发 |
| 按克数创建贵金属 POST metals/holdings | metal_holding_create | draft/write | 策略 | M/R/U/B:待估值、报价、成本盈亏、旧备份 |
| 元数据、分类、分组、图标、归档/恢复、隐藏、计入开关 PATCH positions/:id | position_update,完整 metadata;币种与方向固定 | draft/write | 策略 | M:分组、归档禁止金额更新与恢复;R:隐藏和开关 |
| 分组拖拽排序 PATCH settings | settings_update.accountGroupOrder | draft/write | 策略 | M/R:持久化、排序、备份 |
| 类别选项、名称与分组配置 | position_create/update;positions_list 读取现有值,Schema/描述提供规则 | read + draft/write | 策略 | M/R;当前没有独立分类/分组实体 CRUD |
| 新增余额、资产估值、负债余额及单边还款 POST revisions | balance_record,reason 区分;amount 为变更后余额 | draft/write | 策略 | M:精确余额;R/U:负债、估值、业务时间 |
| 历史全局/单项目 GET history、positions/:id/history | history_list.positionId、cursor、from/to | read | 无 | M/R:页大小、游标、前序余额、日期范围 |
| 更正普通历史 PUT revisions | history_update | draft/write | 策略 | M/R:重放、精度、日历联动 |
| 删除/撤销历史 DELETE revisions | history_delete;配对记录删除完整双边 | draft/write | 策略,destructive annotation | M/R:余额重算及双边撤销 |
| 债务关联账户/资产 PUT links | debt_links_set.targetIds | draft/write | 策略 | M:合法关联、隐藏目标拒绝;R:外用户拒绝 |
| 资金往来列表 GET transfers | movements_list:cursor、日期过滤 | read | 无 | M/R |
| 按历史找双边记录 GET transfers/revision/:revisionId | movement_by_revision | read | 无 | M/R |
| 转账、借入、借出、收款、还款 POST transfers | movement_create.operation:transfer/borrow/lend/collect/repay | draft/write | 策略,双边事务 | M:转账、repay、信用卡溢缴;R:全部 5 种语义;C:错误回滚 |
| 修改配对记录 PUT transfers/:id | movement_update | draft/write | 策略,后续历史重放 | M/R |
| 删除/撤销配对记录 DELETE transfers/:id | movement_delete | draft/write | 策略,双边撤销 | M/R |
| 净资产、总额、结构、变化归因 GET overview | overview_get,明细分页、保留全局总额 | read | 隐藏项目按本连接可见范围 | M/R/U:总额、开关、外币缺失 |
| 轨迹、日期与统计粒度 GET trend | trend_get:day/week/month 及 from/to | read | 无 | M/R/U:范围、首日、期末、归因 |
| 本位币、币种、实际汇率与更新状态 GET settings | settings_get,固定币种枚举且金额无浮点计算 | read | 无 | M/R/U |
| 本位币切换、显示菜单、备注、闲置退出、登录时长、总览卡片、独立资产计入 PATCH settings | settings_update | draft/write | 策略 | M/R |
| 是否查看隐藏资产需密码 PATCH settings | settings_update.requireHiddenPassword | sensitive | 强制网页密码确认 | M:draft 权限无法改变;R:会话锁定规则 |
| 自动/重试日汇率 POST rates/refresh | rates_refresh;已有后台定时更新保留 | draft/write | 策略 | M:真实工具调用;U:成功解析、手工优先、失败保留 |
| 金银报价与状态 GET metals | metals_prices,最近 100 条 | read | 无;查询 MCP 不触发隐式自动更新 | M/U/R |
| 金银报价刷新 POST metals/refresh | metals_refresh | draft/write | 策略,沿用自动估值 | M:无配置资产调用;U:外部响应和失败回退 |
| 每克报价手动回退 POST metals/prices | metal_price_set,Decimal 价格 | draft/write | 策略 | M/R/U:手动优先、精确估值 |
| 克数、品种、纯度、买入成本、自动估价 PUT metals/:id | metal_configure | draft/write | 策略 | M/R/U:估值历史和去重 |
| 应用估价 POST metals/:id/value | metal_value | draft/write | 策略 | M/R/U |
| 收支月日历 GET calendar | calendar_month,YYYY-MM | read | 无 | M/R/U |
| 单日日历明细 GET calendar/day | calendar_day,业务日和分页 | read | 无 | M/R/U:历史修改、转账排除、Decimal |
| 计划列表/状态 GET schedules | schedules_list,按到期排序分页;history_list 查看执行历史 | read | 无 | M/R |
| 新建/修改支出或转账计划 POST/PUT schedules | schedule_create/update | draft/write | 策略 | M/R:真实执行及编辑限制 |
| 启用/停用 PATCH schedules/:id | schedule_toggle | draft/write | 策略 | M/R |
| 删除计划 DELETE schedules/:id | schedule_delete,保留执行历史 | draft/write | 策略 | M/R |
| 按需运行到期计划 POST schedules/run | schedules_run,最多 20 项、hasMore;MCP 失败整批回滚 | draft/write | 策略,幂等事务 | M/C/R/U |
| 登录个人资料 GET auth/me | settings_get;connection_info 提供 Agent 授权资料 | read | 无 | M/C |
| 修改用户名和密码 PATCH auth/credentials | credentials_change_request → 网页 → operation_get | sensitive | 网站验证当前密码、输入新值,Agent 不收到密码 | C/R:真实密码登录、原会话轮换、Agent 降权结果查询 |
| 隐藏资产密码核验 POST auth/reveal | hidden_unlock_request → 网页 → operation_get | sensitive | 网页当前密码,当前连接 5 分钟 | M/R:锁定、隔离、失效规则 |
| 锁定隐藏资产 POST auth/lock | hidden_lock | draft/write | 策略;也可网页锁定 | M/R |
| 退出登录 POST auth/logout | connection_revoke 退出当前 MCP 连接;网页退出仍在原页面 | 当前连接认证 | 撤销是即时缩小授权,不受写入策略阻碍 | M/O/R:后续 401 |
| 注册/登录、网页 activity | OAuth 网页入口复用原注册/登录,Agent 令牌不依赖网页 Cookie;activity 为网页会话维护 | 网页认证/OAuth | 用户登录或注册及授权 | O/R、浏览器验证管理入口 |
| 图标搜索 GET icons | icons_list,60/页、q | read | 无 | M/C/R |
| 图标图片 GET icons/:id/image | icon_image → 同连接 Bearer GET | read | 无 | C/R:PNG 和归属 |
| 上传图标 POST icons/upload | file_upload_request(kind=icon) → POST file → icon_publish | draft/write;共享须 sensitive | 私有按策略;共享网页确认及中文名 | C/R:私有和共享实际保存 |
| 导出备份 GET backup | backup_export → 网页 → operation_get → Bearer 下载 | sensitive | 网页密码,短期授权入口 | M/R:完整 ZIP、隐藏数据、令牌排除、跨用户及未登录拒绝 |
| 上传备份 POST backup/upload | file_upload_request(kind=backup) → Bearer multipart → file_status | draft/write | 用户控制上传;不提交账目 | M/R:真实 ZIP 传输 |
| 预检 POST backup/preview | import_preview(token),上传同时预检 | read(上传需要 draft/write) | 不修改账目 | M/R/U:结构/校验/重复/冲突 |
| 追加恢复 POST backup/import、import-file | backup_import(token) → 网页 → operation_get | sensitive | 强制网页密码及数量/冲突预览 | M/R:真实恢复、重复冲突不改变数据 |
| 清空资格 GET backup/clear-status | data_clear_request 网页确认时复用现有备份资格及指纹 | sensitive | 网站先下载最新备份 | M/R |
| 清空财务数据 POST backup/clear | data_clear_request → 网页 → operation_get | sensitive | 密码、备份指纹及“确定清空” | M/R:未下载拒绝、真实清空、保留账号 |
| 新增接入管理、权限、PAT、撤销、调用日志和待确认页 | /api/agent 管理;connection_info、operation_get、state_get;OAuth 标准路径 | 网站身份/本连接 Bearer | PAT/策略验证密码;操作归属校验 | M/C/O、真实浏览器管理页 |
| 现有页面/API 与功能 | MCP 操作路径 | 权限 | 确认方式 | 验证 |
| --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------- | ---------------------------------------- | --------------------------------------------------------- |
| 账户/独立资产/债务列表 GET positions | positions_list:kind、名称、归档、方向、币种、分组、排序、offset/limit | read | 无 | M:查询、重名、分页和外用户隔离 |
| 项目详情 GET positions/:id | position_get | read | 隐藏项目须连接独立网页解锁 | M:当前余额、隐藏/外用户拒绝 |
| 创建项目 POST positions | position_create,保留账户/资产/债务初始绝对余额语义 | draft/write | 连接权限决定草稿或直接 | M/C:3 类对象、重复调用、无效金额、并发 |
| 按克数创建贵金属 POST metals/holdings | metal_holding_create | draft/write | 连接权限 | M/R/U/B:待估值、报价、成本盈亏、旧备份 |
| 元数据、分类、分组、图标、归档/恢复、隐藏、计入开关 PATCH positions/:id | position_update,完整 metadata;币种与方向固定 | draft/write | 连接权限 | M:分组、归档禁止金额更新与恢复;R:隐藏和开关 |
| 分组拖拽排序 PATCH settings | settings_update.accountGroupOrder | draft/write | 连接权限 | M/R:持久化、排序、备份 |
| 类别选项、名称与分组配置 | position_create/update;positions_list 读取现有值,Schema/描述提供规则 | read + draft/write | 连接权限 | M/R;当前没有独立分类/分组实体 CRUD |
| 新增余额、资产估值、负债余额及单边还款 POST revisions | balance_record,reason 区分;amount 为变更后余额 | draft/write | 连接权限 | M:精确余额;R/U:负债、估值、业务时间 |
| 历史全局/单项目 GET history、positions/:id/history | history_list.positionId、cursor、from/to | read | 无 | M/R:页大小、游标、前序余额、日期范围 |
| 更正普通历史 PUT revisions | history_update | draft/write | 连接权限 | M/R:重放、精度、日历联动 |
| 删除/撤销历史 DELETE revisions | history_delete;配对记录删除完整双边 | draft/write | 连接权限,destructive annotation | M/R:余额重算及双边撤销 |
| 债务关联账户/资产 PUT links | debt_links_set.targetIds | draft/write | 连接权限 | M:合法关联、隐藏目标拒绝;R:外用户拒绝 |
| 资金往来列表 GET transfers | movements_list:cursor、日期过滤 | read | 无 | M/R |
| 按历史找双边记录 GET transfers/revision/:revisionId | movement_by_revision | read | 无 | M/R |
| 转账、借入、借出、收款、还款 POST transfers | movement_create.operation:transfer/borrow/lend/collect/repay | draft/write | 连接权限,双边事务 | M:转账、repay、信用卡溢缴;R:全部 5 种语义;C:错误回滚 |
| 修改配对记录 PUT transfers/:id | movement_update | draft/write | 连接权限,后续历史重放 | M/R |
| 删除/撤销配对记录 DELETE transfers/:id | movement_delete | draft/write | 连接权限,双边撤销 | M/R |
| 净资产、总额、结构、变化归因 GET overview | overview_get,明细分页、保留全局总额 | read | 隐藏项目按本连接可见范围 | M/R/U:总额、开关、外币缺失 |
| 轨迹、日期与统计粒度 GET trend | trend_get:day/week/month 及 from/to | read | 无 | M/R/U:范围、首日、期末、归因 |
| 本位币、币种、实际汇率与更新状态 GET settings | settings_get,固定币种枚举且金额无浮点计算 | read | 无 | M/R/U |
| 本位币切换、显示菜单、备注、闲置退出、总览卡片、独立资产计入 PATCH settings | settings_update | draft/write | 连接权限 | M/R |
| 是否查看隐藏资产需密码 PATCH settings | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 自动/重试日汇率 POST rates/refresh | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 金银报价与状态 GET metals | metals_prices,最近 100 条 | read | 无;查询 MCP 不触发隐式自动更新 | M/U/R |
| 金银报价刷新 POST metals/refresh | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 贵金属手动报价 | 已从网页、REST、MCP 移除 | 无 | 无 | R:原 REST 路由 404;M:无工具 |
| 克数、品种、买入成本、自动估价 PUT metals/:id | metal_configure | draft/write | 连接权限 | M/R/U:估值历史和去重 |
| 应用估价 POST metals/:id/value | metal_value | draft/write | 连接权限 | M/R/U |
| 收支月日历 GET calendar | calendar_month,YYYY-MM | read | 无 | M/R/U |
| 单日日历明细 GET calendar/day | calendar_day,业务日和分页 | read | 无 | M/R/U:历史修改、转账排除、Decimal |
| 计划列表/状态 GET schedules | schedules_list,按到期排序分页;history_list 查看执行历史 | read | 无 | M/R |
| 新建/修改支出或转账计划 POST/PUT schedules | schedule_create/update | draft/write | 连接权限 | M/R:真实执行及编辑限制 |
| 启用/停用 PATCH schedules/:id | schedule_toggle | draft/write | 连接权限 | M/R |
| 删除计划 DELETE schedules/:id | schedule_delete,保留执行历史 | draft/write | 连接权限 | M/R |
| 按需运行到期计划 POST schedules/run | schedules_run,最多 20 项、hasMore;MCP 失败整批回滚 | draft/write | 连接权限,幂等事务 | M/C/R/U |
| 登录个人资料 GET auth/me | settings_get;connection_info 提供 Agent 授权资料 | read | 无 | M/C |
| 修改用户名和密码 PATCH auth/credentials | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 隐藏资产密码核验 POST auth/reveal | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 锁定隐藏资产 POST auth/lock | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 退出登录 POST auth/logout | connection_revoke 退出当前 MCP 连接;网页退出仍在原页面 | 当前连接认证 | 撤销是即时缩小授权,不受写入连接权限阻碍 | M/O/R:后续 401 |
| 注册/登录、网页 activity | OAuth 网页入口复用原注册/登录,Agent 令牌不依赖网页 Cookie;activity 为网页会话维护 | 网页认证/OAuth | 用户登录或注册及授权 | O/R、浏览器验证管理入口 |
| 图标搜索 GET icons | icons_list,60/页、q | read | 无 | M/C/R |
| 图标图片 GET icons/:id/image | icon_image → 同连接 Bearer GET | read | 无 | C/R:PNG 和归属 |
| 上传图标 POST icons/upload | file_upload_request(kind=icon) → POST file → icon_publish | draft/write;共享仅网站 | 私有按连接权限;共享仅网站 | C:私有保存及共享拒绝;R:网站共享保存 |
| 导出备份 GET backup | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 上传备份 POST backup/upload | 仅网站上传当前 ZIP v9,MCP 不发行备份上传入口 | 无 MCP 权限 | 网站预检与确认 | R:JSON 拒绝、ZIP 恢复及文件归属 |
| 预检 POST backup/upload 自动预检 | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 追加恢复 POST backup/import-file | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 清空资格 GET backup/clear-status | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 清空财务数据 POST backup/clear | 按用户最新要求仅在网站操作;MCP 不提供该流程 | 无 MCP 权限 | 网站原确认流程 | R/U;M:相关工具不存在且调用拒绝 |
| 新增接入管理、权限、PAT、撤销、调用日志和待确认页 | /api/agent 管理;connection_info、operation_get、state_get;OAuth 标准路径 | 网站身份/本连接 Bearer | PAT 创建验证密码;操作归属校验 | M/C/O、真实浏览器管理页 |
不存在的业务不列作“已实现”:单个持仓永久删除、账户注销、覆盖导入、批量删除、独立分类/分组对象 CRUD 均不在当前页面/API 中。历史删除、资金往来撤销、计划删除、归档及备份保护清空全部已有路径均已覆盖。
不存在的业务不列作“已实现”:单个持仓永久删除、账户注销、覆盖导入、批量删除、独立分类/分组对象 CRUD 均不在当前页面/API 中。历史删除、资金往来撤销、计划删除、归档仍由上述 MCP 工具覆盖;备份保护清空在网站保留,按最新要求退出 MCP 范围。
共享服务:PortfolioBusinessService、TransfersBusinessService、SchedulesBusinessService、CalendarBusinessService、SettingsBusinessService、MetalsBusinessService、IconsBusinessService、BackupBusinessService、AuthBusinessService。REST Controller 仅转发并保留原参数、文件拦截器、认证和路由;SDK Catalogue 调用同一服务,不复制金额或重放。
共享服务:PortfolioBusinessService、TransfersBusinessService、SchedulesBusinessService、CalendarBusinessService、SettingsBusinessService、MetalsBusinessService、IconsBusinessService。AuthBusinessService 与 BackupBusinessService 保留网站/REST 流程。REST Controller 仅转发并保留原参数、文件拦截器、认证和路由;SDK Catalogue 调用同一服务,不复制金额或重放。
金额状态、OAuth、scope、Origin/Host、文件生命周期和客户端限制见 [接入文档](mcp.md)。当前官方客户端验证通过;未验证其他产品配置和生产 HTTPS 反向代理。
+42 -97
View File
@@ -1,50 +1,42 @@
# WorthPath 远程 MCP 接入
## 开始使用
2026-10-04:服务提供 39 个工具。按用户最新要求,MCP 不再提供敏感操作、汇率或贵金属报价修改。网站保留备份、清空、密码修改和自动行情功能。完整覆盖矩阵见 [功能覆盖](mcp-coverage.md),本次迁移及验证见 [更新记录](update-agent-backup-2026-10-04.md)。
网站「设置与备份 → 连接 Agent」显示实际 MCP 地址、写入策略、OAuth 连接、个人令牌、待确认操作和最近调用。默认写入策略为草稿。现有网页登录、REST 和数据计算规则保留。
## 开始连接
1. 支持远程 OAuth 的客户端填写页面显示的 MCP 地址,选择 Streamable HTTP。
2. 客户端通过 `401 WWW-Authenticate` 或 `/.well-known/oauth-protected-resource/mcp` 发现授权服务。支持 OAuth 2.1 授权码、S256 PKCE、RFC 8707 resource、动态注册的公开客户端。
3. 浏览器进入 WorthPath,登录或注册,核对客户端名称、回调地址、资源和权限后授权。网站会回到注册的精确回调地址并保留 state。
4. 只请求需要的权限:`read` 查询;`draft` 创建草稿;`write` 普通写入;`sensitive` 发起敏感流程。所有授权包含 read。敏感权限仍要求网页验证当前密码,不能用工具参数确认。
5. 查询用稳定 UUID。写入先调用 `state_get`,把返回的 state 作为 `expectedState`,同时提供同用户唯一 `idempotencyKey`。状态变化后重新查询并使用新键;网络重试必须保持同键、同参数、同 expectedState。
6. 返回 pending 时打开 `confirmationUrl`,用户审核影响并提交或取消。Agent 使用 `operation_get(operationId)` 查询 completed、cancelled、expired 及最终结果。提交失败保留草稿并返回最近失败原因,用户可以重试或取消。
在「设置与备份 → 连接 Agent」复制实际 MCP 地址和“Agent 使用教程”。支持远程 OAuth 的客户端填写此地址,选择 Streamable HTTP;在 WorthPath 网页登录,审核客户端名称、回调地址、资源,并选择连接权限。网页会回到已注册的精确回调地址并保留 state。客户端自行验证 state。
密码只在网站填写。账号或密码修改后其他连接撤销,当前发起连接只保留 5 分钟 read 权限以读取完成结果,不可刷新;需要重新授权才能继续写入。隐藏资产解锁仅持续 5 分钟并限定当前连接,网站的解锁不自动授予 Agent。
OAuth 使用发现元数据、动态注册的公开客户端、授权码、S256 PKCE、RFC 8707 resource。每次 MCP 请求独立验证 Bearer;网页登录 Cookie、MCP 会话 ID 均不作为认证凭证。发现入口为 `/.well-known/oauth-protected-resource/mcp`,未授权响应提供 `WWW-Authenticate`。
## 贵金属按克数接入
| 连接权限 | OAuth/PAT scopes | 普通修改行为 |
| -------- | ---------------- | -------------------------------- |
| 只读 | read | 查询,拒绝修改和上传 |
| 草稿修改 | read draft | 保存十分钟草稿,由用户在网页确认 |
| 直接写入 | read write | 普通修改在事务中直接完成 |
新增 `metal_holding_create`:name、currency、metalType(gold/silver)、metalGrams、metalPurity、autoValuation、date,买入价 metalCostPerGram 可省略或 null;无需填写金额或市场价格。写入仍需 expectedState 和 idempotencyKey,并遵循写入策略。有对应业务日或更早报价时复用估值逻辑创建历史,没有报价时返回 valuationAvailable=false,查询总额 complete=false 与 missingValuations。position_get/list 返回可选 metalCost 和 metalProfit,均为原币十进制字符串。成本按实物重量计算,市场价值按重量×纯度×每克纯金属报价计算。
选择一种权限等级,draft 和 write 不能同时授予。没有网站全局写入策略。hidden_read 额外允许读取隐藏账户;hidden_write 额外允许修改,必须同时拥有 hidden_read 和 draft/write。两个附加权限默认关闭,OAuth 网页也可选择关闭。服务在查询和修改时分别构造业务上下文,网页解锁状态不自动授予 Agent。
metal_configure 省略 metalCostPerGram 保留旧成本,传 null 清除。克数或成本修改与其他写入一样参与并发状态校验;盈亏由共享业务服务计算,不存储额外浮点累计值。[更新与验证](update-metal-grams-2026-10-03.md)。
敏感操作(密码/账号修改、清空、备份导出恢复、公开图标发布、安全设置变更)仅在网站进行,不存在 sensitive scope。汇率和参考报价可以查询,MCP 不能修改或主动刷新。贵金属仍可按克数创建、设置成本和重量,并用已有报价更新资产估值;估值历史与报价是不同业务。
## 开发启动与环境
个人访问令牌仅作为支持自定义 Bearer 头客户端的补充。在网站验证当前密码,选择权限和 1、3、7、30 天、365 天或永久。完整值仅创建时展示,数据库只存 SHA-256 摘要。永久令牌数据库到期日为空,每个请求仍重新检查撤销和资源;为兼容 SDK 中间件,每次认证上下文有有限期验证断言,不改变令牌期限。永久令牌内部业务会话按天续期。OAuth 访问令牌一小时、刷新授权三十天,刷新时轮换摘要;不支持永久 OAuth。
```powershell
cd E:\WorthPath
.\scripts\pnpm.ps1 install
# 保留已有 apps/api/.env,按 .env.example 增加下面三项配置。
.\scripts\pnpm.ps1 db:generate
.\scripts\pnpm.ps1 db:migrate
.\scripts\pnpm.ps1 dev
```
旧连接有 write 时,现在直接执行普通修改;旧全局策略不再阻止它。只想创建草稿时,撤销旧连接并重新授权 read draft。历史策略行保留但不参与任何权限判断;旧敏感工具草稿不可提交。
生成 Prisma 前暂停 API,Windows 会锁定其引擎 DLL。迁移仅 deploy,不 reset。
## Agent 操作
| 变量 | 本地示例 | 用途 |
| ------------------- | ------------------------- | ---------------------------------------------------- |
| MCP_PUBLIC_URL | http://localhost:3100/mcp | 固定的 OAuth resource;生产必须 HTTPS,路径必须 /mcp |
| MCP_WEB_URL | http://localhost:5173 | 网页授权和操作确认入口;生产必须 HTTPS |
| MCP_ALLOWED_ORIGINS | http://localhost:5173 | 精确浏览器 Origin 列表,逗号分隔,不支持通配符 |
查询使用稳定 UUID;名称重名时先让用户选择。列表 limit 最大 100;图标固定 60;历史和资金往来使用 cursor。日期为 UTC+8 业务日期 `YYYY-MM-DD` 或 `YYYY-MM-DDTHH:mm`,返回时间戳使用 UTC ISO。金额、克数、汇率与报价为十进制字符串,沿用 Decimal 和 DECIMAL 规则。
生产继续要求 COOKIE_SECURE=true、准确的 WEB_ORIGIN。MCP 请求以独立 Bearer 验证,不接受网页登录 Cookie 作为授权,不把会话 ID 当凭证。未带 Origin 的非浏览器客户端允许接入;带 Origin 的请求必须匹配列表。Host 必须匹配规范资源地址。反向代理应传递规范的 Host,不以任意转发头构造资源 URL。
写入先 `state_get`,再传 expectedState、唯一 idempotencyKey 与具体工具参数。重试必须保持同键、同参数、同状态;状态冲突后重新查询并换键。同用户同键不同参数或不同连接明确拒绝。资金转账、借贷还款、资产估值和绝对余额录入保留原业务语义。
## 已验证的客户端配置
draft 返回 operationId、pending、confirmationUrl;用户在网站审阅影响后确认或取消,Agent 用 `operation_get` 查询最终结果。confirmed=true 不能绕过确认。提交重新检查权限、过期/撤销、账目版本、归属和业务规则。写入记录与业务修改在同一 Serializable 事务提交,失败回滚。MCP 到期计划按批事务执行,REST 原逐计划执行语义保留。
实际验证:官方 `@modelcontextprotocol/sdk@1.31.0`,StreamableHTTPClientTransport;Bearer PAT 和 OAuth 动态注册/发现/PKCE/刷新/撤销均经真实本地服务测试。服务协商 SDK 1.31.0 支持的协议,默认最新 `2025-11-25`。选择维护中的 v1 API 并精确锁定版本,未混用 v2 示例。[官方 SDK](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x)、[对应授权规范](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization)。
私有图标使用 `file_upload_request(kind=icon)` → 同一 Bearer multipart 上传 file → `file_status` → `icon_publish`。最多 2 MiB,入口十分钟有效,绑定用户和连接。`icon_image` 返回同一 Bearer 保护的短期图片入口。MCP 不发行备份文件入口。
下面是测试使用的官方 SDK 构造形式:
贵金属 `metal_holding_create` 无需填写市场金额;metalCostPerGram 可省略或 null。没有报价时 valuationAvailable=false,总额 complete=false 且包含 missingValuations。成本按实物重量计算,新持仓价值按重量×每克参考报价计算,既有持仓历史系数保留,盈亏由共享服务计算。metal_configure 省略成本保留旧值,null 清除。创建与配置均不接受 metalPurity 参数,新持仓使用默认比例 1;既有持仓的历史比例不改写。
## 已验证客户端
真实验证官方 `@modelcontextprotocol/sdk@1.31.0` 的 StreamableHTTPClientTransport:Bearer、OAuth 发现/DCR/PKCE、轮换、撤销与业务操作。精确锁定 v1 SDK,默认协议 2025-11-25。[官方 SDK](https://github.com/modelcontextprotocol/typescript-sdk/tree/v1.x)、[授权规范](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization)。
```typescript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
@@ -59,83 +51,36 @@ console.log(await client.listTools());
await client.close();
```
本项目提供只读协议诊断客户端,完整个人令牌在网站创建时仅展示一次:
OAuth 客户端使用 authProvider,浏览器回调后 finishAuth(code) 再连接;真实 provider 示例在 `apps/api/test/mcp.test.ts` 第三组。客户端安全保存 verifier、注册和令牌,禁止跨用户共享。
```powershell
$env:MCP_SERVER_URL='http://localhost:3100/mcp'
# 在本机终端设置 MCP_ACCESS_TOKEN;不要写进仓库或聊天。
# 在终端安全设置 MCP_ACCESS_TOKEN,不写入仓库或聊天。
pnpm --filter @worthpath/api mcp:probe
Remove-Item Env:MCP_ACCESS_TOKEN
```
OAuth 客户端使用 `authProvider` 代替手工 Bearer 头;实现 SDK 的 OAuthClientProvider,在 `redirectToAuthorization` 打开浏览器,在回调后调用 transport.finishAuth(code) 再连接。真实的 provider、发现和交换实现见 `apps/api/test/mcp.test.ts` 第三组测试。生产客户端还应独立校验 state,安全持久化 verifier、客户端注册和令牌,禁止跨用户共享。WorthPath 返回原 state,但客户端必须自行验证。
未验证 MCP Inspector、Claude、ChatGPT、Cursor、Codex 等商业客户端的配置和 OAuth 实际行为,不提供推测配置。生产 HTTPS 代理未部署验证。
没有验证 MCP Inspector、Claude、ChatGPT、Cursor、Codex 或其他产品的实际 OAuth/config 格式,不提供猜测配置或普遍兼容承诺。HTTPS 代理环境也未实际部署验证。
## 启动与部署
## 写入、权限和一致性
| 用户策略 | draft 权限 | write 权限 | sensitive 权限 |
| ------------- | ------------- | ------------- | -------------------------------------------------- |
| readonly | 拒绝写入/上传 | 拒绝写入/上传 | 仅允许网页确认的完整备份导出和隐藏解锁,不修改账目 |
| draft(默认) | 保存草稿 | 保存草稿 | 强制网页确认 |
| direct | 保存草稿 | 执行普通写入 | 强制网页确认 |
草稿 10 分钟到期,保存用户、连接、具体参数、账目摘要和状态。提交重新检查连接过期/撤销、scope、当前策略、账目状态、数据归属及业务规则。`confirmed=true` 被严格 Schema 拒绝。修改隐藏密码要求的设置、发布共享图标也升级为敏感确认。
幂等记录和业务变更在同一 Serializable 数据库事务提交,用户唯一键保证重试不重复入账。同键不同参数或不同连接明确拒绝。所有普通直接写入和草稿提交通过状态摘要防止覆盖 REST 或其他 Agent 的并发修改。状态包括全部用户账目、历史、计划、汇率、金属报价及相关设置,只返回摘要,不返回隐藏数据。
复用现有 Decimal、余额计算、转账和历史重放。AsyncLocalStorage 仅保存当前数据库事务,认证信息来自每请求的 Bearer 上下文。现有服务中的嵌套事务加入 MCP 外层事务;MCP 计划执行任一失败会回滚整批,REST 仍保留逐计划执行和失败列表语义。
金额为十进制字符串,现有 DECIMAL(24,8) 和报价/汇率 DECIMAL(24,12) 保留。`balance_record.amount` 为绝对余额;转账本金/到账/手续费是增量。负债账户数据库正数为欠款,负数为溢缴存款;网站显示相反符号。独立资产和借贷本金非负。业务日期 `YYYY-MM-DD` 或 `YYYY-MM-DDTHH:mm` 为 UTC+8;返回时间戳为 UTC ISO。计划 nextAt 可在未来,余额记录日期不可在未来。
查询页 limit 最多 100;图标固定 60;历史和资金往来使用 cursor,列表使用 offset。净资产轨迹沿用范围上限:日 366 天、周 3 年、月 10 年。金属和汇率返回最近 100 条。大备份通过文件入口传输。
## 备份、图标和敏感操作
备份追加:`file_upload_request(kind=backup)` → 使用返回 URL 和当前 Bearer 以 multipart/form-data 的 file 字段上传 ZIP/旧 JSON → 获取 token 或 `file_status` → `import_preview` → `backup_import` → 网页核对影响并验证密码 → `operation_get`。文件上传上限 512 MiB,ZIP 解压上限沿用现有 1 GiB;实际预检与追加恢复沿用现有严格校验和事务,任何冲突不修改账目。
完整导出:`backup_export` → 网页密码确认 → `operation_get` 获得 10 分钟有效的 GET URL → 同一连接 Bearer 下载 ZIP。URL 单独不可下载,其他用户/连接不可下载,账目变化必须重新确认。备份包含隐藏项目,但不含密码、Cookie 或 MCP 令牌。Agent 授权、草稿和调用日志不属于财务备份。
图标:`file_upload_request(kind=icon)` 上传不超过 2 MiB 的图像 → `icon_publish` 保存私有图标;shared=true 需敏感权限、中文名称、网页明确确认 → `icon_image` 获取受 Bearer 保护的 PNG URL。
清空数据:`data_clear_request` → 网页展示项目/历史/计划数量 → 先在网页下载最新备份 → 验证当前密码并输入“确定清空” → 提交 → `operation_get`。已有备份指纹与 10 分钟有效期规则保留,任何账目变化都要求重新备份。登录账号和共享图标保留。
当前产品不存在账户注销、任意单个持仓删除、覆盖导入、批量删除和另外的分类实体;因此不新增此类业务。已有删除路径是历史、资金往来、计划删除及备份保护的全量清空,完整支持。名称、分组、分类、图标、归档和统计开关通过 position_update/settings_update 设置。完整覆盖和逐项证据见 [覆盖矩阵](mcp-coverage.md)。
## 服务和代理
采用无状态 Streamable HTTP:每个 POST 新建 server/transport,独立 Bearer 认证;关闭响应时释放 transport。响应为 SDK 标准 JSON MCP 结果,支持初始化、协商、工具发现和调用。GET/DELETE 返回 405,没有长期 SSE 会话或会话凭证。当前没有订阅通知需求。
现有备份上传及 MCP 文件票据在进程内,10–15 分钟过期;进程重启或切换节点后需重新上传/生成入口。**当前部署必须单 API 实例**,不能直接在多节点间轮询文件请求;OAuth、令牌、草稿、幂等和审计本身已持久化。日志不保存工具参数、密码、令牌或财务内容,管理页只展示用户自己的最近 100 条。
反向代理参考(示例未经实际部署,修改为自己的 HTTPS 域名及上游):
```nginx
location = /mcp {
proxy_pass http://127.0.0.1:3100;
proxy_set_header Host $host;
proxy_buffering off;
proxy_read_timeout 330s;
proxy_send_timeout 330s;
}
location /api/ {
proxy_pass http://127.0.0.1:3100;
proxy_set_header Host $host;
client_max_body_size 512m;
proxy_read_timeout 330s;
}
# 同样代理 /.well-known/、/authorize、/token、/register、/revoke。
# 前端静态站点与 MCP_WEB_URL 应位于已配置的 HTTPS origin。
```powershell
cd E:\WorthPath
.\scripts\pnpm.ps1 install
# 生成 Prisma 前暂停 API,Windows 会锁定引擎 DLL。
.\scripts\pnpm.ps1 db:generate
.\scripts\pnpm.ps1 db:migrate
.\scripts\pnpm.ps1 dev
```
用户认证数据不进入全局共享变量。SDK OAuth 路由包含进程内限流,现有登录限流也保留,已认证动作按用户及来源 IP 限流。生产单实例应另外配置代理级流量限制和日志保留策略;不得在代理访问日志中记录 Authorization、上传正文或敏感查询参数。数据库账号需要现有 DDL 迁移权限及正常业务 DML 权限。
| 环境变量 | 本地示例 | 用途 |
| ------------------- | ------------------------- | ------------------------------------ |
| MCP_PUBLIC_URL | http://localhost:3100/mcp | 规范资源 URL,路径必须 /mcp |
| MCP_WEB_URL | http://localhost:5173 | 网页授权及草稿确认入口 |
| MCP_ALLOWED_ORIGINS | http://localhost:5173 | 精确 Origin 列表,逗号分隔,无通配符 |
## 实际验证与交付
本次没有新增环境变量。保留本机 .env;示例不含凭据。生产必须 HTTPS、COOKIE_SECURE=true、准确 WEB_ORIGIN。Host 匹配规范资源;带 Origin 的请求匹配白名单,无 Origin 的非浏览器客户端允许接入。不得用任意转发头构造授权地址。
迁移:`20261003090000_agent_access` 新增授权/令牌/策略/操作 5 表;`20261003100000_agent_audit` 新增无参数调用审计;`20261003110000_agent_comments` 补齐 6 张新表字段的 MySQL 注释。原有财务表与记录保留。已经 migrate deploy,未执行 reset。
服务采用无状态 Streamable HTTP,请求结束关闭 transport/server;不共享用户认证上下文,不支持长期 GET SSE 或持久会话。代理转发规范 Host,禁用 MCP 响应缓冲,超时建议 330 秒;同时代理 /.well-known/、/authorize、/token、/register、/revoke 和 /api/。网站备份上传上限 512 MiB,ZIP 解压总计 1 GiB,代理配置对应 body 限制。日志不能保存 Authorization、密码、令牌或上传正文。
主要修改:原 8 个业务模块及 auth 抽取 BusinessService;database 增加事务上下文;新增 `src/mcp/{oauth,catalogue,operations,files,management,transport}.ts`;设置页新增 AgentConnections;SDK 精确版本和 pnpm lock;新增真实 MCP 测试及只读 probe。
实际通过:前后端 typecheck/build、36 项单元检查、18 组真实 REST/MySQL 回归、3 组真实官方 MCP SDK 端到端检查,工具发现验证 49 个工具(原 mcp:probe 的 48 个工具上增加 metal_holding_create)。新迁移 deploy 成功,实际 MySQL 17 张表(含 Prisma 迁移表)、159 个字段注释完整。测试真实连接 MySQL,使用随机临时用户并清理,未替代现有 REST 回归。贵金属创建、待估值、买入成本、盈亏及报价完成后的页面自动同步已通过真实浏览器验证,测试用户已清理。端到端文件传输、事务回滚、归属、金额精度、幂等、并发、失效/撤销和 OAuth 均在测试中检查;外部行情源的正常和失败路径由原业务单元测试验证,不保证外部报价服务实时可用。
部署未执行;未推送代码;其他客户端及实际 HTTPS/代理兼容性尚未验证。
当前实际通过前后端类型检查/构建、34 项单元测试、18 组 REST/MySQL、4 组官方 SDK 测试。24 项迁移已 deploy;17 张表、159 个字段注释完整。未部署或推送。
+2
View File
@@ -1,5 +1,7 @@
# 2026-10-02 更新验收与使用
> 历史验收记录:2026-10-04 起所有旧备份兼容与单文件 JSON 支持已删除,当前仅接受 ZIP v9;本文旧版本测试记录不代表现行功能。现行 MCP 权限与工具范围见 [本次更新](update-agent-backup-2026-10-04.md)。
## 本次范围
按主目录 `update.md` 的要求完成 13 项代码更新,包括执行期间追加的红色金额和收支日历;完成时间为 2026-10-02 17:37(Asia/Hong_Kong)。
+2
View File
@@ -1,5 +1,7 @@
# 2026-10-03 账号、删除与备份更新
> 历史验收记录:2026-10-04 起所有旧备份兼容与单文件 JSON 支持已删除,当前仅接受 ZIP v9;本文旧版本测试记录不代表现行功能。现行 MCP 权限与工具范围见 [本次更新](update-agent-backup-2026-10-04.md)。
## 已完成
- 设置分类新增“账号与密码”。可单独修改账号、密码或同时修改,须验证当前密码;新密码须二次输入。服务端沿用账号格式、密码长度和认证限流,重复账号返回冲突;在事务中撤销全部旧会话并重新签发当前会话,财务数据和个人设置保留。
+60
View File
@@ -0,0 +1,60 @@
# 2026-10-04 Agent、备份与界面更新
本次按 update.md 和聊天补充要求完成。MCP 工具由 49 个调整为 39 个;敏感操作与汇率、贵金属报价修改退出 MCP 范围。该范围变更取代最初的全部业务 MCP 覆盖要求,网站原业务入口保留。
## 用户使用
进入「设置与备份 → 连接 Agent」。默认仅显示服务地址与复制教程,其他内容分为「权限与工具」「连接管理」「操作记录」。教程、SDK 配置与个人令牌表单按需展开。工具清单来自实际后端注册内容。复制教程不会包含密码或令牌。
OAuth 授权选择只读、草稿修改或直接写入;个人令牌创建也选择相同三档。read 为必需基础权限;draft 与 write 互斥。隐藏账户读取与修改为独立附加授权,默认关闭;修改还要求读取权限及 draft/write。网页解锁不会自动授予 Agent。旧全局策略入口及运行时判断已移除;已有 write 连接现在直接执行普通修改,如需草稿应撤销并重新授权 read draft。
个人令牌期限为 1、3、7、30、365 天或永久;只展示一次完整值,数据库保存摘要。永久令牌每次请求检查资源与撤销;内部会话有界续期。OAuth 仍使用一小时访问令牌和三十天刷新授权,刷新轮换。实际接入步骤、环境示例和经过验证的官方 SDK 配置见 [MCP 接入](mcp.md)。
贵金属手动报价入口已从网页、REST 与 MCP 删除。创建、编辑和 MCP Schema 也不再提供纯度输入,新持仓按默认比例 1 估值;保留已有比例、报价来源及历史金额,不静默改写既有账目。重量、可选买入成本、盈亏、自动估值和网站报价刷新保留。账户卡片不重复显示分组徽标,分组标题、筛选与排序保留。
## 仅支持当前 ZIP v9
网站「备份与恢复」下载新的 ZIP,并通过上传预检、影响预览、确认追加恢复。单文件 JSON(包括 v3)全部拒绝;ZIP v3–v8 也拒绝,不保留补字段、缺文件回退或版本分支。旧 /api/backup/import 与 /api/backup/preview JSON 路由删除;仅保留 /api/backup、/upload、/import-file 与原清空资格流程。
ZIP 内仍有可读 JSON 数据文件及校验摘要,但不能将单文件 JSON 作为备份上传。manifest version=9,所有当前文件、设置和元数据必须完整。上传 512 MiB、解压总计 1 GiB;文件绑定用户与会话、十五分钟失效。预检失败删除临时上传;正式恢复冲突或失败在事务中回滚。
升级前导出的旧备份无法再导入,请从升级后的网站重新导出。此次没有删除用户保存的备份文件,也没有改写财务记录。备份操作仅在网站完成,MCP 不提供导出、恢复或备份上传。
## 迁移、文件与启动
两项新增迁移已在本机 MySQL 应用:
- 20261004090000_agent_permanent_tokens:AgentGrant.expiresAt 可为空,表示可撤销的永久 PAT。
- 20261004103000_agent_connection_permissions:更新权限字段及已停用策略表的说明,不删除旧策略行。
自动审批拒绝了 DROP TABLE 和批量取消待确认操作的提案,原因是具体数据副作用未获授权。因此采用保留原数据的实现;历史 AgentPolicy 表不参与权限判断,已撤下工具的旧草稿无法提交。未执行 reset、drop 或批量取消。
当前 24 项迁移状态最新;17 张表(含 Prisma 迁移表)、159 个字段注释全部核验通过。核验清单在 [database-comments.json](database-comments.json)。无新增环境变量、无新依赖、无硬编码数据库或授权凭据。
主要修改文件组:
- API:backup.ts、backup-format.ts、zip.ts、metals.ts、openapi.ts。
- MCP:catalogue.ts、oauth.ts、operations.ts、files.ts、management.ts、transport.ts、information.ts。
- 网页:AgentConnections.tsx、MetalPanel.tsx、App.tsx、style.css 及两份翻译字典。
- 数据:Prisma Schema 和两项迁移。
- 测试:ZIP、MCP、贵金属与设置及所有使用备份恢复的 REST 测试;backup-fixture.ts 将测试数据打包成 ZIP,实际调用上传/确认 API,没有调用已删除 JSON 路由。
```powershell
cd E:\WorthPath
# 暂停 API 后生成客户端;保留现有 apps/api/.env。
.\scripts\pnpm.ps1 db:generate
.\scripts\pnpm.ps1 db:migrate
.\scripts\pnpm.ps1 dev
```
现有开发地址 http://localhost:5173,MCP http://localhost:3100/mcp。本次隔离回归用 3101/3102;临时测试服务完成后关闭。没有修改本机 .env,没有部署或推送。README、update.md 原有删除及 Vite 的用户修改保持未提交,只提交与此次功能直接相关的文档更改。
## 实际验证
- 前后端 typecheck 与生产 build 通过。
- 34 项单元测试通过:精确金额、历史重放、行情失败保留、完整 ZIP 校验、旧版本拒绝、大量记录、无缺字段回退。
- 18 组真实 REST/MySQL 通过:全部原业务、配对余额、历史、计划、隐私、设置和 ZIP 恢复;实际上传 JSON v1/v2/v3/v9 都返回 400,旧 JSON 路由返回 404,目标数据不变。
- 4 组官方 SDK 1.31.0 MCP 测试通过:39 工具、初始化/发现/调用、普通写入和草稿、幂等/并发/回滚、只读拒绝写入、隐藏读取不授予修改、永久令牌会话续期、期限和撤销、资源/来源限制、OAuth DCR/PKCE/一次性码/轮换及越范围授权拒绝。
- 临时账户真实浏览器验证:默认页面分区、折叠表单、固定期限、三档权限、隐藏权限默认关闭、复制教程成功提示、账户卡片无分组徽标,贵金属新增与编辑无纯度或手动报价输入。截图在工作区外的验证目录,docs 不保存图片;临时用户及虚构账户清理。
没有验证商业 Agent 配置、MCP Inspector 或生产 HTTPS 反向代理;未声称所有客户端兼容。外部行情供应商实时可用性不作为本次通过条件。完整当前功能覆盖与撤下项见 [覆盖矩阵](mcp-coverage.md)。
+2
View File
@@ -1,5 +1,7 @@
# 2026-10-03 分组拖拽与账户分行
> 历史验收记录:2026-10-04 起所有旧备份兼容与单文件 JSON 支持已删除,当前仅接受 ZIP v9;本文旧版本测试记录不代表现行功能。现行 MCP 权限与工具范围见 [本次更新](update-agent-backup-2026-10-04.md)。
## 使用方式
分组排序弹窗移除上下移动按钮,改为带拖拽手柄、分组名称和序号的列表。按住手柄拖到目标位置即可调整顺序,拖拽时高亮当前分组,靠近列表边缘自动滚动。点击保存后,账户页、分组筛选及账户选择弹窗同步使用新顺序;取消弹窗不会保存。
+2
View File
@@ -1,5 +1,7 @@
# 2026-10-03 账户分组排序
> 历史验收记录:2026-10-04 起所有旧备份兼容与单文件 JSON 支持已删除,当前仅接受 ZIP v9;本文旧版本测试记录不代表现行功能。现行 MCP 权限与工具范围见 [本次更新](update-agent-backup-2026-10-04.md)。
当前排序界面已改为拖拽;最新操作及全部账户分行行为见 [后续更新](update-group-drag-2026-10-03.md)。以下保留首轮验收记录。
## 使用方式
@@ -1,5 +1,7 @@
# 账户转账、计入总览与贵金属估价
> 历史验收记录:2026-10-04 起所有旧备份兼容与单文件 JSON 支持已删除,当前仅接受 ZIP v9;本文旧版本测试记录不代表现行功能。现行 MCP 权限与工具范围见 [本次更新](update-agent-backup-2026-10-04.md)。
完成与验收:2026-10-03 18:56(UTC+8)。
## 账户转账
+2
View File
@@ -1,5 +1,7 @@
# 贵金属克数与数据库注释更新
> 历史验收记录:2026-10-04 起所有旧备份兼容与单文件 JSON 支持已删除,当前仅接受 ZIP v9;本文旧版本测试记录不代表现行功能。现行 MCP 权限与工具范围见 [本次更新](update-agent-backup-2026-10-04.md)。
独立资产新增弹窗选择「贵金属」后,填写黄金/白银、克数、纯度、原币和业务时间,无需填写金额或市场单价。默认随参考价自动估值;没有有效报价时为「待估值」,总览提示不完整,不把未知价值作为已知零值。后续自动/手动报价继续沿用现有 MetalsService 和历史逻辑。
买入价为可选的每克实物成本(原币)。成本 = 总克数 × 买入价;估值 = 总克数 × 纯度 × 对应币种纯金属每克报价;盈亏 = 当前估值 − 成本。全程 Decimal,金额 8 位小数四舍五入;每克成本最多 12 位整数、12 位小数且必须大于零。它是估值盈亏,不包含未记录的税费/已实现卖出收益。省略或清空价格不显示盈亏,缺少估值时盈亏待定。旧贵金属资产可在详情补充成本。