# Use bot API for draw and points data

## Goal

将当前 nonebot 抽卡与积分运行时数据读写接入 xapi `/bot` API，避免继续写本地抽卡和积分 SQLite，并保持现有命令层行为不变。

## What I already know

* 用户指定的 API 文档位于 `C:\Users\14244\source\repos\Danding_Webs\xapi_new_web\docs\bot-api.md` 和 `nonebot-migration-guide.md`。
* `danding_points` 当前已经通过 `aiohttp` 调用 `/bot/points/*`，未发现 `database.py` 或本地 points SQLite 写入。
* `onmyoji_gacha/data_manager.py` 当前已经通过 `aiohttp` 调用 `/bot/gacha/*`，核心抽卡概率仍保留在 nonebot 本地。
* 抽卡签到当前流程为先调用 `/bot/points/add` 发积分，再调用 `/bot/gacha/sign-in` 记录签到；若 xapi 返回重复签到，会造成重复发积分。
* `tests/test_danding_points_http_api.py` 和 `tests/test_onmyoji_gacha_http_api.py` 已覆盖主要 HTTP 鉴权和 no-SQLite 约束。

## Requirements

* 积分账户、积分流水读写继续严格通过 `/bot/points` API。
* 抽卡结果、三连抽、式神基础数据、用户统计、每日统计、排行榜、每日记录、成就查询与成就 claim 继续严格通过 `/bot/gacha` API。
* 抽卡概率、SSR/SP viptime 奖励、成就奖励编排继续保留在 nonebot 本地。
* 抽卡签到必须避免重复发积分：只有 xapi 成功记录本日签到后，才允许调用 `/bot/points/add` 发放签到积分。
* 不实现历史 SQLite 到 xapi 的数据迁移，不生成回滚快照。

## Acceptance Criteria

* [x] `danding_points` 不写本地积分 SQLite，HTTP 请求的鉴权位置符合文档。
* [x] `onmyoji_gacha` 不写本地抽卡 SQLite，抽卡写入走 `/bot/gacha/draw` 和 `/bot/gacha/draw/triple`。
* [x] 重复签到时不会调用 `/bot/points/add` 发放积分。
* [x] API 失败时保持当前命令层可恢复失败语义，不空 catch。
* [x] 相关单元测试通过。

## Definition of Done

* 代码改动局限在抽卡/积分 API 数据流。
* 更新或补充能覆盖本次行为的测试。
* 运行相关测试，必要时运行 lint/type-check。
* 若发现文档外接口缺口，停止并向用户说明具体阻塞点。

## Technical Approach

沿用现有 `PointsAPI` 与 `DataManager` HTTP 适配层，不新增依赖。最小修改抽卡签到编排顺序：先调用 `/bot/gacha/sign-in` 以 xapi 的幂等/唯一约束判断是否首次签到，成功后再调用 `/bot/points/add` 发放积分。若积分发放失败，只记录错误，不补写本地库，不自行发起额外兜底。

## Out of Scope

* 本地历史 SQLite 数据迁移。
* admin-ui 改造。
* 赛马数据改造。
* 旧 `onmyoji_gacha/handlers/` 模块清理。

## Technical Notes

* xapi 响应统一为 `{code,message,data}`，成功 `code=200`。
* GET 鉴权参数放 query，POST/PUT 鉴权参数放 JSON body。
* `/bot/gacha/sign-in` 只记录签到，积分仍由 nonebot 调 `/bot/points/add`。
* `/bot/gacha/draw` 与 `/bot/gacha/draw/triple` 由 xapi 写抽卡结果和成就进度，nonebot 传入本地抽取的式神结果。
