Skip to content

Add critical protocol definitions: Field Widget, Plugin Lifecycle, Driver Interface, and Trigger Context#34

Merged
huangyiirene merged 3 commits intomainfrom
copilot/add-field-widget-contract
Jan 20, 2026
Merged

Add critical protocol definitions: Field Widget, Plugin Lifecycle, Driver Interface, and Trigger Context#34
huangyiirene merged 3 commits intomainfrom
copilot/add-field-widget-contract

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 20, 2026

✅ Implementation Complete: Critical Protocol Definitions

Successfully implemented 4 critical protocol definitions that unblock major ObjectStack features:

📦 Deliverables

1. Field Widget Contract ⚠️ CRITICAL

  • File: packages/spec/src/ui/widget.zod.ts
  • Tests: 22 tests (all passing)
  • Purpose: Enables third-party developers to build custom field components
  • Features: Value binding, onChange callbacks, validation states, field schema, custom options

2. Plugin Lifecycle Interface ⚠️ CRITICAL

  • File: packages/spec/src/system/plugin.zod.ts
  • Tests: 17 tests (all passing)
  • Purpose: Contract between ObjectOS and all plugins
  • Features: PluginContext (ql, os, logger, metadata, events) + lifecycle hooks (onInstall, onEnable, onDisable, onUninstall, onUpgrade)

3. Driver Interface ⚠️ CRITICAL

  • File: packages/spec/src/system/driver.zod.ts
  • Tests: 22 tests (all passing)
  • Purpose: Unified interface for multi-database support
  • Features: CRUD operations, bulk operations, DDL (syncSchema, dropTable), transactions, capability flags

4. Trigger Context Protocol 🟡 HIGH

  • File: packages/spec/src/data/trigger.zod.ts
  • Tests: 22 tests (all passing)
  • Purpose: Standardize trigger code for AI generation
  • Features: before/after timing, insert/update/delete actions, doc/previousDoc, validation helpers

📊 Quality Metrics

  • Tests: 356/356 passing (83 new tests added)
  • Build: TypeScript compilation successful
  • JSON Schemas: 131 schemas generated (10 new)
  • Documentation: MDX docs auto-generated for all schemas
  • Security: CodeQL scan clean (0 vulnerabilities)
  • Code Review: All type references fixed

🎯 Impact

These protocol definitions unblock:

  1. Custom Field Components - Third-party widget development
  2. Plugin Ecosystem - Marketplace and plugin management
  3. Multi-Database Support - ObjectQL data virtualization
  4. Business Logic Automation - AI-powered trigger code generation

🏗️ Technical Implementation

  • Zod-first: All schemas defined with Zod for runtime validation
  • Type-safe: TypeScript types derived via z.infer<>
  • Conventions: camelCase for config, snake_case for machine names
  • Comprehensive: 83 tests covering all use cases
  • Documented: Auto-generated JSON schemas and MDX docs
Original prompt

完善协议

  1. Field Widget Contract ⚠️ CRITICAL

File: packages/spec/src/ui/widget.zod.ts
Effort: 1-2 days
Blocks: Custom field components, plugin UI extensions
Dependencies: None

Why Critical: Third-party developers cannot build custom field components without this contract.

Definition:

export const FieldWidgetPropsSchema = z.object({
value: z.any(),
onChange: z.function(),
readonly: z.boolean().default(false),
required: z.boolean().default(false),
error: z.string().optional(),
field: FieldSchema,
record: z.record(z.any()).optional(),
options: z.record(z.any()).optional(),
});

export type FieldWidgetProps = z.infer;
2. Plugin Lifecycle Interface ⚠️ CRITICAL

File: packages/spec/src/system/plugin.zod.ts
Effort: 2-3 days
Blocks: Plugin ecosystem, marketplace
Dependencies: None

Why Critical: This is the contract between ObjectOS and all plugins. Without it, plugins cannot be loaded.

Definition:

export const PluginContextSchema = z.object({
ql: z.any().describe('ObjectQL data access API'),
os: z.any().describe('ObjectOS system API'),
logger: z.any().describe('Logging interface'),
metadata: z.any().describe('Metadata registry'),
events: z.any().describe('Event bus'),
});

