153 lines
9.7 KiB
Markdown
153 lines
9.7 KiB
Markdown
# 善缘丹阳 V1.1 项目重新审查报告
|
||
|
||
> 审查日期:2026-09-09
|
||
> 审查范围:`docs` 产品与技术基线、后端、微信小程序、运营管理后台、数据库迁移、自动化测试、本地部署
|
||
> 审查原则:只把“能构建、能运行、能通过有效测试、符合业务不变量”的成果计为完成
|
||
|
||
## 一、结论
|
||
|
||
当前项目不具备进入正式 UAT 或上线准备阶段的条件。数据库迁移和大部分模块骨架已经建立,但前端运行链路、后端权限边界、核心业务闭环与测试可信度存在发布阻断问题。
|
||
|
||
建议将当前 V1.1 状态从“核心功能 100% 完成”纠正为:
|
||
|
||
| 口径 | 评估值 | 说明 |
|
||
|---|---:|---|
|
||
| 文件/模块存在度 | 约 70% | 多数模块、表、控制器和页面文件已经出现 |
|
||
| 可验证功能完成度 | 约 35% | 多个页面未进入真实运行链路,接口存在占位实现 |
|
||
| 发布就绪度 | 不高于 15% | P0 权限问题、编译错误、无效测试尚未清零 |
|
||
| 相对现有“100%”声明的偏移 | 约 -65 个百分点 | 现有完成报告主要按文件存在和接口返回成功计数 |
|
||
|
||
本评估是基于抽样复现的项目管理基线,不是代码行数统计。后续每个 Phase 必须以自动化验收证据重新计量。
|
||
|
||
## 二、证据摘要
|
||
|
||
### 1. 可确认的真实进展
|
||
|
||
- PostgreSQL 中 `flyway_schema_history` 显示 V001~V027 全部成功应用。
|
||
- 本地 Backend、Admin Web、PostgreSQL、Redis、MinIO 容器均在运行,Backend 健康检查正常。
|
||
- 后端已形成模块化单体基本结构,V1.1 的 banner、local eligibility、counseling、content、service program、activity mutual 等包和迁移文件存在。
|
||
- 管理后台可以登录并打开工作台;V1.1 菜单项已部分接入。
|
||
- 小程序已存在本地资格、咨询、婚前辅导、活动互选等新增页面文件。
|
||
|
||
### 2. 发布阻断问题
|
||
|
||
#### P0-01:后台权限只做“已登录”检查,没有接口级权限控制
|
||
|
||
- `PermissionFilter` 将全部 `/api/v1/operator/**` 映射为同一个 `operator_login` 权限。
|
||
- 没有按 `banner.manage`、`counseling.manage`、`user.view` 等权限码保护后端接口。
|
||
- 实测 `service_station_operator` 可成功访问咨询待分配队列和 V1.1 全局统计接口。
|
||
- `/counseling/services/operator/**` 位于用户路径下,绕过 `/operator/**` 权限过滤。
|
||
|
||
影响:违反 INV-012、INV-013、INV-018、INV-019、INV-020,并使前端菜单隐藏失去安全意义。
|
||
|
||
#### P0-02:服务预约存在 IDOR 与代用户创建风险
|
||
|
||
- `ServiceAppointmentController.create` 优先采用请求体 `userId`,普通已登录主体可指定其他用户。
|
||
- `ServiceAppointmentService.getAppointmentDetail` 接收 `viewerUserId` 但未校验预约归属。
|
||
- 后台查询接口把 `operatorId` 当作用户 ID 查询“我的预约”,没有站点数据范围控制。
|
||
|
||
影响:用户可能读取或创建不属于自己的预约记录,服务站人员也没有真正的 Assigned/Station Scope。
|
||
|
||
#### P0-03:咨询权限与状态机未落地
|
||
|
||
- 咨询的排期、开始、跟进、完成、关闭方法不校验当前咨询师是否为 Assigned Operator。
|
||
- 状态变更没有严格校验前置状态,可跨状态调用。
|
||
- DTO 默认带出全部 followup 正文,没有按角色裁剪字段。
|
||
- 风险日志写入用户咨询摘要,存在敏感内容进入日志的风险。
|
||
|
||
影响:核心隐私硬规则和 Counselor Assigned Service 规则未满足。
|
||
|
||
#### P0-04:活动互选二阶段流程没有创建 Match/Conversation 的闭环
|
||
|
||
- `ActivityMutualConsentService.confirmConnection` 只更新双方确认状态。
|
||
- 双方确认后没有创建或复用 Match,也没有创建 Conversation。
|
||
- `hasActiveMatch` 方法存在但未用于确认事务;Prior Unmatch 新建 Episode 未实现。
|
||
- `detectMutualResults` 查询的是“双方已确认”,与“互选结果等待双方确认”的概念混淆。
|
||
|
||
影响:INV-014/INV-015 的后半闭环缺失,活动互选成功后无法进入安全聊天。
|
||
|
||
### 3. 前端运行链路问题
|
||
|
||
#### 管理后台
|
||
|
||
- `npm run type-check` 失败:`CounselingView.vue` 存在语法错误,完成操作包含残缺的 `post(, {})`。
|
||
- 菜单存在 `/counseling`,但路由表没有注册该页面;实测点击后整页空白。
|
||
- 前端咨询接口使用 `/operator/counseling/services/...`,后端实际为 `/counseling/services/operator/...`。
|
||
- `npm run build` 会成功,但 Vite 构建不执行类型检查,当前 CI 也只执行 build,因此错误被掩盖。
|
||
- 工作台信息密度低、指标全为 0、导航过长且缺少业务分组;这属于第二阶段体验问题,必须在功能链路修复后处理。
|
||
|
||
#### 微信小程序
|
||
|
||
- `project.config.json` 明确关闭 TypeScript 编译插件,实际运行 `.js` 文件。
|
||
- 13 个页面同时保留 `.ts` 与 `.js`,两套实现发生漂移。
|
||
- 首页 `index.wxml` 是 V1.1 结构,但运行中的 `index.js` 仍是旧版每日推荐逻辑,不请求 `/home`,且缺少多数 V1.1 事件处理。
|
||
- `index.ts` 虽包含新版逻辑,但当前配置不会将其作为运行源;其中多个入口仍错误跳往本地资格页。
|
||
- `npx tsc --noEmit` 失败,活动互选、咨询、婚前辅导页面存在变量重复和错误的请求返回类型。
|
||
- 文档要求的 U49~U64 中,公益服务中心、服务站、服务预约、我的预约、婚恋课堂、文章详情、婚恋反诈、专项服务、公益服务记录等页面尚未形成完整页面目录。
|
||
- 首页固定结构缺少“婚恋课堂”内容区,后端 `articles` 直接返回空列表。
|
||
|
||
### 4. 后端占位与错误路由
|
||
|
||
- 首页 `verified` 被硬编码为 `true`。
|
||
- 今日推荐始终返回空列表,没有复用现有推荐引擎。
|
||
- 首页服务站返回硬编码对象,没有读取 `service_locations`。
|
||
- 5 个核心入口和多处 CTA 都跳到本地资格页。
|
||
- 服务端没有独立、可复用的 `CapabilityService`;能力判断散落在首页聚合服务内,也没有完整接入 Feature Flag。
|
||
|
||
### 5. 测试可信度问题
|
||
|
||
- `tests/e2e` 没有 `conftest.py`,大量测试引用不存在的 fixture,测试启动即报错。
|
||
- 首页、咨询权限、活动互选、本地资格、预约等测试中存在大量空 `pass` 和“实现后完善”注释。
|
||
- `V11InvariantsTest` 大多只断言常量存在,例如用文章状态常量“证明”Content Editor 无用户权限,不能验证业务不变量。
|
||
- `run_v11_tests.py` 使用管理员令牌调用用户接口,掩盖主体类型隔离问题。
|
||
- 首页 8 入口测试只判断元素存在,不判断精确顺序。
|
||
- 转介测试允许成功或失败,只打印结果而不失败。
|
||
- 本轮复跑结果:`run_v11_tests.py` 为 15 通过、1 失败;其余 E2E 在前 5 个用例即因 fixture 缺失报错。
|
||
- Backend Dockerfile 使用 `mvn package -DskipTests -Dmaven.test.skip=true`,容器镜像构建明确跳过测试。
|
||
- 当前主机没有可用 JDK/Maven,且仓库没有可用的 Java 测试报告,因此本轮无法复现后端单元测试结论。
|
||
|
||
### 6. 项目治理问题
|
||
|
||
- 当前目录不是可识别的 Git 工作区,无法核验提交历史、变更来源和未提交修改。
|
||
- `docs/STATUS.md` 同时把相同模块标为“已完成”和“待开发”,并重复记录 Phase 21/22 与多次部署完成结论。
|
||
- Completion Report 的生成速度与验证证据不匹配,完成口径偏向“文件已创建”。
|
||
- 文档版本、Backend 版本、Admin 版本仍混用 1.0.0-RC.1、1.0.0-RC.2、1.1.0-dev、1.1.0-RC.1。
|
||
|
||
## 三、分域进度重估
|
||
|
||
| 领域 | 文件存在度 | 可验证完成度 | 结论 |
|
||
|---|---:|---:|---|
|
||
| 文档与数据库设计 | 90% | 65% | 基线完整,但状态文档失真 |
|
||
| 数据库迁移 | 95% | 80% | V001~V027 已应用;仍需约束与回滚验证 |
|
||
| 后端基础模块 | 80% | 45% | CRUD 骨架较多,权限和状态机严重不足 |
|
||
| 首页聚合 | 70% | 25% | 多处硬编码、空数据和错误跳转 |
|
||
| 本地资格 | 65% | 30% | 数据结构存在,证据权限未被有效测试 |
|
||
| 咨询/婚前辅导 | 70% | 20% | 后端骨架存在,权限、路由、前端均未闭环 |
|
||
| 活动互选二阶段同意 | 65% | 25% | 状态表存在,Match/Conversation 事务缺失 |
|
||
| 服务站/预约 | 65% | 20% | 存在 IDOR 与数据范围问题 |
|
||
| 内容/专项服务 | 60% | 25% | CRUD 文件存在,小程序消费页面缺失 |
|
||
| 管理后台 | 65% | 30% | 可登录,但关键页面空白且类型检查失败 |
|
||
| 微信小程序 | 55% | 20% | TS/JS 双轨漂移,V1.1 首页实际未运行 |
|
||
| 自动化测试 | 45% | 10% | 文件很多,但大量为空壳或无法执行 |
|
||
| 部署运维 | 70% | 35% | 本地容器运行,镜像构建跳过测试 |
|
||
|
||
## 四、视觉与体验抽查
|
||
|
||
本轮通过本地浏览器实际检查了三个步骤:
|
||
|
||
1. 登录页:可用但品牌层级普通,表单对比度偏低;健康度“可用”。
|
||
2. 管理工作台:能展示导航和卡片,但全零指标、缺少任务优先级与业务分组,难以支持日常运营;健康度“较差”。
|
||
3. 婚恋咨询入口:点击后为空白页;健康度“阻断”。
|
||
|
||
局限:本轮未通过微信开发者工具运行小程序,移动端视觉结论仅基于源码结构与编译结果,不能替代真机可用性、触控目标、读屏和对比度测试。
|
||
|
||
## 五、立即执行的管理决策
|
||
|
||
1. 暂停 Phase 24~26 和任何上线表述。
|
||
2. 将所有既有 V1.1 Completion Report 标记为“待复验”,不删除历史。
|
||
3. 先恢复 Git/版本可追溯性,再开始代码修复。
|
||
4. 以 P0 权限和有效测试为第一开发阶段,不先做视觉美化。
|
||
5. 每个恢复阶段只在测试、构建、截图和核心流程证据齐全后关闭。
|
||
|
||
详细恢复顺序见 `docs/V1.1_RECOVERY_DEVELOPMENT_PLAN_2026-09-09.md`。
|