Skip to content

feat(spec)!: DashboardWidgetSchema.strict() — 拒绝未声明的 widget 键 (framework#3251) - #3316

Merged
os-zhuang merged 1 commit into
mainfrom
claude/dashboard-analytics-migration-46qeuj
Jul 19, 2026
Merged

feat(spec)!: DashboardWidgetSchema.strict() — 拒绝未声明的 widget 键 (framework#3251)#3316
os-zhuang merged 1 commit into
mainfrom
claude/dashboard-analytics-migration-46qeuj

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes#3251

背景

ADR-0021 分析迁移的终点。平台模式是「AI 写元数据、人类审核」,而被静默剥离的未声明键正是人类审核最容易漏掉的静默 no-op。本 PR 让 DashboardWidgetSchema 拒绝任何未声明的顶层键,把这类错误从易错的人工审核移到确定性的 CI 硬报错。options: z.unknown() 仍是渲染器额外配置的逃生舱。

改动

  • packages/spec/src/ui/dashboard.zod.tsDashboardWidgetSchema.strict() + 自定义 error map。错误信息会指名违规键,并在键属于已移除的 pre-ADR-0021 内联分析键(object/categoryField/valueField/aggregate,透视表 rowField/columnField)或 objectui 内部 prop(component、内联 data)时,引导作者改用 dataset 形态(dataset + dimensions + values)。
  • packages/spec/src/migrations/registry.ts — 新增 protocol-16 迁移项 step16dashboard-widget-strict-unknown-keys),对齐 protocol-15 step15 对 form/page schema 的 strict 翻转(ADR-0089 D3a)。内联分析形态本身已在 protocol 9(single-form cutover)移除,因此无机械转换,残留即 strictness 本身,交由作者处理。
  • packages/lint/src/validate-widget-bindings.tswidget-legacy-analytics-* 规则保留为原始配置路径lint / doctor)的友好桥(strict 会在已解析的 compile / validate 路径先行拦截);更新文档注释说明二者关系。
  • dashboard.test.ts — 新增拒绝用例:合法 dataset widget 携带遗留键、component/data、typo 键;并验证 options 逃生舱仍可用。

⚠️ 需维护者注意 — 版本闸门

  • 本 PR 不改 PROTOCOL_VERSIONprotocol-version.test.ts 要求 PROTOCOL_MAJOR == @objectstack/spec 包主版本(当前 15.1.1),在本 PR 里改 16.0.0 会挂 CI。PROTOCOL_VERSION = '16.0.0' 应由发布列车的 Version-Packages PR 设置。在此之前 step16惰性且安全的(composeMigrationChain 会截到 PROTOCOL_MAJOR;已跑 check:spec-changes / check:upgrade-guide 均无 drift)。
  • Changeset 为 minor@objectstack/spec):按发布窗口政策,破坏性变更以 minor 搭乘已在待发的 16.0.0 列车(.changeset/console-*.md 已声明 @objectstack/console: major),不单独 burn major。no-major guard 对本 changeset 通过(其 exit 1 来自既有的 console major,需发布 PR 的 allow-major 标签处理,与本 PR 无关)。

⚠️ 合并顺序(两仓协作)

必须在 objectstack-ai/objectui#2703 合并之后 再合并本 PR,且需先把 .objectui-sha bump 到 objectui 的合并 commit(pnpm objectui:refresh,本 PR 暂未包含该 bump —— 因为 objectui 合并 commit 尚不存在)。顺序反了会让新 strict schema 拒绝旧 console 生成的遗留键(Studio 保存 422)。

验证

  • @objectstack/spec 全量 6797 passed;dashboard/migrations/protocol-version 定向通过。
  • @objectstack/lintvalidate-widget-bindings 40 passed。
  • drift gate:check:api-surface / check:spec-changes / check:upgrade-guide / check:docs 均 in-sync(strict 只在构建期给 JSON schema 加 additionalProperties:false,产物为 gitignore 构建物)。

🤖 Generated with Claude Code


Generated by Claude Code

…t keys (framework#3251)
The ADR-0021 analytics endpoint. DashboardWidgetSchema now rejects any
undeclared top-level key instead of silently stripping it, moving a class of
author error (a hallucinated or legacy key that renders as a silent no-op) from
fallible human review to deterministic CI. options: z.unknown() stays the
escape hatch for renderer-specific extras.
- A custom error map names the offending key(s) and, when a key is a removed
pre-ADR-0021 inline-analytics key (object/categoryField/valueField/aggregate,
pivot rowField/columnField) or an objectui-internal prop (component, inline
data), points the author at the dataset shape (dataset + dimensions + values).
- Recorded as protocol-16 migration step16 (dashboard-widget-strict-unknown-keys),
mirroring protocol-15 step15's strict flip on the form/page schemas
(ADR-0089 D3a). PROTOCOL_VERSION is NOT bumped here — the release train's
Version-Packages PR sets it to 16.0.0; until then step16 is inert
(composeMigrationChain caps at PROTOCOL_MAJOR).
- lint: the widget-legacy-analytics-* rules are kept as the friendly bridge on
the raw-config lint/doctor paths (strict preempts them on parsed paths);
doc comment updated.
Shipped as minor per the launch-window policy, riding the pending 16.0.0 train.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T4qmiXd4wjnJMLt18Cir1Y
@vercel

vercelBot commented Jul 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specBuildingBuildingPreview, CommentJul 19, 2026 5:50pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests protocol:ui tooling size/m labels Jul 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/lint, @objectstack/spec.

103 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/spec)
  • content/docs/automation/approvals.mdx(via packages/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/cli.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via packages/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via packages/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/spec)
  • content/docs/permissions/authorization.mdx(via @objectstack/lint, @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/runtime-capabilities.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P2] Finish the dashboard analytics migration: Studio → dataset shape, then enable DashboardWidgetSchema strict validation

2 participants

@os-zhuang@claude