Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 28, 2026

  • Understand current ObjectQL implementation and IDataEngine interface
  • Create IDataEngine schema in @objectstack/spec
  • Make ObjectQL class implement IDataEngine interface
  • Align method signatures with IDataEngine requirements
  • Update ObjectQLPlugin to register ObjectQL as 'data-engine' service
  • Verify the integration works with test files
  • Run existing tests to ensure no regressions (1718 tests passing)
  • Fix naming collisions and delete method implementation
  • Address code review feedback
  • Final code review - no issues found
  • Clarify data-engine location (should be in spec/system)

Summary

Successfully implemented the IDataEngine interface for ObjectQL following the three-layer architecture pattern:

Consumer → DataEngine (ObjectQL) → Driver

Confirmed data-engine.zod.ts should remain in spec/system/ (infrastructure layer) not spec/data/ (business metadata layer), following the pattern where system/ contains runtime interfaces like DriverInterface and PluginInterface.

All tests passing ✅

Original prompt

调整 packages/objectql 改为符合 dataengine 的插件接入。


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel
Copy link

vercel bot commented Jan 28, 2026

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

Project Deployment Review Updated (UTC)
spec Ready Ready Preview, Comment Jan 28, 2026 6:28am

Request Review

Copilot AI and others added 2 commits January 28, 2026 05:47
- Created data-engine.zod.ts in spec/system with Zod schemas
- Updated ObjectQL class to implement IDataEngine interface
- Modified method signatures to match IDataEngine contract
- Updated ObjectQLPlugin to register as both 'objectql' and 'data-engine'
- Re-exported IDataEngine from runtime for backward compatibility

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
- Fixed Zod schema to use manual TypeScript interface for better type safety
- Added proper QueryOptions to QueryAST conversion (sort Record to orderBy array)
- Created comprehensive test suite for IDataEngine interface
- Updated test-objectql-plugin.ts import path
- All tests passing (spec package: 1718 tests, custom tests: 100%)

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
@hotlong hotlong closed this Jan 28, 2026
Copilot AI requested a review from hotlong January 28, 2026 05:56
Copilot stopped work on behalf of hotlong due to an error January 28, 2026 05:56
@hotlong hotlong reopened this Jan 28, 2026
@github-actions github-actions bot added documentation Improvements or additions to documentation protocol:system size/l labels Jan 28, 2026
@hotlong
Copy link
Contributor

hotlong commented Jan 28, 2026

@copilot 参考以下内容进一步优化,这是一个非常深刻的架构分层问题。
答案是:必须定义 Driver(驱动层)。
如果不定义 Driver,而是让 IDataEngine 直接去连数据库,你会遇到一个巨大的痛点:业务逻辑重复。

  1. 为什么需要分离 DataEngine 和 Driver?
    在 ObjectStack 这样的低代码平台中,“数据引擎”不仅仅是存取数据的,它还承担了大量平台级逻辑:
  • Permissions (权限):检查当前用户是否有权读写。
  • Hooks (钩子/沙箱):触发 beforeInsert / afterUpdate。
  • Validation (校验):检查必填项、字段格式。
  • Events (事件):发送消息到 Flow Engine。
    如果不分离 (Anti-Pattern):
    如果你有两个插件:PostgresDataEngine 和 MongoDataEngine,你必须在这两个插件里分别写两遍权限检查、Hooks 执行和校验逻辑。这违反了 DRY 原则,且极其容易出 Bug。
    分离后 (Best Practice):
  • Data Engine (业务层):负责权限、Hooks、校验。它是唯一的,逻辑只写一次。
  • Driver (适配层):只负责“把处理好的数据写入磁盘”。
  1. 架构设计:三层模型
  • Consumer (调用者): API / Flow / UI。它们只调用 DataEngine。
  • Data Engine (中间件): 核心逻辑层。处理 Hooks, Validation, ACL。
  • Driver (驱动): Postgres / Mongo / MySQL。只负责翻译 SQL。
  1. 代码契约定义
    你需要定义两套接口。
    A. 第一层:Driver Interface (底座)
    这是给插件实现的。它的任务是屏蔽 SQL 和 NoSQL 的差异。
    // packages/core/src/interfaces/driver.ts

