跳转至

DIP1 P3-B 师傅端 + 客户端业务测试 · 亲手操作指南

字段
指南编号 DWLG-20260811-04
关联文档 DWLG-20260811-02(P3-B 测试报告)/ 03(C-B7 师傅账号接入)
目标 指导 TL 亲手执行师傅端 + 客户端全链路业务测试
预计耗时 30-45 分钟
后端地址 http://localhost:8000/api/v1
执行日期 2026-08-11

〇、测试准备

0.1 环境确认

在 PowerShell 中执行,确认后端服务正常:

curl -s -o NUL -w "HTTP %{http_code}`n" http://localhost:8000/health
# 预期:HTTP 200

0.2 测试账号清单

师傅账号(C-B7 已接入)

账号 密码 师傅 手机号 级别 被指派订单数
worker_uat_0001 worker123 張師傅 +85291130001 L1 5 单(L4×2, L5, L6, L8)
worker_uat_0002 worker123 劉師傅 +85291130002 L1 -
worker_uat_0006 worker123 周師傅 +85291130006 L3 -

客户账号(OTP 登录)

手机号 客户名 订单情况
+85292230009 周太 2 单(L2 橱柜 676HKD + L6 电视柜 280HKD)
+85292230010 吴生 2 单(L2 + L7)
+85292230017 唐太 1 单(L8)

管理员账号

账号 密码 角色
admin admin123 TL(全权限)

0.3 工具选择

工具 适用场景 推荐度
PowerShell + curl 本指南默认方式,可直接复制 ⭐⭐⭐⭐⭐
Apifox / Postman 可视化 API 测试,支持环境变量 ⭐⭐⭐⭐
浏览器 Swagger UI http://localhost:8000/docs 交互式文档 ⭐⭐⭐

本指南所有命令均在 PowerShell 中执行,可直接复制粘贴。

0.4 通用说明

  • 所有请求的 Content-Type: application/json
  • Token 有效期 15 分钟,过期后需重新登录
  • 师傅 token 的 role=FL,受 RLS 限制只能看自己的订单
  • 客户 token 的 role=CST,受 RLS 限制只能看自己的订单

第一部分:师傅端业务测试(10 步)

Step W1:师傅账密登录 ⭐核心

操作说明:使用师傅账号 worker_uat_0001 登录,获取 access_token。

$workerResp = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/login" `
    -Method Post -Body '{"username":"worker_uat_0001","password":"worker123"}' `
    -ContentType "application/json"
$workerToken = $workerResp.access_token
$workerHeaders = @{"Authorization"="Bearer $workerToken"; "Content-Type"="application/json"}
$workerResp.user | ConvertTo-Json

预期响应

{
  "user_id": "USR-WKR-UAT0000001",
  "username": "worker_uat_0001",
  "display_name": "張師傅",
  "roles": ["FL"],
  "permissions": ["cpt:list:self"]
}

✅ 验证点: - [ ] roles 包含 FL(一线师傅) - [ ] display_name = "張師傅" - [ ] permissions = ["cpt:list:self"](只能看自己的订单)


Step W2:师傅 OTP 登录(可选)

操作说明:使用师傅手机号 +85291130001 通过 OTP 登录。

$send = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/otp-send" `
    -Method Post -Body '{"whatsapp":"+85291130001"}' `
    -ContentType "application/json"
Write-Host "收到 OTP: $($send.otp)"
Start-Sleep -Seconds 1
$verify = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/otp-verify" `
    -Method Post -Body "{`"otp_session_id`":`"$($send.otp_session_id)`",`"otp_code`":`"$($send.otp)`"}" `
    -ContentType "application/json"
Write-Host "师傅 OTP 登录成功,worker_id: $($verify.customer_id)"

预期响应customer_id 字段返回 WKR0UAT0000001(师傅场景返回 worker_id)。

✅ 验证点: - [ ] OTP 6 位数字回显(开发环境) - [ ] customer_idWKR 开头(师傅身份判定正确)


Step W3:查看师傅个人信息(冷启动 hydrate)

操作说明:调用 /auth/me 获取当前登录师傅信息(模拟 App 冷启动后的会话恢复)。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/me" -Headers $workerHeaders | ConvertTo-Json

