Admin:新增幂等 Client 登记接口 #12

Closed
opened 2026-08-06 17:17:03 +08:00 by ila · 3 comments
Owner

基本信息

  • 类型:跨模块接口需求
  • 关联 Client 工单:#11
  • 关联 Client Epic / MVP:#1 / #2
  • 阶段:Admin–Client 联调
  • 状态:验收通过

背景

Client 设置页需要在用户点击“保存”时立即登记或更新当前 Windows 客户端。现有 claim 会同时领取任务;如果设置页为了登记调用 claim,可能得到 200 + task 并改变任务状态,造成设置保存与任务领取耦合。

因此新增一个没有任务副作用的幂等登记接口。保留 claim 的隐式登记作为兼容兜底,不新增定时心跳、租约或状态查询。

接口契约

请求

PUT /api/v1/client/registration
X-Client-Id: <稳定设备号>
X-Request-Id: <uuid>
Content-Type: application/json
Authorization: Bearer <token>
{
  "client": {
    "name": "办公室-01"
  },
  "supported_types": ["collect", "purchase"],
  "device": {
    "address": "192.168.0.173:5555",
    "platform": "android",
    "pdd_package": "com.xunmeng.pinduoduo"
  },
  "capabilities": {
    "purchase_mode": "dry_run",
    "schema_versions": [1]
  }
}

规则:

  • X-Client-Id 必填,是 clients.client_id 唯一键;
  • client.name 可选,最多 50 字;
  • supported_types 必须非空,只允许 collect、purchase;
  • device 可选;提供时 platform 当前只接受 android;
  • purchase_mode 只允许 dry_run、live;
  • schema_versions 必须包含正整数;
  • MVP 当前读取但不校验 Authorization,token 不得进入日志。

成功响应

新增和更新统一返回 200 OK:

{
  "registered": true,
  "client_id": "CLIENT-123456",
  "registered_at": "2026-08-06T09:00:00Z"
}

错误

沿用统一错误结构,至少支持:

  • 400 MISSING_CLIENT_ID;
  • 400 INVALID_BODY;
  • 422 INVALID_CLIENT_PROFILE;
  • 500 CLIENT_REGISTER_FAILED,retryable: true。

数据与名称规则

  • 相同 X-Client-Id 重复 PUT 执行 upsert,不创建重复 Client;
  • 显式登记可以更新 Client 名称,因为这是用户点击“保存”的明确操作;
  • 名称为空:新建时用 Client ID 兜底,更新时保留 Admin 现有名称;
  • 更新设备信息、能力、last_seen_at 和 updated_at;
  • 不保存原始硬件指纹、token 或其他敏感信息;
  • 接口不领取任务、不修改任务状态、不返回任务。

与 claim 的关系

  • claim 继续支持隐式登记,避免旧 Client 无法使用;
  • claim 新建 Client 时采用上报名称或 Client ID;
  • claim 更新已有 Client 时不覆盖名称,只更新设备、能力和最近活动时间;
  • claim、result、failure 继续刷新 last_seen_at;
  • 不增加独立心跳接口,在线状态仍由最近活动时间派生。

做什么

  • 更新 Admin/Client 权威契约与联调手册;
  • 新增 PUT /api/v1/client/registration 路由、Handler、Service、Repository 方法;
  • 保持现有 claim 隐式登记兼容行为;
  • 增加 Handler/Service/Repository 测试;
  • 使用真实 curl 验证新增、重复登记、名称更新和错误响应。