export interface IDatabaseDriver {
/**

  • 驱动名称 (e.g., 'postgres', 'mongo')
    */
    name: string;

/**

  • 连接数据库
    */
    connect(): Promise;

/**

  • 基础 CRUD (Driver 不关心 Hooks,只关心落库)
    */
    create(table: string, data: any): Promise;
    update(table: string, id: any, data: any): Promise;
    delete(table: string, id: any): Promise;
    find(table: string, query: any): Promise<any[]>;

/**

  • 执行原生查询 (给高级用户用)
    */
    raw(sql: string, params?: any[]): Promise;
    }

B. 第二层:Data Engine (核心逻辑)
这是核心自带的,通常不需要插件替换它,插件只需要注入 Driver。
// packages/core/src/services/data-engine.ts
import { IDatabaseDriver } from '../interfaces/driver';

export class DataEngine {
private driver: IDatabaseDriver;

constructor(driver: IDatabaseDriver) {
this.driver = driver;
}

// 对外暴露的 API
async insert(objectName: string, data: any, user: any) {
console.log('[DataEngine] 1. Checking Permissions for', user.id);
// if (!canCreate) throw Error...

console.log('[DataEngine] 2. Running Before Hooks');
// await sandbox.run('before', data)...

console.log('[DataEngine] 3. Delegating to Driver');
// 真正落库
const result = await this.driver.create(objectName, data);

console.log('[DataEngine] 4. Running After Hooks');
// await sandbox.run('after', result)...

return result;

}
}

  1. 插件该怎么写?
    在这个架构下,你只需要编写 Driver Plugin。
    plugins/driver-postgres/index.ts
    import { Plugin, IDatabaseDriver } from '@objectstack/core';
    import { Pool } from 'pg';

class PostgresDriver implements IDatabaseDriver {
name = 'postgres';
// ... 实现 create, find 等具体的 SQL 拼接逻辑
async create(table, data) {
// INSERT INTO table ...
}
}

export const PostgresDriverPlugin: Plugin = {
name: 'driver-postgres',
async init(ctx) {
const driver = new PostgresDriver();
// 关键:注册的是 'db-driver',而不是 'data-engine'
ctx.registerService('db-driver', driver);
}
};

Kernel 的组装逻辑 (bootstrap):
Kernel 启动时,先加载 Driver 插件,然后自动实例化默认的 DataEngine 并注入 Driver。
// kernel.bootstrap()
const driver = ctx.getService('db-driver');
// 核心 DataEngine 接管驱动,对外提供完整的业务能力
const engine = new DataEngine(driver);
ctx.registerService('data-engine', engine);

总结

  • DataEngine: 是管家。它不懂 SQL,但它懂业务(权限、校验、Hook)。它存在于 Core 中。
  • Driver: 是工人。它不懂业务,但它懂 SQL。它存在于 Plugin 中。
    修改建议:

import { ObjectKernel } from './packages/runtime/src/mini-kernel.js';
import { ObjectQLPlugin } from './packages/runtime/src/objectql-plugin.js';
import { DriverPlugin } from './packages/runtime/src/driver-plugin.js';
import { ObjectQL } from './packages/objectql/src/index.js';

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note test

Unused import ObjectQL.

Copilot Autofix

AI about 6 hours ago

To fix an unused import, you remove it if it truly is not used, or you start using it if the omission was a bug. Here, the cleanest fix that does not affect current behavior is to delete the ObjectQL import statement.

Concretely, in test-dataengine-interface.ts, remove line 13:

import { ObjectQL } from './packages/objectql/src/index.js';

No other code changes are required, as no references to ObjectQL exist in the provided snippet. This will eliminate the unused import warning without changing any functionality.

Suggested changeset 1
test-dataengine-interface.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test-dataengine-interface.ts b/test-dataengine-interface.ts
--- a/test-dataengine-interface.ts
+++ b/test-dataengine-interface.ts
@@ -10,7 +10,6 @@
 import { ObjectKernel } from './packages/runtime/src/mini-kernel.js';
 import { ObjectQLPlugin } from './packages/runtime/src/objectql-plugin.js';
 import { DriverPlugin } from './packages/runtime/src/driver-plugin.js';
-import { ObjectQL } from './packages/objectql/src/index.js';
 import type { IDataEngine } from './packages/spec/src/system/data-engine.zod.js';
 
 // Mock driver for testing
