从 3 到 30:可扩展的集成目录设计
用简单的数据模型、清晰的状态、权限模型和设置进度 UI,设计一个能从 3 个扩展到 30 个集成的目录。

集成界面需要完成的事(通俗说)
用户打开集成目录只有一个目的:连接工具并让它们无需每日操心地持续工作。如果界面让用户猜测哪些已连接、哪些损坏或下一步该点哪里,信任会迅速下降。
当只有 3 个集成时,简单的 logo 网格可能够用;当增到 30 个时就不行了:人们不再浏览,支持工单增加,“Connect”按钮变成陷阱,因为每个集成都可能处在不同状态。
每张集成卡(或行)应在一眼之内回答三个问题:
- 这是什么?(名称 + 简短用途)
- 现在工作正常吗?(清晰的状态与最近检查/同步时间)
- 我接下来要做什么?(Connect、继续设置、重新授权、管理)
大多数混淆来自真实团队里经常发生的边缘情况。有人用个人账号而不是公司账号连接 Google;Stripe 的令牌过期导致账单停止同步;Slack 已连接,但未授予所需的 channel scope,于是设置显示“半完成”而 UI 看起来正常。
好的界面会把这些情形显而易见地展示出来。不要只写“Connected”,可以显示“Connected(需要权限)”或“Connected to: [email protected]”,并在卡片上放置下一步操作。这能避免猜测,并在规模扩大时保持列表可读。
简单数据模型:catalog vs installs vs connections
扩展集成目录最简单的方法是区分:
- 你提供的内容(catalog)
- 每个工作区启用的项(installs)
- 正在使用的外部帐号或凭据(connections)
这个模型在 3 个集成时仍清晰,在 30 个时仍可行。
三个核心对象
Integration 是目录条目,全局存在,不与某个工作区绑定。
Install 表示某个工作区启用了该 Integration(例如:“Workspace A 已启用 Slack”)。
Connection 表示真实的外部帐号或凭据(例如:“通过 OAuth 的 Slack workspace X” 或 “通过 API key 的 Stripe 帐号 Y”)。一个 Install 可以有多个 Connection。
一个常用的最小字段集:
- Integration:id、key("slack")、display_name、category、auth_type(oauth/api_key/webhook)、docs_hint(简短提示)、created_at
- Install:id、workspace_id、integration_id、status(enabled/disabled)、setup_state(not_started/in_progress/complete)、created_by、created_at、updated_at
- Connection:id、install_id、label("Marketing Slack")、connection_status(ok/expired/error)、external_account_id(若已知)、scopes/permissions_granted、last_success_at、created_at
配置 vs 机密(以及什么绝不能泄露)
把用户可见的配置(选定频道、webhook 昵称、启用的事件)作为普通数据存储在 Install 或 Connection 上。把密钥(OAuth 刷新令牌、API keys、签名密钥)只放在 secrets store 或加密字段里,并严格控制访问。
不要把密钥、完整授权码或原始 webhook 负载写入日志。如果必须记录,记录引用(connection_id)和安全的元数据(HTTP 状态、错误码)。
为兼容 OAuth、API keys 和 webhooks,把认证相关的字段放在 Connection(token 元数据 vs key 指纹 vs webhook 校验状态)。把面向 UI 的状态(enabled 与设置进度)放在 Install。
用户能理解的状态与设置进度
用户打开集成目录想快速回答三件事:是否工作、设置进行到哪一步、下一步做什么。如果状态词模糊,支持工单会上升且信任下降。
从一组能维持多年的小状态集开始:
- Not set up
- In progress
- Connected
- Needs attention
- Disabled
优先使用派生状态而非存储好的标签。存储的标签会漂移:问题修复后徽章仍然红。派生状态由你已经记录的事实计算得出,例如令牌是否有效、必需的设置步骤是否完成、管理员是否暂停集成。如果必须存储,存储的是底层事实(最后成功同步、最后错误码),而非最终标签。
设置进度最好用简短清单表示,并清晰区分必需与可选步骤。把它建模为步骤定义(每个集成静态)加上步骤结果(每个 install 的运行时结果)。
示例:Slack 可能要求“授权工作区”和“选择频道”为必需,可选步骤为“启用消息预览”。UI 可以显示“已完成 2/3 个必需步骤”,同时把可选项保留供发现但不阻塞。
在一个集成下存在多个 Connection 会把目录变成混乱,除非提前规划。保持每个集成只对应一个卡片,显示 connection 数量,并诚实地汇总状态。如果任一 connection 出问题,显示“Needs attention”并附上提示,例如“4 个工作区中 1 个需要重新授权”。总览保持整洁,同时反映真实情况。
在不复杂化的前提下的权限与角色
当把所有权限都当作一个开关处理时,集成权限会变得混乱。更清晰的做法是分开:
- 谁可以查看集成
- 谁可以配置它
- 谁可以日常使用它
先用一个轻量的角色检查在每处适用。很多产品只需三个角色就够:Admin、Manager、Member。Admin 无所不能。Manager 可以为其团队设置大多数集成。Member 可以使用已启用的集成,但不能更改设置。
仅在必要时才为特定集成添加额外权限标记。大多数集成(日历、聊天)遵循默认角色规则。敏感集成(支付、工资、导出)应额外要求诸如“Payments admin”或“Billing manager”之类的标志。把这作为 install 上的一个简单布尔值,而不是一个全新的角色系统。
一个易读的映射示例:
- View:Admin、Manager、Member
- Configure:Admin、Manager(Member 可以看但不能连接或编辑)
- Use:工作区内任何人一旦启用即可使用(除非有限制)
- Sensitive override:只有带特定标志的用户可以配置或触发操作
审计不必很重,但要存在。记录足够回答支持与安全问题的信息:谁连接了它、何时更改凭据、谁禁用了它。详情页上的 “Activity” 面板列出 5 到 20 条最近事件通常足够。
示例:Stripe 对所有人可见,但只有 Admin(或被标记为“Billing manager” 的用户)可以连接、轮换密钥或禁用支付。Slack 可能允许 Manager 来连接,而 Member 在启用后仍能接收通知但不能管理连接。
在 30 个集成时仍然好用的 UI 布局
3 个集成时你可以展示所有内容;30 个时目录必须快速回答一个问题:“哪些能用,下一步我该做什么?”最干净的方式是把扫描与操作分开。
保持目录视图专注于快速决策。把更多控制放到“Manage”后的详情页。
在列表里只展示支持下一次点击所需的信息:
- 图标、名称与一行描述(长度保持一致)
- 清晰的状态 pill(Connected、Needs setup、Error、Disabled)
- 一个主要动作按钮
- 一个二级“Manage”按钮用于其他操作
卡片结构很重要,因为它建立了使用习惯。主要操作应始终表示“下一步”:对新项显示 Connect,对部分完成显示 Continue setup,对认证过期显示 Reconnect,对一切正常的显示 Manage。避免每张卡上出现两个同样突出的按钮,否则页面会显得嘈杂。
示例:
- 若 Google 为 Connected,主要动作可以是 Manage。
- 若 Slack 昨晚出错,显示 Error 并把主要动作设置为 Reconnect。
- 若 Stripe 半完成,显示 Needs setup 并把主要动作作为 Continue setup。
空状态应在不推送长篇指南的前提下引导:
- 无集成已安装:推荐 2–3 个热门选择并说明它们能带来什么价值
- 搜索无结果:给出简单提示,例如“试试 ‘CRM’ 或 ‘billing’”
- 首次设置:一句话说明权限与将访问的数据
这样在 30 个集成时页面仍然冷静,因为每张卡都回答了:它是什么、是否正常、下一步做什么?
详情页:设置流程、Connections 与控制项
目录列表将人们导向正确的集成。详情页是他们决定设置、修复或关闭的地方。保持每个集成页结构一致,即便后端实现不同。
从紧凑的概览开始:集成名、一行描述与清晰状态标签(Connected、Needs attention、Disabled)。加一行“Setup progress”让用户知道是只差一步还是刚开始。
让设置流程感觉安全
简单的向导很有效:3 到 6 步,每次一屏,且始终有“Back”。用通俗语言命名步骤(Connect account、Choose workspace、Pick data to sync、Confirm)。若某步为可选,明确标注为可选而不是隐藏。
如果可以中途暂停,要明确说明:“你可以稍后完成。我们会保存你的选择。”这能降低用户因怕丢失选择而中止的顾虑。
让用户不后悔的 Connections 与控制项
把 Connections 显示为小表格:帐号名、连接人(谁)、创建日期、最后同步时间。
对于“下次同步”,避免给出你无法保证的精确时间。用你能保证的措辞,例如“Next sync:scheduled soon”或“Next sync:within the next hour”,基于系统实际能力来写。
把高风险操作放在主要路径之外。把主要动作放在顶部(Continue setup、Reconnect)。把 Disable 与 Disconnect 放在页面底部的“Danger zone”并说明影响。如果支持角色控制,简短说明(例如“仅 Admin 可断开连接”)。
加一个小的活动日志:最近事件(connected、token refreshed、sync failed)、时间戳与可复制的短错误信息,便于提交支持工单。
逐步流程:从头添加一个新集成
把添加集成当成一个小产品来做。它需要一个目录条目、连接方式、存储连接的地方,以及清晰的成功/失败结果。
1) 从目录条目开始
把集成加入 catalog,这样即便没人连接它也会在目录中展示。包含清晰名称、简短描述、图标和一到两个分类(Messaging、Payments 等)。用通俗的话写设置预期,例如“Connect an account”和“Choose a workspace”。同时定义后续需要的内容(OAuth scopes、必填字段、支持的功能)。
2) 构建连接方式
为提供商选择最简单且匹配的连接方式:
- 当用户必须登录并批准访问时用 OAuth(常见于 Google、Slack)
- 当用户可以粘贴 token 时用 API key
- 当提供商向你的应用推送事件时用 Webhooks
3) 保存凭据并创建 Connection 记录
用户完成流程后,创建一个与工作区或账户关联的 Connection 记录,而不是只和用户绑定。安全地存储凭据(静态加密并避免再次展示完整密钥)。保存支持所需的基础信息:提供商帐号 ID、创建时间、谁连接的、授予了哪些权限。
4) 进行首次检查并设置状态与进度
立即运行一次简单测试(例如对 Stripe:获取帐号详情)。如果通过,显示 Connected 并把进度标记为完成;如果部分通过(连接成功但缺少权限),标记为 Needs attention 并指出准确的修复步骤。
5) 决定失败时用户看到的内容
展示一条清晰的信息、一条推荐操作和一个安全的备选方案。例如:“无法访问 Stripe。请检查 API key 或重试。”即便某个集成出问题也要保证目录可用。
如果你在 Koder.ai (koder.ai) 上构建,可以先在 Planning Mode 起草 catalog、设置流程与状态规则,再从此计划生成 UI 与后端。
错误、重试与对支持友好的历史记录
集成因为一些枯燥的原因失败。若目录不能清楚解释这些原因,用户会责怪你的应用,支持也无从下手。
把失败分为能对应真实修复的类别:登录过期、缺少权限、提供商宕机或速率限制。内部保留详细错误码,但向用户展示他们能理解的简短标签。
当出问题时,信息应回答三点:发生了什么、用户该怎么做、系统接下来会做什么。例如:“Slack 连接已过期。请重新连接以继续同步。重连后我们会自动重试。”比原始 API 错误信息更冷静、可操作。
不让人烦的重试规则
仅在用户无法自行修复时才自动重试。一个简单规则集通常足够:
- 提供商宕机或网络错误:自动重试并退避,同时保留最后成功时间
- 速率限制:暂停并稍后重试,显示“Paused (rate limit)”
- 认证过期:停止重试并要求用户重新连接
- 缺少权限:停止重试并明确显示需要哪项权限
- 配置错误:停止并指向必须填写的设置
状态会变陈旧,除非你刷新它们。添加一个轻量的健康检查任务,定期确认令牌是否仍有效、最近同步是否运行、目录徽章是否与现实一致。
支持可用的历史
为每个 install 保留小规模事件历史。你不需要完整日志,只要足够的面包屑:时间戳、事件(“token refreshed”、“sync failed”)、简短原因以及触发者(用户或系统)。添加一个仅内部可见的备注字段,便于支持记录他们做了什么与为何这样做。
搜索、筛选与组织目录
一旦超过几个应用,目录会迅速变得杂乱。目标很简单:帮助用户在几秒内找到所需内容,并在不打开每张卡的情况下发现问题。
从覆盖集成名称与分类的基本搜索开始。大多数用户会直接输入他们知道的名字(“Slack”、“Stripe”),因此名称匹配比复杂排序更重要。分类搜索在用户只知道功能(payments、messaging)时有用。
筛选应反映真实意图,这三项通常覆盖大多数用例:
- Connected(当前工作)
- Needs attention(错误、令牌过期、缺少权限)
- Not set up(可用但尚未安装)
在组织列表时选一个主分组并坚持使用。分类分组在较多数量时效果好(CRM、Payments、Messaging)。若按流行度排序也可以,但前提是它反映你的用户群而非市场部。一个实用默认:先显示使用率最高的,再按分类分组其余项。
你还需要针对“不是每个人都应看到所有内容”有清晰策略。如果某个集成受 feature flag 或付费等级限制,要么对大多数用户隐藏,要么以禁用状态显示并短述原因,例如“Business plan”。避免显示一整页灰掉的卡片,那会让界面看起来坏掉了。
通过把列表与详情设为分离加载来保持性能。对列表进行分页或虚拟化,避免一次渲染 30 张重量级卡片;当用户打开某个集成时再惰性加载详情。目录可以只展示摘要字段(Slack:Connected,Google:Needs attention,Stripe:Not set up),详情页再请求完整的 connection 历史。
示例:在真实应用中使用 Slack、Google 与 Stripe
假设一个名为 Pinework 的团队工作区应用。有两个角色:Admin 与 Member。Admin 可以连接工具并修改设置;Member 可以使用已连接的工具但不能增删。
在 Pinework 的集成目录中,每张卡显示明确标签(Connected、Needs setup、Error)、一句“它做什么”的说明,以及像“2 of 3 steps”这样的设置进度。用户无需频繁点击就能判断什么可用、什么待完成。
Slack 用于通知。Admin 打开 Slack 会看到:Status:Connected,Setup:“3 of 3 steps”。Member 也能看到 Slack,但主要操作被禁用并显示“Ask an Admin to manage”。如果 Slack 断开,Member 仍能看到出错信息,但不能执行重连。
Google 用于日历。Pinework 支持多个部门,因此允许多个连接。Google 卡片会显示:Status:Connected(2 accounts)。下方短行列出“Marketing Calendar”和“Support Calendar”。详情页显示两个独立的 connection,Admin 可以仅撤销其中一个。
Stripe 用于结算。常见的半完成情况是:帐号已连接,但 webhook 未完成。卡片显示:Status:Needs setup,Progress:“2 of 3 steps”,并警示“Payments may not sync”。详情页明确列出剩余步骤:
- Connect Stripe account(已完成)
- Choose billing plan mapping(已完成)
- Add webhook endpoint(未完成)
这避免了“看起来已连接但实际上无法工作”的尴尬情形。
常见错误,会让集成难以管理
当应用从几项集成扩展到几十项时,集成目录通常会出问题。问题很少是“大技术难题”,而是日常的小标签与建模错误不断累积,最终让人困惑。
常见问题之一是混淆“installed”与“connected”。Installed 通常指“在你的工作区可用”,而 Connected 指有真实凭据且数据可流动。当这两者模糊时,用户会点击看似准备好的集成却遇到死胡同。
另一个错误是发明太多状态。团队从简单徽章开始,然后加入边缘状态:pending、verifying、partial、paused、degraded、blocked、expiring 等等。随着时间推移,这些标签会与现实脱节。保持一套小且可检测的状态,比如 Not connected、Connected、Needs attention。
隐藏权限也会造成麻烦。有人连接了帐号,后来发现该集成拥有比预期更广的访问权限。在最终“Connect”步骤前把 scope 明确列出,并在详情页再次展示以便管理员审计。
不要假设每个集成都只有一个 connection
许多应用需要多个连接:两个 Slack workspace、好几个 Stripe 帐号,或公司共享的 Google 帐号加上个人帐号。如果你把“一次集成 = 一个连接”写死,后来会被丑陋的权宜方案打脸。
要为以下场景做准备:
- 在一个集成下允许多个连接
- 提供明确的“默认”连接(如需)
- 区分共享连接与个人连接
- 提供看到谁连接了它的地方
保持目录列表轻量。把日志、字段映射和长描述塞到卡片里会让扫描变慢。把历史与高级设置放到详情页。
快速检查表与下一步
可扩展的集成目录归结为简单模型与诚实的 UI。如果用户能迅速回答三件事,系统就会变得可预期:哪些已连接、哪些损坏、下一步该做什么?
发版前的检查表:
- 分离模型:Integration(catalog)vs Install(在此工作区启用)vs Connection(OAuth 令牌、API key 或 webhook)。只有需要审计与支持历史时再加 Event。
- 派生状态:从可检测的检查项(令牌有效、scopes OK、webhook 可达)与设置步骤完成情况计算标签,确保徽章准确。
- 保持列表可扫描:每一行显示名称、清晰状态标签和一个“下一步动作”(Connect、Continue、Reconnect、Fix permissions)。
- 使生命周期操作成为一等公民:Connect、Continue setup、Reconnect、Disable、Disconnect 应易于找到并有简短确认。
- 让权限可见且可审计:展示谁可以连接或断开,并记录谁在何时更改了什么。
下一步:选三个你熟悉的集成并端到端建模:一个聊天工具(OAuth)、一个类似 Google 的账号连接(带 scopes 的 OAuth)、一个支付工具(API key 加 webhook)。如果模型能表达这三种情况而无特别分支,通常能扩展到 30 个集成。
常见问题
What’s the one job an integrations directory screen should do?
把它当成控制面板,而不是营销页。每张卡片应该快速说明集成的用途、当前是否可用,以及用户应采取的单一下一步行动。如果用户必须点进去才能知道“是否已连接?”,目录在增长时会变得不可靠。
What should every integration card show at a glance?
一个简单的规则是:每张集成卡应回答“这是什么”“是否正常”以及“下一步怎么办”。通常包括名称与一句话用途、带最近时间戳的状态(最后同步或最后检查),以及一个根据状态变化的主要按钮。把其他操作都放到“Manage”里,保持快速扫描。
Why split the data model into Integration, Install, and Connection?
把“你提供什么”与“某个工作区启用了什么”和“实际凭据是什么”分开。用全局的 Integration(目录条目)、Install(工作区启用记录)和 Connection(实际的 OAuth 帐号、API key 或 webhook)来建模,避免“已安装”与“已连接”混淆。
How do I handle integrations that need multiple connected accounts?
现实团队常常需要为同一提供商连接多个外部帐号:不同部门的 Google 日历、多个 Stripe 帐号等。在一个 Install 下建多个 Connection 可以让目录保持简洁,同时在详情页里让管理员逐个管理帐号。
What status labels should I use so they don’t become confusing later?
使用一小组你能长期维持的一致标签,例如:Not set up、In progress、Connected、Needs attention、Disabled。并从可检测的事实推导标签(令牌是否有效、必需步骤是否完成、最近同步时间),避免标签变成过时的红色徽章。
How should I model and show setup progress without building a huge wizard?
把设置进度做成简短的清单:必需步骤与可选步骤。把步骤定义放在每个 Integration 下(静态),把步骤结果放在每个 Install 下(运行时),这样 UI 能显示“已完成 2/3 个必需步骤”并把下一个缺失的必需步骤直接呈现出来。
How do I keep integration permissions simple but safe?
先用一个全局简单的角色规则,只有在敏感集成上才增加额外校验。对大多数产品而言:Admin 可以配置一切,Manager 可以完成大多数集成的设置,Member 可以使用已启用的集成但不能修改设置。像付款或工资这样的敏感集成,添加一个单独的“支付/结算管理员”标记比新建整个角色系统更好。
Where should I store OAuth tokens and API keys, and what should never go in logs?
把用户可见的配置(选定频道、webhook 名称、启用事件等)作为普通数据存储,把机密(OAuth 刷新令牌、API key、签名密钥)存到专门的 secrets store 或加密字段并限制访问。不要把原始密钥、授权码或 webhook 载荷写入日志;日志记录应只包含引用(connection_id)和安全元数据(HTTP 状态、错误码)。
How should the UI handle errors like expired tokens, outages, and missing permissions?
错误信息要回答三件事:发生了什么、用户应做什么、系统会做什么。重试规则应仅适用于用户无法自行修复的问题(如提供者宕机或网络错误)。对于令牌过期或缺少权限,停止自动重试并把“Reconnect”或“Fix permissions”作为主要操作。
What’s the easiest way to add search, filters, and keep the directory usable at 30+ integrations?
搜索以提供商名称为主,其次是分类。增加能反映意图的筛选:Connected、Needs attention、Not set up,让用户秒速定位问题。若使用 Koder.ai,先在 Planning Mode 起草目录字段、状态规则和设置步骤,这样生成的 UI 与后端会保持一致。