# 数据库表结构(account-manager v2) ## 数据库路径 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/account-manager/account-manager.db` 路径解析细节见 [RUNTIME.md](RUNTIME.md)。 ## Schema 版本 `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 文件布局 ``` {DATA_ROOT}/{USER_ID}/account-manager/ ├── account-manager.db └── profiles/ └── {domain}/ └── {platform_key}/ └── {safe_label}[_{login_id_suffix}]/ ``` 删除账号时实现会尽量同时删除对应目录。 ## 与 JSON 输出的对应关系 `account get/list/pick-web` 和 `credential pick` 的 JSON 输出字段与上表一一对应。详见 [INTEGRATION.md](INTEGRATION.md) 与 `assets/schemas/`。