保持 Agent Skill 文档与代码同步:PostHog 仪表盘组件维护文档架构指南

保持 Agent Skill 文档与代码同步:PostHog 仪表盘组件维护文档架构指南

【免费下载链接】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. 【免费下载链接】posthog 项目地址: https://gitcode.com/GitHub_Trending/po/posthog

Dashboard widget(仪表盘组件)平台是 PostHog 中一个横跨后端注册表、OpenAPI 生成、前端 Zod 类型与 MCP 工具的复杂系统。当工程师修改 widget_specs/registry.py 或任何组件相关代码时,如果配套的 Agent Skill 文档没有同步更新,就会出现「文档与代码漂移」——Agent 依据过期文档给出错误指引。本文基于 skill-maintenance.md 系统讲解 PostHog 如何通过「单一权威文档 + 触发路径 + 变更映射 + 最小清单」这套机制,让 /manage-dashboard-widgets 技能文档始终与仓库代码保持一致。读完你将掌握:何时需要触发文档维护、每个主题该去哪里更新、如何借助 CI 与 codegen 避免手工维护类型清单,以及新增/更新/废弃组件类型时各自的最小文档清单。

两条铁律:同一 PR 提交 + CI 强制对等

skill-maintenance 开篇即定义了文档维护的两条不可妥协的规则:

  1. 与代码变更放在同一个 PR 中(Same PR as the code change)——只要 agent-facing 行为或贡献者工作流发生变化,文档必须在同一个 PR 内更新,不允许「代码先合并、文档后补」。
  2. 注册表对等由 CI 强制,不在 Markdown 中手工维护类型清单(Registry parity is CI-enforced in code tests — do not hand-maintain type lists in markdown)——EXPECTED_WIDGET_TYPES、catalog 键、registry.test.tsx 这些「运行时真相」都活在代码与测试里,文档只负责解释,不负责复制清单。

这两条规则的深层动机可以从源码中找到印证:在 registry.py 中,DashboardWidgetType 是一个 Literal 联合类型,EXPECTED_WIDGET_TYPESWIDGET_SPECS 的键由 test_run_widgets.py 断言必须完全一致;前端的 DASHBOARD_WIDGET_REGISTRY 则通过 satisfies Record<DashboardWidgetCatalogKey, DashboardWidgetDefinition> 在编译期约束 catalog 键与注册表一一对应。类型清单一旦被复制进 Markdown,就会成为一处必然过期的平行真相——这正是该文档禁止手工维护列表的根本原因。

文档架构:一个主题只有一个权威文档

为避免重复,skill 采用了「每主题一个 canonical doc,其他文档一律链接过去,不复制表格或长篇段落」的架构。以下是主题到权威文档的映射(全部路径已转换为仓库根目录相对路径):

主题权威文档
Intake / 规格问题widget-intake.md
新增流程(文件与顺序)checklist-new-widget-type.md
模型、命名、扩展规则architecture.md
配置契约 / codegenconfig-and-codegen.md
Codegen 与 CI(本地 + 漂移)config-and-codegen.md § Codegen & CI
产品级 RBACpermissions-and-sharing.md § Product RBAC
瓦片最小/最大尺寸layout-and-ux.md § Tile min/max size
注册表条目形态(代码)architecture.md
更新流程managing-existing-widgets.mdSKILL.md §3
验证命令SKILL.md §6 Verify
人工入口 / 导航products/dashboards/CONTRIBUTING.md

这套架构的精髓在于「去重」:同一份表格、同一段长文只存在于一个位置,其他文档通过相对链接引用。例如瓦片最小尺寸的完整指南只写在 layout-and-ux.md 的 § Tile min/max size 一节,其余文档(如 managing-existing-widgets.md、architecture.md)只链接过去,避免多个文档各自维护一份会互相打架的尺寸说明。

何时需要触发文档维护:触发路径清单

只要以下任一路径发生变化,就应加载 /manage-dashboard-widgets 技能并完成维护清单。这张表本质上是「代码变更 → 是否影响文档」的判定器:

