Skip to content

Commit 7a4a845

Browse files
Copilothotlong
andcommitted
Clarify Plugin Lifecycle terminology to avoid confusion with Triggers
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 25940cd commit 7a4a845

3 files changed

Lines changed: 85 additions & 16 deletions

File tree

HOOK_TRIGGER_CLARIFICATION.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Hook vs Trigger Clarification
2+
3+
## 问题 (Question)
4+
审核所有的zod,我们之前有定义一个类似现在trigger的hook规范,现在还需要保留吗?
5+
6+
## 分析结果 (Analysis Results)
7+
8+
### 现有的 "Hook-like" 规范 (Current "Hook-like" Specifications)
9+
10+
经过全面审查,发现以下几个与"hook"或"trigger"相关的规范:
11+
12+
1. **Trigger** (`src/data/trigger.zod.ts`) - 数据库级别的业务逻辑钩子
13+
- 目的:在数据库操作前后执行业务逻辑
14+
- 时机:before/after insert/update/delete
15+
- 功能:数据验证、设置默认值、更新关联记录、阻止操作
16+
17+
2. **Plugin Lifecycle** (`src/system/plugin.zod.ts`) - 插件生命周期回调
18+
- 目的:插件安装和生命周期管理
19+
- 回调:onInstall, onEnable, onDisable, onUninstall, onUpgrade
20+
- 功能:插件初始化、服务启停、数据迁移、资源清理
21+
22+
3. **Webhook** (`src/system/webhook.zod.ts`) - 外部HTTP集成
23+
- 目的:与外部系统的HTTP回调集成
24+
- 类型:create, update, delete, undelete, api
25+
- 方向:出站(push)和入站(receive)
26+
27+
4. **Workflow** (`src/data/workflow.zod.ts`) - 业务流程自动化
28+
- 目的:业务流程自动化规则
29+
- 触发器:on_create, on_update, on_create_or_update, on_delete, schedule
30+
- 动作:field_update, email_alert, sms_notification等
31+
32+
### 发现的问题 (Issues Found)
33+
34+
1. **术语混淆**:Plugin Lifecycle 在描述中使用了 "Hook" 术语,但其实是生命周期回调,与 Trigger 的语义不同
35+
2. **未实现的计划**:开发路线图中提到的 `hooks.zod.ts`(包含 beforeObjectCreate, afterRecordSave 等)实际上与现有的 Trigger 重复
36+
37+
### 建议 (Recommendations)
38+
39+
**✅ 推荐方案:保留现有结构,澄清术语**
40+
41+
1. **Trigger** - 保留,作为数据库级别的业务逻辑钩子(这是正确的设计)
42+
2. **Plugin Lifecycle** - 保留,但将术语从 "Hook" 改为 "Lifecycle callback",避免混淆
43+
3. **不需要新的 hooks.zod.ts** - Trigger 已经覆盖了计划中的扩展点
44+
45+
### 已实施的更改 (Changes Made)
46+
47+
1. 更新了 `src/system/plugin.zod.ts` 中的描述,将 "Hook called on..." 改为 "Lifecycle callback on..."
48+
2. 将类型名称从 `PluginLifecycleHooks` 改为 `PluginLifecycleCallbacks`,更准确地反映其用途
49+
3. 更新了相关测试文件
50+
51+
### 语义区别 (Semantic Differences)
52+
53+
| 方面 | Trigger | Plugin Lifecycle | Webhook | Workflow |
54+
|------|---------|------------------|---------|----------|
55+
| **层级** | 数据/记录 | 系统/插件 | 集成 | 流程 |
56+
| **同步** ||| 可异步 | 可异步 |
57+
| **可修改数据** | 是(before) | 通过QL API |||
58+
| **可阻止操作** | 是(before) ||| 通过条件 |
59+
| **执行上下文** | 每条记录 | 每个插件 | 每个事件 | 每条规则 |
60+
61+
## 结论 (Conclusion)
62+
63+
**不需要保留旧的 hook 规范,因为:**
64+
1. 代码库中不存在单独的旧 `hook.zod.ts` 文件
65+
2. 当前的 Trigger 规范已经非常完善,涵盖了数据库级别的钩子需求
66+
3. Plugin Lifecycle 服务于不同的目的(插件生命周期管理),已通过术语澄清与 Trigger 区分开来
67+
4. 计划中的 Hook Registry Protocol 会与 Trigger 重复,不需要实现
68+
69+
**Trigger 规范应该作为 ObjectStack 的主要 "hook" 机制保留和使用。**

