feat(onboarding): 新增重置新手引导端点 /api/v1/user/onboarding/reset

- user.py:新增 reset_onboarding 端点(需登录),删当前账号+该设备的引导完成标记,
  与 /onboarding/complete 互逆;幂等(无记录也返回 ok),只删自己不影响他人
- repositories/onboarding.py:新增 delete_completion(user_id, device_id),
  device_id 为空忽略,返回删除行数
- tests:补 test_onboarding_reset_makes_relogin_reonboard,覆盖
  完成 → 重置 → 再登录变未完成 + 重复重置幂等

配合客户端「开发设置 → 重置新手引导」:先删后端行再退登录重开,复现全新用户。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 18:30:09 +08:00
parent 93f052535e
commit ea60dc391b
3 changed files with 53 additions and 1 deletions
+25
View File
@@ -65,3 +65,28 @@ def test_onboarding_missing_device_id_treated_as_incomplete(client) -> None:
phone = "13800138003"
data = _login(client, phone, device_id=None)
assert data["onboarding_completed"] is False
def _reset(client, access: str, device_id: str):
return client.post(
"/api/v1/user/onboarding/reset",
json={"device_id": device_id},
headers={"Authorization": f"Bearer {access}"},
)
def test_onboarding_reset_makes_relogin_reonboard(client) -> None:
"""重置(删完成标记)后,同 (账号, 设备) 再登录 → onboarding_completed=False,重走引导。
对应客户端「开发设置 → 重置新手引导」:先删后端行,再退登录重开。"""
phone = "13800138004"
dev = "android-id-reset"
# ① 走完引导 → 标记完成 → 再登录已完成
access = _login(client, phone, dev)["access_token"]
assert _mark_complete(client, access, dev).status_code == 200
assert _login(client, phone, dev)["onboarding_completed"] is True
# ② 重置(幂等:重复重置也 200)→ 再登录变未完成 → 重走引导
assert _reset(client, access, dev).status_code == 200
assert _reset(client, access, dev).json()["ok"] is True
assert _login(client, phone, dev)["onboarding_completed"] is False