Files
DanDingNoneBot/openspec/changes/archive/fix-horse-racing-issues/specs/horse-race-room-flow/spec.md

3.7 KiB
Raw Blame History

MODIFIED Requirements

Requirement: 房间作用域与创建

系统 SHALL 按会话作用域管理赛马房间。群聊场景 MUST 以 group_id 作为房间键;测试模式私聊场景 MUST 以 test_<user_id> 作为房间键。单一作用域同一时间 SHALL 最多存在一个活动房间。房间在首位用户发送报名命令且该作用域不存在活动房间时自动创建。finishedinterrupted 房间在结果公告后自动释放,允许同作用域立即创建新房间。正式模式下群聊 MUST 仅对 ALLOWED_GROUPS 配置列表中的群开放。

Scenario: 群聊首次报名自动建房

  • WHEN10001 中第一位用户发送报名命令且该群不存在活动房间
  • THEN 系统创建属于 group_id=10001 的新房间,并将该用户登记为首位参赛者

Scenario: 私聊测试使用独立房间键

  • WHEN 测试人员在私聊中发送报名命令且 TEST_MODE=True
  • THEN 系统创建房间键为 test_<user_id> 的测试房间,不影响任何群聊房间

Scenario: 正式模式下非白名单群拒绝

  • WHEN TEST_MODE=False 且用户在不在 ALLOWED_GROUPS 列表中的群发送赛马命令
  • THEN 系统拒绝请求,并提示该群未开放赛马功能

Scenario: 比赛结束后立即可建新房

  • WHEN 某群的房间状态为 finished 且结果已公告
  • THEN 系统释放该房间,用户再次发送报名命令可创建新房间

Requirement: 房间状态恢复

系统 SHALL 在关键状态变化后持久化活动房间快照,并在插件重启后重建可恢复房间。关键持久化点包括:房间创建、报名/取消报名、下注/退还、比赛开始、比赛结束、房间取消。若重启后发现 running 状态的房间,系统 MUST 将其标记为 interrupted,自动退还所有有效下注,并向用户发送中断通知。持久化数据 MUST 包含房间元数据scope、状态、创建时间、马匹列表owner、名称、位置、状态、下注记录user_id、马匹名、金额、当前赔率快照。数据库操作 MUST 使用 aiosqlite 进行异步 IO避免阻塞 NoneBot 事件循环。

Scenario: 重启后恢复等待中的房间

  • WHEN 插件重启前某群房间状态为 waiting 且快照已落盘
  • THEN 插件启动时重新加载该房间,使用户可以继续报名、下注或开赛

Scenario: 重启后处理中断中的比赛

  • WHEN 插件重启前某房间状态为 running 但推进任务已丢失
  • THEN 插件启动时将房间标记为 interrupted,退还所有有效下注,并通知用户该场比赛已因中断取消

Scenario: 数据库操作异步化

  • WHEN 系统执行任何 SQLite 持久化操作
  • THEN 系统通过 aiosqlite 异步连接执行,不阻塞事件循环

Requirement: 比赛结果持久化

系统 SHALL 在每场比赛结束后将结果持久化到 data/group_horse_racing/race.db 的历史记录表中。记录 MUST 包含:比赛 ID、作用域、冠军马匹名称和主人、所有参赛者列表、下注分布概要各马下注总额和人次、比赛时长tick 数)、完成时间戳、积分变化详情(每位用户的赔付/奖励/退还金额及原因摘要)。历史数据不设置自动清理策略。

Scenario: 比赛结束后保存历史

  • WHEN 一场比赛完成结算
  • THEN 系统将比赛结果写入历史记录表,包含冠军信息、参赛者、下注分布、比赛时长和积分变化详情

Scenario: 查询历史时显示积分变化

  • WHEN 用户查询某场比赛的历史记录
  • THEN 系统返回包含每位用户的赔付/奖励/退还金额及原因的积分变化摘要