packages/spec/src/system/plugin.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { describe, it, expect } from 'vitest';
2-
import {
3-
PluginContextSchema,
2+
import {
3+
PluginContextSchema,
44
PluginLifecycleSchema,
55
PluginSchema,
66
type PluginContextData,
7-
type PluginLifecycleHooks,
7+
type PluginLifecycleCallbacks,
88
type PluginDefinition,
99
} from './plugin.zod';
1010

@@ -139,13 +139,13 @@ describe('PluginContextSchema', () => {
139139

140140
describe('PluginLifecycleSchema', () => {
141141
it('should accept empty lifecycle (all hooks optional)', () => {
142-
const lifecycle: PluginLifecycleHooks = {};
142+
const lifecycle: PluginLifecycleCallbacks = {};
143143

144144
expect(() => PluginLifecycleSchema.parse(lifecycle)).not.toThrow();
145145
});
146146

147147
it('should accept lifecycle with onInstall hook', () => {
148-
const lifecycle: PluginLifecycleHooks = {
148+
const lifecycle: PluginLifecycleCallbacks = {
149149
onInstall: async (context: PluginContextData) => {
150150
// Installation logic
151151
},
@@ -155,7 +155,7 @@ describe('PluginLifecycleSchema', () => {
155155
});
156156

157157
it('should accept lifecycle with onEnable hook', () => {
158-
const lifecycle: PluginLifecycleHooks = {
158+
const lifecycle: PluginLifecycleCallbacks = {
159159
onEnable: async (context: PluginContextData) => {
160160
// Enable logic
161161
},
@@ -165,7 +165,7 @@ describe('PluginLifecycleSchema', () => {
165165
});
166166

167167
it('should accept lifecycle with onDisable hook', () => {
168-
const lifecycle: PluginLifecycleHooks = {
168+
const lifecycle: PluginLifecycleCallbacks = {
169169
onDisable: async (context: PluginContextData) => {
170170
// Disable logic
171171
},
@@ -175,7 +175,7 @@ describe('PluginLifecycleSchema', () => {
175175
});
176176

177177
it('should accept lifecycle with onUninstall hook', () => {
178-
const lifecycle: PluginLifecycleHooks = {
178+
const lifecycle: PluginLifecycleCallbacks = {
179179
onUninstall: async (context: PluginContextData) => {
180180
// Uninstall logic
181181
},
@@ -185,7 +185,7 @@ describe('PluginLifecycleSchema', () => {
185185
});
186186

187187
it('should accept lifecycle with onUpgrade hook', () => {
188-
const lifecycle: PluginLifecycleHooks = {
188+
const lifecycle: PluginLifecycleCallbacks = {
189189
onUpgrade: async (context: PluginContextData, fromVersion: string, toVersion: string) => {
190190
// Upgrade logic
191191
},
@@ -195,7 +195,7 @@ describe('PluginLifecycleSchema', () => {
195195
});
196196

197197
it('should accept lifecycle with all hooks', () => {
198-
const lifecycle: PluginLifecycleHooks = {
198+
const lifecycle: PluginLifecycleCallbacks = {
199199
onInstall: async (context: PluginContextData) => {
200200
await context.ql.object('plugin_data').syncSchema();
201201
},

packages/spec/src/system/plugin.zod.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ export const PluginLifecycleSchema = z.object({
172172
.args(PluginContextSchema)
173173
.returns(z.promise(z.void()))
174174
.optional()
175-
.describe('Hook called on plugin installation'),
175+
.describe('Lifecycle callback on plugin installation'),
176176

177177
/**
178178
* Called when the plugin is enabled.
@@ -184,7 +184,7 @@ export const PluginLifecycleSchema = z.object({
184184
.args(PluginContextSchema)
185185
.returns(z.promise(z.void()))
186186
.optional()
187-
.describe('Hook called when plugin is enabled'),
187+
.describe('Lifecycle callback when plugin is enabled'),
188188

189189
/**
190190
* Called when the plugin is disabled.
@@ -196,7 +196,7 @@ export const PluginLifecycleSchema = z.object({
196196
.args(PluginContextSchema)
197197
.returns(z.promise(z.void()))
198198
.optional()
199-
.describe('Hook called when plugin is disabled'),
199+
.describe('Lifecycle callback when plugin is disabled'),
200200

201201
/**
202202
* Called when the plugin is uninstalled.
@@ -208,7 +208,7 @@ export const PluginLifecycleSchema = z.object({
208208
.args(PluginContextSchema)
209209
.returns(z.promise(z.void()))
210210
.optional()
211-
.describe('Hook called on plugin uninstallation'),
211+
.describe('Lifecycle callback on plugin uninstallation'),
212212

213213
/**
214214
* Called when the plugin is upgraded to a new version.
@@ -222,7 +222,7 @@ export const PluginLifecycleSchema = z.object({
222222
.args(PluginContextSchema, z.string(), z.string())
223223
.returns(z.promise(z.void()))
224224
.optional()
225-
.describe('Hook called on plugin upgrade'),
225+
.describe('Lifecycle callback on plugin upgrade'),
226226
});
227227

228228
/**
@@ -248,5 +248,5 @@ export const PluginSchema = PluginLifecycleSchema.extend({
248248
* TypeScript types
249249
*/
250250
export type PluginContextData = z.infer<typeof PluginContextSchema>;
251-
export type PluginLifecycleHooks = z.infer<typeof PluginLifecycleSchema>;
251+
export type PluginLifecycleCallbacks = z.infer<typeof PluginLifecycleSchema>;
252252
export type PluginDefinition = z.infer<typeof PluginSchema>;

0 commit comments

Comments
 (0)