Release v1.0.56: Credential & Browser Profile Manager
All checks were successful
技能自动化发布 / release (push) Successful in 7s

This commit is contained in:
2026-05-05 18:51:00 +08:00
parent 6b6d2969c3
commit 91057fa3b7
29 changed files with 4582 additions and 900 deletions

View File

@@ -1,28 +1,122 @@
# 数据存储(account-manager)
# 数据库表结构(account-manager v2
## 数据库路径
`{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/account-manager/account-manager.db`
`JIANGCHANG_DATA_ROOT``JIANGCHANG_USER_ID` 由宿主注入,与兄弟技能保持一致。路径解析细节见 [RUNTIME.md](RUNTIME.md)。
路径解析细节见 [RUNTIME.md](RUNTIME.md)。
## `accounts` 表(核心字段)
## Schema 版本
- `id` —— 自增主键,CLI 与跨技能常称「账号 id」
- `name` —— 展示用名称(如「豆包1号」)
- `platform` —— 平台英文键(小写,如 `doubao``sohu`),见 [PLATFORMS.md](PLATFORMS.md)
- `phone` —— 归一化后的 11 位数字串
- `profile_dir` —— 持久化浏览器用户数据目录绝对路径,供 Playwright 等复用
- `url` —— 该平台默认入口 URL
- `extra_json` —— 可选扩展(JSON 文本),`get` 成功时可能并入返回对象
- `created_at` / `updated_at` —— Unix 秒;`pick-web` 等按更新时间排序选候选
`PRAGMA user_version = 2`
**说明**:表中**不**存「是否已登录」字段;业务侧在真实浏览器会话中自行处理登录态。
## 1. platforms — 平台注册表
| 字段 | 类型 | 说明 |
|------|------|------|
| `platform_key` | TEXT PK | 平台唯一键maersk / deepseek / sohu 等) |
| `display_name` | TEXT NOT NULL | 展示名Maersk / DeepSeek / 搜狐号) |
| `domain` | TEXT NOT NULL | 业务域logistics / llm / content / ecommerce / generic |
| `provider_code` | TEXT | 供应商代码,物流 profile 可复用 |
| `default_url` | TEXT | 默认入口 URL |
| `aliases_json` | TEXT | 别名 JSON 数组 |
| `capabilities_json` | TEXT | 能力声明 JSON`{"web":true,"api_key":true,"rpa":true}` |
| `enabled` | INTEGER | 是否启用1=yes 0=no |
| `created_at` | INTEGER | Unix 秒 UTC |
| `updated_at` | INTEGER | Unix 秒 UTC |
**索引:** `idx_platforms_domain`, `idx_platforms_provider_code`
## 2. accounts — 账号身份
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER PK AUTO | 主键 |
| `platform_key` | TEXT NOT NULL | 对应 platforms.platform_key |
| `account_label` | TEXT NOT NULL | 人可读名称 |
| `login_id` | TEXT | 登录标识email/phone/username/customer_code可空 |
| `login_id_type` | TEXT | email / username / phone / customer_code / api_account / unknown |
| `tenant_id` | TEXT | 租户/项目标识,可空 |
| `environment` | TEXT | simulator / staging / production / test |
| `role` | TEXT | booking / tracking / admin / sales / api / default |
| `provider_code` | TEXT | 冗余供应商码 |
| `profile_dir` | TEXT | Playwright 持久化浏览器 profile 目录 |
| `url` | TEXT | 账号默认入口 URL |
| `status` | TEXT | active / disabled / needs_review |
| `session_status` | TEXT | unknown / likely_valid / needs_login / expired |
| `last_used_at` | INTEGER | 最近 pick/使用时间 |
| `last_login_check_at` | INTEGER | 最近登录检查时间 |
| `last_error_code` | TEXT | 最近错误代码 |
| `last_error_message` | TEXT | 最近错误消息 |
| `extra_json` | TEXT | 扩展字段 JSON |
| `created_at` | INTEGER | Unix 秒 UTC |
| `updated_at` | INTEGER | Unix 秒 UTC |
**索引:** `idx_accounts_platform`, `idx_accounts_pick_web`, `idx_accounts_provider`, `idx_accounts_status`
**唯一约束说明:** `(platform_key, login_id, tenant_id, environment, role)` 通过应用层检查,因为 SQLite 允许多条 NULL login_id。
## 3. credentials — 凭据API Key / Token / Password
**核心原则SQLite 只保存元数据,不保存 secret 明文。**
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER PK AUTO | 主键 |
| `account_id` | INTEGER | 关联 accounts.id可空平台级 API Key |
| `platform_key` | TEXT NOT NULL | 平台唯一键 |
| `credential_label` | TEXT NOT NULL | 人可读名称 |
| `credential_type` | TEXT | api_key / password / bearer_token / oauth_client / refresh_token / browser_profile / note |
| `secret_storage` | TEXT | none / env / windows_credential |
| `secret_ref` | TEXT | env 时为环境变量名windows_credential 时为 target name |
| `secret_mask` | TEXT | 打码展示sk-****abcd不可反推 |
| `expires_at` | INTEGER | 过期时间 |
| `status` | TEXT | active / disabled / expired / needs_rotation |
| `last_used_at` | INTEGER | 最近使用时间 |
| `extra_json` | TEXT | 扩展字段 JSON |
| `created_at` | INTEGER | Unix 秒 UTC |
| `updated_at` | INTEGER | Unix 秒 UTC |
**索引:** `idx_credentials_platform_type`, `idx_credentials_account`, `idx_credentials_status`
## 4. account_leases — RPA 并发锁
防止多个任务同时打开同一个 profile_dir。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | INTEGER PK AUTO | 主键 |
| `account_id` | INTEGER NOT NULL | 关联 accounts.id |
| `lease_token` | TEXT UNIQUE | 随机 token用于 release/heartbeat |
| `holder` | TEXT NOT NULL | 持有者标识 |
| `purpose` | TEXT | 用途说明 |
| `expires_at` | INTEGER NOT NULL | 过期时间 |
| `heartbeat_at` | INTEGER | 最近心跳时间 |
| `released_at` | INTEGER | 主动释放时间 |
| `status` | TEXT | active / released / expired |
| `created_at` | INTEGER | Unix 秒 UTC |
| `updated_at` | INTEGER | Unix 秒 UTC |
**索引:** `idx_leases_account_status`, `idx_leases_token`, `idx_leases_expires`
**约束:**
- acquire 前先把过期 active lease 标记为 expired
- 同一 account_id 同时只能有一个 active 未过期 lease
- release 必须校验 lease_token
## Profile 文件布局
浏览器配置目录通常位于技能数据目录下的 `profiles/` 分层路径,由实现生成。删除账号时实现会尽量同时删除对应目录,见 [CLI.md](CLI.md) `delete` 说明。
```
{DATA_ROOT}/{USER_ID}/account-manager/
├── account-manager.db
└── profiles/
└── {domain}/
└── {platform_key}/
└── {safe_label}[_{login_id_suffix}]/
```
删除账号时实现会尽量同时删除对应目录。
## 与 JSON 输出的对应关系
`get` / `list-json` / `pick-web` 单行 JSON 的键名与上表及 `extra_json` 展开规则见 [INTEGRATION.md](INTEGRATION.md) 与仓库 `assets/schemas/`
`account get/list/pick-web` `credential pick` JSON 输出字段与上表一一对应。详见 [INTEGRATION.md](INTEGRATION.md) 与 `assets/schemas/`