🔴 严重问题

以下问题影响数据安全或核心功能,需优先修复。

P01 — CSV 覆盖式导入,数据不可恢复

APIPOST /api/transactions/:billId/upload

🔍 问题描述

上传 CSV 文件后,后端执行的是 先删后插 策略:

DELETE FROM transactions WHERE bill_id = :billId;
-- 批量 INSERT 新数据

⚠️ 影响

  • 旧数据全部被不可恢复地删除
  • 用户误上传、空文件上传、列错位上传都会导致数据全部丢失
  • CSV 上传没有"追加"模式

💡 改进建议

  • 提供"追加模式"与"覆盖模式"两个选项
  • 覆盖前先备份旧数据到 transactions_archive
  • 上传前做数据校验,校验失败则不删除旧数据

P02 — 邀请成员无通知机制,功能不可用

APIPOST /api/bills/:id/invite

🔍 问题描述

邀请流程只有插入 bill_invitations 记录,但:

  • 不发送短信/邮件/站内通知
  • 被邀请人在 notifications 表中无任何记录
  • 被邀请人登录后不知道有邀请存在
  • bill_invitations 表24h 过期但整个流程无人触发

⚠️ 影响

  • 邀请功能对被邀请人完全无感知
  • owner 邀请成员永远不会成功
  • 邀请记录24h 后自动失效,但用户不知道

💡 改进建议

  • 发送短信/邮件/站内通知给被邀请人
  • notifications 表插入通知记录
  • 被邀请人登录后弹窗/横幅提示待确认邀请

P03 — 图形验证码存内存 Map,重启后失效

APIGET /api/auth/login-captcha · GET /api/auth/register-captcha

🔍 问题描述

验证码 ID 和答案存在内存 Map 中,服务器重启后全部清空。用户拿到的 captchaId 在重启前一直有效(正常),但服务器重启后 map.get(captchaId) 永远返回 undefined。

⚠️ 影响

  • 服务器重启后,所有已发出的图形验证码 ID 全部失效
  • 用户输入正确的图形验证码答案,但后端 map 中已无此 ID
  • 登录/注册页面显示验证码但提交永远失败
  • 临时修复:前端需引导用户刷新页面重新获取验证码

💡 改进建议

  • 将验证码存储到数据库 captchas 表(captchaId, answer, expires_at, ip)
  • 或使用 Redis 等持久化 KV 存储
  • 图形验证码与 IP 绑定(防刷)