EOF
@@ -10,7 +10,6 @@
import { ObjectKernel } from './packages/runtime/src/mini-kernel.js';
import { ObjectQLPlugin } from './packages/runtime/src/objectql-plugin.js';
import { DriverPlugin } from './packages/runtime/src/driver-plugin.js';
import { ObjectQL } from './packages/objectql/src/index.js';
import type { IDataEngine } from './packages/spec/src/system/data-engine.zod.js';

// Mock driver for testing
Copilot is powered by AI and may make mistakes. Always verify output.

// Verify objectql service is still available (backward compatibility)
try {
const ql = kernel.getService('objectql');

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note test

Unused variable ql.

Copilot Autofix

AI about 6 hours ago

In general, to fix an unused variable warning, remove the variable declaration or use the variable meaningfully. Here, the variable ql at line 75 is only used to hold the result of kernel.getService('objectql') and is never read; the test only needs to ensure that the call succeeds without throwing. The cleanest fix that preserves existing behavior is to drop the binding and just call kernel.getService('objectql'); as a standalone statement inside the try block.

Concretely, in test-dataengine-interface.ts, within testDataEngineService, replace the line const ql = kernel.getService('objectql'); with kernel.getService('objectql');. No imports, new methods, or additional definitions are required; we just remove the unused variable binding.

Suggested changeset 1
test-dataengine-interface.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test-dataengine-interface.ts b/test-dataengine-interface.ts
--- a/test-dataengine-interface.ts
+++ b/test-dataengine-interface.ts
@@ -72,7 +72,7 @@
   
   // Verify objectql service is still available (backward compatibility)
   try {
-    const ql = kernel.getService('objectql');
+    kernel.getService('objectql');
     console.log('✅ objectql service still available (backward compatibility)');
   } catch (e: any) {
     throw new Error(`FAILED: objectql service not found: ${e.message}`);
EOF
@@ -72,7 +72,7 @@

// Verify objectql service is still available (backward compatibility)
try {
const ql = kernel.getService('objectql');
kernel.getService('objectql');
console.log('✅ objectql service still available (backward compatibility)');
} catch (e: any) {
throw new Error(`FAILED: objectql service not found: ${e.message}`);
Copilot is powered by AI and may make mistakes. Always verify output.
*/

import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from '../packages/runtime/src';
import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from './packages/runtime/src/index.js';

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note test

Unused import SchemaRegistry.

Copilot Autofix

AI about 7 hours ago

In general, unused imports should be removed from the import list to avoid confusion and keep the codebase clean. Since SchemaRegistry is not referenced anywhere in test-objectql-plugin.ts, the best fix is to delete it from the named imports on line 10.

Concretely, edit test-objectql-plugin.ts at the import statement on line 10, changing:

import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from './packages/runtime/src/index.js';

to:

import { ObjectKernel, ObjectQLPlugin, ObjectQL } from './packages/runtime/src/index.js';

No other code changes, imports, or definitions are required, and this does not alter any existing functionality since SchemaRegistry was never used.

Suggested changeset 1
test-objectql-plugin.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/test-objectql-plugin.ts b/test-objectql-plugin.ts
--- a/test-objectql-plugin.ts
+++ b/test-objectql-plugin.ts
@@ -7,7 +7,7 @@
  * 3. Multiple plugins with ObjectQL work
  */
 
-import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from './packages/runtime/src/index.js';
+import { ObjectKernel, ObjectQLPlugin, ObjectQL } from './packages/runtime/src/index.js';
 
 async function testPluginBasedRegistration() {
   console.log('\n=== Test 1: Plugin-based ObjectQL Registration ===');
EOF
@@ -7,7 +7,7 @@
* 3. Multiple plugins with ObjectQL work
*/

import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from './packages/runtime/src/index.js';
import { ObjectKernel, ObjectQLPlugin, ObjectQL } from './packages/runtime/src/index.js';

async function testPluginBasedRegistration() {
console.log('\n=== Test 1: Plugin-based ObjectQL Registration ===');
Copilot is powered by AI and may make mistakes. Always verify output.
- Fixed ObjectQL.delete() to return boolean directly from driver
- Removed incorrect comment about driver returning record/null
- Fixed MockDriver.delete() to return boolean per DriverInterface spec
- Renamed QueryFilter/QueryOptions to DataEngineFilter/DataEngineQueryOptions to avoid naming collisions with existing data protocol types
- All tests passing

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 28, 2026

@copilot 参考以下内容进一步优化,这是一个非常深刻的架构分层问题。
答案是:必须定义 Driver(驱动层)。
如果不定义 Driver,而是让 IDataEngine 直接去...

感谢您详细的架构指导!我确认当前实现已经正确遵循了您描述的三层架构模式:

1. Consumer 层 (API/Flow/UI)

  • 使用 IDataEngine 接口

2. DataEngine 层 (ObjectQL)

  • 实现 IDataEngine 接口
  • 负责业务逻辑:Hooks、Validation、Permissions
  • 内部使用 DriverInterface

3. Driver 层 (Postgres/Mongo/Memory)

  • 实现 DriverInterface
  • 仅负责数据库适配:连接、SQL翻译、CRUD

这样做到了业务逻辑不重复 - 所有的权限检查、Hooks 执行、校验等只在 ObjectQL 中实现一次,各个 Driver 只专注于数据持久化。

最新提交 (bc82cda) 修复了:

  • delete() 方法正确返回 boolean
  • 解决了类型命名冲突
  • 所有测试通过 ✅

@hotlong
Copy link
Contributor

hotlong commented Jan 28, 2026

@copilot dataengine 应该在 spec/data下还是 spec/system下

Copy link
Contributor Author

Copilot AI commented Jan 28, 2026

@copilot dataengine 应该在 spec/data下还是 spec/system下

应该在 spec/system 下。

理由:

  1. data/ = 业务元数据层(用户定义的:Object、Field、Query、Validation)
  2. system/ = 运行时基础设施层(平台如何工作:Driver、Plugin、Engine)

IDataEngine 是运行时服务接口,类似 DriverInterface(也在 system/),是基础设施而非业务元数据。

当前位置正确 ✅ 但需要删除 content/docs/references/data/data-engine.mdx 重复文档。

@hotlong
Copy link
Contributor

hotlong commented Jan 28, 2026

@copilot 帮我继续修改

- Renamed QueryFilterSchema to DataEngineFilterSchema
- Renamed QueryOptionsSchema to DataEngineQueryOptionsSchema
- Updated all imports in objectql and runtime packages
- This prevents the doc generator from creating duplicate files in data/
- Confirmed data-engine.zod.ts should remain in spec/system (infrastructure layer)
- All tests passing

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI requested a review from hotlong January 28, 2026 06:28
Copy link
Contributor Author

Copilot AI commented Jan 28, 2026

@copilot 帮我继续修改

请问具体需要修改什么呢?

当前已完成:

  • ✅ IDataEngine 接口已实现
  • ✅ ObjectQL 实现了 IDataEngine
  • ✅ 三层架构正确分离(Consumer → DataEngine → Driver)
  • ✅ 位置确认在 spec/system(正确)
  • ✅ 所有测试通过

如果有具体的改进点或新需求,请告知,我会继续优化。

@hotlong hotlong marked this pull request as ready for review January 28, 2026 06:34
Copilot AI review requested due to automatic review settings January 28, 2026 06:34
*/

import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, QueryOptions } from './index.js';
import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, DataEngineQueryOptions } from './index.js';

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note test

Unused imports IHttpRequest, IHttpResponse.

Copilot Autofix

AI about 6 hours ago

To fix the problem, we should remove the unused imports IHttpRequest and IHttpResponse from the import list in packages/runtime/src/test-interfaces.ts. This eliminates the unused program elements without changing any runtime or type-checking behavior, since they are not referenced elsewhere in the file.

Concretely, in packages/runtime/src/test-interfaces.ts, edit the import on line 8 so that only the actually used symbols remain. Replace:

import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, DataEngineQueryOptions } from './index.js';

with:

import { IHttpServer, IDataEngine, RouteHandler, Middleware, DataEngineQueryOptions } from './index.js';

No additional methods, imports, or definitions are needed. This is a minimal change that only removes unused imports and preserves all existing functionality.

Suggested changeset 1
packages/runtime/src/test-interfaces.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/runtime/src/test-interfaces.ts b/packages/runtime/src/test-interfaces.ts
--- a/packages/runtime/src/test-interfaces.ts
+++ b/packages/runtime/src/test-interfaces.ts
@@ -5,7 +5,7 @@
  * and IDataEngine interfaces without depending on concrete implementations.
  */
 
-import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, DataEngineQueryOptions } from './index.js';
+import { IHttpServer, IDataEngine, RouteHandler, Middleware, DataEngineQueryOptions } from './index.js';
 
 /**
  * Example: Mock HTTP Server Plugin
EOF
@@ -5,7 +5,7 @@
* and IDataEngine interfaces without depending on concrete implementations.
*/

import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, DataEngineQueryOptions } from './index.js';
import { IHttpServer, IDataEngine, RouteHandler, Middleware, DataEngineQueryOptions } from './index.js';

