/** * process 的 sys schema 表(编码规范 §7 / ADR-002)。 * 流程包定义与版本 + 工作流实例 + 节点实例(重开产生新实例,旧实例不再入算)。 */ import { boolean, index, integer, jsonb, primaryKey, text, timestamp } from 'drizzle-orm/pg-core'; import { sys } from '@shared/db.ts'; export const processPackageTable = sys.table( 'process_package', { id: text('id').notNull(), version: integer('version').notNull(), name: text('name').notNull(), state: text('state').notNull().default('draft'), definition: jsonb('definition').notNull(), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), publishedAt: timestamp('published_at', { withTimezone: true }), }, (t) => [primaryKey({ columns: [t.id, t.version] }), index('process_package_state_idx').on(t.state)], ); export const workflowTable = sys.table( 'workflow', { id: text('id').primaryKey(), packageId: text('package_id').notNull(), packageVersion: integer('package_version').notNull(), subject: text('subject').notNull(), state: text('state').notNull().default('running'), /** 凡单必有来源 */ source: jsonb('source').notNull(), initiation: jsonb('initiation').notNull(), /** 工作组绑定快照(ADR-011)—— 起单时装载,之后改组不影响这条单 */ workGroup: jsonb('work_group'), /** 节点指派:{ 节点id → 员工id } —— 测试台定向;生产起单不传,照旧轮值 */ assignments: jsonb('assignments'), ports: jsonb('ports').notNull().default({}), vars: jsonb('vars').notNull().default({}), startedAt: timestamp('started_at', { withTimezone: true }).notNull().defaultNow(), finishedAt: timestamp('finished_at', { withTimezone: true }), }, (t) => [index('workflow_state_idx').on(t.state, t.startedAt)], ); export const nodeInstanceTable = sys.table( 'node_instance', { workflowId: text('workflow_id').notNull(), nodeId: text('node_id').notNull(), instance: integer('instance').notNull(), running: boolean('running').notNull().default(false), waiting: boolean('waiting').notNull().default(false), activated: boolean('activated').notNull().default(true), terminal: text('terminal'), failureDigested: boolean('failure_digested'), taskId: text('task_id'), approvalId: text('approval_id'), assigneeId: text('assignee_id'), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), }, (t) => [ primaryKey({ columns: [t.workflowId, t.nodeId, t.instance] }), index('node_instance_task_idx').on(t.taskId), ], ); /** * 节点负责人(**运营配置**,2026-07-30):流程包的哪个节点归谁。 * 起单时垫在显式指派之下、轮值之上 —— 显式指派 > 这里 > 员工组轮值 > 全员轮值。 * 不随包版本:它说的是「这家企业现在这活谁管」,不是流程长什么样。 */ export const nodeOwnerTable = sys.table('node_owner', { packageId: text('package_id').notNull(), nodeId: text('node_id').notNull(), staffId: text('staff_id').notNull(), });