Skip to content

fix(spec): trim dead webhook triggers undelete + api - #3209

Merged
os-zhuang merged 1 commit into
mainfrom
claude/validation-multi-row-updates-kqxgg4
Jul 18, 2026
Merged

fix(spec): trim dead webhook triggers undelete + api#3209
os-zhuang merged 1 commit into
mainfrom
claude/validation-multi-row-updates-kqxgg4

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Summary

Closes#3196. WebhookTriggerType declared five triggers (create/update/delete/undelete/api) but only the first three ever fired. The other two had no event source and silently no-op'd — the same declared ≠ enforced pattern as #3184 (validation delete-event) and #3195 (hook events).

Per the design decision (both confirmed with the user), trim both rather than build out an entire restore subsystem or a manual-fire endpoint. Reintroduce undelete only alongside a real restore subsystem, and api only alongside a real manual-fire endpoint.

Changes

  • packages/spec/src/automation/webhook.zod.tsWebhookTriggerType narrowed to create/update/delete; a "Deliberately NOT triggers" doc block records why undelete/api were removed; object describe no longer references manual webhooks.
  • packages/plugins/plugin-webhooks/src/auto-enqueuer.ts — dropped undelete from the CachedSubscription type, the action union, and mapActionToTrigger. Added a drift-guard: parseRow now warns and drops any trigger it can't map to an emitted record event (e.g. a legacy sys_webhook row authored with undelete/api), so a dead trigger can't silently cache a subscription that matches nothing.
  • packages/plugins/plugin-webhooks/src/sys-webhook.object.ts — trigger select options → create/update/delete; field help updated.
  • Locale help strings (en/zh-CN/ja-JP/es-ES*.objects.generated.ts) — dropped undelete,api from the trigger list and the "manual / API" object hint.
  • Docscontent/docs/automation/webhooks.mdx (trigger list + action values); regenerated content/docs/references/automation/webhook.mdx.
  • .changeset/ — patch (spec + plugin-webhooks).

Behavior change

  • Authoring a webhook with undelete/api now fails at parse/validate time instead of registering a webhook that never fires. Verified zero shipped/authored webhook metadata used either — the only references were the enum, the authoring-UI options, docs, and a parse-only test.
  • Legacy persisted sys_webhook rows with those triggers keep working for their valid triggers; the dead ones are dropped with a warning instead of sitting in the cache.

Tests

  • webhook.test.ts — enum rejects undelete/api; the multi-trigger case uses the 3 live triggers.
  • auto-enqueuer.test.ts — a legacy create,undelete,api row still fires create and warns (unknown: ['undelete','api']); a row whose only triggers are removed values enqueues nothing.

Verified: spec 253 files / 6763 tests green, plugin-webhooks 14 tests green, check:docs 253 files in sync, spec + plugin-webhooks builds green, eslint clean. The 'api' references elsewhere are the unrelated automation flow trigger (a live feature), not webhooks.

Lineage

Fourth fix in the PD #10 events-enum audit line: #3160#3189#3195/#3206 → this. Remaining sibling: #3197 (schema-only event surfaces — graphql subscriptions, connector webhooks/triggers, realtime, websocket, record subscriptions).

🤖 Generated with Claude Code

https://claude.ai/code/session_01VCUSMJBsX14C3RQdWFw7N7


Generated by Claude Code

WebhookTriggerType declared 5 triggers but only create/update/delete ever
fired. The other two had no event source:
- undelete: the engine has no soft-delete/restore capability (delete is a hard
delete; no deleted_at convention, no restore operation, no
data.record.undeleted emit). The undeleted case in the auto-enqueuer's
action mapper was dead code awaiting a producer that doesn't exist.
- api ("manually triggered"): no manual/programmatic fire path exists — the
only webhook HTTP surface re-queues already-failed deliveries.
Same declared≠enforced pattern as #3184 (validation delete-event) and #3195
(hook events). Trim, contract-first: authoring a webhook on a removed trigger
now fails loudly at os validate / registration instead of registering a
webhook that silently never fires. No shipped webhook metadata used either.
The auto-enqueuer now also warns when a persisted sys_webhook row carries a
trigger it can't map to an emitted record event (drift-guard, mirroring
#3195's registerHook warning) and drops it rather than caching a subscription
that matches nothing. Updated the sys_webhook trigger options + field help
(all locales), docs, and regenerated reference; added rejection + drift-guard
tests.
Reintroduce undelete only with a real restore subsystem, and api only with a
real manual-fire endpoint.
Closes#3196
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCUSMJBsX14C3RQdWFw7N7
@vercel

vercelBot commented Jul 18, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
specBuildingBuildingPreview, CommentJul 18, 2026 12:27pm

Request Review

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

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/plugin-webhooks, @objectstack/spec.

102 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 packages/plugins/plugin-webhooks, @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/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/plugin-webhooks, @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/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 packages/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/plugin-webhooks, @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.

@os-zhuang
os-zhuang marked this pull request as ready for review July 18, 2026 12:49
@os-zhuang
os-zhuang merged commit 4b6fde8 into mainJul 18, 2026
16 of 17 checks passed
@os-zhuang
os-zhuang deleted the claude/validation-multi-row-updates-kqxgg4 branch July 18, 2026 12:49
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Webhook triggers undelete and api are declared but never fire

2 participants

@os-zhuang@claude