不做什么

  • 不增加定时心跳、租约或状态查询;
  • 不从登记接口领取或返回任务;
  • 不实现 Client Qt/HTTP 调用(由 #11 完成);
  • 不改动 PDD 自动化或采购流程;
  • 不在本工单确定正式认证方案。

验收标准

  • 权威契约和联调手册不存在“无登记接口”的冲突描述;
  • 新 Client 登记返回 200 并写入 clients;
  • 相同 Client ID 重复登记不新增记录;
  • 显式登记可更新非空名称;
  • 空名称更新不覆盖已有名称;
  • 登记会更新设备、能力和 last_seen_at;
  • 登记接口不读取、领取或修改任务;
  • claim 隐式登记行为保持兼容;
  • 错误响应符合统一结构和 retryable 语义;
  • token 和原始硬件信息不进入日志;
  • Admin 全量 Go 测试和真实 curl 联调通过;
  • 完成后在 docs/task 归档。
## 基本信息 - 类型:跨模块接口需求 - 关联 Client 工单:#11 - 关联 Client Epic / MVP:#1 / #2 - 阶段:Admin–Client 联调 - 状态:验收通过 ## 背景 Client 设置页需要在用户点击“保存”时立即登记或更新当前 Windows 客户端。现有 `claim` 会同时领取任务;如果设置页为了登记调用 `claim`,可能得到 `200 + task` 并改变任务状态,造成设置保存与任务领取耦合。 因此新增一个没有任务副作用的幂等登记接口。保留 `claim` 的隐式登记作为兼容兜底,不新增定时心跳、租约或状态查询。 ## 接口契约 ### 请求 ```http PUT /api/v1/client/registration X-Client-Id: <稳定设备号> X-Request-Id: <uuid> Content-Type: application/json Authorization: Bearer <token> ``` ```json { "client": { "name": "办公室-01" }, "supported_types": ["collect", "purchase"], "device": { "address": "192.168.0.173:5555", "platform": "android", "pdd_package": "com.xunmeng.pinduoduo" }, "capabilities": { "purchase_mode": "dry_run", "schema_versions": [1] } } ``` 规则: - `X-Client-Id` 必填,是 `clients.client_id` 唯一键; - `client.name` 可选,最多 50 字; - `supported_types` 必须非空,只允许 `collect`、`purchase`; - `device` 可选;提供时 `platform` 当前只接受 `android`; - `purchase_mode` 只允许 `dry_run`、`live`; - `schema_versions` 必须包含正整数; - MVP 当前读取但不校验 Authorization,token 不得进入日志。 ### 成功响应 新增和更新统一返回 `200 OK`: ```json { "registered": true, "client_id": "CLIENT-123456", "registered_at": "2026-08-06T09:00:00Z" } ``` ### 错误 沿用统一错误结构,至少支持: - `400 MISSING_CLIENT_ID`; - `400 INVALID_BODY`; - `422 INVALID_CLIENT_PROFILE`; - `500 CLIENT_REGISTER_FAILED`,`retryable: true`。 ## 数据与名称规则 - 相同 `X-Client-Id` 重复 PUT 执行 upsert,不创建重复 Client; - 显式登记可以更新 Client 名称,因为这是用户点击“保存”的明确操作; - 名称为空:新建时用 Client ID 兜底,更新时保留 Admin 现有名称; - 更新设备信息、能力、`last_seen_at` 和 `updated_at`; - 不保存原始硬件指纹、token 或其他敏感信息; - 接口不领取任务、不修改任务状态、不返回任务。 ## 与 claim 的关系 - `claim` 继续支持隐式登记,避免旧 Client 无法使用; - `claim` 新建 Client 时采用上报名称或 Client ID; - `claim` 更新已有 Client 时不覆盖名称,只更新设备、能力和最近活动时间; - `claim`、`result`、`failure` 继续刷新 `last_seen_at`; - 不增加独立心跳接口,在线状态仍由最近活动时间派生。 ## 做什么 - 更新 Admin/Client 权威契约与联调手册; - 新增 `PUT /api/v1/client/registration` 路由、Handler、Service、Repository 方法; - 保持现有 claim 隐式登记兼容行为; - 增加 Handler/Service/Repository 测试; - 使用真实 curl 验证新增、重复登记、名称更新和错误响应。 ## 不做什么 - 不增加定时心跳、租约或状态查询; - 不从登记接口领取或返回任务; - 不实现 Client Qt/HTTP 调用(由 #11 完成); - 不改动 PDD 自动化或采购流程; - 不在本工单确定正式认证方案。 ## 验收标准 - [x] 权威契约和联调手册不存在“无登记接口”的冲突描述; - [x] 新 Client 登记返回 200 并写入 clients; - [x] 相同 Client ID 重复登记不新增记录; - [x] 显式登记可更新非空名称; - [x] 空名称更新不覆盖已有名称; - [x] 登记会更新设备、能力和 last_seen_at; - [x] 登记接口不读取、领取或修改任务; - [x] claim 隐式登记行为保持兼容; - [x] 错误响应符合统一结构和 retryable 语义; - [x] token 和原始硬件信息不进入日志; - [x] Admin 全量 Go 测试和真实 curl 联调通过; - [x] 完成后在 `docs/task` 归档。
Author
Owner

状态:进行中(契约文档阶段)。本轮先更新双方权威契约和联调手册,不实现 Admin 代码;文档提交后等待 Admin 按本工单实施。

状态:进行中(契约文档阶段)。本轮先更新双方权威契约和联调手册,不实现 Admin 代码;文档提交后等待 Admin 按本工单实施。
Author
Owner

契约文档阶段完成:已更新 Admin/Client 需求、架构、数据模型、接口契约和设备登记联调手册。文档提交 02073ea。接口仍未实现,工单保持打开,等待 Admin 开发路由、Service、Repository、测试及真实 curl 联调。

契约文档阶段完成:已更新 Admin/Client 需求、架构、数据模型、接口契约和设备登记联调手册。文档提交 `02073ea`。接口仍未实现,工单保持打开,等待 Admin 开发路由、Service、Repository、测试及真实 curl 联调。
ila closed this issue 2026-08-06 17:41:37 +08:00
Author
Owner

用户已确认 #12 验收通过。

验收复核:

  • 合法登记返回 200,并写入 Client;
  • 相同 Client ID 重复登记保持一条记录;
  • 名称、设备、能力和活动时间更新符合契约;
  • 非法资料返回统一 422 错误;
  • 登记没有任务副作用;
  • go vet ./...、go test ./... 通过;
  • 使用 Gin httptest 和隔离 SQLite 完成独立 HTTP 验证。

本地归档:docs/task/12-admin-新增幂等-client-登记接口.md
归档提交:262f48c

非阻塞技术债已写入归档:补长期 Handler 测试、清理 Handler 中过期注释。Epic #1 和 MVP #2 已同步勾选。

用户已确认 #12 验收通过。 验收复核: - 合法登记返回 200,并写入 Client; - 相同 Client ID 重复登记保持一条记录; - 名称、设备、能力和活动时间更新符合契约; - 非法资料返回统一 422 错误; - 登记没有任务副作用; - `go vet ./...`、`go test ./...` 通过; - 使用 Gin httptest 和隔离 SQLite 完成独立 HTTP 验证。 本地归档:`docs/task/12-admin-新增幂等-client-登记接口.md` 归档提交:`262f48c` 非阻塞技术债已写入归档:补长期 Handler 测试、清理 Handler 中过期注释。Epic #1 和 MVP #2 已同步勾选。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#12