预期响应

{
  "user_id": "USR-WKR-UAT0000001",
  "username": "worker_uat_0001",
  "display_name": "張師傅",
  "roles": ["FL"],
  "worker_id": "WKR0UAT0000001"
}

✅ 验证点: - [ ] worker_id = WKR0UAT0000001 - [ ] roles 包含 FL


Step W4:查看工作看板 ⭐核心

操作说明:师傅端首页看板,查看 6 个订单池的分组统计。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders/board" -Headers $workerHeaders | ConvertTo-Json -Depth 3

预期响应:返回 6 个池(POOL_L1_NEW_LEADS / POOL_L3_PENDING_QUOTE / POOL_L4_PENDING_ASSIGN / POOL_L6_INSTALL_TODAY / POOL_L8_PENDING_FOLLOWUP / POOL_EXCEPTION),每个池包含 countitems

✅ 验证点: - [ ] 6 个池全部返回 - [ ] POOL_L4_PENDING_ASSIGNPOOL_L6_INSTALL_TODAY 有订单(張師傅有 L4/L6 订单) - [ ] 池中订单的 assigned_worker_id 都是 WKR0UAT0000001(RLS 限定)


Step W5:查看订单列表(按阶段筛选)

操作说明:查看师傅被指派的所有订单,并按 L6 阶段筛选。

# 查看所有订单
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders?page=1&page_size=20" -Headers $workerHeaders | ConvertTo-Json -Depth 2

# 按 L6 筛选
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders?stage=L6&page=1&page_size=10" -Headers $workerHeaders | ConvertTo-Json -Depth 2

预期响应total=5(5 个被指派订单),L6 筛选后 total=1(订单 ORD0UAT0000036 周太 电视柜 280HKD)。

✅ 验证点: - [ ] total = 5 - [ ] 所有订单的 assigned_worker_id = WKR0UAT0000001 - [ ] L6 筛选返回 1 个订单(ORD0UAT0000036)


Step W6:查看订单详情 ⭐核心

操作说明:查看 L6 订单(周太 电视柜)的完整详情,包含阶段时间线、报价、附件、审计日志。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders/ORD0UAT0000036" -Headers $workerHeaders | ConvertTo-Json -Depth 4

预期响应:包含 order_id / stage=L6 / customer_name=周太 / stages[](阶段时间线)/ attachments[] / audit_log[] 等字段。

✅ 验证点: - [ ] order_id = ORD0UAT0000036 - [ ] stage = L6 - [ ] customer_name = 周太 - [ ] stages 是数组,包含 L1-L6 阶段记录 - [ ] attachments 字段存在(即使为空数组) - [ ] audit_log 字段存在


Step W7:查看订单报价

操作说明:查看 L6 订单的报价详情(含因子展开)。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders/ORD0UAT0000036/quote" -Headers $workerHeaders | ConvertTo-Json -Depth 3

预期响应:包含 quote_id / final_hkd=280.00 / base_fee_hkd / factor_total / factor_breakdown(JSON 展开各因子系数)。

✅ 验证点: - [ ] final_hkd = 280.00 - [ ] status = CONFIRMED(已确认报价) - [ ] factor_breakdown 包含 category_base 等因子


Step W8:接单流转(L4 → L5 配送)⭐核心

操作说明:取一个 L4 阶段订单,执行状态流转 L4→L5(确认配送)。

