YAOTU INSIGHTS

PostHog 仪表盘组件可用性与门控(Availability Gating)完整指南:从 Catalog 配置到运行时守卫的落地实践

PostHog 仪表盘组件可用性与门控(Availability  Gating)完整指南:从 Catalog 配置到运行时守卫的落地实践
PostHog 仪表盘组件可用性与门控Availability Gating完整指南从 Catalog 配置到运行时守卫的落地实践【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog导读本文聚焦 PostHog 仪表盘组件平台Dashboard Widget Platform中的可用性availability与门控gating机制讲解如何在组件尚未满足项目级前置条件时例如尚未开启 Exception Autocapture、Session Replay向用户展示正确的设置引导界面而不是直接渲染空数据或报错。读完本文你将掌握 PostHog 中目录驱动守卫catalog-driven guard与组件层设置门widget-layer setup gate两种模式的选型与实现、WidgetAvailabilityRequirementId的扩展流程以及WidgetRuntimeAvailabilityGuard的完整运行链路并可直接对照仓库源码落地你自己的组件类型。一、三种门控必须分清项目前置条件、产品访问权限、发布门控在进入实现细节之前必须先厘清 PostHog 中三个经常被混为一谈的概念它们各自解决不同的问题概念本质作用对象判定依据项目前置条件Prerequisites项目是否配置为能产出该组件所需的数据如 Exception Autocapture、Session Recording 采集组件 tile 的渲染run_widgets、锁定的 tilelocked tiles产品访问权限Product access /productAccess用户/团队是否有权查看该产品数据谁能看到组件数据RBAC /productAccess字段发布门控Release gating未发布的组件是否出现在选择器中、是否允许被创建选择器条目 后端创建接口WidgetSpec.creation_flag本指南讨论的核心是第一类项目前置条件availability。文档开篇明确说明产品访问productAccess是独立体系它通过run_widgets和锁定 tile 来限制谁能看到组件数据而 availability 解决的是这个项目是否被配置为能产出数据。1.1 发布门控Release gatingcreation_flag 是回滚开关不是可用性发布门控与 availability 的关键区别值得单独强调前端选择器组件选择器picker渲染的是手写的 FE 目录products/dashboards/frontend/widget_types/catalog.ts因此一个未发布的组件组widget group只要把 catalog 条目与发布一并合入就不会出现在选择器中。后端创建门真正的后端创建门是WidgetSpec上的creation_flag它通过widget_create.py中的widget_flag_enabled泛化解析同时保护直接通过 API/MCP 创建的路径。它是回滚开关rollout kill-switch而非可用性当 flag 被关闭时已经放置的 tile 依然继续渲染只是不允许再创建新的。文档还指出一个当前不存在的机制FE 侧没有针对选择器条目的 flag 映射FE flag map。如果某个组件族需要条目已发布但隐藏entry shipped but hidden的效果目前没有现成机制——catalog 响应需要自行暴露解析后的门控结果。下文所述的渲染时规则render-time rules仅适用于 availability与发布门控无关。二、产品铁律在渲染时门控绝不在添加时门控这是本指南最核心的一条产品规则违反它会导致糟糕的用户体验用户在AddWidgetModal中始终可以挑选并添加任何组件——不允许基于 availability 对 catalog 条目做过滤filtering、禁用disabling或隐藏hiding。当某个前置条件未满足时dashboard tile 的正文tile body显示设置引导 UIsetup UI而 tile 本身依然存在——header、布局、编辑/删除菜单照常工作。明确禁止以下做法在添加组件选择器中隐藏或禁用变体variants拦截POST .../widgets/batch/或 dashboard PATCH 的添加路径只在编辑弹窗edit modal里做可用性检查这种设计的理由很直接组件是否可用取决于项目配置而项目配置随时可能被开启把门控放在渲染时用户一旦开启配置tile 无需重新添加即可自动显示内容。三、两种模式每个组件类型二选一PostHog 为组件可用性门控提供了两种模式每个组件类型必须二选一模式适用场景CatalogavailabilityTile 渲染目录驱动守卫Catalog-driven guard单个团队 flag可在widgetAvailability.ts中检查必填WidgetRuntimeAvailabilityGuard包裹Component在DashboardWidgetItem中始终接入组件层设置门Widget-layer setup gate更复杂的规则多信号、采集轮询、产品逻辑省略——守卫是 no-op在组件Component内部内联私有门 设置 UI关键告诫当组件在内部自行处理设置引导时绝不要再设置 catalogavailability——否则守卫会使用错误的更简单的检查造成双重门控double-gate。3.1 实际案例Error Tracking 采用内联设置门Error tracking 组件是组件层设置门的参考实现它在ErrorTrackingWidget.tsx中做内联设置门控检查的是exceptionIngestionLogic事件已收到 或 已开启 autocapture而不仅仅是autocapture_exceptions_opt_in这一个 flag。这个例子很好地说明了组件层设置门的价值当判定条件比单个 team flag 更丰富涉及采集链路状态时就适合放到组件内部处理。四、Catalogavailability的数据结构前置文件products/dashboards/frontend/widget_types/catalog.tsFE catalog 条目上的availability字段结构如下TypeScript 类型来自widgetAvailability.ts中的WidgetAvailabilityConfigavailability?: { requirement: WidgetAvailabilityRequirementId // e.g. exception_autocapture unavailableTitle: string unavailableReason: string setupActionLabel: string docsHref?: string compactSetupPrompt?: boolean // 短 tile 内使用紧凑间距源码中的可选字段 }各字段含义结合源码WidgetAvailabilityConfig注释requirement稳定的需求 id由widgetAvailability的辅助函数求值unavailableTitle需求未满足时设置提示中显示的标题unavailableReason需求未满足时设置提示中的正文文案setupActionLabel主设置 CTA 按钮文案docsHref?可选次级 CTA 的文档链接compactSetupPrompt?可选当设置提示需要放进较矮的 widget tile 时使用紧凑间距源码中catalog.ts的conversations_recent_tickets条目就使用了compactSetupPrompt: true。4.1 真实 catalog 条目示例以session_replay_list为例源码catalog.tssession_replay_list: { groupId: session_replay, label: Recent recordings, badge: Crowd favorite, defaultConfig: sessionReplayWidgetConfigSchema.parse({ dateRange: { date_from: -7d } }), defaultLayout: { w: 6, h: 5, minW: 3, minH: 3 }, productAccess: session_recording, titleHref: urls.replay(), sharedPlaceholder: { title: Recent recordings, message: Log in to PostHog to watch session replays from this dashboard., }, availability: { requirement: session_replay_enabled, unavailableTitle: Session replay is not enabled, unavailableReason: Turn on session recordings for this project to watch recent replays from your dashboard., setupActionLabel: Enable session replay, docsHref: https://posthog.com/docs/session-replay, }, ... }而error_tracking_list条目故意省略了availability——因为它采用组件层内联设置门见上文 §3.1。4.2 类型与求值器widgetAvailability.ts类型定义和求值逻辑集中在products/dashboards/frontend/widget_types/widgetAvailability.ts这是 catalog 条目与运行时守卫之间的单一事实来源WidgetAvailabilityRequirementId当前支持的三个 id——exception_autocapture、session_replay_enabled、conversations_enabled。新增通用需求时在这里扩展源码注释明确写着 New catalog-driven setup requirements: add here — CONTRIBUTING.md。isWidgetAvailabilityRequirementMet(requirement, team)对 team 字段做穷尽式 switchexhaustive switch求值exception_autocapture→team?.autocapture_exceptions_opt_insession_replay_enabled→team?.session_recording_opt_inconversations_enabled→team?.conversations_enableddefault分支用never类型做穷尽性检查const _exhaustive: never requirement保证新增 id 时编译器会强制你补全 case。getWidgetAvailabilityStatus(config, team)/useWidgetAvailability(config)返回{ isAvailable, config }。注意一个细节没有config即availability键缺失时返回isAvailable: true——这正是省略availability→ 守卫原样渲染 childrenno-op的实现基础。WIDGET_AVAILABILITY_PRESENTATION按 requirement id 键控的产品展示信息productName、productKey、thingName、settingsUrl与 catalog 保持单一事实来源例如exception_autocapture对应 Error tracking 产品的设置页settings(environment-error-tracking, error-tracking-exception-autocapture)。五、后端availability_requirementsMCP 目录前置文件products/dashboards/backend/widget_catalog.py后端WIDGET_CATALOG中每个条目都包含availability_requirements——这是一组字符串 idAgent 可以通过dashboard-widget-catalog-list看到它们例如[session_replay_enabled]、[exception_autocapture]。从源码看目录条目通过_build_catalog_entry从WIDGET_SPECS构建widget_catalog.py其中availability_requirements: list(spec.availability_requirements),两条硬性要求即使 FE 省略了 catalogavailability、组件在Component内部做内联设置门控也必须在后端设置availability_requirements。error_tracking_list就是两者同时做的例子FE 无availabilityBE 有exception_autocapture。当 FE catalog 的availability.requirement与 BE 的availability_requirements[0]同时存在时两者必须使用同一个 id保持一致避免 Agent 看到的目录信息与前端实际行为矛盾。六、WidgetRuntimeAvailabilityGuard运行链路前置文件products/dashboards/frontend/components/WidgetRuntimeAvailabilityGuard/WidgetRuntimeAvailabilityGuard.tsxWidgetRuntimeAvailabilityGuard在DashboardWidgetItem中始终包裹组件Component无论 catalog 是否设置availability。其数据流如下catalogEntry.availability → useWidgetAvailability() → isAvailable? render children (widget Component) → else render unavailableContentFallback ?? WidgetAvailabilitySetupPrompt对照源码守卫组件逻辑非常简洁清晰export function WidgetRuntimeAvailabilityGuard({ availability, unavailableContentFallback, widgetType, widgetId, dashboardId, children, }: WidgetRuntimeAvailabilityGuardProps): JSX.Element { const { isAvailable, config } useWidgetAvailability(availability) if (isAvailable || !config) { return {children}/ } const Fallback unavailableContentFallback ?? WidgetAvailabilitySetupPrompt return Fallback availability{config} widgetType{widgetType} widgetId{widgetId} dashboardId{dashboardId} / }Props 说明availability— 来自getDashboardWidgetCatalogEntry(widget_type)?.availabilityunavailableContentFallback— 可选来自DashboardWidgetDefinition.unavailableContentFallback用于自定义设置 UIchildren— widgetComponentwidgetType/widgetId/dashboardId— 透传给 fallback 组件用于定位上下文。默认设置 UIWidgetAvailabilitySetupPromptproducts/dashboards/frontend/components/WidgetAvailabilitySetupPrompt/WidgetAvailabilitySetupPrompt.tsx——通用的WidgetCardProductIntroduction 按requirement定制的 CTA管理员门控的启用操作、文档链接、产品意图采集。新增WidgetAvailabilityRequirementId时需要扩展它的switch (availability.requirement)分支。守卫组件还有配套测试WidgetRuntimeAvailabilityGuard.test.tsx覆盖需求满足/未满足两种渲染路径。七、组件层设置门Widget-layer setup gate当 catalogavailability被省略守卫退化为 no-op时需要在 widgetComponent内部处理设置门控做法是私有子组件——例如ErrorTrackingWidget.tsx中的ErrorTrackingWidgetSetupGate。两条约束不要为 widget 布局去修改产品的SetupPrompt、ProductIntroduction等共享库组件——这些是产品独立界面不应被 dashboard tile 的布局需求污染。复用产品逻辑如exceptionIngestionLogic从 widget wrapper 中调用设置 UI 用WidgetCardProductIntroduction组合成 tile 友好的布局。7.1 Error tracking 参考实现全景组件路径职责Widgetwidgets/error_tracking/ErrorTrackingWidget.tsx设置门 正文 空/加载状态产品提示仅参考products/error_tracking/frontend/components/SetupPrompt/SetupPrompt.tsx之外的产品独立界面独立产品界面——禁止为 dashboard tile 导入或扩展它通用提示catalog 守卫components/WidgetAvailabilitySetupPrompt/WidgetAvailabilitySetupPrompt.tsx目录驱动的启用 exception autocapture UITile 布局包装components/WidgetCardProductIntroduction/WidgetCardProductIntroduction.tsx在WidgetCardBody内部对设置提示做 container-query 响应式布局一个重要的实现细节加载状态loading state在设置包装之外渲染——这样数据获取期间先显示骨架屏skeleton而不是设置提示。八、新增一个通用需求Adding a new generic requirement如果你的组件满足单个 team flag 可判定的简单场景按以下 5 步扩展通用需求体系在widgetAvailability.ts中向WidgetAvailabilityRequirementId添加 id在isWidgetAvailabilityRequirementMet中实现检查基于 team 字段或辅助函数并补上WIDGET_AVAILABILITY_PRESENTATION的展示配置productName、productKey、thingName、settingsUrl在WidgetAvailabilitySetupPrompt中添加 UI 分支启用操作、文档、意图采集在 catalog 条目上设置availabilitycatalog.ts测试widgetAvailability.test.ts与WidgetRuntimeAvailabilityGuard.test.tsx。由于isWidgetAvailabilityRequirementMet的 default 分支使用了never类型穷尽性检查第 1 步之后编译器会强制要求你完成第 2 步的 case——这是 PostHog 用类型系统保证扩展完整性的一个典型实践。九、检查清单组件类型需要设置门控时当你要为一个组件类型接入设置门控时逐项确认简单的团队 flag设置 catalogavailability 在widgetAvailability.ts中添加求值器 在WidgetAvailabilitySetupPrompt中添加提示分支。可选在 registry 上设置unavailableContentFallback以使用自定义设置 UI。更丰富的产品规则省略 catalogavailability在widgets/product/Component.tsx内添加私有设置门 提示 UI复用产品逻辑不修改产品SetupPrompt。确认添加弹窗add modal仍然无条件列出该组件。设置 UI 只替换 tile 的正文body——header/菜单不变。加载骨架屏绕过设置提示loading skeleton bypasses setup prompt。破坏性启用操作受管理员限制useRestrictedArea。渲染时的需求满足/未满足两种状态均有测试覆盖。相关参考文档checklist-new-widget-type.md 第 4 节catalogavailability条目composition.md加载状态归属完整的组件平台技能入口SKILL.md十、关键决策速查最后把本文的核心决策浓缩成一张速查表决策点结论什么时候在添加流程中过滤/禁用组件永不。用户在AddWidgetModal中始终能添加任何组件简单团队 flag单一条件目录驱动守卫设availabilitywidgetAvailability.ts求值器 WidgetAvailabilitySetupPrompt分支复杂规则多信号、采集状态、产品逻辑组件层设置门省略availability在Component内做私有门 复用产品逻辑FE 省略availability时 BE 怎么办仍必须在WIDGET_CATALOG中设置availability_requirementsFE 与 BE 都设置时使用同一个 requirement id保持一致发布门控creation_flag与 availability 的关系两者独立flag 关闭只阻止新创建已放置 tile 继续渲染加载中显示什么骨架屏在设置包装之外渲染不显示设置提示【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考