/**
* Example: Mock HTTP Server Plugin
Copilot is powered by AI and may make mistakes. Always verify output.
@hotlong hotlong merged commit 27be77f into main Jan 28, 2026
15 of 16 checks passed
Copy link
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 the IDataEngine interface for ObjectQL, following a three-layer architecture pattern (Consumer → DataEngine → Driver). The implementation creates a standardized interface in @objectstack/spec and integrates it with the existing ObjectQL engine while maintaining backward compatibility.

Changes:

  • Created IDataEngine schema definition following Zod-first approach in the spec package
  • Modified ObjectQL class to implement the IDataEngine interface with proper query conversion logic
  • Updated ObjectQLPlugin to register ObjectQL as both 'data-engine' and 'objectql' services for backward compatibility

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/spec/src/system/data-engine.zod.ts New schema definition for IDataEngine interface with DataEngineQueryOptions and DataEngineFilter types
packages/spec/src/system/index.ts Exports the new data-engine protocol definitions
packages/spec/json-schema/system/DataEngine*.json Generated JSON schemas for data engine types
packages/objectql/src/index.ts Modified ObjectQL to implement IDataEngine, converting DataEngineQueryOptions to internal QueryAST format
packages/runtime/src/interfaces/data-engine.ts Consolidated interface file to re-export from spec package
packages/runtime/src/objectql-plugin.ts Registers ObjectQL as both 'data-engine' and 'objectql' services
packages/runtime/src/test-interfaces.ts Updated to use DataEngineQueryOptions type
test-dataengine-interface.ts New test file validating IDataEngine interface compliance
test-objectql-plugin.ts Minor updates to test error messages and import paths
content/docs/references/system/data-engine.mdx Documentation for the new data engine protocol
content/docs/references/system/index.mdx Added data-engine to the system references index
content/docs/references/system/meta.json Added data-engine to navigation metadata


```typescript
import { DataEngineSchema, DataEngineFilterSchema, DataEngineQueryOptionsSchema } from '@objectstack/spec/system';
import type { DataEngine, DataEngineFilter, DataEngineQueryOptions } from '@objectstack/spec/system';
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

The documentation references a type DataEngine that doesn't exist in the schema file. The schema file exports DataEngineSchema but doesn't export a corresponding type derived from it using z.infer.

Following the established pattern in other schema files (like driver.zod.ts which exports export type DriverInterface = z.infer<typeof DriverInterfaceSchema>), you should add:

export type DataEngine = z.infer<typeof DataEngineSchema>;

after line 98 in the schema file. However, note that the manually defined IDataEngine interface (lines 102-107) serves the same purpose but with better type safety for optional parameters. Consider whether you need both or if the documentation should reference IDataEngine instead.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +107
import { z } from 'zod';

/**
* Data Engine Protocol
*
* Defines the standard interface for data persistence engines.
* This allows different data engines (ObjectQL, Prisma, TypeORM, etc.)
* to be used interchangeably through a common interface.
*
* Following the Dependency Inversion Principle - plugins depend on this interface,
* not on concrete database implementations.
*/

