This commit is contained in:
ray zhou
2026-06-29 14:51:55 +08:00
parent 225fb2bd28
commit 2dd9f17da9
319 changed files with 29461 additions and 9412 deletions

View File

@@ -0,0 +1,121 @@
<!-- 23416728-def1-424f-ba2f-16a110d1f084 -->
---
todos:
- id: "internal-layer"
content: "新建 internal DeviceController + 迁移 logic/dto/validateDTO 含 user_id"
status: pending
- id: "cleanup-api"
content: "从 api DeviceController 移除绑定三接口并删除 api 侧绑定文件"
status: pending
- id: "remove-user-auth"
content: "删除 UserAuth、UserRequestContext 及无引用错误码"
status: pending
- id: "docs-update"
content: "更新 device.md §10、03-user-binding.md、06-internal-api.md 路径与调用方说明"
status: pending
- id: "verify"
content: "docker php -l + slot-backend-completion-report"
status: pending
isProject: false
---
# SR-3 设备绑定迁入 internal 应用
## 架构判断(同意你的方向)
与 [device.md](device/docs/requirements/device.md) 中已有分层一致:
| 应用 | 调用方 | 鉴权 | 职责 |
|------|--------|------|------|
| **api** | 物理设备 | `device_sn` + 签名 | 激活、心跳、OTA 入口 |
| **admin** | 后台 BFF / admin-service | `Authorization`(骨架) | 产品/型号/设备档案管理 |
| **internal** | user-service、message-service、ota-service 等 | `X-Internal-Token` | 跨服务读写设备主数据 |
绑定关系是 **device-service 的领域数据**,但 **用户登录态不应在本服务校验**——应由 user-service或 App BFF完成 session/JWT 校验后,再调用 device-service 的 internal 接口写入绑定。这与 §4.3「后台 → BFF → device-service」模式同构。
```mermaid
sequenceDiagram
participant User as 用户App
participant UserSvc as user_service_BFF
participant Device as device_service_internal
User->>UserSvc: 扫码绑定 device_sn
Note over UserSvc: 校验登录态,解析 user_id
UserSvc->>Device: POST /internal/device/bind
Note over Device: X-Internal-Token + user_id + device_sn
Device-->>UserSvc: code=0
UserSvc-->>User: 绑定成功
```
**结论**SR-3 应落在 **internal**,而不是 api当前 [DeviceController.php](device/app/api/controller/DeviceController.php) 上的 `#[Middleware(UserAuth)]` + `UserRequestContext` 应移除。
---
## 目标接口默认路由id 走 body/query
| 方法 | 路径 | 入参 |
|------|------|------|
| POST | `/internal/device/bind` | `user_id`, `device_sn` |
| POST | `/internal/device/unbind` | `user_id`, `device_id` |
| GET | `/internal/device/list` | `user_id`query |
鉴权:应用级 [InternalTokenAuth](device/app/middleware/InternalTokenAuth.php)(已挂在 `internal`**不再**使用 [UserAuth](device/app/middleware/UserAuth.php)。
---
## 代码迁移步骤
### 1. 新建 internal 分层(从 api 平移)
- 新增 [app/internal/controller/DeviceController.php](device/app/internal/controller/DeviceController.php)`extends InternalController`
- `bind` / `unbind` / `list` 三个 action
- 将以下文件 **改 namespace 为 `app\internal\*`**(逻辑基本不变):
- [app/api/logic/DeviceBindLogic.php](device/app/api/logic/DeviceBindLogic.php) → `app/internal/logic/DeviceBindLogic.php`
- [app/api/dto/DeviceBindDTO.php](device/app/api/dto/DeviceBindDTO.php) → 增加 `userId` 字段
- [app/api/dto/DeviceUnbindDTO.php](device/app/api/dto/DeviceUnbindDTO.php) → 增加 `userId` 字段
- [app/api/validate/DeviceBindValidate.php](device/app/api/validate/DeviceBindValidate.php) → 增加 `user_id` 规则(`require|integer|gt:0`)及 validation 文案
Controller 从 DTO 读取 `userId`**不再**调用 `UserRequestContext::getUserId()`
### 2. 清理 api 应用
- 从 [app/api/controller/DeviceController.php](device/app/api/controller/DeviceController.php) 删除 `bind` / `unbind` / `list``DeviceBindLogic``DeviceBindValidate``UserAuth` 相关 use/构造注入
- 删除 api 侧已迁移的 logic/dto/validate 文件
### 3. 删除用户鉴权骨架(若无其它引用)
- 删除 [app/middleware/UserAuth.php](device/app/middleware/UserAuth.php)
- 删除 [app/support/UserRequestContext.php](device/app/support/UserRequestContext.php)
- `OtaErrorCode::USER_AUTH_FAILED (1004)` 可保留翻译条目(无害),或一并移除——以「无引用」为准
### 4. Logic 行为
[DeviceBindLogic](device/app/api/logic/DeviceBindLogic.php) 业务规则 **不变**(幂等、唯一约束、状态校验);仅入参来源从「上下文 user_id」改为「请求体/Query 显式 `user_id`」。
**安全说明**(写入 SR-3/SR-6 文档internal 信任「调用方已在网关/BFF 完成用户鉴权」;`user_id` 由调用方传入device-service 只负责绑定域规则。与 SR-6 §5「服务间 token」一致。
### 5. 需求文档同步
- [03-user-binding.md](device/docs/requirements/device/03-user-binding.md):路径改为 `/internal/device/*`,注明调用方为 user-service/BFF
- [device.md](device/docs/requirements/device.md) §10同上§10 标题可改为「用户绑定(内部接口,由 user-service 暴露给 App
- [06-internal-api.md](device/docs/requirements/device/06-internal-api.md):补充 bind/unbind/list 三条(扩展 SR-6 范围或交叉引用 SR-3
### 6. 调用方 SDK可选本仓库外
按 [cross-service-sdk](.cursor/rules/cross-service-sdk.mdc),若 user-service 在 monorepo 内,后续在 `slot_sdk` 增加 `DeviceClient`(或 `DeviceBindService`)方法指向上述三条 internal 路径;**本次 device 仓库内可不实现**,仅在计划中标注为调用方跟进项。
---
## 不涉及
- `DeviceBindModel`、错误码 `4208`/`4209`、翻译文案:已存在,无需改业务码
- SR-6 只读查询(单设备档案/批量/在线状态):可另 PR 实现,与本次迁移独立
- 「查询设备绑定用户」admin 详情已只读;若 internal 需要可加 `GET /internal/device/bind-owner?device_id=`**非本次必须**,除非你要求一并做
---
## 验收
1. `api` 仅保留 `activate``heartbeat`(及后续 OTA
2. `internal` 三条绑定接口带 `X-Internal-Token` 可通,缺 token 返回 `1001` + HTTP 403
3. 绑定/解绑/列表业务行为与现 SR-3 验收要点一致
4. `docker php -l` + completion-report 通过