Files
pangolin/docs/superpowers/plans/2026-06-29-device-session-management.md
T
wangjia 889cff4556 docs(plan): 设备&会话管理 实现计划 P1-P6(md执行源 + html阅读版 + 登记 + 链接)
新增 docs/superpowers/plans/2026-06-29-device-session-management.md(执行真相,
checkbox) + docs/device-session-management-plan.html(阅读版);登记进 index.html
「实现计划」;总方案顶部加「→ 实现计划」链接。P1 设备注册打通→P2 sessions表+
在线→P3 强制退出/清除→P4 每设备流量→P5 2FA(future)→P6 UI重做。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 00:15:35 +08:00

69 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 设备 & 会话管理 + 每设备流量归因 —— 实现计划(P1–P6)
> 执行真相源(checkbox)。设计见 `docs/device-session-management-design.html`;阅读版 `docs/device-session-management-plan.html`。
> SQL 走中性方言(`dialect.Upsert`、无 `NOW()`/`UTC_TIMESTAMP()`);UI 走 token 单源;不碰 CI-gated golden 的 Linux 基线。每期 build+test 过即 commit。
## 计划文档(先产出)
- [x] `docs/superpowers/plans/2026-06-29-device-session-management.md`(本文件)
- [ ] `docs/device-session-management-plan.html`(阅读版)
- [ ] 登记 `docs/index.html`「实现计划」
- [ ] 总方案 `device-session-management-design.html` 加「→ 实现计划」链接
## P1 · 设备注册打通(登录即注册设备)
- [ ] 客户端加依赖 `uuid` + `device_info_plus``client/pubspec.yaml`
- [ ]`client/lib/services/device_identity.dart``deviceId()`secure storage 读;无则 `Uuid().v4()` 写;读失败 ≠ 没有,不重生成)、`deviceName()`/`platform()``clientVersion()`
- [ ] 弃用 `connection_provider.dart``_kDeviceId='mac-001'` → 用 `device_identity`
- [ ] `auth_api.dart` login/register 请求体加 `device:{id,name,platform,client_version}`
- [ ] `auth/handler.go``loginRequest`/`registerRequest``Device deviceMeta`
- [ ] `auth/service.go` Login/Register:成功签发后调 `DeviceRegistrar.RegisterIfAbsent`consumer-side 接口;`devices.Service` 实现;`RegisterIfAbsent` 增返回 `deviceID`);`MaxDevices` 由 plan 解析
- [ ] `normalizePlatform``linux`
- [ ] `main.go` 构造 `devices.Service` 注入 `authSvc`
- [ ] 测试:`device_identity` 单测;auth 集成(登录后 devices 落行)
- [ ] 验收:登录后 `GET /v1/me/devices` 非空
## P2 · sessions 表 + 在线/最后登录
- [ ] migration `000016_sessions_and_device_meta`mysql+sqlite,含 down):建 sessions 表;devices 加 `client_version`+`totp_trusted_until`;唯一键 `UNIQUE(uuid)``UNIQUE(user_id,uuid)`platform CHECK 加 `linux`
- [ ]`server/internal/sessions/``Store`Create/RotateJTI/RevokeByJTI/RevokeByDevice/ActiveByUserWithDevice/LastLoginByDevice
- [ ] `TokenManager.Issue`/`Refresh` 外露 refresh JTI
- [ ] `auth.Service` 注入 `sessions.Store`Login/Register `Create`Refresh `RotateJTI`+last_activeLogout `RevokeByJTI`
- [ ] `nodes/handler_grpc.go: ReportUsage` deviceID>0 时 touch `devices.last_seen`
- [ ] `devices.Service.ListDevices`+API struct+store join:增 `client_version`/`online`/`last_login`
- [ ] 客户端 `Device` model 加 `clientVersion`/`online`/`lastLogin``account_api` 解析
- [ ] 测试:sessions storeJTI surfaceReportUsage touchListDevices 计算;migration sqlite 实库
- [ ] 验收:列表显示在线/版本/最后登录;停 agent ~3min 转离线
## P3 · 两个操作(强制退出 + 清除增强)
- [ ] 新端点 `POST /v1/me/devices/{uuid}/logout`handler + `Service.ForceLogout`):`sessions.RevokeByDevice` + 逐 jti `TokenManager.Revoke`
- [ ] `DeleteDevice` 增强:加 `sessions.RevokeByDevice``CredentialRevoker` 改 per-device
- [ ] `CredentialRevoker` 接口改 `RevokeDevice(ctx, dpUUID)``nodes.Hub` 实现;`main.go` 注入 hub 替 NoopRevoker
- [ ] 客户端 `account_api.forceLogout` + `devicesProvider.forceLogout`
- [ ] 测试:ForceLogout 删 jti+标 revoked_atDeleteDevice per-device revoke
- [ ] 验收:强制退出→refresh 失败;清除→设备消失+凭证作废
## P4 · 每设备流量验证
- [ ] `ConnectNode` 兜底 `RegisterIfAbsent`device 缺失时)
- [ ] 端到端确认 `usage_device_daily` 填充
- [ ] 统计页设备下拉接真实设备 + `deviceUsageProvider`#10
- [ ] 测试:集成(注册→连接→上报→有行);统计页设备下拉 widget
- [ ] 验收:统计页按设备看分流量
## P5 · (未来)2FA 信任设备 —— 本轮不编码
- 占位:清除联动 `totp_trusted_until`P2 已预留列)。
## P6 · UI 重做(DevicesScreen,五端)
- [ ] `DevicesScreen` 重做:名称/平台·版本/在线绿点/最后登录 + 本机标 + 行尾 ⋯ 菜单 + 危险确认弹窗;走 token
- [ ] 宽/窄屏适配;空/加载态
- [ ] l10n`app_text.dart`+`strings_{zh,en}.dart` 新增文案
- [ ] goldenDevicesScreen 新 goldenMac 生成,非 CI-gated
- [ ] 测试:widget(在线/离线/菜单/确认/调用)
- [ ] 验收:与 §7 视觉稿一致,五端生效
## Verification
- 后端 `go build ./... && go test ./...`(含 sqlite 实库)+ `./server/run_sqlite_test.sh`
- 客户端 `flutter analyze` + `flutter test`
- 端到端:登录→设备列表;停 agent→离线;强制退出→refresh 失败;清除→消失+凭证作废;走流量→`usage_device_daily` 有行
- **线上 000016 迁移在 pangolin1 跑 `pangolin-migrate up` —— 生产写,执行前单独确认**
## 不在本轮
- P5 只占位;存量空 devices 无需回填(新登录自然铺开)