/**
* Data Engine Query filter conditions
* Simple key-value filter structure for IDataEngine.find() operations
*/
export const DataEngineFilterSchema = z.record(z.any()).describe('Data Engine query filter conditions');

/**
* Query options for IDataEngine.find() operations
*/
export const DataEngineQueryOptionsSchema = z.object({
/** Filter conditions */
filter: DataEngineFilterSchema.optional(),
/** Fields to select */
select: z.array(z.string()).optional(),
/** Sort order */
sort: z.record(z.union([z.literal(1), z.literal(-1), z.literal('asc'), z.literal('desc')])).optional(),
/** Limit number of results (alternative name for top, used by some drivers) */
limit: z.number().optional(),
/** Skip number of results (for pagination) */
skip: z.number().optional(),
/** Maximum number of results (OData-style, takes precedence over limit if both specified) */
top: z.number().optional(),
}).describe('Query options for IDataEngine.find() operations');

/**
* Data Engine Interface Schema
*
* Defines the contract for data engine implementations.
*/
export const DataEngineSchema = z.object({
/**
* Insert a new record
*
* @param objectName - Name of the object/table (e.g., 'user', 'order')
* @param data - Data to insert
* @returns Promise resolving to the created record (including generated ID)
*/
insert: z.function()
.args(z.string(), z.any())
.returns(z.promise(z.any()))
.describe('Insert a new record'),

/**
* Find records matching a query
*
* @param objectName - Name of the object/table
* @param query - Query conditions (optional)
* @returns Promise resolving to an array of matching records
*/
find: z.function()
.args(z.string())
.returns(z.promise(z.array(z.any())))
.describe('Find records matching a query'),

/**
* Update a record by ID
*
* @param objectName - Name of the object/table
* @param id - Record ID
* @param data - Updated data (partial update)
* @returns Promise resolving to the updated record
*/
update: z.function()
.args(z.string(), z.any(), z.any())
.returns(z.promise(z.any()))
.describe('Update a record by ID'),

/**
* Delete a record by ID
*
* @param objectName - Name of the object/table
* @param id - Record ID
* @returns Promise resolving to true if deleted, false otherwise
*/
delete: z.function()
.args(z.string(), z.any())
.returns(z.promise(z.boolean()))
.describe('Delete a record by ID'),
}).describe('Data Engine Interface');

