2026-11-03 对生产库做了一次只读关系审计,结论三条:
format 字段同时存在 single、single_elimination、se 三种写法。本规范只解决「下一场真实赛事出生形状要正」的问题,不重构生产库,不拆表。
| 新字段 | 取值 | 含义 | 旧字段(继续同步) |
|---|---|---|---|
discipline | singles(预留 doubles) | 单打 / 双打——「打几个人」 | 无(新增维度) |
draw_type | single_elimination / double_elimination / round_robin | 签表类型——「怎么淘汰」 | format:single / double / rr |
draw_random_seed | 整数或 null | 随机排种时的洗牌种子,仅 seeding=random 时生效 | seed |
同步规则:服务器(POST /api/tournaments 与 PATCH)负责双向同步——来文带任一侧字段,就补齐另一侧。存量页面与工具继续读旧字段不受影响;新代码只读新字段。历史值 se 只做读映射(= single_elimination),不回写老数据。
data.player_ids 与 data.players 等长、同序,一一对应。p_ + 8 位随机十六进制;选手改名不换 ID。data.locked(布尔)与 data.lock_log(数组,元素 {ts, action})。unlock: true;服务器写入 lock_log 并解除锁定。无声改名单从此不可能。score(如「7-5 6-3」)与结构化 score_sets(逐盘)。两者必须一致,或 score_sets 为空——不允许互相矛盾(2026-11-03 修复:改文本分未带逐盘比分时,服务器清除旧 score_sets 并明示,不再静默保留)。score_sets 为空,该场结果必须被阻止提交,并提示补录逐盘比分;空值不得当作有效比分放行。此规则约束今后一切 DUPR 对接代码。mcp_audit 中。| 环节 | 现状 |
|---|---|
| 赛事 → 报名 | entries 独立表仅 MCP 链在用,活跃赛事报名记录为 0 |
| 报名 → 签表 | 页面链由名单实时推导;MCP 链物化为 mcp_bracket,双轨并存 |
| 签表 → 比赛 | 比赛无独立表,是签表推导结果或 mcp_bracket 内嵌对象 |
| 比赛 → 比分 → 晋级 | MCP 已实现(比分、胜者、自动晋级、撤销级联、mcp_audit),未在真实赛事用过 |
| 完赛归档 | 缺失,目前终点是 deleted_at 软删除 |
现在做(本规范):字段规范化、player_id、锁定。三者只动服务器一处咽喉,老数据不批量迁移。
第一场真实赛事测试前:报名审核与签到状态、退赛、裁判分配、排程字段(court / scheduled_at)、比分纠错流程。
商业化再做:organizers 多租户、matches 独立表、DUPR 账户关联、通知系统。matches 拆独立实体的触发条件:一场真实赛事完整跑完,且出现跨场查询或多裁判并发记分的实际需求。
原则:不是所有信息都进赛事 JSON。比分、报名、选手身份终将是独立实体;但拆分时机由真实赛事的使用证据决定,不由想象决定。