触发路径(glob)示例变更
products/dashboards/backend/widgets/**新增 run_*、配置校验、查询接线
products/dashboards/backend/widget_specs/**Pydantic 配置模型、校验、OpenAPI、注册表清单
products/dashboards/backend/widget_specs/pydantic_openapi.pymodel_json_schema() 注入、DashboardWidgetConfigoneOf(供 Orval 使用)
products/dashboards/backend/widget_registry.py仅重导出——真正的编辑在 widget_specs/registry.py
products/dashboards/backend/widget_catalog.py派生目录——label/availability 请编辑 registry.pyWidgetSpec
products/dashboards/backend/api/widget_openapi_serializers.py重导出——OpenAPI 序列化器派生自 WIDGET_SPECS
products/dashboards/backend/api/test/dashboard_openapi_test_helpers.pydashboard PATCH OpenAPI 契约排除项(供 test_dashboard_openapi.py
bin/build-dashboard-widget-types.pywidget-date-from-options.jsonwidget-form-fields.json、源自 WIDGET_SPECS 的 ENUM 预检
tools/openapi-codegen/package.jsonorval 版本)组件目录 Zod 要求 Orval 8.14+ 的 generateReusableSchemas
tools/openapi-codegen/src/zod-postprocess.mjsfixNullDefaultsannotatePureZodExports——共享的 Orval Zod 后处理
tools/openapi-codegen/src/schema.mjsdiscoverComponentSchemaNamesdiscoverCatalogEntryConfigPropertyKeys
products/dashboards/frontend/bin/generate-widget-config-zod.mjsOrval generateReusableSchemaswidget-config-schemas/*.zod.ts + widget-configs.zod.ts
products/dashboards/backend/api/test/test_widget_config_schema_parity.pycatalog config_schema ↔ Pydantic 对等性
products/dashboards/frontend/widgets/widgetConfigSchemaParity.test.tsFE Zod 键 ↔ widget-config-property-keys.json
posthog/openapi/enum_collisions.pyfind_enum_collisions 的共享枚举冲突逻辑与 CI
products/dashboards/backend/api/dashboard.pyrun_widgets、批量添加、分享序列化器(仅通用逻辑)
products/dashboards/backend/widget_query_throttle.pyrun_widgets 的每团队突发/持续配额
products/dashboards/backend/widget_access.pyRBAC 拒绝文案
products/dashboards/frontend/widgets/**组件、编辑弹窗、注册表、预览
products/dashboards/frontend/widget_types/**目录、widgetConfigShared.ts UI 标签、availability
products/dashboards/frontend/generated/widget-config-*.ts仅重新生成——不要手工编辑;codegen 输出变化时更新架构/清单文档
products/dashboards/frontend/generated/widget-config-schemas/**Orval 可复用的每组件 Zod——通过 hogli build:widget-types 重新生成
posthog/settings/web.pyENUM_NAME_OVERRIDES新增按类型 widget_type 的 OpenAPI 枚举冲突覆盖
products/dashboards/frontend/components/WidgetCard/**共享瓦片 chrome、占位、概览 fixtures
products/dashboards/frontend/components/DashboardWidgetItem/**瓦片胶水、公共展示、TileFilters 挂载
products/dashboards/frontend/widgets/constants.ts列表 footer、抓取错误、瓦片刷新防抖毫秒数
frontend/src/scenes/dashboard/widgetTileRefreshScheduler.ts瓦片筛选 PATCH 后的防抖 run_widgets
frontend/src/scenes/dashboard/dashboardLogic.tsxscheduleRefreshDashboardWidgets 与立即刷新
products/dashboards/frontend/widgets/*WidgetTileFilters.tsx瓦片内筛选器(日期、状态、属性选择器)
frontend/src/scenes/dashboard/DashboardItems.tsxshowEditingControlsisDashboardEditMode、瓦片筛选挂载
products/dashboards/mcp/tools.yaml组件 MCP 工具
frontend/src/scenes/dashboard/tileLayouts.ts布局算法(仅当行为/文档变化时)
posthog/api/test/test_sharing.py共享 dashboard 组件 payload 期望
tach.tomlproducts.dashboardsdepends_on新增产品导入边界

需要特别说明的是:纯平台重构(platform-only refactors)只要不改变行为、不改变 agent-facing 表面,可以跳过叙事性文档更新,但仍然必须运行 Verify 测试

变更 → 文档映射表:改了哪里就去更新哪份文档

与上面的「触发路径」互补,「变更 → 文档映射」从工程师的实际改动出发,直接告诉你该去更新哪份 skill 文档:

你改了什么在技能中更新哪里
新增或删除 widget_type新增流程变化时更新 checklist-new-widget-type.mdENUM_NAME_OVERRIDESconfig-and-codegen.md § Codegen & CI;发现新的不变量则补 footguns
配置字段 / 校验config-and-codegen.mdmanaging-existing-widgets.md § Config schema migration;对等测试见 SKILL.md §6 Verify
公开/共享/导出行为permissions-and-sharing.md;SKILL.md §4 不变量
安装/availability 门槛availability-and-gating.md;BE 的 availability_requirements 注意事项
瓦片布局 / 最小尺寸 / 添加位置layout-and-ux.md;REST/MCP 添加路径变化时更新 architecture.md
WidgetCard / 编辑弹窗组合composition.md
瓦片筛选栏 / widgetFilters 配置list-widget-patterns.md
列表分页 footer / run_* 总量list-widget-patterns.md(dashboard 路径上的 include_total_count
run_widgets 限流composition.mdarchitecture.mdwidget_query_throttle.py + 产品列表限流(replay)
筛选 PATCH 后的防抖瓦片刷新constants.tsWIDGET_TILE_REFRESH_DEBOUNCE_MSdashboardLogic.tsx
头部标题链接 / dashboard 编辑模式list-widget-patterns.mdlayout-and-ux.md 的 ⋯ 菜单对等性
MCP 工具或 Agent 流程mcp.md
新产品域 / tach / UI 复用模式checklist-new-widget-type.md §4c
人工贡献者入口products/dashboards/CONTRIBUTING.md 的注册表表格 / Verify 块

维护原则是:优先编辑现有 reference,而不是新增文件SKILL.md 始终扮演索引的角色,细节一律下沉到 references/ 目录中。

三份最小维护清单

新增 widget_type(Add checklist)

完整代码清单见 checklist-new-widget-type.md,此处是文档侧的最小更新项:

  1.  checklist-new-widget-type.md —— 若新增流程或易遗漏路径有变化则更新
  2.  architecture.md —— 若发现了值得记录的新 footgun 或平台不变量
  3.  CONTRIBUTING.md —— 若 Verify 命令或注册表对等表格有变化

更新已有类型(Update checklist)

  1.  managing-existing-widgets.md —— 若变更具备可复用性,扩展路由表或迁移说明
  2.  mcp.md —— 若 Agent 工作流或工具语义发生变化

移除 / 废弃一个类型

  1. 只有当没有瓦片引用该类型时,才先从注册表移除(或记录 unknown-type 回退机制)
  2. 若废弃流程有变化,在 managing-existing-widgets.md 的 § Deprecating 下补充说明

值得注意的是,「废弃」没有软删除机制:widget_type 字符串是不可变的,已存在的 DashboardWidget 行无法就地修改类型;同时不要为仍存在 posthog_dashboardwidget 行的类型移除后端校验,孤儿瓦片会回退到 unknown-type UI(header 回退 + body ErrorBoundary)。

文档与代码一起验证:Verify

验证命令的 canonical 清单只存在于 SKILL.md §6 Verify,其他文档一律链接过去,不在别处复制命令列表。核心验证分三层:

MVP smoke(渲染 + 核心测试,非发版点):

hogli test products/dashboards/backend/api/test/test_run_widgets.py
hogli test products/dashboards/backend/api/test/test_dashboard_widgets.py
hogli test products/dashboards/frontend/widgets/registry.test.tsx

发版门槛(PR 前必须完成): checklist §8 + hogli build:openapi + 每个新类型必须配套专用 Storybook stories(组件 + 编辑弹窗,二者缺一不可,仅 catalog 概览故事不算数)。

Config SSOT 变更(编辑 widget_specs/ 后同样要跑):

hogli test products/dashboards/backend/api/test/test_widget_config_schema_parity.py
hogli test products/dashboards/frontend/widgets/widgetConfigSchemaParity.test.ts
hogli test products/dashboards/backend/api/test/test_widget_openapi_enums.py   # 仅新增 widget_type 时

更新路径上,至少覆盖所触碰层的测试:后端改动跑 test_run_widgets.py,前端改动跑 products/dashboards/frontend/widgets/ 下的测试,config OpenAPI 变化则跑 hogli build:openapi

什么不该在文档中重复

文档维护的边界同样重要——以下两类内容严禁复制进 Markdown:

  • **运行时真相(Runtime truth)**留在代码与测试中:EXPECTED_WIDGET_TYPES、catalog 键、registry.test.tsx。不要在文档里维护一份平行的类型列表。
  • 生成文件(Generated files)frontend/generated/*、MCP schema JSON):一律用 hogli build:openapi 重新生成,不要逐字段复制成文档。

从源码看,这份「不要重复」的底气来自 registry.py 的自洽设计:

  • WIDGET_SPECS 是唯一的 WidgetSpec 清单(registry.py),每个条目携带 config_modelquery_fnrequired_scopesgroup_idlabeldescriptionrequired_product_accessavailability_requirementsform_fieldsfilter_fields 等元数据——catalog、OpenAPI、前端 Zod 全部由此派生;
  • validate_widget_config() 通过 config_model.model_validate(config) 做 Pydantic 校验,再以 model_dump(mode="json", exclude_none=True) 输出规范化的配置字典,类型校验完全收敛在代码层;
  • WidgetSpec.__post_init__ 甚至会在构造时校验 live widget 的非法配置字段(dateRangefilterTestAccounts_LIVE_FORBIDDEN_CONFIG_FIELDS 禁止),把「文档要写」的不变量直接前置到代码运行时。

也就是说,文档只负责解释「去哪里改、改了会影响什么」,而「什么值合法、什么组合不允许」全部由代码与测试兜底——这正是 CI 强制对等原则能够成立的基础。

落地实践:一次真实维护的完整路径

结合 products/dashboards/CONTRIBUTING.md 的 Frontend/backend parity 表格,一次完整的文档维护应当这样落地:

  1. 改代码:编辑 widget_specs/configs.py(Pydantic SSOT,先改这里)→ registry.pyWidgetSpec 条目)→ run_* runner。
  2. 跑 codegenhogli build:openapi 一条命令完成 openapi-schema → build:widget-types → openapi-types → MCP 全链路,重新生成 products/dashboards/frontend/generated/*(Zod、property-keys、date-from-options、form-fields),并提交生成差异。
  3. 过 CIci-backend.yml 中的 check-openapi-types 会重跑同一命令并对 diff——本地未提交生成文件时 PR 会失败并提示「run hogli build:openapi locally」;同仓库 PR 可能被自动提交漂移。
  4. 更新文档:按「变更 → 文档映射」表找到对应 reference,在同一 PR 内完成最小清单,然后运行 Verify 命令。
  5. 自查对等:参考 CONTRIBUTING.md 的 parity 表格逐层核对——Pydantic 模型、注册表清单、catalog、OpenAPI、FE Zod、property keys、date presets、form fields、UI catalog、previews、运行时注册表是否全部对齐。

这套「代码变更 → 触发路径判定 → 权威文档映射 → 最小清单 → Verify 兜底」的闭环,保证了 /manage-dashboard-widgets 这个 Agent 技能始终与仓库的真实行为一致——文档因代码而生,也随代码而变,唯一不变的是 CI 与 codegen 构成的强制对等防线。

【免费下载链接】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. 【免费下载链接】posthog 项目地址: https://gitcode.com/GitHub_Trending/po/posthog

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值