/**
* TypeScript types derived from schemas
*/
export type DataEngineFilter = z.infer<typeof DataEngineFilterSchema>;
export type DataEngineQueryOptions = z.infer<typeof DataEngineQueryOptionsSchema>;

// Define the TypeScript interface manually for better type safety
// Zod function schema doesn't handle optional parameters well
export interface IDataEngine {
insert(objectName: string, data: any): Promise<any>;
find(objectName: string, query?: DataEngineQueryOptions): Promise<any[]>;
update(objectName: string, id: any, data: any): Promise<any>;
delete(objectName: string, id: any): Promise<boolean>;
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

Following the established testing pattern in this codebase (as seen in driver.test.ts, datasource.test.ts, audit.test.ts, etc.), a test file should be created for the data engine schema to validate the schema definitions.

Create a new file packages/spec/src/system/data-engine.test.ts that validates the DataEngineQueryOptionsSchema, DataEngineFilterSchema, and the IDataEngine interface implementation. This ensures the schema behaves as expected and provides examples of valid/invalid data structures.

Copilot uses AI. Check for mistakes.
*/

import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, QueryOptions } from './index.js';
import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, DataEngineQueryOptions } from './index.js';
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

Unused imports IHttpRequest, IHttpResponse.

Suggested change
import { IHttpServer, IDataEngine, RouteHandler, IHttpRequest, IHttpResponse, Middleware, DataEngineQueryOptions } from './index.js';
import { IHttpServer, IDataEngine, RouteHandler, Middleware, DataEngineQueryOptions } from './index.js';

Copilot uses AI. Check for mistakes.
import { ObjectKernel } from './packages/runtime/src/mini-kernel.js';
import { ObjectQLPlugin } from './packages/runtime/src/objectql-plugin.js';
import { DriverPlugin } from './packages/runtime/src/driver-plugin.js';
import { ObjectQL } from './packages/objectql/src/index.js';
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

Unused import ObjectQL.

Suggested change
import { ObjectQL } from './packages/objectql/src/index.js';

Copilot uses AI. Check for mistakes.
// Verify objectql service is still available (backward compatibility)
try {
const ql = kernel.getService('objectql');
console.log('✅ objectql service still available (backward compatibility)');
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

Unused variable ql.

Suggested change
console.log('✅ objectql service still available (backward compatibility)');
console.log('✅ objectql service still available (backward compatibility). Service type:', ql.constructor.name);

Copilot uses AI. Check for mistakes.
*/

import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from '../packages/runtime/src';
import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from './packages/runtime/src/index.js';
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

Unused import SchemaRegistry.

Suggested change
import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from './packages/runtime/src/index.js';
import { ObjectKernel, ObjectQLPlugin, ObjectQL } from './packages/runtime/src/index.js';

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:system size/l

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants