/** * 登记触发的路由(编码规范 §3;语义出处 OS 3.1)。 * * 「登记触发 = 人工起单的统一形态:登记人选择流程包、按调用接口 schema 填写输入、 * 提交即起单。」**凡单必有来源** —— 登记起单的来源就是登记人,记在工作流上。 * * 与事件触发同走一条 `trigger.fire` 通路:差别只在**时机由谁给定**,不在起单本身。 */ import type { Hono } from 'hono'; import type { ApiError } from '@contracts'; import { fireRegistrationRoute, listRegistrationTriggersRoute, triggerKindOf } from '@contracts'; import type { Container } from '../container.ts'; import type { AppEnv } from '../http-env.ts'; export function registerRegistrationRoutes(app: Hono, container: Container): void { const unauthenticated: ApiError = { code: 'unauthenticated', message: '会话无效' }; /** 可登记起单的触发器 + 各自流程包的调用接口 schema(表单由它自动渲染) */ app.get(listRegistrationTriggersRoute.path, async (c) => { const me = await container.org.findByAccount(c.get('account')); if (me === undefined) return c.json(unauthenticated, 401); const triggers = await container.trigger.list(); const registration = triggers.filter((t) => triggerKindOf(t.spec) === 'registration'); const rows = await Promise.all( registration.map(async (t) => { const pkg = await container.process.getPackage(t.processPackageId); return { id: t.id, name: t.name, processPackageId: t.processPackageId, enabled: t.enabled, inputSchema: (pkg?.callInterface.input ?? {}) as Record, }; }), ); return c.json({ triggers: rows }); }); app.post(fireRegistrationRoute.path, async (c) => { const me = await container.org.findByAccount(c.get('account')); if (me === undefined) return c.json(unauthenticated, 401); const parsed = fireRegistrationRoute.body.safeParse(await c.req.json()); if (!parsed.success) { const body: ApiError = { code: 'validation-failed', message: '登记入参不合法' }; return c.json(body, 400); } // 登记人即来源 —— 由会话给定,不由前端传 const outcome = await container.trigger.fireByRegistration( c.req.param('triggerId'), me.id, parsed.data.data, ); return c.json({ ok: outcome.workflowId !== undefined, ...(outcome.workflowId === undefined ? {} : { workflowId: outcome.workflowId }), ...(outcome.skipped === undefined ? {} : { skipped: outcome.skipped }), ...(outcome.missing === undefined ? {} : { missing: [...outcome.missing] }), }); }); }