Add market watch and match hub workflows

这个提交包含在:
cryptocommuniums-afk
2026-04-07 11:00:03 +08:00
父节点 495da60212
当前提交 32ffad1545
修改 39 个文件,包含 6974 行新增330 行删除

查看文件

@@ -1,5 +1,47 @@
# Tennis Training Hub - 变更日志
## 2026.03.27-match-review-hub (2026-03-27)
### 功能更新
- 新增 `/matches` 比赛入库板块和侧边栏入口,用户可以查看自己绑定的双人双摄比赛、自动计分事件、审核状态与正式入库结果
- 服务端新增 `match_sessions``match_participants``match_score_events` 数据表,并把“自动计分建议”“正式结算”接入现有 `background_tasks` worker 异步链路
- 补齐 `0012_market_watch``0013_match_hub` 的 Drizzle statement breakpoint,让 MySQL 生产迁移可以顺序执行球拍行情与比赛入库表结构并完成上线
- 管理后台新增“比赛入库”工作台,H1 / 管理员可以创建日常或竞赛比赛、固定两位用户与对应双机位、刷新自动计分建议、提交审核比分并发起正式结算
- 排行榜新增训练榜 / 竞赛榜双视图;竞赛榜只统计已正式结算的竞赛比赛,不会把未审核自动计分直接计入正式名次
- 正式结算后会把比赛写入用户训练记录;日常比赛同步累计训练型指标,竞赛比赛单独进入正式比赛统计与排行榜,避免未审核比赛直接影响 NTRP
### 测试
- `pnpm check`
- `pnpm exec vitest run server/match.test.ts server/features.test.ts`
- `pnpm build`
- `docker compose up -d --build migrate app app-worker`
- 线上 smoke公开站点部署前仍停留在 2026-03-17 的旧 revision;重新部署后已切到包含比赛入库与更新日志修正的新构建,Playwright 真实登录 `H1` 验证 `/matches``/admin` 的“比赛入库”工作台、`/leaderboard` 的“训练榜 / 竞赛榜”以及 `/changelog` 最新条目均可访问;当前仅剩 `/favicon.ico` 404,不影响功能使用
### 仓库版本
- `495da60`
## 2026.03.23-racket-market-watch (2026-03-23)
### 功能更新
- 新增 `/market` 球拍行情板块和侧边栏入口,集中展示低价雷达、监控规则、命中记录以及相关后台任务状态
- 服务端新增球拍行情数据表、用户监控规则和命中历史,并把市场刷新、来源抓取、飞书推送接入现有 `background_tasks` worker 流程
- 抓取结果会为球拍补齐品牌、型号、系列、品类、重量、成色与价格分级;命中用户目标价后,会先写入站内记录,再按去重规则推送到默认飞书 webhook
- 全局设置新增默认飞书 webhook、抓取超时、重试次数、闲鱼/京东/转转抓取 UA/Cookie 与转转搜索模板配置,管理员可在后台直接调整
### 测试
- `pnpm check`
- `pnpm exec vitest run server/market.test.ts server/market.routes.test.ts`
- `pnpm build`
### 仓库版本
- `495da60`
## 2026.03.17-live-camera-relay-mp4-hardening (2026-03-17)
### 功能更新

查看文件

@@ -60,6 +60,18 @@
- media service 暂时抖动时,不会把前台提交动作直接拖成超时
- 真正的会话校验、归档、回放可用性判断都在 worker 中执行
### 1.4 media-worker 会话刷新
`media-worker` 现在每轮都会从磁盘重新读取 `/data/media/sessions/*/session.json`
这样做是为了避免独立 worker 只在启动时加载一次会话,导致:
- 新创建的录制会话虽然已经写盘,但 worker 看不到
- `archiveStatus = queued` 的会话长期卡住
- `media_finalize` 任务反复重试直到耗尽次数
如果线上出现“归档一直 queued,但 media-worker 没报错”的情况,优先确认当前镜像是否已经包含这项修复。
## 2. 前端任务观测与降级
### 2.1 任务中心
@@ -169,6 +181,34 @@ docker compose logs --tail=80 app-worker
curl http://127.0.0.1:8081/media/health
```
如问题涉及训练计划超时或录制归档卡住,优先使用全链路重建,而不是只重启单个容器:
```bash
docker compose up -d --build migrate app app-worker media media-worker
```
重启后建议额外确认:
- `docker compose logs --tail=120 app-worker` 中不再出现旧的 `Request timed out after 45000ms`
- `docker compose logs --tail=120 media-worker` 中 worker 已正常启动
- 容器内 `dist/worker.js` 已包含新的训练计划超时/自动重试逻辑
## 6.1 损坏 media 会话处理
如果 `media-data` 中出现 `0` 字节或无法解析的 `session.json`,不要继续保留在 `sessions/*` 主目录。
建议处理方式:
1. 将损坏会话目录移动到隔离目录,例如 `sessions_broken/<session_id>`
2. 保留原始 `segments/*` 作为排障材料
3. 不直接猜测补写 `session.json`
原因:
-`session.json` 往往意味着写盘被中断
- 这类会话即使继续重试,也无法可靠恢复业务语义
- 将其移出主扫描路径可以避免后续 worker 误处理
## 7. 线上 Smoke Check
全量重启后建议至少执行: