Add critical protocol definitions: Field Widget, Plugin Lifecycle, Driver Interface, and Trigger Context - #34
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…trigger Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
|
This PR is very large. Consider breaking it into smaller PRs for easier review. |
There was a problem hiding this comment.
Pull request overview
This PR implements four foundational Zod schemas that establish critical contracts for the ObjectStack protocol: Field Widget Props (custom UI components), Plugin Lifecycle (plugin ecosystem), Driver Interface (database abstraction), and Trigger Context (business logic execution). These schemas enable third-party development, multi-database support, and standardized trigger code generation.
Changes:
- Added Field Widget contract (
ui/widget.zod.ts) defining props interface for custom field components with value binding, validation state, and record context - Added Plugin Lifecycle interface (
system/plugin.zod.ts) with runtime context and hooks for install/enable/disable/uninstall/upgrade operations - Added Driver Interface (
system/driver.zod.ts) providing unified abstraction for CRUD, DDL, and transaction operations across SQL/NoSQL/SaaS databases with capability flags - Added Trigger Context protocol (
data/trigger.zod.ts) standardizing execution context for before/after triggers with validation helpers and data access APIs
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
packages/spec/src/ui/widget.zod.ts |
Defines FieldWidgetProps schema for custom field component integration |
packages/spec/src/ui/widget.test.ts |
Comprehensive test coverage for widget props validation scenarios |
packages/spec/src/system/plugin.zod.ts |
Defines plugin context and lifecycle hooks for plugin ecosystem |
packages/spec/src/system/plugin.test.ts |
Tests for plugin context, lifecycle hooks, and integration scenarios |
packages/spec/src/system/driver.zod.ts |
Defines unified driver interface for multi-database support |
packages/spec/src/system/driver.test.ts |
Tests for driver capabilities, CRUD operations, and real-world driver examples |
packages/spec/src/data/trigger.zod.ts |
Defines trigger context for standardized business logic execution |
packages/spec/src/data/trigger.test.ts |
Tests for trigger actions, timing, context, and use case scenarios |
packages/spec/src/index.ts |
Exports new schemas for public API consumption |
packages/spec/json-schema/*.json |
Auto-generated JSON schemas for IDE support |
content/docs/references/**/*.mdx |
Generated documentation pages for new schema types |
| const plugin: Plugin = { | ||
| id: 'test.plugin', | ||
| version: '1.0.0', | ||
| onInstall: async (context) => { | ||
| installed = true; | ||
| await context.ql.object('test_object').syncSchema(); | ||
| }, | ||
| }; |
There was a problem hiding this comment.
The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.
There was a problem hiding this comment.
Fixed in ba9dd35 - changed type from Plugin to PluginDefinition
| const plugin: Plugin = { | ||
| onEnable: async (context) => { | ||
| enabled = true; | ||
| context.logger.info('Plugin enabled'); | ||
| }, | ||
| onDisable: async (context) => { | ||
| enabled = false; | ||
| context.logger.info('Plugin disabled'); | ||
| }, | ||
| }; |
There was a problem hiding this comment.
The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.
There was a problem hiding this comment.
Fixed in ba9dd35 - changed type from Plugin to PluginDefinition
| const plugin: Plugin = { | ||
| onUpgrade: async (context, from, to) => { | ||
| upgradeCalled = true; | ||
| upgradeFrom = from; | ||
| upgradeTo = to; | ||
| }, | ||
| }; |
There was a problem hiding this comment.
The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.
There was a problem hiding this comment.
Fixed in ba9dd35 - changed type from Plugin to PluginDefinition
| const plugin: Plugin = { | ||
| onUninstall: async (context) => { | ||
| uninstalled = true; | ||
| await context.ql.object('test_object').dropTable(); | ||
| }, | ||
| }; |
There was a problem hiding this comment.
The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.
There was a problem hiding this comment.
Fixed in ba9dd35 - changed type from Plugin to PluginDefinition
|
@copilot fix all |
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
|
This PR is very large. Consider breaking it into smaller PRs for easier review. |
Add $notContains to StringOperatorSchema, FieldOperatorsSchema, Filter<T>, FILTER_OPERATORS, VALID_AST_OPERATORS, and AST_OPERATOR_MAP with both 'notcontains' and 'not_contains' AST aliases. Fixes #34 Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Adds entries 26-40 covering the gaps that make the helpdesk template 'pretty but not daily-usable' from an end-user perspective: P0 additions: - #26 No inline message composer on detail pages - #27 No external-user portal mechanism - #28 Attachment/file-list field UI not E2E P1 additions: - #29 No 'changed since last visit' indicator - #30 Bulk operations UI unverified (escalates #17) - #31 Rich-text editor scoped to comments only - #32 No first-class canned response / macro - #33 No collaboration presence indicators - #34 No keyboard-shortcut API - #35 No conditional SLA timer (pause on waiting_customer) - #36 Formula fields can't reference foreign object fields P2 additions: - #37 No chart drill-down - #38 No period-over-period analytics primitive - #39 No inbound-channel abstraction (email-to-ticket etc.) - #40 i18n translation namespace validation weak Includes 'user-pain → platform-gap' mapping table tracing each end-user complaint to a specific issue number. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…re it at +36 against the 358 ceiling (objectstack-ai#15265) * docs(pm-skill): write the third platform-readings increment and measure it against the ceiling Four members, each written in the file's voice and wrapped by the gate's own `wrapLine` rather than by hand, so the counts are landing costs and not estimates: the channel/input-scoped attribution-footer row, the MCP-side rate-refusal reading, the CDN cause behind the payload channel's absence rule, and the Routine transport family with its orphan-recovery path. The ceiling row is deliberately NOT touched: raising it is a maintainer-floor act and this change exists to give that ruling a measured number to size. The ratchet is expected RED. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox * docs(pm-skill): fold a fourth footer observation, measured by this flight, into the same row Opening this PR over a raw REST create measured a combination none of the three prior observations covered: the create end appended a SECOND session-URL footer (a leading horizontal rule, exactly +90 bytes, the sent body a strict prefix of the stored one) rather than the bare form the edit end appends. The row now says the append shape varies by channel AND by action, and still refuses to state a law. Re-measured after the change: the member costs 12 lines instead of 9, so the increment is +39 rather than +36. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox * tooling(pm): raise the platform-readings ceiling to 397 on the ruling, as an ordinary ruled raise The maintainer sized the third increment at the measured +39 (decision batch objectstack-ai#34, item 1 = A). The ceiling row moves 358 to 397 and carries the ruling verbatim beside it, with the four members and their line counts, the same way the row above carries the previous one. The move declaration takes a SECOND `ruledRaises` record rather than a carried- forward `was`: an ordinary ruled raise is the maintainer's, so it is subtracted before the move is priced. `was` stays at this file's literal pre-move 314, and the verdict reads +10 (314 to 397, less 73 lines of ordinary ruled raise) against the same net source decrease of 11. Item 2 of the ruling is C: the two quota sentences left in tension stay exactly as written, pending a discriminating read. Neither is edited. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox --------- Co-authored-by: Claude <noreply@anthropic.com>
✅ Implementation Complete: Critical Protocol Definitions
Successfully implemented 4 critical protocol definitions that unblock major ObjectStack features:
📦 Deliverables
1. Field Widget Contract⚠️ CRITICAL
packages/spec/src/ui/widget.zod.ts2. Plugin Lifecycle Interface⚠️ CRITICAL
packages/spec/src/system/plugin.zod.ts3. Driver Interface⚠️ CRITICAL
packages/spec/src/system/driver.zod.ts4. Trigger Context Protocol 🟡 HIGH
packages/spec/src/data/trigger.zod.ts📊 Quality Metrics
🎯 Impact
These protocol definitions unblock:
🏗️ Technical Implementation
z.infer<>Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.