基于 skill-template 脚手架开发,包含: - payroll_config(费率配置,可编辑)+ payslip_snapshots(解析历史,只读)2 张业务表 - 全国默认 + 北上广 4 套费率(社保/公积金/个税起征点/7 级税率表) - 5 个业务 Action:calculate-payslip-simple / calculate-payslip-full / explain-term / view-config / edit-config - 个税累计预扣法计算,支持多月历史累加 - 20 个薪资名词库(社保/公积金/个税/全勤/加班费等) - 完整市场文档(README/TUTORIAL/DEMO/CHANGELOG) - 296 测试全部通过
217 lines
11 KiB
Markdown
217 lines
11 KiB
Markdown
# account-manager 接入标准(账号 / Profile / 租约)
|
||
|
||
> 本文是浏览器 RPA 技能接入账号体系的统一标准。开发者和 AI 编程工具在编写 `account_client.py`、处理多账号、排查登录状态或验收浏览器任务前,必须阅读本文。
|
||
|
||
## 目录
|
||
|
||
- [1. 为什么必须依赖 account-manager](#1-为什么必须依赖-account-manager)
|
||
- [2. 核心模型](#2-核心模型)
|
||
- [3. 强制规则](#3-强制规则)
|
||
- [4. 标准生命周期](#4-标准生命周期)
|
||
- [5. 账号选择与多账号](#5-账号选择与多账号)
|
||
- [6. 创建后去哪里查看](#6-创建后去哪里查看)
|
||
- [7. 登录状态与 Profile 验收](#7-登录状态与-profile-验收)
|
||
- [8. 租约与异常退出](#8-租约与异常退出)
|
||
- [9. 工业级测试](#9-工业级测试)
|
||
- [10. 排障顺序与提问证据](#10-排障顺序与提问证据)
|
||
- [11. 安全边界](#11-安全边界)
|
||
|
||
## 1. 为什么必须依赖 account-manager
|
||
|
||
真实用户会长期使用同一个账号,也会在批量发布、矩阵运营、多店铺、多租户等场景中使用多个账号。一次打开临时浏览器、成功操作一两条数据,不能证明技能可交付。
|
||
|
||
account-manager 统一负责:
|
||
|
||
- 账号身份及平台归属;
|
||
- 一账号一份持久化浏览器 Profile;
|
||
- Cookie、会话和登录状态的持续复用;
|
||
- 多任务之间的账号租约与并发互斥;
|
||
- 账号状态、最近错误和运维排查入口。
|
||
|
||
业务技能只负责编排业务动作,不得再造一套账号库,也不得随意找一个浏览器目录直接运行。
|
||
|
||
## 2. 核心模型
|
||
|
||
| 对象 | 含义 | 业务技能应如何使用 |
|
||
|------|------|--------------------|
|
||
| `account` | 某个平台上的一个账号身份 | 通过 account-manager CLI 获取,不自行落库 |
|
||
| `profile_dir` | 该账号独占的浏览器用户数据目录 | 只传给 `launch_persistent_context`,长期复用 |
|
||
| 登录状态 | 目标站 Cookie / Session 等实际会话 | 由业务技能打开同一 Profile 后检查;账号已登记不代表已登录 |
|
||
| `lease_token` | 当前任务对账号的临时独占权 | 打开浏览器前取得,所有退出路径释放 |
|
||
| `session_status` / error | 会话健康和最近故障线索 | 登录失效或账号异常时按约定回写 |
|
||
|
||
关系必须保持为:
|
||
|
||
```text
|
||
一个账号记录 ──绑定──► 一个稳定 profile_dir
|
||
│
|
||
└──任务运行前取得 lease_token ──► 同一时刻只允许一个任务使用
|
||
```
|
||
|
||
## 3. 强制规则
|
||
|
||
1. 所有浏览器 RPA,包括公开页和无需登录的页面,都必须先经 account-manager 取得 `profile_dir`。
|
||
2. 一个账号只能绑定一个稳定 Profile;不同账号禁止共用 Profile。
|
||
3. 禁止使用本机日常 Chrome / Edge 用户目录,禁止每次运行创建无归属的临时 Profile。
|
||
4. 获取账号时必须同时取得租约;仅 `account get <id>` 不能代替租约。
|
||
5. 业务代码只通过单一 `scripts/service/account_client.py` 集中调用 account-manager CLI。
|
||
6. 禁止 import account-manager 的 `service/`、`db/`、`util/`、`rpa_helpers` 等内部模块。
|
||
7. 未取得非空 `profile_dir` 和 `lease_token` 时禁止打开浏览器。
|
||
8. 账号均被占用时返回 `ERROR:LEASE_CONFLICT`,不得自动创建重复账号或换号绕过。
|
||
9. 所有成功、失败、取消和异常路径都必须在 `finally` 中释放租约。
|
||
10. 密码、Cookie、Token、短信验证码等敏感信息不得写入业务技能配置、数据库、日志或错误信息。
|
||
|
||
对应机器门禁:`POLICY-RPA-004`、`POLICY-RPA-006`。
|
||
|
||
## 4. 标准生命周期
|
||
|
||
```text
|
||
解析用户指定账号
|
||
→ ensure / pick 账号并取得租约
|
||
→ 校验账号平台、profile_dir、lease_token
|
||
→ 用 profile_dir 启动持久浏览器
|
||
→ 打开目标站并检查实际登录状态
|
||
→ 执行业务并记录结果
|
||
→ 回写会话状态 / 最近错误
|
||
→ 关闭浏览器
|
||
→ finally 释放租约
|
||
```
|
||
|
||
参考结构:
|
||
|
||
```python
|
||
account = pick_web_account(platform=TARGET_PLATFORM, account_id=account_id, login_id=login_id)
|
||
lease_token = account["lease_token"]
|
||
try:
|
||
profile_dir = account["profile_dir"]
|
||
# 只用 profile_dir 启动 persistent context,然后检查登录并执行任务
|
||
finally:
|
||
release_lease(lease_token)
|
||
```
|
||
|
||
浏览器启动、登录门禁、业务执行和关闭顺序见 [`RPA.md`](RPA.md) §0.2;CLI 封装边界见 [`ADAPTER.md`](ADAPTER.md)。
|
||
|
||
## 5. 账号选择与多账号
|
||
|
||
选择优先级:
|
||
|
||
1. 用户明确指定纯数字 `DEFAULT_ACCOUNT_ID`:先确认账号存在且平台一致,再通过可定位该账号的 pick 流程取得租约;不得只 `get` 后返回空租约。
|
||
2. 用户指定 `DEFAULT_LOGIN_ID`:使用 `ensure-web --login-id` 获取或登记,并取得租约。
|
||
3. 用户未指定账号:按平台 `ensure-web`,有则选择可用账号,无则登记一条。
|
||
4. 多条记录无法唯一确定:返回 `ERROR:AMBIGUOUS_ACCOUNT`,要求用户明确选择。
|
||
5. 匹配账号均被占用:返回 `ERROR:LEASE_CONFLICT`,等待或由运维确认租约状态。
|
||
|
||
批量和矩阵任务必须以账号为隔离单元:
|
||
|
||
- 每个账号独立 Profile、独立租约、独立任务结果和失败原因;
|
||
- 同一账号默认串行,不因追求吞吐提高同账号并发;
|
||
- 一个账号失败不得污染其他账号的 Profile 或结果;
|
||
- 设置单账号批量上限、单位时间操作上限和任务总时长;
|
||
- 风控、封禁或权限错误不得自动切换下一个账号继续试探。
|
||
|
||
## 6. 创建后去哪里查看
|
||
|
||
账号创建成功后必须可见、可查,不得只相信命令没有报错。
|
||
|
||
### 6.1 宿主数据管理
|
||
|
||
优先在匠厂宿主的**数据管理页面**查看 account-manager 数据:
|
||
|
||
- 账号记录:确认账号 ID、平台、账号名称 / 登录标识、状态、`profile_dir`、会话状态;
|
||
- 租约记录:确认当前持有者、用途、到期时间和是否已释放;
|
||
- 凭据记录:只能查看类型、引用和脱敏值,不应出现明文密码或 Token。
|
||
|
||
宿主版本若直接展示数据库表,对应核心表为 `accounts`、`account_leases`、`credentials`、`platforms`。不得在数据管理页面或 SQLite 工具中随意修改记录。
|
||
|
||
### 6.2 account-manager CLI
|
||
|
||
在 account-manager 仓库或宿主提供的入口中检查:
|
||
|
||
```powershell
|
||
python scripts/main.py account list --platform <platform_key> --limit 50
|
||
python scripts/main.py account get <account_id>
|
||
python scripts/main.py lease list --active
|
||
python scripts/main.py account open <account_id>
|
||
```
|
||
|
||
`account open` 仅用于查看指定 Profile。业务运行仍须走带租约的 pick / ensure 流程。
|
||
|
||
### 6.3 本地用户数据目录
|
||
|
||
实际数据按宿主注入的用户隔离:
|
||
|
||
```text
|
||
{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/account-manager/
|
||
├── account-manager.db
|
||
└── profiles/
|
||
└── {domain}/
|
||
└── {platform_key}/
|
||
└── {safe_label}[_{login_id_suffix}]/
|
||
```
|
||
|
||
- `account-manager.db` 保存账号、平台、凭据元数据和租约。
|
||
- `profiles/...` 是真实浏览器用户数据目录,保存对应账号的 Cookie / Session 等浏览器状态。
|
||
- 实际路径以 `account get <id>` 返回的 `profile_dir` 为准,不得在代码里拼写固定盘符或用户 ID。
|
||
- Profile 正在使用时禁止复制、移动、删除或同时打开;需要迁移或清理时先停止任务并释放租约。
|
||
|
||
## 7. 登录状态与 Profile 验收
|
||
|
||
“账号已创建”只表示账号记录和 Profile 已准备,不代表目标站已经登录。
|
||
|
||
最小验收必须完成:
|
||
|
||
1. 数据管理页面或 `account list` 能看到账号记录。
|
||
2. `profile_dir` 非空、真实存在,并位于当前用户的 account-manager 数据目录。
|
||
3. 两个不同账号的 `profile_dir` 不相同。
|
||
4. 第一次用该 Profile 打开目标站,按平台要求人工登录或扫码。
|
||
5. 正常关闭浏览器并释放租约。
|
||
6. 再次取得同一账号租约,用同一 `profile_dir` 重开浏览器。
|
||
7. 验证登录状态仍有效;失效时返回 `ERROR:REQUIRE_LOGIN`,不得假成功。
|
||
|
||
## 8. 租约与异常退出
|
||
|
||
- 租约持有者应使用技能 slug 或可追踪任务标识,`purpose` 写明用途。
|
||
- 租约 TTL 应覆盖正常任务时长;长任务需要平台支持的续租策略,不能依赖永不过期。
|
||
- `finally release_lease(...)` 是最低要求,浏览器关闭失败也不能跳过释放尝试。
|
||
- 进程被强制结束后可能留下租约;先用 `lease list --active` 核对,确认没有真实任务仍在使用后再释放或清理。
|
||
- 禁止看到租约冲突就直接删数据库记录、删 Profile、换账号或新建重复账号。
|
||
|
||
## 9. 工业级测试
|
||
|
||
除单账号冒烟测试外,至少覆盖:
|
||
|
||
- 指定账号 ID、指定登录标识和自动选择三条路径;
|
||
- 账号不存在、平台不匹配、Profile 缺失、返回格式异常;
|
||
- 同一账号并发抢占和 `LEASE_CONFLICT`;
|
||
- 业务成功、业务失败、用户取消、浏览器崩溃后的租约释放;
|
||
- 登录过期、验证码 / 二次验证、账号风险和权限不足;
|
||
- 两个以上账号轮换且 Profile、登录态、结果互不污染;
|
||
- 关闭重开后登录保持;
|
||
- 批量长时间运行、限流、有限重试和断点续跑。
|
||
|
||
不得以“单账号成功操作一两次”作为多账号或矩阵能力已经交付的证明。
|
||
|
||
## 10. 排障顺序与提问证据
|
||
|
||
开发者和 AI 在群里提问前按顺序自查:
|
||
|
||
1. 阅读本文以及 [`RPA.md`](RPA.md)、[`ADAPTER.md`](ADAPTER.md)。
|
||
2. 在数据管理页面确认账号记录是否存在、平台和状态是否正确。
|
||
3. 执行 `account list/get`,核对账号 ID、`profile_dir`、`session_status`。
|
||
4. 在文件系统确认 `profile_dir` 是否存在、是否错用了其他用户目录。
|
||
5. 执行 `lease list --active`,确认是否被其他任务占用或残留。
|
||
6. 查看运行日志、任务中心终态、错误码、失败截图和浏览器当前页面。
|
||
7. 判断问题属于账号不存在、租约冲突、登录失效、Profile 损坏、页面变化还是业务失败。
|
||
|
||
仍需协助时必须提供:技能 slug、平台、脱敏账号标识 / 账号 ID、任务时间、错误码、账号与租约检查结果、`profile_dir` 是否存在、脱敏日志和截图。禁止发送密码、Cookie、Token 或验证码。
|
||
|
||
## 11. 安全边界
|
||
|
||
- 账号和 Profile 只能用于用户或企业明确授权的正常业务操作。
|
||
- 多账号管理用于账号隔离、矩阵业务和稳定调度,不得用于绕过频控、封禁或平台限制。
|
||
- 禁止破解协议、逆向客户端、伪造设备指纹、验证码破解、养号、撞库、代理池轮换或自动换号继续试探。
|
||
- 风控、封禁、安全警告和权限不足必须停止或转人工。
|
||
- 不手工编辑 `account-manager.db`,不在账号使用期间操作 Profile 文件。
|
||
|
||
完整合规与风控边界见 [`AI_RPA.md`](AI_RPA.md)。
|