# 先取一个 L4 订单
$l4Orders = (Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders?stage=L4&page=1&page_size=5" -Headers $workerHeaders).items
$l4Orders | Select-Object order_id, stage, customer_name | Format-Table

# 执行 L4 → L5 流转(用第一个 L4 订单)
if ($l4Orders) {
    $oid = $l4Orders[0].order_id
    Write-Host "对订单 $oid 执行 L4→L5 流转"
    Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders/$oid/transition" `
        -Method Post -Body '{"to_stage":"L5"}' -Headers $workerHeaders | ConvertTo-Json
}

预期响应:返回 {"order_id":"...","stage":"L5","status":"IN_PROGRESS"}

✅ 验证点: - [ ] 流转后 stage = L5 - [ ] 订单状态变更记录写入审计日志

⚠️ 注意:此操作会改变订单状态,重复执行同一订单会返回 409(状态机不允许 L5→L5)。


Step W9:注册推送 Token

操作说明:模拟师傅端 App 注册 Expo Push Token(用于接收推送通知)。

$pushBody = @{
    push_token = "ExponentPushToken[manual-test-worker-001]"
    platform = "IOS"
    app_type = "WKR"
    app_version = "1.0.0"
    device_id = "device-worker-manual-001"
} | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/push/register" `
    -Method Post -Body $pushBody -Headers $workerHeaders | ConvertTo-Json

预期响应{"token_id":"...","status":"REGISTERED"}

✅ 验证点: - [ ] status = REGISTERED(首次注册)

二次注册验证幂等性

# 同一 push_token 再注册一次
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/push/register" `
    -Method Post -Body $pushBody -Headers $workerHeaders | ConvertTo-Json
# 预期 status="UPDATED"(幂等更新)

✅ 验证点: - [ ] 二次注册 status = UPDATED(C-B7 修复的 upsert 幂等性)


Step W10:RLS 权限验证(越权访问拦截)⭐安全红线

操作说明:尝试访问不分配给当前师傅的订单,验证 RLS 拦截。

# ORD0UAT0000001 不是分配给 worker_uat_0001 的订单
try {
    Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders/ORD0UAT0000001" -Headers $workerHeaders
} catch {
    $err = $_.Exception.Response
    Write-Host "HTTP 状态码: $([int]$err.StatusCode)"
    $reader = New-Object System.IO.StreamReader($err.GetResponseStream())
    Write-Host "错误信息: $($reader.ReadToEnd())"
}

预期响应:HTTP 403 Forbidden,{"code":1002,"message":"无权限查看该订单(仅可查看本人被指派订单)"}

✅ 验证点: - [ ] HTTP 状态码 = 403 - [ ] 错误信息包含"无权限" - [ ] 师傅无法越权访问他人订单


第二部分:客户端业务测试(12 步)

Step C1:客户 OTP 登录 ⭐核心

操作说明:客户周太(+85292230009)通过 OTP 登录。

$send = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/otp-send" `
    -Method Post -Body '{"whatsapp":"+85292230009"}' `
    -ContentType "application/json"
Write-Host "收到 OTP: $($send.otp)"
Start-Sleep -Seconds 1
$verify = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/otp-verify" `
    -Method Post -Body "{`"otp_session_id`":`"$($send.otp_session_id)`",`"otp_code`":`"$($send.otp)`"}" `
    -ContentType "application/json"
$custToken = $verify.access_token
$custHeaders = @{"Authorization"="Bearer $custToken"; "Content-Type"="application/json"}
Write-Host "客户登录成功,customer_id: $($verify.customer_id)"

预期响应customer_id = CUS0UAT0000009(周太)。

✅ 验证点: - [ ] OTP 6 位数字回显 - [ ] customer_idCUS 开头(客户身份)


Step C2:查看客户个人信息

操作说明:查看客户档案(WhatsApp 脱敏展示)。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/profile" -Headers $custHeaders | ConvertTo-Json -Depth 3

预期响应:包含 customer_id / name=周太 / whatsapp(脱敏如 +852-****) / total_orders / trust_badges 等字段。

✅ 验证点: - [ ] name = 周太 - [ ] whatsapp 字段脱敏(不显示完整号码) - [ ] customer_id = CUS0UAT0000009


Step C3:浏览首页品类

操作说明:客户端首页浏览 8 大品类入口。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/categories" -Headers $custHeaders | ConvertTo-Json -Depth 2

预期响应:返回品类列表,每个品类包含 category_id / code / name_zh / base_fee_hkd / cap_price_hkd

✅ 验证点: - [ ] 至少 6 个品类 - [ ] 每个品类有 cap_price_hkd(封顶价) - [ ] 品类包含床架(BED)/橱柜(KITCHEN_CABINET)/电视柜(TV_CABINET)等


Step C4:询价提交 ⭐核心

操作说明:提交一个询价表单,生成新订单(L1→L2)。

$inquiryBody = @{
    category_id = "CAT2997234892DCFEB4907651"  # 橱柜品类
    product_model = "欧派 OP-1800"
    size_info = "长1800×宽600×高850mm"
    address = "新界沙田第一城 12 座 8 楼 3 室"
    building_id = "BLD0UAT0000001"
    preferred_slot = @{
        date = "2026-08-20"
        slot = "AM"
    }
    site_conditions = @{
        elevator = $true
        floor = 8
        parking = $true
    }
} | ConvertTo-Json -Depth 3
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/inquiries" `
    -Method Post -Body $inquiryBody -Headers $custHeaders | ConvertTo-Json

预期响应{"order_id":"ORD0UAT...","stage":"L2","lead_source":"CST_APP_SELF"}

✅ 验证点: - [ ] 返回 order_id(新生成的订单 ID) - [ ] stage = L2 - [ ] lead_source = CST_APP_SELF(客户端自助询价)


Step C5:查看我的订单列表

操作说明:查看客户的所有订单。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/orders?status=ALL&page=1&page_size=20" -Headers $custHeaders | ConvertTo-Json -Depth 2

预期响应total ≥ 2(周太原有 2 单 + 刚询价的新单),包含订单基本信息。

✅ 验证点: - [ ] total ≥ 2 - [ ] 包含 ORD0UAT0000009(L2 橱柜 676HKD)和 ORD0UAT0000036(L6 电视柜 280HKD) - [ ] 询价生成的新订单出现在列表中


Step C6:查看订单详情 + Timeline ⭐核心

操作说明:查看 L6 订单的完整 Timeline(L1-L8 阶段时间线)。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/orders/ORD0UAT0000036" -Headers $custHeaders | ConvertTo-Json -Depth 4

预期响应:包含 order_id / current_stage=L6 / timeline[](L1-L6 阶段记录)/ quote(报价信息)/ worker(师傅信息)。

✅ 验证点: - [ ] current_stage = L6 - [ ] timeline 数组包含多个阶段节点 - [ ] quote 字段存在(报价已生成) - [ ] worker 字段存在(师傅已派单)


Step C7:查看报价(含因子展开) ⭐核心一致性

操作说明:查看 L2 订单的报价详情。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/orders/ORD0UAT0000009/quote" -Headers $custHeaders | ConvertTo-Json -Depth 3

预期响应:包含 quote_id / final_hkd=676.00 / base_fee_hkd / factor_total / factor_breakdown

✅ 验证点: - [ ] final_hkd = 676.00 - [ ] status = DRAFT(待确认)或 CONFIRMED - [ ] factor_breakdown 包含因子展开

💡 三端一致性验证:此金额应与运营后台(admin token)查看的同一订单报价金额一致。


Step C8:确认报价 ⭐核心

操作说明:确认 L2 订单的报价(L2→L3 流转)。

try {
    Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cpt/orders/ORD0UAT0000009/quote/confirm" `
        -Method Post -Body '{"action":"CONFIRM"}' -Headers $custHeaders | ConvertTo-Json
} catch {
    $err = $_.Exception.Response
    Write-Host "HTTP 状态码: $([int]$err.StatusCode)"
    # 409 = 报价已被前次测试确认过(幂等保护),视为通过
    if ([int]$err.StatusCode -eq 409) {
        Write-Host "报价已被确认过(409 幂等保护),视为通过"
    }
}

⚠️ 注意:客户端确认报价的端点是 /cst/orders/{id}/quote/confirm,不是 /cpt/orders/。如果上面的端点报 404,请改用:

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/orders/ORD0UAT0000009/quote/confirm" `
    -Method Post -Body '{"action":"CONFIRM"}' -Headers $custHeaders | ConvertTo-Json

预期响应{"order_id":"...","quote_id":"...","status":"CONFIRMED"}

✅ 验证点: - [ ] status = CONFIRMED(或 409 幂等保护) - [ ] 订单阶段从 L2 流转到 L3


Step C9:查看师傅信息(脱敏) ⭐安全红线

操作说明:查看 L6 订单已派单师傅的公开信息(脱敏,不返回电话)。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/orders/ORD0UAT0000036/worker" -Headers $custHeaders | ConvertTo-Json -Depth 2

预期响应:包含 worker_id / display_name=張師傅 / level=L1 / avg_nps / total_orders不包含 phone / whatsapp 字段。

✅ 验证点: - [ ] display_name = 張師傅 - [ ] phone 字段(脱敏) - [ ] whatsapp 字段(脱敏) - [ ] avg_npstotal_orders 有值


Step C10:提交服务评价 ⭐核心

操作说明:对 L8 阶段订单提交评价(NPS + 星级 + 文字)。

# 先查看是否有 L8 订单(用唐太 +85292230017 登录)
$send2 = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/otp-send" `
    -Method Post -Body '{"whatsapp":"+85292230017"}' -ContentType "application/json"
Start-Sleep -Seconds 1
$verify2 = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/otp-verify" `
    -Method Post -Body "{`"otp_session_id`":`"$($send2.otp_session_id)`",`"otp_code`":`"$($send2.otp)`"}" `
    -ContentType "application/json"
$tangToken = $verify2.access_token
$tangHeaders = @{"Authorization"="Bearer $tangToken"; "Content-Type"="application/json"}

# 查看唐太的订单
$tangOrders = (Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/orders?status=ALL&page=1&page_size=5" -Headers $tangHeaders).items
$tangOrders | Select-Object order_id, stage, category_name | Format-Table

# 对 L8 订单提交评价
$l8Order = $tangOrders | Where-Object { $_.stage -eq "L8" } | Select-Object -First 1
if ($l8Order) {
    $reviewBody = @{
        nps_score = 9
        star_rating = 5
        text_review = "張師傅安裝非常專業,準時到達,安裝後清理乾淨,強烈推薦!"
        photo_urls = @()
    } | ConvertTo-Json
    try {
        Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/orders/$($l8Order.order_id)/review" `
            -Method Post -Body $reviewBody -Headers $tangHeaders | ConvertTo-Json
    } catch {
        $err = $_.Exception.Response
        if ([int]$err.StatusCode -eq 409) {
            Write-Host "订单已评价过(409 幂等保护),视为通过"
        }
    }
}

预期响应{"order_id":"...","nps_score":9,"star_rating":5,"status":"RECORDED"}

✅ 验证点: - [ ] status = RECORDED(或 409 幂等保护) - [ ] nps_score = 9 - [ ] star_rating = 5


Step C11:生成推荐码

操作说明:生成/查询客户的推荐码(用于口碑营销)。

Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/referral/code" `
    -Method Post -Headers $custHeaders | ConvertTo-Json -Depth 2

预期响应:包含 referral_code / share_link

✅ 验证点: - [ ] referral_code 不为空(6 位大写字母数字) - [ ] share_link 不为空

二次生成验证幂等性

# 同一客户再生成一次,应返回相同推荐码
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/referral/code" `
    -Method Post -Headers $custHeaders | ConvertTo-Json

✅ 验证点: - [ ] 二次生成返回相同的 referral_code


Step C12:推送偏好查询与更新

操作说明:查看和修改推送偏好(8 类推送开关)。

# 查询当前推送偏好
Write-Host "=== 当前推送偏好 ==="
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/push-preferences" -Headers $custHeaders | ConvertTo-Json

# 关闭"系统通知"推送
$updateBody = '{"PUSH_SYSTEM":false}' | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/push-preferences" `
    -Method Put -Body '{"PUSH_SYSTEM":false}' -Headers $custHeaders | ConvertTo-Json

# 再查询确认已关闭
Write-Host "=== 修改后推送偏好 ==="
Invoke-RestMethod -Uri "http://localhost:8000/api/v1/cst/push-preferences" -Headers $custHeaders | ConvertTo-Json

预期响应:8 类推送开关(PUSH_NEW_ORDER / PUSH_ORDER_REMINDER_1H / PUSH_ORDER_STATUS / PUSH_WORKER_DEPARTED / PUSH_REVIEW_INVITE / PUSH_REFERRAL_REWARD / PUSH_QUOTE_READY / PUSH_SYSTEM)。

✅ 验证点: - [ ] 8 类推送开关全部返回 - [ ] 修改 PUSH_SYSTEM=false 后,再查询确认 PUSH_SYSTEM=false - [ ] 其他开关保持不变


第三部分:验收 Checklist

师傅端验收(10 项)

# 验收项 验证结果
W1 师傅账密登录返回 role=FL + worker_id ☐ 通过 ☐ 失败
W2 师傅 OTP 登录签发 FL token ☐ 通过 ☐ 失败
W3 /auth/me 返回师傅信息 ☐ 通过 ☐ 失败
W4 看板 6 池结构完整 ☐ 通过 ☐ 失败
W5 订单列表 RLS 限定自己的订单 ☐ 通过 ☐ 失败
W6 订单详情字段完整(timeline+attachments+audit) ☐ 通过 ☐ 失败
W7 报价查看含因子展开 ☐ 通过 ☐ 失败
W8 接单流转 L4→L5 成功 ☐ 通过 ☐ 失败
W9 Push Token 注册 + 幂等 UPDATED ☐ 通过 ☐ 失败
W10 RLS 越权访问 → 403 ☐ 通过 ☐ 失败

客户端验收(12 项)

# 验收项 验证结果
C1 客户 OTP 登录签发 CST token ☐ 通过 ☐ 失败
C2 个人档案 WhatsApp 脱敏 ☐ 通过 ☐ 失败
C3 首页 ≥6 品类 + 封顶价 ☐ 通过 ☐ 失败
C4 询价提交生成订单 L2 + lead_source ☐ 通过 ☐ 失败
C5 我的订单列表正确 ☐ 通过 ☐ 失败
C6 订单 Timeline L1-L8 完整 ☐ 通过 ☐ 失败
C7 报价金额与运营后台一致 ☐ 通过 ☐ 失败
C8 确认报价 L2→L3(或 409 幂等) ☐ 通过 ☐ 失败
C9 师傅信息脱敏(无 phone/whatsapp) ☐ 通过 ☐ 失败
C10 L8 评价提交 NPS+星级 ☐ 通过 ☐ 失败
C11 推荐码生成 + 幂等 ☐ 通过 ☐ 失败
C12 推送偏好 8 类开关可读写 ☐ 通过 ☐ 失败

安全红线验收(5 项)

# 验收项 验证结果
S1 师傅 RLS 只看自己订单(W10) ☐ 通过 ☐ 失败
S2 客户 RLS 只看自己订单 ☐ 通过 ☐ 失败
S3 师傅信息脱敏(C9) ☐ 通过 ☐ 失败
S4 客户 WhatsApp 脱敏(C2) ☐ 通过 ☐ 失败
S5 重复操作幂等保护(W9/C8/C10/C11) ☐ 通过 ☐ 失败

附录:常用排障

A.1 Token 过期

Token 有效期 15 分钟,过期后需重新登录:

# 重新登录获取新 token
$workerResp = Invoke-RestMethod -Uri "http://localhost:8000/api/v1/auth/login" `
    -Method Post -Body '{"username":"worker_uat_0001","password":"worker123"}' `
    -ContentType "application/json"
$workerToken = $workerResp.access_token
$workerHeaders = @{"Authorization"="Bearer $workerToken"; "Content-Type"="application/json"}

A.2 OTP 60 秒频控

同一手机号 60 秒内只能发送一次 OTP,第二次会返回 429。如需重新发送,等待 60 秒或更换手机号。

A.3 后端服务未启动

# 检查后端健康
curl -s -o NUL -w "HTTP %{http_code}`n" http://localhost:8000/health
# 如果不是 200,启动后端:
cd D:\AC\TF\hk2026\dip1\backend
D:\AC\TF\hk2026\dip1\backend\.venv312\Scripts\python.exe -m uvicorn app.main:create_app --factory --port 8000

A.4 Swagger UI 交互式文档

浏览器打开 http://localhost:8000/docs,可直接在页面上测试所有 API。


修订记录

版本 日期 修订人 修订内容
V1.0 2026-08-11 DT 初版:师傅端 10 步 + 客户端 12 步 + 验收 Checklist 22 项 + 安全红线 5 项

本指南对齐 DIP1-WLG V1.1 规范,编号 DWLG-20260811-04。