export const PluginLifecycleSchema = z.object({
onInstall: z.function().optional(),
onEnable: z.function().optional(),
onDisable: z.function().optional(),
onUninstall: z.function().optional(),
onUpgrade: z.function().optional(),
});
3. Driver Interface ⚠️ CRITICAL

File: packages/spec/src/system/driver.zod.ts
Effort: 3-4 days
Blocks: Multi-database support, data virtualization
Dependencies: None

Why Critical: This enables ObjectQL to work with any database through a unified interface.

Definition:

export const DriverInterfaceSchema = z.object({
name: z.string(),
version: z.string(),

// CRUD
find: z.function(),
findOne: z.function(),
create: z.function(),
update: z.function(),
delete: z.function(),
bulkCreate: z.function(),
bulkUpdate: z.function(),
bulkDelete: z.function(),

// DDL
syncSchema: z.function(),
dropTable: z.function(),

// Transaction
beginTransaction: z.function().optional(),
commit: z.function().optional(),
rollback: z.function().optional(),

// Capabilities
supports: z.object({
transactions: z.boolean(),
joins: z.boolean(),
fullTextSearch: z.boolean(),
jsonFields: z.boolean(),
arrayFields: z.boolean(),
}),
});
4. Trigger Context Protocol 🟡 HIGH

File: packages/spec/src/data/trigger.zod.ts
Effort: 1-2 days
Blocks: Business logic, trigger code generation
Dependencies: None

Why Important: Standardizes how trigger code is written, enabling AI code generation.

Definition:

export const TriggerContextSchema = z.object({
action: z.enum(['insert', 'update', 'delete']),
timing: z.enum(['before', 'after']),
doc: z.record(z.any()),
previousDoc: z.record(z.any()).optional(),
userId: z.string(),
user: z.record(z.any()),
ql: z.any(),
logger: z.any(),
addError: z.function(),
getOldValue: z.function(),
});


💡 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.

@vercel
Copy link
Copy Markdown

vercel bot commented Jan 20, 2026

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

Project Deployment Review Updated (UTC)
spec Ready Ready Preview, Comment Jan 20, 2026 4:16am

Request Review

…trigger

Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Copilot AI changed the title [WIP] Add field widget contract for third-party developers Add critical protocol definitions: Field Widget, Plugin Lifecycle, Driver Interface, and Trigger Context Jan 20, 2026
Copilot AI requested a review from huangyiirene January 20, 2026 03:59
@github-actions
Copy link
Copy Markdown
Contributor

This PR is very large. Consider breaking it into smaller PRs for easier review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment on lines +204 to +211
const plugin: Plugin = {
id: 'test.plugin',
version: '1.0.0',
onInstall: async (context) => {
installed = true;
await context.ql.object('test_object').syncSchema();
},
};
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ba9dd35 - changed type from Plugin to PluginDefinition

Comment on lines +235 to +244
const plugin: Plugin = {
onEnable: async (context) => {
enabled = true;
context.logger.info('Plugin enabled');
},
onDisable: async (context) => {
enabled = false;
context.logger.info('Plugin disabled');
},
};
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ba9dd35 - changed type from Plugin to PluginDefinition

Comment on lines +276 to +282
const plugin: Plugin = {
onUpgrade: async (context, from, to) => {
upgradeCalled = true;
upgradeFrom = from;
upgradeTo = to;
},
};
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ba9dd35 - changed type from Plugin to PluginDefinition

Comment on lines +310 to +315
const plugin: Plugin = {
onUninstall: async (context) => {
uninstalled = true;
await context.ql.object('test_object').dropTable();
},
};
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type 'Plugin' is used but not defined in the imports. Should be 'PluginDefinition' to match the exported type from plugin.zod.ts.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ba9dd35 - changed type from Plugin to PluginDefinition

@huangyiirene
Copy link
Copy Markdown
Collaborator

@copilot fix all

Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 20, 2026

@copilot fix all

All type references fixed in ba9dd35. Changed 4 instances from Plugin to PluginDefinition in plugin.test.ts. All 356 tests passing and build successful.

@github-actions
Copy link
Copy Markdown
Contributor

This PR is very large. Consider breaking it into smaller PRs for easier review.

@huangyiirene huangyiirene merged commit 29ed0c7 into main Jan 20, 2026
10 checks passed
Copilot AI added a commit that referenced this pull request Mar 3, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants