## 1. SQLite 异步化 [P0]

- [x] 1.1 在 requirements.txt / pyproject.toml 中添加 aiosqlite 依赖
- [x] 1.2 重写 room_store.py 中 RoomStore 类：将所有 sqlite3.connect() 替换为 await aiosqlite.connect()，同步 .execute() 替换为 await .execute()
- [x] 1.3 将 _init_db() 改为 async _init_db()，在首次 async 操作时调用
- [x] 1.4 将 save_race_result()、get_last_horse_name()、set_last_horse_name() 均改为 async
- [x] 1.5 修改 commands.py 中所有 room_store.xxx() 调用为 await room_store.xxx()
- [ ] 1.6 验证插件加载正常，比赛流程可跑通

## 2. 积分扣款重试 [P0]

- [x] 2.1 统一 points_service.py 异常处理：统一 exception type
- [x] 2.2 添加轻量重试：网络异常时等待 0.5~1s 重试一次
- [x] 2.3 返回值与调用处对齐

## 3. 消息发送异常日志 [P0]

- [x] 3.1 _send_to_scope 中 catch Exception，log.warning 记录发送失败详情
- [x] 3.2 catch 后静默继续（比赛不中断）

## 4. 积分历史记录字段补充 [P1]

- [x] 4.1 update_points 调用时传入 source="horse_race"
- [x] 4.2 下注/退款/派彩均记录对应 reason

## 5. 赔率快照 [P1]

- [x] 5.1 在 horse_race 结算时写入 participants 快照（赔率 + 下注金额）
- [x] 5.2 验证 history 表中可查到积分变化数据

## 6. 测试数据隔离 [P1]

- [x] 6.1 修改 test_commands.py：不再导入生产 room_store，通过 commands_mod 间接访问
- [x] 6.2 将测试命令中的 room_store/points_service 操作指向 commands_mod（支持 monkey-patch）
- [ ] 6.3 验证测试操作不影响生产数据

## 7. 马名去重统一 [P2]

- [x] 7.1 修改 _find_duplicate_horse：统一使用 casefold() 比较 dict key
- [x] 7.2 _normalize_horse_name 已用 casefold() 做统一归一化
- [ ] 7.3 验证 "Test" 和 "test" 无法同时注册

## 8. 代码审查后修复 [P3]

- [x] 8.1 settle_race 返回 tuple[RaceResult, odds]，消除 run_race_with_settlement 中 odds 重复计算
- [x] 8.2 _test_send_to_scope 签名兼容性：已有 *args/**kwargs，兼容 _send_to_scope 的 message_type 参数