|
| 1 | +# 账号卡身份模型迁移执行计划 v01 |
| 2 | + |
| 3 | +## 核心决策 |
| 4 | + |
| 5 | +1. 本地产品实体只有账号卡,没有用户实体。 |
| 6 | +2. `account_key` / `account_id` 是账号卡的唯一业务身份。 |
| 7 | +3. `auth-id` / `auth-index` / `source_hash` / `provider` / OAuth subject / email / API key hash 只作为 runtime evidence。 |
| 8 | +4. rate-limit 是账号卡资产级策略,只能以 `account_key` 为匹配键。 |
| 9 | +5. 本次不兼容旧版本:迁移后移除 rate-limit `match_key` schema、DTO、API 和前端字段。 |
| 10 | + |
| 11 | +## 数据模型 |
| 12 | + |
| 13 | +### Sidecar Config |
| 14 | + |
| 15 | +`config.CodexKey` 增加: |
| 16 | + |
| 17 | +```go |
| 18 | +LocalID string `yaml:"local-id,omitempty" json:"local-id,omitempty"` |
| 19 | +``` |
| 20 | + |
| 21 | +规则: |
| 22 | + |
| 23 | +- 账号登录 / 新增 key:创建新账号卡,生成新 `local-id`。 |
| 24 | +- 重新登录 / 编辑当前卡凭证:保留原 `local-id`。 |
| 25 | +- standalone sidecar 发现缺失 `local-id` 的 codex key:启动或保存时生成并持久化。 |
| 26 | + |
| 27 | +### Runtime Auth |
| 28 | + |
| 29 | +`sdk/cliproxy/auth.Auth` 增加: |
| 30 | + |
| 31 | +```go |
| 32 | +AccountKey string `json:"account_key,omitempty"` |
| 33 | +``` |
| 34 | + |
| 35 | +runtime candidate 生成规则: |
| 36 | + |
| 37 | +- Codex API key:`config.CodexKey.LocalID` |
| 38 | +- auth-file:`auth-file:<file-name>` |
| 39 | +- OpenAI-compatible:`openai-compatible:<provider-name>` |
| 40 | + |
| 41 | +### SQLite |
| 42 | + |
| 43 | +`usage_attribution_events` 保留: |
| 44 | + |
| 45 | +- `account_key`:业务归属,必须优先写入。 |
| 46 | +- `attribution_key`:运行态证据,仅用于诊断和迁移回填。 |
| 47 | + |
| 48 | +`rate_limit_rules` 删除: |
| 49 | + |
| 50 | +- `match_key` |
| 51 | +- `idx_rate_limit_rules_match` |
| 52 | + |
| 53 | +`rate_limit_events` 删除: |
| 54 | + |
| 55 | +- `match_key` |
| 56 | + |
| 57 | +## 执行阶段 |
| 58 | + |
| 59 | +### 阶段 1:红灯测试(已完成) |
| 60 | + |
| 61 | +Sidecar tests: |
| 62 | + |
| 63 | +1. `CodexKey` 缺失 `local-id` 时,synthesizer/runtime auth 必须失败当前新测试。 |
| 64 | +2. `Auth` 缺失 `AccountKey` 时,runtime identity 测试失败。 |
| 65 | +3. rate-limit schema 仍含 `match_key` 的结构测试失败。 |
| 66 | +4. evaluator 仍使用 `attribution_key` fallback 的源码结构测试失败。 |
| 67 | + |
| 68 | +GetTokens tests: |
| 69 | + |
| 70 | +1. 前端 rate-limit 源码不允许出现 `matchKey` 的测试先失败。 |
| 71 | +2. Wails / cliproxyapi DTO 不允许出现 `MatchKey` 的测试先失败。 |
| 72 | + |
| 73 | +### 阶段 2:sidecar identity foundation(已完成) |
| 74 | + |
| 75 | +修改: |
| 76 | + |
| 77 | +- `internal/config/config.go` |
| 78 | +- `internal/api/handlers/management/config_lists.go` |
| 79 | +- `internal/watcher/synthesizer/config.go` |
| 80 | +- `sdk/cliproxy/auth/types.go` |
| 81 | +- 必要时补充 auth-file / OpenAI-compatible synthesizer 的 `AccountKey` |
| 82 | + |
| 83 | +验收: |
| 84 | + |
| 85 | +- `go test ./internal/config ./internal/api/handlers/management ./internal/watcher/synthesizer ./sdk/cliproxy/auth` |
| 86 | + |
| 87 | +### 阶段 3:usage attribution account_key 写入(已完成) |
| 88 | + |
| 89 | +修改: |
| 90 | + |
| 91 | +- `internal/gettokenshooks/usage_attribution.go` |
| 92 | +- `internal/gettokenshooks/usage_attribution_test.go` |
| 93 | + |
| 94 | +验收: |
| 95 | + |
| 96 | +- GetTokens 管理账号的新 usage event 必须有 `account_key`。 |
| 97 | +- unresolved event 保留 `attribution_key`,但不参与账号卡策略。 |
| 98 | + |
| 99 | +### 阶段 4:rate-limit 破坏性清理(已完成) |
| 100 | + |
| 101 | +修改: |
| 102 | + |
| 103 | +- `internal/gettokenshooks/rate_limit.go` |
| 104 | +- `internal/gettokenshooks/rate_limit_test.go` |
| 105 | + |
| 106 | +验收: |
| 107 | + |
| 108 | +- `PRAGMA table_info(rate_limit_rules)` 不含 `match_key`。 |
| 109 | +- `PRAGMA table_info(rate_limit_events)` 不含 `match_key`。 |
| 110 | +- usage 查询只按 `account_key = ?`。 |
| 111 | +- 两个相同凭证不同账号卡的用量和规则互不影响。 |
| 112 | + |
| 113 | +### 阶段 5:GetTokens bridge/frontend 清理(已完成) |
| 114 | + |
| 115 | +修改: |
| 116 | + |
| 117 | +- `internal/cliproxyapi/types.go` |
| 118 | +- `internal/cliproxyapi/client_test.go` |
| 119 | +- `internal/wailsapp/rate_limit_test.go` |
| 120 | +- `app_types.go` |
| 121 | +- `app_mappers.go` |
| 122 | +- `frontend/src/features/accounts/model/rateLimit.ts` |
| 123 | +- `frontend/src/features/accounts/components/RateLimitRulesSection.tsx` |
| 124 | +- `frontend/src/features/accounts/tests/rateLimit.test.mjs` |
| 125 | + |
| 126 | +验收: |
| 127 | + |
| 128 | +- 前端和 Wails rate-limit 类型不再出现 `matchKey` / `MatchKey`。 |
| 129 | +- UI 保持单行摘要 + 编辑配置态,不再横向滚动。 |
| 130 | +- 账号详情弹窗不直接 import Wails rate-limit CRUD;由 Accounts/Codex page shell 根据 desktop/preview 注入 `RateLimitRulesAPI`。 |
| 131 | + |
| 132 | +### 阶段 6:文档、memory、索引(已完成) |
| 133 | + |
| 134 | +修改: |
| 135 | + |
| 136 | +- 本 space README / plan |
| 137 | +- `docs-linhay/dev/account-card-identity-model.md` |
| 138 | +- `docs-linhay/memory/2026-05-29.md` |
| 139 | + |
| 140 | +命令: |
| 141 | + |
| 142 | +```bash |
| 143 | +docs-linhay/scripts/check-docs.sh |
| 144 | +qmd update |
| 145 | +qmd embed |
| 146 | +``` |
| 147 | + |
| 148 | +## 验证命令 |
| 149 | + |
| 150 | +Sidecar: |
| 151 | + |
| 152 | +```bash |
| 153 | +go test ./internal/gettokenshooks |
| 154 | +go test ./internal/config ./internal/api/handlers/management ./internal/watcher/synthesizer ./sdk/cliproxy/auth |
| 155 | +``` |
| 156 | + |
| 157 | +GetTokens: |
| 158 | + |
| 159 | +```bash |
| 160 | +go test ./internal/cliproxyapi ./internal/wailsapp |
| 161 | +cd frontend && node --test src/features/accounts/tests/rateLimit.test.mjs |
| 162 | +cd frontend && npm run typecheck |
| 163 | +docs-linhay/scripts/check-docs.sh |
| 164 | +qmd update && qmd embed |
| 165 | +``` |
| 166 | + |
| 167 | +## 风险 |
| 168 | + |
| 169 | +1. WebSocket pinned auth 可能存在独立路径,必须确认同样携带 `AccountKey`。 |
| 170 | +2. 破坏性迁移会丢弃无法归属账号卡的旧 rate-limit 规则;这是本次明确接受的行为。 |
| 171 | + |
| 172 | +## 执行记录 |
| 173 | + |
| 174 | +- 2026-05-29:sidecar runtime auth 已覆盖 Codex API key、auth-file、OpenAI-compatible provider 的 `AccountKey`。 |
| 175 | +- 2026-05-29:sidecar standalone Codex API key 缺失 `local-id` 时会生成 `codex-api-key:legacy-*` 并写回配置。 |
| 176 | +- 2026-05-29:sidecar rate-limit schema/API/evaluator 删除 `match_key`,只按 `account_key` 查询 usage。 |
| 177 | +- 2026-05-29:GetTokens Wails / frontend rate-limit DTO 删除 `matchKey`,规则区改为单行摘要 + 配置态。 |
| 178 | +- 2026-05-29:修复 browser preview 根因,`UnifiedAccountDetailModal` / `CodexAccountDetailModal` 不再直连真实 Wails rate-limit CRUD。 |
| 179 | +- 2026-05-29:已运行 Sidecar 聚焦 Go 测试、GetTokens Go 测试、frontend `typecheck`、`build` 和 `test:unit`。 |
| 180 | +- 2026-05-29:已用 `playwright-cli` 验收账号详情限流区 summary / config 态,并归档截图。 |
0 commit comments