From de283acbdbe65d47d10d4f318f19f96b0952d876 Mon Sep 17 00:00:00 2001 From: 18628386721 <18628386721@163.com> Date: Mon, 27 Jul 2026 21:12:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=89=E9=9D=A2=E6=8B=86=E5=88=86=E2=91=A5:?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E5=99=A8=20upsert=20=E8=B7=AF=E7=94=B1=20?= =?UTF-8?q?=E2=80=94=E2=80=94=20=E5=AE=9A=E4=B9=89=E9=9D=A2=E7=9A=84=20HTT?= =?UTF-8?q?P=20=E5=8F=A3(=E5=90=AF=E5=81=9C=E4=BB=8D=E8=B5=B0=20toggle)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m --- .../contracts/src/api/governance.d.ts | 113 ++++++++++++++++++ apps/api/src/app/routes/governance-ops.ts | 16 +++ packages/contracts/src/api/governance.ts | 14 +++ 3 files changed, 143 insertions(+) diff --git a/api-report/packages/contracts/src/api/governance.d.ts b/api-report/packages/contracts/src/api/governance.d.ts index 3b51c98..eae1450 100644 --- a/api-report/packages/contracts/src/api/governance.d.ts +++ b/api-report/packages/contracts/src/api/governance.d.ts @@ -1380,6 +1380,119 @@ export declare const toggleTriggerRoute: { ok: z.ZodBoolean; }, z.core.$strip>; }; +/** + * 调起规则的**定义面**(设计中心):新建 / 改规则 / 改起单装配。 + * + * 与 `toggleTriggerRoute` 分开是有意的:定义归设计,启停归运营 —— + * 同一个触发器,「它按什么规则调起」和「今天开不开」是两个人在两个台面上做的两件事。 + * 触发器与流程包平级:改它**不动任何包版本**。 + */ +export declare const upsertTriggerRoute: { + readonly method: "PUT"; + readonly path: "/api/gov/triggers"; + readonly body: z.ZodObject<{ + trigger: z.ZodObject<{ + id: z.core.$ZodBranded; + name: z.ZodString; + enabled: z.ZodDefault; + processPackageId: z.core.$ZodBranded; + mapping: z.ZodDefault; + port: z.ZodString; + path: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"workflow-var">; + name: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"initiation">; + path: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"constant">; + value: z.ZodUnknown; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"expression">; + sfeel: z.ZodString; + }, z.core.$strip>], "from">; + }, z.core.$strip>>>; + spec: z.ZodDiscriminatedUnion<[z.ZodObject<{ + kind: z.ZodLiteral<"periodic-calendar">; + calendar: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + kind: z.ZodLiteral<"periodic-data">; + domain: z.ZodString; + object: z.ZodString; + dateField: z.ZodString; + offset: z.ZodString; + filter: z.ZodOptional; + }, z.core.$strip>, z.ZodObject<{ + kind: z.ZodLiteral<"event">; + rule: z.ZodString; + eventType: z.ZodDefault>; + }, z.core.$strip>, z.ZodObject<{ + kind: z.ZodLiteral<"registration">; + formHint: z.ZodOptional; + }, z.core.$strip>], "kind">; + }, z.core.$strip>; + }, z.core.$strip>; + readonly output: z.ZodObject<{ + trigger: z.ZodObject<{ + id: z.core.$ZodBranded; + name: z.ZodString; + enabled: z.ZodDefault; + processPackageId: z.core.$ZodBranded; + mapping: z.ZodDefault; + port: z.ZodString; + path: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"workflow-var">; + name: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"initiation">; + path: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"constant">; + value: z.ZodUnknown; + }, z.core.$strip>, z.ZodObject<{ + from: z.ZodLiteral<"expression">; + sfeel: z.ZodString; + }, z.core.$strip>], "from">; + }, z.core.$strip>>>; + spec: z.ZodDiscriminatedUnion<[z.ZodObject<{ + kind: z.ZodLiteral<"periodic-calendar">; + calendar: z.ZodString; + }, z.core.$strip>, z.ZodObject<{ + kind: z.ZodLiteral<"periodic-data">; + domain: z.ZodString; + object: z.ZodString; + dateField: z.ZodString; + offset: z.ZodString; + filter: z.ZodOptional; + }, z.core.$strip>, z.ZodObject<{ + kind: z.ZodLiteral<"event">; + rule: z.ZodString; + eventType: z.ZodDefault>; + }, z.core.$strip>, z.ZodObject<{ + kind: z.ZodLiteral<"registration">; + formHint: z.ZodOptional; + }, z.core.$strip>], "kind">; + }, z.core.$strip>; + }, z.core.$strip>; +}; export declare const listActivitiesRoute: { readonly method: "GET"; readonly path: "/api/gov/activities"; diff --git a/apps/api/src/app/routes/governance-ops.ts b/apps/api/src/app/routes/governance-ops.ts index 1394ca7..75dbb68 100644 --- a/apps/api/src/app/routes/governance-ops.ts +++ b/apps/api/src/app/routes/governance-ops.ts @@ -29,6 +29,7 @@ import { staffIdSchema, taskIdSchema, toggleTriggerRoute, + upsertTriggerRoute, validateProcessRoute, } from '@contracts'; import { NotPublishableError } from '@modules/process'; @@ -331,6 +332,21 @@ export function registerGovernanceOpsRoutes(app: Hono, container: Contai return c.json({ ok: true }); }); + /** + * 调起规则的定义面(设计中心)—— 新建 / 改规则 / 改起单装配。 + * 启停不走这里(那是运营的事,见 toggle);改定义同样不动任何流程包版本。 + */ + app.put(upsertTriggerRoute.path, async (c) => { + const denied = await governTrigger(c.get('account')); + if (denied) return c.json(denied, denyStatus(denied)); + const parsed = upsertTriggerRoute.body.safeParse(await c.req.json()); + if (!parsed.success) { + const body: ApiError = { code: 'validation-failed', message: '触发器不合 schema', detail: parsed.error.issues }; + return c.json(body, 400); + } + return c.json({ trigger: await container.trigger.upsert(parsed.data.trigger) }); + }); + /* ── 活动库管理:两维分类 × 两条版本序列 ─────────────────────────── */ app.get(listActivitiesRoute.path, async (c) => { diff --git a/packages/contracts/src/api/governance.ts b/packages/contracts/src/api/governance.ts index ebad5bc..6f2cda7 100644 --- a/packages/contracts/src/api/governance.ts +++ b/packages/contracts/src/api/governance.ts @@ -236,6 +236,20 @@ export const toggleTriggerRoute = { output: z.object({ ok: z.boolean() }), } as const satisfies RouteContract; +/** + * 调起规则的**定义面**(设计中心):新建 / 改规则 / 改起单装配。 + * + * 与 `toggleTriggerRoute` 分开是有意的:定义归设计,启停归运营 —— + * 同一个触发器,「它按什么规则调起」和「今天开不开」是两个人在两个台面上做的两件事。 + * 触发器与流程包平级:改它**不动任何包版本**。 + */ +export const upsertTriggerRoute = { + method: 'PUT', + path: '/api/gov/triggers', + body: z.object({ trigger: triggerConfigSchema }), + output: z.object({ trigger: triggerConfigSchema }), +} as const satisfies RouteContract; + /* ── 活动库管理:两维分类 × 包版本 × 资产版本 ─────────────────────────── */ export const listActivitiesRoute = {