6.1 KiB
todos:
- id: "internal-layer" content: "新建 internal DeviceController + 迁移 logic/dto/validate(DTO 含 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 中已有分层一致:
| 应用 | 调用方 | 鉴权 | 职责 |
|---|---|---|---|
| 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」模式同构。
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 上的 #[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(已挂在 internal),不再使用 UserAuth。
代码迁移步骤
1. 新建 internal 分层(从 api 平移)
- 新增 app/internal/controller/DeviceController.php(
extends InternalController)bind/unbind/list三个 action
- 将以下文件 改 namespace 为
app\internal\*(逻辑基本不变):- app/api/logic/DeviceBindLogic.php →
app/internal/logic/DeviceBindLogic.php - app/api/dto/DeviceBindDTO.php → 增加
userId字段 - app/api/dto/DeviceUnbindDTO.php → 增加
userId字段 - app/api/validate/DeviceBindValidate.php → 增加
user_id规则(require|integer|gt:0)及 validation 文案
- app/api/logic/DeviceBindLogic.php →
Controller 从 DTO 读取 userId,不再调用 UserRequestContext::getUserId()。
2. 清理 api 应用
- 从 app/api/controller/DeviceController.php 删除
bind/unbind/list及DeviceBindLogic、DeviceBindValidate、UserAuth相关 use/构造注入 - 删除 api 侧已迁移的 logic/dto/validate 文件
3. 删除用户鉴权骨架(若无其它引用)
- 删除 app/middleware/UserAuth.php
- 删除 app/support/UserRequestContext.php
OtaErrorCode::USER_AUTH_FAILED (1004)可保留翻译条目(无害),或一并移除——以「无引用」为准
4. Logic 行为
DeviceBindLogic 业务规则 不变(幂等、唯一约束、状态校验);仅入参来源从「上下文 user_id」改为「请求体/Query 显式 user_id」。
安全说明(写入 SR-3/SR-6 文档):internal 信任「调用方已在网关/BFF 完成用户鉴权」;user_id 由调用方传入,device-service 只负责绑定域规则。与 SR-6 §5「服务间 token」一致。
5. 需求文档同步
- 03-user-binding.md:路径改为
/internal/device/*,注明调用方为 user-service/BFF - device.md §10:同上;§10 标题可改为「用户绑定(内部接口,由 user-service 暴露给 App)」
- 06-internal-api.md:补充 bind/unbind/list 三条(扩展 SR-6 范围或交叉引用 SR-3)
6. 调用方 SDK(可选,本仓库外)
按 cross-service-sdk,若 user-service 在 monorepo 内,后续在 slot_sdk 增加 DeviceClient(或 DeviceBindService)方法指向上述三条 internal 路径;本次 device 仓库内可不实现,仅在计划中标注为调用方跟进项。
不涉及
DeviceBindModel、错误码4208/4209、翻译文案:已存在,无需改业务码- SR-6 只读查询(单设备档案/批量/在线状态):可另 PR 实现,与本次迁移独立
- 「查询设备绑定用户」:admin 详情已只读;若 internal 需要可加
GET /internal/device/bind-owner?device_id=,非本次必须,除非你要求一并做
验收
api仅保留activate、heartbeat(及后续 OTA)internal三条绑定接口带X-Internal-Token可通,缺 token 返回1001+ HTTP 403- 绑定/解绑/列表业务行为与现 SR-3 验收要点一致
docker php -l+ completion-report 通过