# M1 账户与用户管理 — Chatwoot 功能梳理文档 > 基于 Chatwoot 源码深度阅读 + CodeGraph 上下文梳理 > 生成日期:2026-05-22 > 参照仓库:chatwoot-reference --- ## 1. 账户 CRUD + 设置 + 品牌 ### 账户创建(注册时自动建账) - 功能描述:用户注册时同步创建其第一个 Account,Account 与 User 通过 AccountUser 关联。AccountBuilder 事务性地创建 Account + User + AccountUser(角色默认 administrator)。 - 用户操作流程: 1. 用户在注册页面填写账户名、用户名、邮箱、密码 2. 系统验证邮箱有效性( disposable / blocked domain 检测) 3. 如通过 CAPTCHA 校验,事务性地创建 Account 和 User 4. 发送确认邮件;API-only 模式下直接返回 auth token 5. 已登录用户点击"添加账户"可创建新账户,自动成为该账户 administrator - 涉及的API端点: - `POST /api/v1/accounts` — 创建账户(无需认证) - 请求参数:`{ account_name, user_full_name, email, password, locale }` - 响应(已认证/API-only):`{ data: { id, email, ... }, meta: { access_token, ... } }` - 响应(未确认注册):`{ email: "user@example.com" }` - 涉及的数据模型: - **Account**(`accounts` 表):`id, name, domain, locale, status, feature_flags, settings, custom_attributes, limits, support_email, auto_resolve_duration, internal_attributes` - `status` enum:active(0), suspended(1) - `settings` jsonb:包含 auto_resolve_after, auto_resolve_message, auto_resolve_ignore_waiting, audio_transcriptions 等大量配置项(参见 AccountSettingsSchema) - `feature_flags` bigint:位运算存储(FlagShihTzu) - 涉及的业务逻辑: - **AccountBuilder**(`app/builders/account_builder.rb`):事务性创建 Account → User → AccountUser - **Account::SignUpEmailValidationService**:邮箱验证(valid_email2 + blocked domain) - **Account::BrandingEnrichmentJob**:注册后异步从邮箱域名拉取品牌信息(logo/favicon) - 涉及的自动化/规则/事件: - `before_create :enable_default_features` — 根据 InstallationConfig 启用默认 feature flags - `after_create_commit :notify_creation` — ActionCable 通知 - `Account::BrandingEnrichmentJob.perform_later` — 品牌信息异步填充 - `AccountSettingsSchema` — JSON Schema 校验 settings 字段合法性 - CAPTCHA 验证(`validate_captcha` before_action) - 邮件域名黑名单(`SignUpEmailValidationService.blocked_domains`) - Chatwoot原实现关键代码文件路径: - `app/controllers/api/v1/accounts_controller.rb` - `app/builders/account_builder.rb` - `app/services/account/sign_up_email_validation_service.rb` - `app/jobs/account/branding_enrichment_job.rb` - `app/models/account.rb` - `app/models/concerns/account_settings_schema.rb` - `app/models/concerns/featurable.rb` - 版本标注:**社区版** ### 账户查看(Show) - 功能描述:返回当前账户详情,包含 feature flags、settings、limits、品牌信息等。 - 用户操作流程:用户切换到某账户后,前端自动请求账户数据以渲染侧边栏和设置页。 - 涉及的API端点: - `GET /api/v1/accounts/:id` - 响应:`{ id, name, domain, locale, features, settings, limits, ... }` - 涉及的数据模型:Account 全字段 + `latest_chatwoot_version`(Redis::Alfred) - 涉及的业务逻辑:`AccountsController#show` — 查 Redis 获取最新 Chatwoot 版本号用于版本提示 - 涉及的自动化/规则/事件:Pundit 授权(AccountPolicy#show? → administrator || agent) - Chatwoot原实现关键代码文件路径: - `app/controllers/api/v1/accounts_controller.rb` - `app/policies/account_policy.rb` - 版本标注:**社区版** ### 账户更新(Update) - 功能描述:管理员更新账户名称、域名、语言、支持邮箱、settings(自动解决配置等)、custom_attributes。 - 用户操作流程: 1. 管理员进入 Settings → Account Settings 2. 编辑账户名称/域名/locale/support_email 3. 编辑 auto_resolve_after、auto_resolve_message 等会话自动解决配置 4. 保存 - 涉及的API端点: - `PUT /api/v1/accounts/:id` - 请求参数:`{ name, locale, domain, support_email, settings: { auto_resolve_after, ... }, custom_attributes: { ... } }` - 涉及的数据模型:Account 的 `name, locale, domain, support_email, settings, custom_attributes` - 涉及的业务逻辑: - 合并 `custom_attributes` 和 `settings`(merge! 策略,非覆盖) - JSON Schema 校验 settings(`AccountSettingsSchema`) - onboarding_step 步进逻辑:account_details → invite_team - 涉及的自动化/规则/事件:Pundit(AccountPolicy#update? → 仅 administrator) - Chatwoot原实现关键代码文件路径: - `app/controllers/api/v1/accounts_controller.rb` - `app/models/concerns/account_settings_schema.rb` - `app/policies/account_policy.rb` - 版本标注:**社区版** ### 账户激活时间更新(Update Active At) - 功能描述:用户切换账户时更新 AccountUser 的 `active_at`,用于前端判断当前活跃账户。 - 涉及的API端点:`POST /api/v1/accounts/:id/update_active_at` - 涉及的数据模型:AccountUser `active_at` - 涉及的业务逻辑:直接更新 `active_at = Time.now.utc` - Chatwoot原实现关键代码文件路径:`app/controllers/api/v1/accounts_controller.rb` - 版本标注:**社区版** ### 账户缓存键(Cache Keys) - 功能描述:前端轮询获取账户级别缓存键,用于判断数据是否需要刷新。 - 涉及的API端点:`GET /api/v1/accounts/:id/cache_keys` - 涉及的业务逻辑:`CacheKeysHelper#cache_keys_for_account` 生成多维缓存键 - Chatwoot原实现关键代码文件路径:`app/controllers/api/v1/accounts_controller.rb`, `app/helpers/cache_keys_helper.rb` - 版本标注:**社区版** --- ## 2. 用户注册 / 登录 / OAuth ### 用户注册(邮箱+密码) - 功能描述:通过 AccountBuilder 创建账户时同步注册用户;独立注册仅通过账户创建入口。Devise Confirmable 模块要求邮箱确认后才能登录。 - 用户操作流程: 1. 填写邮箱、密码、全名 2. 系统调用 AccountBuilder → User.create! + Account.create! + AccountUser.create! 3. 发送确认邮件 4. 用户点击邮件链接确认邮箱 5. 确认后可正常登录 - 涉及的API端点: - `POST /api/v1/accounts`(注册入口与账户创建合一) - `GET /auth/confirmation?confirmation_token=xxx`(Devise 确认回调) - `POST /api/v1/resend_confirmation`(重发确认邮件) - 涉及的数据模型: - **User**(`users` 表):`id, name, email, display_name, encrypted_password, provider, uid, confirmation_token, confirmed_at, confirmation_sent_at, unconfirmed_email, reset_password_token, reset_password_sent_at, sign_in_count, current_sign_in_at, current_sign_in_ip, last_sign_in_at, last_sign_in_ip, availability, message_signature, custom_attributes, ui_settings, pubsub_token, tokens, type` - Devise 模块:`:database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :password_has_required_content` - 涉及的业务逻辑: - **Account::SignUpEmailValidationService**:邮箱有效性 + disposable + blocked domain - **AccountBuilder**:事务创建 User → Account → AccountUser - Devise Confirmable:确认邮件 → token 校验 → 设置 confirmed_at - 涉及的自动化/规则/事件: - 邮箱确认后才能登录(`DeviseOverrides::SessionsController` 检查 confirmed?) - 密码必须包含数字+字母+特殊字符(`:password_has_required_content`) - Chatwoot原实现关键代码文件路径: - `app/builders/account_builder.rb` - `app/services/account/sign_up_email_validation_service.rb` - `app/controllers/devise_overrides/confirmations_controller.rb` - `app/controllers/auth/resend_confirmations_controller.rb` - `app/models/user.rb` - 版本标注:**社区版** ### 用户登录(邮箱+密码 + MFA + SSO) - 功能描述:支持邮箱密码登录、MFA 二次验证、SSO 一次性令牌登录。基于 DeviseTokenAuth 实现 JWT 式 token 认证(多 token 机制,支持并发多设备)。 - 用户操作流程: 1. 用户输入邮箱 + 密码 → `POST /auth/sign_in` 2. 若启用 MFA,返回 `mfa_required` 错误,前端引导用户输入 OTP/backup code 3. 用户输入 `mfa_token` → 再次 `POST /auth/sign_in` 完成 MFA 校验 4. 若使用 SSO 登录(`sso_auth_token`),直接通过令牌认证 5. 成功后返回 auth headers(`access-token, client, uid, expiry`) - 涉及的API端点: - `POST /auth/sign_in` — 登录 - 请求:`{ email, password }` 或 `{ email, password, mfa_token }` 或 `{ email, sso_auth_token }` - 响应成功:auth headers + 用户 JSON - 响应 MFA:`{ errors: ["mfa_required"], mfa_required: true }` - 响应未确认:`{ errors: ["user_not_confirmed"] }` - 涉及的数据模型:User `email, encrypted_password, otp_required_for_login, otp_secret, confirmed_at, provider` - 涉及的业务逻辑: - **DeviseOverrides::SessionsController**: - `find_user_for_authentication`:邮箱 + 密码校验 - `handle_mfa_verification`:Mfa::AuthenticationService 校验 OTP 或 backup code - `handle_mfa_required`:返回 MFA 提示 - `handle_sso_authentication`:SsoAuthenticatable#valid_sso_auth_token? - `process_sso_auth_token`:SSO token 前置处理 - **Mfa::AuthenticationService**:OTP / backup code 校验 - **SsoAuthenticatable**:Redis 管理临时 SSO token(5 分钟有效期) - 涉及的自动化/规则/事件: - MFA 启用的用户必须经过二次验证 - SSO auth token 5 分钟过期(Redis::Alfred setex) - DeviseTokenAuth 多 token 机制:每次登录生成新 token 对(access-token + client) - Chatwoot原实现关键代码文件路径: - `app/controllers/devise_overrides/sessions_controller.rb` - `app/models/concerns/sso_authenticatable.rb` - `app/services/mfa/management_service.rb` - `app/services/mfa/authentication_service.rb` - 版本标注:**社区版** ### 用户密码重置 - 功能描述:通过邮箱发送重置密码链接,用户点击链接后设置新密码。 - 用户操作流程: 1. 用户在登录页点击"忘记密码" 2. 输入邮箱 → `POST /auth/password` → 发送重置邮件 3. 用户点击邮件中的链接 4. 输入新密码 + 确认密码 → `PUT /auth/password` → 返回 auth headers - 涉及的API端点: - `POST /auth/password` — 请求重置邮件 - `PUT /auth/password` — 执行重置(`{ reset_password_token, password, password_confirmation }`) - 涉及的数据模型:User `reset_password_token, reset_password_sent_at, encrypted_password` - 涉及的业务逻辑:**DeviseOverrides::PasswordsController** — 标准 Devise 流程 + 返回 auth headers - Chatwoot原实现关键代码文件路径:`app/controllers/devise_overrides/passwords_controller.rb` - 版本标注:**社区版** ### OAuth 登录(Google OAuth2 / SAML) - 功能描述:支持 Google OAuth2 和 SAML 作为外部认证提供者。OAuth 回调后查找或创建用户,生成 SSO auth token 重定向到前端登录页完成认证。 - 用户操作流程: 1. 用户点击"Google 登录"按钮 2. 重定向到 Google OAuth 授权页 3. 授权后回调到 `/auth/google_oauth2/callback` 4. 系统查找/创建用户,生成 SSO auth token 5. 重定向到前端 `/app/login?email=xxx&sso_auth_token=xxx` 6. 前端用 SSO auth token 调用 `POST /auth/sign_in` 完成认证 - 涉及的API端点: - `GET /auth/google_oauth2` — 发起 OAuth - `GET /auth/google_oauth2/callback` — OAuth 回调 - `POST /auth/saml_login` — SAML 登录入口(企业版) - 涉及的数据模型:User `provider, uid`(OAuth 用户 provider='google_oauth2', uid=Google sub) - 涉及的业务逻辑: - **DeviseOverrides::OmniauthCallbacksController**: - `sign_in_user`:找到用户 → 生成 SSO auth token → 重定向到登录页 - `sign_up_user`:创建新用户 → 设置随机密码 → 重定向到登录页 - `sign_in_user_on_mobile`:移动端 deeplink 方式 - **SsoAuthenticatable**:`generate_sso_auth_token`(Redis 5分钟有效期) - 涉及的自动化/规则/事件: - OAuth 新用户自动确认邮箱(`skip_confirmation!`) - OAuth 新用户设置随机密码 - 移动端通过 deeplink 跳转 - Chatwoot原实现关键代码文件路径: - `app/controllers/devise_overrides/omniauth_callbacks_controller.rb` - `app/models/concerns/sso_authenticatable.rb` - `enterprise/app/controllers/api/v1/auth_controller.rb` - 版本标注:**社区版**(Google OAuth2)/ **企业版**(SAML) ### Token 验证 - 功能描述:验证当前 access-token 是否有效,用于前端刷新时校验 session。 - 涉及的API端点:`GET /auth/validate_token` - 涉及的业务逻辑:**DeviseOverrides::TokenValidationsController** — DeviseTokenAuth 标准 + 自定义渲染 - Chatwoot原实现关键代码文件路径:`app/controllers/devise_overrides/token_validations_controller.rb` - 版本标注:**社区版** --- ## 3. AccountUser 多账户角色 ### AccountUser 关联管理 - 功能描述:一个 User 可属于多个 Account(通过 AccountUser 中间表),每个 AccountUser 独立设定 role(administrator/agent)、availability、auto_offline、custom_role_id、agent_capacity_policy_id。 - 用户操作流程: 1. 管理员在 Settings → Agents 列表中邀请/删除/编辑成员 2. 用户切换账户时前端调用 `update_active_at` 更新活跃账户 3. 用户可在 Profile 中设置各账户的 availability 和 auto_offline - 涉及的API端点: - `POST /api/v1/accounts/:account_id/agents` — 邀请成员 - `PUT /api/v1/accounts/:account_id/agents/:id` — 更新成员角色/availability - `DELETE /api/v1/accounts/:account_id/agents/:id` — 删除成员 - `POST /api/v1/accounts/:account_id/agents/bulk_create` — 批量邀请 - `GET /api/v1/accounts/:account_id/agents` — 列出成员 - `POST /api/v1/profile/availability` — 更新当前用户在某账户的 availability - `POST /api/v1/profile/auto_offline` — 更新 auto_offline - `PUT /api/v1/profile/set_active_account` — 切换活跃账户 - 涉及的数据模型: - **AccountUser**(`account_users` 表):`id, account_id, user_id, role, availability, auto_offline, active_at, inviter_id, custom_role_id, agent_capacity_policy_id` - `role` enum:agent(0), administrator(1) - `availability` enum:online(0), offline(1), busy(2) - 索引:`uniq_user_id_per_account_id`(account_id + user_id 联合唯一) - 涉及的业务逻辑: - **AgentBuilder**(`app/builders/agent_builder.rb`):查找或创建 User → 创建 AccountUser → 发送邀请邮件 - **AccountsController#update_active_at**:更新 active_at - **ProfilesController#availability / #auto_offline / #set_active_account**:各账户独立设置 - 删除 Agent 时:`AccountUser.destroy!` → 如果用户无其他账户则删除 User 记录 - 涉及的自动化/规则/事件: - `after_create_commit :notify_creation, :create_notification_setting` — 创建 AccountUser 时自动创建通知设置 - `after_destroy :notify_deletion, :remove_user_from_account` — 删除时清理 - `after_save :update_presence_in_redis` — availability 变更时更新 Redis 在线状态 - **AvailabilityStatusable**:用户 availability_status 综合判断(DB availability + Redis online presence + auto_offline) - Chatwoot原实现关键代码文件路径: - `app/models/account_user.rb` - `app/controllers/api/v1/accounts/agents_controller.rb` - `app/builders/agent_builder.rb` - `app/controllers/api/v1/profiles_controller.rb` - `app/models/concerns/availability_statusable.rb` - `app/policies/user_policy.rb` - 版本标注:**社区版**(role=agent/administrator)/ **企业版**(custom_role_id, agent_capacity_policy_id) --- ## 4. Profile 管理 ### Profile 查看 / 更新 - 功能描述:用户查看和更新自己的个人信息,包括姓名、邮箱、显示名、消息签名、头像、UI 设置等。 - 用户操作流程: 1. 用户点击侧边栏头像 → 进入 Profile 页 2. 编辑 name / display_name / email / message_signature / custom_attributes 3. 更换头像(上传/删除) 4. 修改密码(需输入当前密码验证) 5. 重置 access token(用于 API 访问) 6. 重发邮箱确认 - 涉及的API端点: - `GET /api/v1/profile` — 查看 - `PUT /api/v1/profile` — 更新(含密码修改需 current_password) - `DELETE /api/v1/profile/avatar` — 删除头像 - `POST /api/v1/profile/resend_confirmation` — 重发确认邮件 - `POST /api/v1/profile/reset_access_token` — 重置 access token - `POST /api/v1/profile/availability` — 更新某账户 availability - `POST /api/v1/profile/auto_offline` — 更新某账户 auto_offline - `PUT /api/v1/profile/set_active_account` — 设置活跃账户 - 涉及的数据模型:User `name, display_name, email, message_signature, ui_settings, custom_attributes, avatar(ActiveStorage)` - 涉及的业务逻辑: - **ProfilesController**: - `update`:密码修改需验证 current_password;其他字段直接 assign_attributes + merge custom_attributes - `avatar`:删除 ActiveStorage attachment - `reset_access_token`:`user.access_token.regenerate_token` - 邮箱变更触发 Devise Confirmable reconfirmation 流程 - 涉及的自动化/规则/事件: - 邮箱变更需重新确认(unconfirmed_email 机制) - 密码修改必须验证当前密码 - Chatwoot原实现关键代码文件路径: - `app/controllers/api/v1/profiles_controller.rb` - `app/views/api/v1/profiles/show.json.jbuilder` - 版本标注:**社区版** ### MFA(多因子认证)管理 - 功能描述:用户启用/禁用/验证 TOTP 二步认证,支持 OTP code 和 backup code。 - 用户操作流程: 1. 用户在 Profile → Security 页点击"启用 MFA" 2. 系统生成 otp_secret → 返回 provisioning URI(QR 码) 3. 用户用 Authenticator App 扫码绑定 4. 输入 OTP code 验证 → `POST /api/v1/profile/mfa/verify` 5. 验证成功后启用 MFA,返回 10 个 backup codes 6. 可随时重新生成 backup codes 或禁用 MFA(需验证 OTP) - 涉及的API端点: - `GET /api/v1/profile/mfa` — 查看 MFA 状态 - `POST /api/v1/profile/mfa` — 启用(生成 otp_secret) - `POST /api/v1/profile/mfa/verify` — 验证并激活 - `POST /api/v1/profile/mfa/backup_codes` — 重新生成 backup codes - `DELETE /api/v1/profile/mfa` — 禁用 MFA - 涉及的数据模型:User `otp_secret(encrypted), otp_required_for_login, otp_backup_codes(encrypted)` - 涉及的业务逻辑: - **Mfa::ManagementService**:enable/disable/verify/generate_backup_codes - **Mfa::AuthenticationService**:authenticate(OTP 或 backup code) - backup code 消耗机制:验证后标记为 'XXXXXXXX'(不可重用) - OTP secret 和 backup codes 使用 ActiveRecord encryption - 涉及的自动化/规则/事件: - 全局 MFA 开关:`Chatwoot.mfa_enabled?`(环境变量控制) - 禁用 MFA 需验证当前 OTP/backup code - backup code 常量时间比较(防 timing attack) - Chatwoot原实现关键代码文件路径: - `app/controllers/api/v1/profile/mfa_controller.rb` - `app/services/mfa/management_service.rb` - `app/services/mfa/authentication_service.rb` - `app/services/mfa/token_service.rb` - 版本标注:**社区版** --- ## 5. JWT 认证 + Devise ### DeviseTokenAuth 认证机制 - 功能描述:Chatwoot 使用 DeviseTokenAuth 实现 token-based 认证,而非传统 JWT。每次登录生成一对 token(`access-token` + `client`),通过 HTTP headers 传递。支持多设备并发登录(每个 client 一个 token)。 - 用户操作流程: 1. 登录成功后响应 headers 包含 `access-token, client, uid, expiry, token-type` 2. 前端存储 headers,后续请求携带这些 headers 3. Token 验证:`GET /auth/validate_token` 4. Token 过期后自动刷新(DeviseTokenAuth 内置机制) - 涉及的API端点: - `POST /auth/sign_in` — 登录 - `DELETE /auth/sign_out` — 登出 - `GET /auth/validate_token` — 验证 token - Auth headers:`access-token, client, uid, expiry, token-type` - 涉及的数据模型:User `tokens`(json 列,存储多 client token 信息) - 涉及的业务逻辑: - DeviseTokenAuth 管理多 client token 存储/验证/过期 - `Api::BaseController#authenticate_user!` → DeviseTokenAuth `set_user_by_token` - `Api::BaseController#set_current_user` → 设置 `Current.user` - `Api::BaseController#set_current_account` → 根据 `account_id` 参数设置 `Current.account` + `Current.account_user` - 涉及的自动化/规则/事件: - Token 过期时间 configurable(默认 2 周) - 每次请求可更新 token(change_headers_on_each_request) - Chatwoot原实现关键代码文件路径: - `app/controllers/api/base_controller.rb` - `app/controllers/devise_overrides/sessions_controller.rb` - `app/controllers/devise_overrides/token_validations_controller.rb` - `config/routes.rb`(mount_devise_token_auth_for 'User', at: 'auth') - `app/models/user.rb`(DeviseTokenAuth::Concerns::User) - 版本标注:**社区版** --- ## 6. RBAC 权限 + CustomRole(企业版) ### 内置角色 RBAC - 功能描述:AccountUser 内置两种角色:administrator(1) 和 agent(0)。各 Policy 类基于 `@account_user.role` 做授权判断。administrator 有全部权限,agent 权限受限。 - 用户操作流程:管理员在邀请成员时选择角色(administrator / agent / custom_role)。 - 涉及的API端点: - `POST /api/v1/accounts/:account_id/agents`(role 参数) - `PUT /api/v1/accounts/:account_id/agents/:id`(可更改 role) - 涉及的数据模型:AccountUser `role` enum(agent:0, administrator:1) - 涉及的业务逻辑: - **ApplicationPolicy**:所有 Policy 的基类,接收 `user_context[:account_user]` 进行角色判断 - **AccountPolicy**:show/limits → agent+administrator;update/toggle_deletion/subscription → 仅 administrator - **UserPolicy**:create/update/destroy/bulk_create → 仅 administrator - **AgentPolicy**:通过 Pundit + AccountPolicy 授权 - 涉及的自动化/规则/事件:Pundit 中间件在每次 controller action 前调用 `authorize` 方法 - Chatwoot原实现关键代码文件路径: - `app/policies/application_policy.rb` - `app/policies/account_policy.rb` - `app/policies/user_policy.rb` - `app/controllers/api/base_controller.rb`(`check_authorization` before_action) - 版本标注:**社区版** ### CustomRole 自定义角色(企业版) - 功能描述:企业版允许管理员创建自定义角色(CustomRole),定义细粒度权限(conversation_manage, contact_manage 等),并将 CustomRole 关联到 AccountUser,替代内置 agent 角色提供更精细的权限控制。 - 用户操作流程: 1. 管理员进入 Settings → Custom Roles 2. 创建自定义角色:填写名称、描述、勾选权限列表 3. 在邀请/编辑 Agent 时选择自定义角色 - 涉及的API端点: - `GET /api/v1/accounts/:account_id/custom_roles` — 列出 - `POST /api/v1/accounts/:account_id/custom_roles` — 创建 - `GET /api/v1/accounts/:account_id/custom_roles/:id` — 查看 - `PUT /api/v1/accounts/:account_id/custom_roles/:id` — 更新 - `DELETE /api/v1/accounts/:account_id/custom_roles/:id` — 删除 - 请求:`{ name, description, permissions: ["conversation_manage", "contact_manage", ...] }` - 涉及的数据模型: - **CustomRole**(`custom_roles` 表):`id, name, description, permissions(array), account_id` - 可用权限列表(PERMISSIONS 常量): - `conversation_manage` — 管理所有会话 - `conversation_unassigned_manage` — 管理未分配会话并自分配 - `conversation_participating_manage` — 管理参与的会话 - `contact_manage` — 管理联系人 - `report_manage` — 管理报告 - `knowledge_base_manage` — 管理知识库 - AccountUser `custom_role_id`(FK → custom_roles) - 涉及的业务逻辑: - **CustomRolesController**:CRUD,依赖 EnterpriseAccountsController(企业版校验) - 删除 CustomRole 时 `account_users.custom_role_id` 被 nullify - 涉及的自动化/规则/事件: - Feature flag `custom_roles` 必须启用 - CustomRolePolicy 全部操作仅 administrator - Chatwoot原实现关键代码文件路径: - `enterprise/app/models/custom_role.rb` - `enterprise/app/controllers/api/v1/accounts/custom_roles_controller.rb` - `enterprise/app/policies/custom_role_policy.rb` - `enterprise/app/controllers/api/v1/accounts/enterprise_accounts_controller.rb` - 版本标注:**企业版** --- ## 7. SAML SSO 设置(企业版) ### SAML SSO 配置 - 功能描述:管理员为账户配置 SAML IdP 参数(SSO URL、证书、Entity ID),配置后账户内用户的 `provider` 字段自动更新为 'saml',强制通过 SAML 认证登录。 - 用户操作流程: 1. 管理员进入 Settings → SAML SSO 2. 填写 IdP SSO URL、X.509 Certificate、IdP Entity ID、SP Entity ID 3. 可选配置 role_mappings(SAML 属性 → Chatwoot 角色映射) 4. 保存后,账户用户 provider 字段批量更新为 'saml' - 涉及的API端点: - `GET /api/v1/accounts/:account_id/saml_settings` — 查看 - `POST /api/v1/accounts/:account_id/saml_settings` — 创建 - `PUT /api/v1/accounts/:account_id/saml_settings` — 更新 - `DELETE /api/v1/accounts/:account_id/saml_settings` — 删除 - `POST /api/v1/auth/saml_login` — 发起 SAML 登录 - 请求:`{ sso_url, certificate, idp_entity_id, sp_entity_id, role_mappings: {} }` - 涉及的数据模型: - **AccountSamlSettings**(`account_saml_settings` 表):`id, account_id, sso_url, certificate, idp_entity_id, sp_entity_id, role_mappings(json)` - Account `saml_settings`(has_one 关联) - User `provider`(更新为 'saml') - 涉及的业务逻辑: - **SamlSettingsController**:CRUD + SAML feature flag 校验 + SSO 全局开关校验 - **AccountSamlSettings**: - `after_create_commit :update_account_users_provider` — 批量将账户用户 provider 改为 'saml' - `after_destroy_commit :reset_account_users_provider` — 批量恢复 provider 为 'email' - 证书 X.509 校验(`certificate_must_be_valid_x509`) - SP Entity ID 自动生成(`set_sp_entity_id`) - `certificate_fingerprint`:计算证书指纹 - **Saml::UpdateAccountUsersProviderJob**:批量更新 provider,1000条/批 - **Api::V1::AuthController#saml_login**:根据邮箱查找 SAML 启用的账户,重定向到 `/auth/saml?account_id=xxx` - 涉及的自动化/规则/事件: - Feature flag `saml` 必须启用 - 全局配置 `ENABLE_SAML_SSO_LOGIN` 必须为 true - SAML 设置创建/删除触发批量 provider 更新 Job - SAML 回调 → OmniauthCallbacksController → sign_in_user(生成 SSO auth token) - role_mappings 可将 SAML 属性映射到 Chatwoot 角色 - Chatwoot原实现关键代码文件路径: - `enterprise/app/models/account_saml_settings.rb` - `enterprise/app/controllers/api/v1/accounts/saml_settings_controller.rb` - `enterprise/app/controllers/api/v1/auth_controller.rb` - `enterprise/app/jobs/saml/update_account_users_provider_job.rb` - `enterprise/app/policies/account_saml_settings_policy.rb` - `app/controllers/devise_overrides/omniauth_callbacks_controller.rb` - 版本标注:**企业版** --- ## 8. Company 组织管理(企业版) ### Company CRUD + 品牌 - 功能描述:企业版提供 Company 模型,用于组织/公司级别管理联系人归属。Company 可设置名称、域名、描述、自定义属性,支持自动从域名拉取 favicon 作为 logo。 - 用户操作流程: 1. 管理员/用户进入 Contacts → Companies 页面 2. 创建公司:填写名称、域名(可选)、描述 3. 编辑/删除公司 4. 将联系人关联到公司 5. 搜索公司(按名称或域名) - 涉及的API端点: - `GET /api/v1/accounts/:account_id/companies` — 列出(分页25/页) - `GET /api/v1/accounts/:account_id/companies/search?q=xxx` — 搜索 - `POST /api/v1/accounts/:account_id/companies` — 创建 - `GET /api/v1/accounts/:account_id/companies/:id` — 查看 - `PUT /api/v1/accounts/:account_id/companies/:id` — 更新 - `DELETE /api/v1/accounts/:account_id/companies/:id` — 删除(仅 administrator) - `DELETE /api/v1/accounts/:account_id/companies/:id/destroy_custom_attributes` — 删除自定义属性 - 涉及的数据模型: - **Company**(`companies` 表):`id, account_id, name, domain, description, additional_attributes(jsonb), custom_attributes(jsonb), contacts_count, last_activity_at` - 索引:`(account_id, domain) UNIQUE WHERE domain IS NOT NULL` - 关联:`contacts`(has_many, dependent: nullify) - `Avatarable` — 支持 ActiveStorage avatar + 从域名 favicon 自动拉取 - 涉及的业务逻辑: - **CompaniesController**:CRUD + 搜索 + 分页 + 排序(Sift gem: name/domain/created_at/last_activity_at/contacts_count) - `after_create_commit :fetch_favicon` — 从域名自动拉取 favicon 作为 logo - `record_activity_at!` — 5分钟 rollup 间隔内不重复更新 last_activity_at - 品名长度限制(COMPANY_NAME_LENGTH_LIMIT) - 品域名格式校验 + 账户内唯一 - 涉及的自动化/规则/事件: - Feature flag `companies` 必须启用 - CompanyPolicy:所有用户可 index/show/create/update/search;仅 administrator 可 destroy - favicon 自动拉取(Avatar::AvatarFromFaviconJob) - last_activity_at 活动汇总(ACTIVITY_ROLLUP_INTERVAL = 5分钟) - Chatwoot原实现关键代码文件路径: - `enterprise/app/models/company.rb` - `enterprise/app/controllers/api/v1/accounts/companies_controller.rb` - `enterprise/app/policies/company_policy.rb` - 版本标注:**企业版** --- ## 9. AgentCapacityPolicy 容量策略(企业版) ### 容量策略 CRUD - 功能描述:企业版支持定义 Agent 容量策略(AgentCapacityPolicy),限制每个 Agent 在指定 Inbox 中同时处理的会话数量上限。一个策略可关联多个 Inbox 的容量上限(InboxCapacityLimit),并可分配给多个 AccountUser。 - 用户操作流程: 1. 管理员进入 Settings → Agent Capacity Policies 2. 创建策略:填写名称、描述、排除规则(exclusion_rules) 3. 为策略添加 Inbox 容量限制:选择 Inbox + 设置 conversation_limit 4. 将策略分配给特定 Agent 5. 编辑/删除策略 - 涉及的API端点: - `GET /api/v1/accounts/:account_id/agent_capacity_policies` — 列出 - `POST /api/v1/accounts/:account_id/agent_capacity_policies` — 创建 - `GET /api/v1/accounts/:account_id/agent_capacity_policies/:id` — 查看 - `PUT /api/v1/accounts/:account_id/agent_capacity_policies/:id` — 更新 - `DELETE /api/v1/accounts/:account_id/agent_capacity_policies/:id` — 删除 - 子资源: - `GET /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/users` — 查看分配的 Agent - `POST /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/users` — 分配 Agent - `DELETE /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/users/:id` — 取消分配 - `POST /api/v1/accounts/:account_id/agent_capacity_policies/:policy_id/inbox_limits` — 创建 Inbox 容量限制 - `PUT .../inbox_limits/:id` — 更新容量限制值 - `DELETE .../inbox_limits/:id` — 删除容量限制 - 涉及的数据模型: - **AgentCapacityPolicy**(`agent_capacity_policies` 表):`id, account_id, name, description, exclusion_rules(jsonb)` - `exclusion_rules`:`{ exclude_older_than_hours: int, excluded_labels: [string] }` - 含排除逻辑:超过指定小时数的会话不计入容量;带特定标签的会话不计入容量 - **InboxCapacityLimit**(`inbox_capacity_limits` 表):`id, agent_capacity_policy_id, inbox_id, conversation_limit` - 索引:`(agent_capacity_policy_id, inbox_id) UNIQUE` - `conversation_limit` 必须 >= 0 - **AccountUser** `agent_capacity_policy_id`(FK → agent_capacity_policies) - 涉及的业务逻辑: - **AgentCapacityPoliciesController**:CRUD + 企业版校验 - **AgentCapacityPolicies::UsersController**:分配/取消 Agent → 更新 AccountUser.agent_capacity_policy_id - **AgentCapacityPolicies::InboxLimitsController**:管理各 Inbox 的 conversation_limit - 涉及的自动化/规则/事件: - 仅 administrator 可操作(AgentCapacityPolicyPolicy 全操作限 administrator) - 一个 Inbox 在同一策略下只能有一个容量限制(唯一索引) - AccountUser 删除时 `agent_capacity_policy_id` 被 nullify - Chatwoot原实现关键代码文件路径: - `enterprise/app/models/agent_capacity_policy.rb` - `enterprise/app/models/inbox_capacity_limit.rb` - `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies_controller.rb` - `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies/users_controller.rb` - `enterprise/app/controllers/api/v1/accounts/agent_capacity_policies/inbox_limits_controller.rb` - `enterprise/app/policies/agent_capacity_policy_policy.rb` - `db/migrate/20250806140004_add_agent_capacity_policy_to_account_users.rb` - 版本标注:**企业版** --- ## 10. FeatureFlags 功能开关 ### FeatureFlags 管理 - 功能描述:Account 级别功能开关,通过 FlagShihTzu 位运算存储在 `feature_flags` bigint 列中。支持按 Account 启用/禁用特定功能,前端根据 feature flags 动态显示/隐藏功能入口。 - 用户操作流程: 1. 管理员进入 Settings → Account Features 2. 切换功能开关(enable/disable) 3. 前端实时响应功能可见性变化 - 涉及的API端点: - 通过 Account show/update 间接管理(settings 返回 enabled_features / disabled_features) - Super Admin 可通过 InstallationConfig 设置 `ACCOUNT_LEVEL_FEATURE_DEFAULTS` - 涉及的数据模型: - **Account** `feature_flags`(bigint,位运算存储) - **Featurable** concern:`enable_features! / disable_features! / feature_enabled? / all_features / enabled_features / disabled_features` - **config/features.yml**:定义所有功能开关列表(名称 + 显示名 + 默认启用 + premium 标记) - 涉及的业务逻辑: - **Featurable**(`app/models/concerns/featurable.rb`): - `enable_default_features`:创建 Account 时根据 InstallationConfig 设置默认值 - `feature_enabled?(name)` → 位运算检查 - 功能列表(config/features.yml 关键项): | Feature | Display Name | Default | Premium | |---|---|---|---| | inbound_emails | Inbound Emails | true | - | | channel_email | Email Channel | true | - | | channel_facebook | Facebook Channel | true | - | | help_center | Help Center | true | - | | agent_bots | Agent Bots | true | - | | macros | Macros | true | - | | agent_management | Agent Management | true | - | | team_management | Team Management | true | - | | inbox_management | Inbox Management | true | - | | labels | Labels | true | - | | custom_attributes | Custom Attributes | true | - | | automations | Automations | true | - | | campaigns | Campaigns | true | - | | reports | Reports | true | - | | crm | CRM | true | - | | auto_resolve_conversations | Auto Resolve | true | - | | disable_branding | Disable Branding | false | ✅ premium | | custom_roles | Custom Roles | false | ✅ premium | | sla | SLA | false | ✅ premium | | audit_logs | Audit Logs | false | ✅ premium | | saml | SAML | false | ✅ premium | | companies | Companies | false | ✅ premium | | channel_voice | Voice Channel | false | ✅ premium | | advanced_search | Advanced Search | false | ✅ premium | - 涉及的自动化/规则/事件: - `before_create :enable_default_features` — Account 创建时设置默认 features - premium 功能需要企业版许可证 - feature flag 变更触发缓存清除(`after_update_commit :clear_unread_conversation_counts_cache` 等条件回调) - Chatwoot原实现关键代码文件路径: - `app/models/concerns/featurable.rb` - `config/features.yml` - `app/models/account.rb` - 版本标注:**社区版**(基础功能)/ **企业版**(premium 功能需许可证) --- ## 附录:关键数据模型汇总 ### accounts 表 | 字段 | 类型 | 说明 | |---|---|---| | id | integer PK | 主键 | | name | string NOT NULL | 账户名称 | | domain | string(100) | 入站邮件域名 | | locale | integer default(en) | 账户语言 | | status | integer default(active) | active(0)/suspended(1) | | feature_flags | bigint default(0) | 位运算功能开关 | | settings | jsonb | 账户设置(自动解决、Captain等) | | custom_attributes | jsonb | 自定义属性(含 onboarding_step) | | limits | jsonb | 使用限制 | | support_email | string(100) | 支持邮箱 | | auto_resolve_duration | integer | 自动解决时长 | | internal_attributes | jsonb | 内部属性 | ### users 表 | 字段 | 类型 | 说明 | |---|---|---| | id | integer PK | 主键 | | name | string NOT NULL | 用户名 | | email | string | 邮箱(唯一) | | display_name | string | 显示名 | | encrypted_password | string NOT NULL | 加密密码 | | provider | string default(email) | 认证提供者(email/google_oauth2/saml) | | uid | string NOT NULL | 提供者内ID | | confirmation_token | string | 确认令牌 | | confirmed_at | datetime | 确认时间 | | otp_secret | string(encrypted) | MFA TOTP secret | | otp_required_for_login | boolean default(false) | MFA 启用标志 | | otp_backup_codes | text(encrypted) | MFA 备用码 | | availability | integer default(online) | online(0)/offline(1)/busy(2) | | message_signature | text | 消息签名 | | custom_attributes | jsonb | 自定义属性 | | ui_settings | jsonb | UI偏好设置 | | pubsub_token | string | ActionCable token | | tokens | json | DeviseTokenAuth 多 token 存储 | | type | string | 用户类型(SuperAdmin等STI) | ### account_users 表 | 字段 | 类型 | 说明 | |---|---|---| | id | bigint PK | 主键 | | account_id | bigint FK | 所属账户 | | user_id | bigint FK | 所属用户 | | role | integer default(agent) | agent(0)/administrator(1) | | availability | integer default(online) | online(0)/offline(1)/busy(2) | | auto_offline | boolean default(true) | 自动离线 | | active_at | datetime | 活跃时间 | | inviter_id | bigint FK | 邀请人 | | custom_role_id | bigint FK | 自定义角色(企业版) | | agent_capacity_policy_id | bigint FK | 容量策略(企业版) | ### custom_roles 表(企业版) | 字段 | 类型 | 说明 | |---|---|---| | id | bigint PK | 主键 | | account_id | bigint FK NOT NULL | 所属账户 | | name | string | 角色名称 | | description | string | 角色描述 | | permissions | text array | 权限列表 | ### account_saml_settings 表(企业版) | 字段 | 类型 | 说明 | |---|---|---| | id | bigint PK | 主键 | | account_id | bigint FK NOT NULL | 所属账户 | | sso_url | string | IdP SSO URL | | certificate | text | X.509 Certificate | | idp_entity_id | string | IdP Entity ID | | sp_entity_id | string | SP Entity ID | | role_mappings | json | SAML→角色映射 | ### companies 表(企业版) | 字段 | 类型 | 说明 | |---|---|---| | id | bigint PK | 主键 | | account_id | bigint FK NOT NULL | 所属账户 | | name | string NOT NULL | 公司名称 | | domain | string | 公司域名(账户内唯一) | | description | text | 描述 | | additional_attributes | jsonb | 额外属性 | | custom_attributes | jsonb | 自定义属性 | | contacts_count | integer | 联系人数 | | last_activity_at | datetime | 最后活动时间 | ### agent_capacity_policies 表(企业版) | 字段 | 类型 | 说明 | |---|---|---| | id | bigint PK | 主键 | | account_id | bigint FK NOT NULL | 所属账户 | | name | string(255) NOT NULL | 策略名称 | | description | text | 策略描述 | | exclusion_rules | jsonb NOT NULL | 排除规则 | ### inbox_capacity_limits 表(企业版) | 字段 | 类型 | 说明 | |---|---|---| | id | bigint PK | 主键 | | agent_capacity_policy_id | bigint FK NOT NULL | 所属策略 | | inbox_id | bigint FK NOT NULL | 所属 Inbox | | conversation_limit | integer NOT NULL | 会话容量上限 | --- ## 附录:路由汇总 ``` # 认证路由 POST /auth/sign_in # 登录 DELETE /auth/sign_out # 登出 GET /auth/validate_token # Token 验证 POST /auth/password # 密码重置请求 PUT /auth/password # 密码重置执行 GET /auth/confirmation # 邮箱确认 POST /api/v1/resend_confirmation # 重发确认 GET /auth/google_oauth2 # Google OAuth 发起 GET /auth/google_oauth2/callback # Google OAuth 回调 POST /api/v1/auth/saml_login # SAML 登录(企业版) GET /auth/saml # SAML IdP 重定向 # 账户路由 POST /api/v1/accounts # 创建账户 GET /api/v1/accounts/:id # 查看 PUT /api/v1/accounts/:id # 更新 POST /api/v1/accounts/:id/update_active_at # 更新活跃时间 GET /api/v1/accounts/:id/cache_keys # 缓存键 # 成员管理 GET /api/v1/accounts/:id/agents # 成员列表 POST /api/v1/accounts/:id/agents # 邀请成员 PUT /api/v1/accounts/:id/agents/:id # 更新成员 DELETE /api/v1/accounts/:id/agents/:id # 删除成员 POST /api/v1/accounts/:id/agents/bulk_create # 批量邀请 GET /api/v1/accounts/:id/assignable_agents # 可分配成员 # Profile GET /api/v1/profile # 查看 PUT /api/v1/profile # 更新 DELETE /api/v1/profile/avatar # 删除头像 POST /api/v1/profile/availability # 更新可用状态 POST /api/v1/profile/auto_offline # 更新自动离线 PUT /api/v1/profile/set_active_account # 切换活跃账户 POST /api/v1/profile/resend_confirmation # 重发确认 POST /api/v1/profile/reset_access_token # 重置 token # MFA GET /api/v1/profile/mfa # MFA 状态 POST /api/v1/profile/mfa # 启用 POST /api/v1/profile/mfa/verify # 验证激活 POST /api/v1/profile/mfa/backup_codes # 备用码 DELETE /api/v1/profile/mfa # 禁用 # 企业版路由 GET/POST/PUT/DELETE /api/v1/accounts/:id/saml_settings GET/POST/PUT/DELETE /api/v1/accounts/:id/custom_roles GET/POST/PUT/DELETE /api/v1/accounts/:id/agent_capacity_policies GET/POST/DELETE /api/v1/accounts/:id/agent_capacity_policies/:policy_id/users POST/PUT/DELETE /api/v1/accounts/:id/agent_capacity_policies/:policy_id/inbox_limits GET/POST/PUT/DELETE /api/v1/accounts/:id/companies GET /api/v1/accounts/:id/companies/search ```