diff --git a/README.md b/README.md index de6b963..ce1b25e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## 当前状态 -**Phase 0 已完成,Phase 1 基础切片已完成。** 后端已复制并跑通空库迁移、构建、健康检查与全量测试;前端已完成 SVG 品牌资产、用户首页/登录/商品列表、移动端 `/m` 首页/详情/个人中心、管理员验证码登录、强制改密、浅色后台 Shell 与真实仪表盘。 +**Phase 0–2 已完成,当前进入工程质量收口阶段。** 后端已复制并跑通空库迁移、构建、健康检查与全量测试;前端已完成 PC / 移动端 / 后台三端页面迁移,并接入 ESLint、Prettier、Vitest 与统一 `scripts/check.sh` 门禁。支付、短信、实名仍使用 mock,等待真实渠道凭据。 - 前端:`http://localhost:5289/` - 移动端:`http://localhost:5289/m` @@ -37,7 +37,7 @@ cd frontend && npm install && npm run dev - 主域名:`zuhaoc.com` - 管理后台:环境变量 `VITE_ADMIN_BASE_PATH`,默认 `/console-jy8k3m` - 分销后台:`distribution.zuhaoc.com`(沿用现有 React + AntD 应用,仅做品牌轻改) -- 数据库:全新数据库 `hfb_jysh`,保留全部 89 个迁移 +- 数据库:全新数据库 `hfb_jysh`,保留全部 90 个迁移 - 支付 / 短信 / 实名:先留空,开发环境使用 mock - Logo:无矢量源文件,按现有 PNG 重绘 SVG @@ -49,12 +49,31 @@ cd frontend && npm install && npm run dev - 分销后台:React 19 + Ant Design 5 - 部署:Caddy + Docker Compose +## 质量门禁 + +```bash +# 全量门禁:SQL 约束 + go vet/build/test + 前端格式/lint/类型/测试/构建 +./scripts/check.sh + +# 前端单独检查 +cd frontend +npm run format:check # Prettier +npm run lint # ESLint,--max-warnings=0 +npm run typecheck # tsc --noEmit +npm run test # Vitest +npm run test:coverage # Vitest + coverage +npm run build # Vite 生产构建 +``` + +提交前请启用仓库 hooks:`git config core.hooksPath .githooks`。首次推送会由 `pre-push` 自动执行 `scripts/check.sh`(可用 `SKIP_CHECKS=1` 临时跳过,不推荐)。 + ## 文档 - [项目实施计划](docs/项目计划.md) - [品牌与 UI 规范](docs/品牌与UI规范.md) - [Phase 0 验收报告](docs/Phase0-验收报告.md) - [Phase 1 验收报告](docs/Phase1-验收报告.md) +- [工程质量门禁与优化验收](docs/Phase3-工程质量门禁验收.md) - [后端数据库设计](docs/backend/database.md) - [后端业务规则](docs/backend/business-rules.md) diff --git a/docs/Phase3-工程质量门禁验收.md b/docs/Phase3-工程质量门禁验收.md new file mode 100644 index 0000000..5f3d1ac --- /dev/null +++ b/docs/Phase3-工程质量门禁验收.md @@ -0,0 +1,208 @@ +# Phase 3 验收报告(工程质量门禁与优化) + +> 结论:**全量门禁 `./scripts/check.sh` 通过**。前端格式、ESLint、类型检查、Vitest、生产构建与后端 SQL 约束、`go vet`、`go build`、全量测试全部为绿。 +> +> 验收时间:2026-11-01 + +## 1. 本轮范围 + +- 修复前端质量门禁,接入 ESLint、Prettier、Vitest。 +- 补核心金额、商品展示与后台筛选测试。 +- 将后台商品资产 / 皮肤筛选从内存过滤下推到数据库。 +- 补移动端旧路由兼容与后台看板缓存刷新。 +- 更新 README、迁移数量与验收文档。 +- 运行全量检查,并评估监控、构建拆包、大文件拆分与无障碍回归。 + +## 2. 质量门禁 + +### 2.1 命令 + +```bash +# 全量 +./scripts/check.sh + +# 前端单项 +cd frontend +npm run format:check +npm run lint +npm run typecheck +npm run test +npm run test:coverage +npm run build +``` + +### 2.2 本次结果 + +| 检查项 | 结果 | +| --- | --- | +| SQL 约束检查 | 通过 | +| `go vet ./...` | 通过 | +| `go build ./...` | 通过 | +| 后端测试(真实 MySQL 测试库) | 通过 | +| Prettier `--check` | 通过 | +| ESLint `--max-warnings=0` | 通过 | +| `tsc --noEmit` | 通过 | +| Vitest | 15 / 15 通过 | +| Vite 生产构建 | 通过 | + +全量脚本单次执行约 84 秒。 + +### 2.3 前端测试与覆盖率 + +测试文件: + +- `frontend/src/shared/utils/format.test.ts`:金额分转元、哈夫币 M、日期、手机号脱敏,4 个用例。 +- `frontend/src/shared/utils/pricing.test.ts`:元转分、哈夫币单位、BPS、资源单价、加速比例、平台定价空值,6 个用例。 +- `frontend/src/features/admin/listingDisplay.test.ts`:商品编码、地区、资产、皮肤、全英雄、纯币价格、租期、押金、比例、空值,5 个用例。 + +本次覆盖率: + +| 文件 | 语句 | 分支 | 函数 | 行 | +| --- | --- | --- | --- | --- | +| 全部 | 54.63% | 47.66% | 56.97% | 58.70% | +| `listingDisplay.ts` | 85.71% | 65.38% | 96.15% | 89.70% | +| `format.ts` | 65.78% | 70.58% | 87.50% | 73.07% | +| `pricing.ts` | 39.57% | 36.17% | 32.69% | 42.48% | + +`pricing.ts` 仍是后续补测重点,尤其是发布页定价链路中的组合分支。 + +## 3. 后台商品筛选下推 + +`backend/internal/modules/listing/admin_filter_sql.go` 新增: + +- `applyAdminAssetSQLFilters`:资产、皮肤、皮肤分组条件直接进入 SQL。 +- `jsonMemberPath` / `escapeJSONSearchPattern`:安全拼接 JSON 路径与 `LIKE` 模式。 + +`ListAdmin` 已删除「资产筛选时全表 `Scan` + 内存过滤 + 内存分页」分支,所有筛选统一走数据库 `COUNT + LIMIT/OFFSET`,`COUNT` 查询同步补上 `JOIN game_accounts`。 + +单元测试覆盖: + +- 资产条件生成 `JSON_UNQUOTE(JSON_EXTRACT(...)) IN (?)`。 +- 多皮肤名称生成多个 `JSON_SEARCH(...)` 的 AND 条件。 +- 皮肤分组生成 `JSON_LENGTH(JSON_EXTRACT(...)) > 0` 的 OR 条件。 +- JSON 路径与 `LIKE` 转义。 + +真实 MySQL 验证(MySQL 8.4.11,本地 `hfb_jysh`): + +- 预处理语句 `JSON_EXTRACT(asset_summary, ?)` 传入 `$.skin_groups`,返回预期行。 +- 预处理语句 `JSON_SEARCH(asset_summary, 'one', ?, '!', ?)` 传入皮肤关键字与 `$.skin_groups.*`,返回预期行。 +- 说明 GORM prepared statement 下 JSON 路径参数可用。 + +限制:当前没有为 JSON 条件增加生成列或索引,大数据量下仍需真实库压测。 + +## 4. 移动端旧路由兼容 + +`frontend/src/app/AppRouter.tsx` 新增: + +- `/m/listings/collections`:移动端「我的足迹 / 收藏」页面。 +- `/m/announcements/:id`:移动端公告详情。 +- `/m/i/:code`:移动端邀请落地页,使用移动端布局与 antd-mobile 组件。 + +新增页面: + +- `frontend/src/features/mobile/MobileListingCollectionsPage.tsx` +- `frontend/src/features/mobile/MobileAnnouncementDetailPage.tsx` +- `frontend/src/features/mobile/MobileInviteLandingPage.tsx` + +移动端未登录时继续使用本地足迹 / 收藏,登录后读取账号同步接口,与 PC 行为一致。 + +## 5. 后台看板缓存刷新 + +新增 `frontend/src/features/admin/cache.ts`: + +```ts +export function invalidateAdminDashboard(queryClient: QueryClient) { + return queryClient.invalidateQueries({ queryKey: ['admin-dashboard'] }) +} +``` + +接入位置: + +- 商品审核、驳回、下架、标记异常:`AdminListingDetailDrawer`。 +- 退款审核:`AdminRefundReviewPage`。 +- 提现审核与确认打款:`AdminWithdrawalDetailDrawer`。 +- 申诉仲裁:`AdminDisputeDetailDrawer`。 + +写操作成功后,工作台数字不再依赖手动刷新或页面重进。 + +## 6. 文档与工程配置 + +- README 迁移数量更新为 90。 +- README 增加质量门禁命令、 hooks 启用说明与 Phase 3 文档入口。 +- 新增 `.githooks/pre-push`,推送前自动执行 `scripts/check.sh`。 +- 新增 `scripts/check-frontend-size.sh`,React 页面默认上限 1800 行。 +- 两个脚本已设置可执行权限。 + +注意:仓库 hooks 尚未启用,需要执行 `git config core.hooksPath .githooks`。 + +## 7. 构建体积 + +本次生产构建主要产物: + +| 产物 | 原始体积 | gzip | +| --- | --- | --- | +| `index-*.js`(主入口) | 509.29 kB | 159.25 kB | +| `vendor-react` | 282.80 kB | 90.01 kB | +| `vendor-mobile` | 320.55 kB | 107.65 kB | +| `Table` | 144.26 kB | 47.07 kB | +| `vendor-antd-icons` | 131.13 kB | 36.35 kB | + +结论:现有手动 `manualChunks` 已把 React、antd 图标、移动端依赖与表格拆开,主入口仍在 500 kB 左右但 gzip 159 kB,可接受。**不建议**再做粗暴按目录拆包,避免生成更大的循环依赖 vendor chunk。若继续优化,优先按路由进一步懒加载后台重型页面,并评估 antd 组件级导入。 + +## 8. 大文件评估 + +当前超过 1500 行的前端文件: + +| 文件 | 行数 | +| --- | --- | +| `frontend/src/features/admin/types.ts` | 2177 | +| `frontend/src/features/admin/api.ts` | 2043 | +| `frontend/src/features/seller/SellerListingFormPage.tsx` | 1664 | + +`SellerListingFormPage.tsx` 低于 1800 行门禁,但没有太多余量。建议后续按后台域拆分 `types.ts` 与 `api.ts`(订单、商品、提现、分销、系统配置),并将发布页的资产、皮肤、定价区块拆成子组件;拆分前先补组件级测试,避免纯搬迁引入回归。 + +## 9. 可观测性评估 + +现有能力: + +- `RequestID`、`RequestLogger`、`Recovery` 已挂在全局路由。 +- 慢请求阈值 500 ms,慢请求、5xx、限流、后台认证失败会写 warn / error 日志。 +- 支付回调路径有独立业务日志,避免重复访问日志。 + +仍缺少: + +- 错误聚合与告警(Sentry / OpenTelemetry / 日志平台规则)。 +- 接口耗时指标与分位数看板。 +- 数据库慢查询阈值与上报。 +- 支付回调失败、短信发送失败、实名认证失败的统一计数与告警。 +- 前端运行时错误上报。 + +建议下一阶段先接日志平台告警规则,再补 Prometheus 指标,不引入重量级 APM。 + +## 10. 无障碍回归 + +当前没有 Playwright、axe 或视觉回归基线。建议后续补: + +- 关键链路 E2E:登录、选号、下单、支付 mock 回调、订单操作、提现申请、后台审核。 +- `@axe-core/playwright` 对首页、商品详情、发布页、后台工作台做自动检查。 +- 移动端 375px 与桌面 1440px 两组截图基线。 + +用户已明确不要主动使用浏览器,本轮未执行浏览器验证。 + +## 11. 外部渠道阻塞 + +以下能力仍因外部凭据缺失无法做真实 E2E: + +- 支付商户:当前仅有 mock 渠道,真实下单、回调、退款未验证。 +- 短信签名:当前 `SMS_PROVIDER=mock`,真实发送与到达率未验证。 +- 实名服务:当前 `REALNAME_PROVIDER=mock`,真实三要素 / 人脸核验未验证。 + +在拿到商户号、密钥、回调地址、短信签名与实名服务账号前,不应伪造真实验收结论。 + +## 12. 遗留风险 + +- `npm audit` 当前 14 个漏洞(2 low、12 moderate),未执行 `npm audit fix --force`,避免破坏 React / antd 版本。 +- antd-mobile 与 React 19 存在既有 peer warning,构建与运行正常。 +- JSON 商品筛选尚未做生成列 / 索引和真实大数据量压测。 +- 仓库 hooks 尚未启用。 +- 尚未建立 Playwright、视觉回归与无障碍自动检查。