基线:鉴权会话+工作组+工作台三区修复+编排工作区+产品设计文档

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
2026-07-27 20:43:35 +08:00
co-authored by Claude Fable 5
parent 61fe181678
commit ac85ecf2ea
119 changed files with 16634 additions and 1246 deletions
+62
View File
@@ -0,0 +1,62 @@
/**
* 登记触发的路由(编码规范 §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<AppEnv>, 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<string, unknown>,
};
}),
);
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] }),
});
});
}