forked from ChaiHao/BPOS-MVP
human-tool(L3): - 三规矩机检:调用必附上下文(裸调用拒发)/ 回传即留痕 / 完成只出自放行通过 - 工单两模式 + 对话卡族的形态校验与回传校验;驳回必附意见;补全卡「没法填」旁路; 决策卡自定义收尾项必附理由;已答不得再答(只增不改) - 到达面两路(负责人 → 任务对话流;他人 → 系统消息);驳回重答 = 新卡实例、原卡闭合 - 调人预算由基座在环外强制;落地失败卡 = 执行工单的 preset release(L4): - 落地预检五项(入参 schema / 工具可用与授权 / 连接可达 / 目标预校验 / 数据冲突) - 预检全过才发验收工单,卡面即已验证的动作清单;不过即打回环内,不发卡 - 放行写合并 + 幂等落地(任务 × 意向);落地收敛才发射输出口; 受阻走落地失败卡且 emittedPorts 恒空;已成动作留存不回滚 215 个测试通过,门禁五道全绿 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
/**
|
|
* human-tool 的 sys schema 表(编码规范 §7 / ADR-002)。
|
|
*/
|
|
import { index, jsonb, text, timestamp } from 'drizzle-orm/pg-core';
|
|
import { sys } from '@shared/db.ts';
|
|
|
|
/** 工单两模式 —— 执行 / 验收;落地失败卡是执行工单的 preset,不另立表 */
|
|
export const workOrderTable = sys.table(
|
|
'work_order',
|
|
{
|
|
id: text('id').primaryKey(),
|
|
taskId: text('task_id').notNull(),
|
|
recipientId: text('recipient_id').notNull(),
|
|
mode: text('mode').notNull(),
|
|
title: text('title').notNull(),
|
|
payload: jsonb('payload').notNull(),
|
|
at: timestamp('at', { withTimezone: true }).notNull(),
|
|
done: jsonb('done'),
|
|
},
|
|
(t) => [index('work_order_task_idx').on(t.taskId, t.at), index('work_order_recipient_idx').on(t.recipientId)],
|
|
);
|
|
|
|
/** 对话卡族 —— 决策 / 补全 / 评价 */
|
|
export const chatCardTable = sys.table(
|
|
'chat_card',
|
|
{
|
|
id: text('id').primaryKey(),
|
|
taskId: text('task_id').notNull(),
|
|
recipientId: text('recipient_id').notNull(),
|
|
kind: text('kind').notNull(),
|
|
payload: jsonb('payload').notNull(),
|
|
at: timestamp('at', { withTimezone: true }).notNull(),
|
|
/** 驳回重答:原卡以 supersededBy 闭合 —— 只增不改 */
|
|
supersededBy: text('superseded_by'),
|
|
rejectedReason: text('rejected_reason'),
|
|
},
|
|
(t) => [index('chat_card_task_idx').on(t.taskId, t.at), index('chat_card_recipient_idx').on(t.recipientId)],
|
|
);
|