背景
当前 BF1ServerAdminService 调用 EA API 时,凭据统一来自全局 ea_accounts 后台账号池。这套机制能跑,但丢失了「该 kick 是谁发起的」这一身份语义——所有 EA 操作在 EA 后端看来都是后台账号在做。
decouple-identity-from-ea 已经把身份与 EA 凭据解耦(user / ea_bindings 分离),同时为本 issue 留好了扩展点:抽象出 BF1ClientProvider 接口(当前默认实现 PooledBF1ClientProvider 走账号池)。本 issue 描述的功能就是新增一个或多个 provider 实现,按链路选择凭据。
核心需求
凭据选择按以下优先级链路:
- 发起者身份:如果登录用户的 primary binding 对应 EA persona 是目标服务器的管理员(在 EA 服管列表内),优先用发起者自己的 binding 凭据调 EA。这样 EA 后端看到的操作者就是该 admin 本人,符合最自然的身份语义。
- 群组绑定账号:引入「群组」实体(参考 xiaomai-bot 的群组设计)。群组由全局 admin 创建,群主与群管理员维护成员。一个群组可配置多个服务器,并绑定服管账号。绑定的账号来源有三种组合:
- 全局 admin 分配的后台账号(来自
ea_accounts)
- 群主指定自己的 EA binding 账号
- 两者兼具(群主账号失效时自动降级到后台账号兜底)
- 后台账号池兜底:以上都不可用时回落到
ea_accounts 全局池(当前默认实现)。
涉及实体(新增)
groups:群组主体(id、名称、owner_user_id、created_at)
group_memberships:群组成员关系(group_id、user_id、role: owner / admin / member)
group_servers:群组绑定的服务器(group_id、server_pk)
group_credentials:群组绑定的凭据源(group_id、priority、source_type: user_binding / ea_account、source_id、is_fallback)
实现锚点
decouple-identity-from-ea change 内会新建 app/domain/games/bf1/client_provider.py 与 PooledBF1ClientProvider,并将 BF1ServerAdminService 改造为接收 provider 参数。本 issue 只需新增 GroupRoutedBF1ClientProvider 实现并在路由层按上下文注入,service 与路由签名不动。
AuditLog.acting_persona_id 在 decouple-identity-from-ea 已经改为取自发起者的 primary binding(无 binding 写 0),与凭据实际来源解耦,本 issue 无需改审计字段语义。
范围
本 issue 不属于 `decouple-identity-from-ea` 范围。建议作为后续独立 OpenSpec change 推进(候选命名:`add-group-and-server-admin-credential-routing`)。
Non-Goals
- 不修改 `AuditLog` schema
- 不影响用户面 BF 数据查询(这些仍走后台账号池)
- 群组功能 UI 是另一个独立 change
背景
当前
BF1ServerAdminService调用 EA API 时,凭据统一来自全局ea_accounts后台账号池。这套机制能跑,但丢失了「该 kick 是谁发起的」这一身份语义——所有 EA 操作在 EA 后端看来都是后台账号在做。decouple-identity-from-ea已经把身份与 EA 凭据解耦(user / ea_bindings 分离),同时为本 issue 留好了扩展点:抽象出BF1ClientProvider接口(当前默认实现PooledBF1ClientProvider走账号池)。本 issue 描述的功能就是新增一个或多个 provider 实现,按链路选择凭据。核心需求
凭据选择按以下优先级链路:
ea_accounts)ea_accounts全局池(当前默认实现)。涉及实体(新增)
groups:群组主体(id、名称、owner_user_id、created_at)group_memberships:群组成员关系(group_id、user_id、role: owner / admin / member)group_servers:群组绑定的服务器(group_id、server_pk)group_credentials:群组绑定的凭据源(group_id、priority、source_type: user_binding / ea_account、source_id、is_fallback)实现锚点
decouple-identity-from-eachange 内会新建app/domain/games/bf1/client_provider.py与PooledBF1ClientProvider,并将BF1ServerAdminService改造为接收 provider 参数。本 issue 只需新增GroupRoutedBF1ClientProvider实现并在路由层按上下文注入,service 与路由签名不动。AuditLog.acting_persona_id在 decouple-identity-from-ea 已经改为取自发起者的 primary binding(无 binding 写 0),与凭据实际来源解耦,本 issue 无需改审计字段语义。范围
本 issue 不属于 `decouple-identity-from-ea` 范围。建议作为后续独立 OpenSpec change 推进(候选命名:`add-group-and-server-admin-credential-routing`)。
Non-Goals