/** * module: process —— 本模块要外界提供的能力(编码规范 §10.1 / §5.3)。 */ import type { ProcessPackage, StaffId, TerminalState, WorkflowState } from '@contracts'; import type { NodeInstance } from './internal/domain/owner-resolution.ts'; import type { ActivityContractFace } from './internal/domain/closure.ts'; export type Clock = { now(): Date }; export type IdGenerator = { next(): string }; /** 工作流实例的持久面 —— 崩溃后可续跑 */ export type WorkflowRecord = { readonly id: string; readonly packageId: string; readonly packageVersion: number; readonly subject: string; readonly state: WorkflowState; /** 来源:凡单必有来源(触发器 / 登记人 / 上游系统) */ readonly source: { kind: 'periodic' | 'event' | 'registration'; ref: string; by?: string }; readonly initiation: Record; /** * 工作组绑定的**快照**(ADR-011):起单时按来源人装载,之后改组不影响这条单。 * 留痕要能解释「当时为什么派给他」,而不是被今天的组织调整改写(同 AM 9.1 版本信封)。 */ readonly workGroup?: Record; /** 各节点输出口载荷 —— 边映射装配的来源 */ readonly ports: Record>; readonly vars: Record; readonly startedAt: string; readonly finishedAt?: string; }; export type ProcessStore = { savePackage(pkg: ProcessPackage): Promise; /** 就地写回一版的定义(编辑即其身)—— 撞不存在的版本报错,不静默插入 */ updatePackageDefinition(id: string, version: number, pkg: ProcessPackage): Promise; /** 钉在该版上的未完结工作流数 —— 在途钉版不可变的判据 */ countPinnedInFlight(id: string, version: number): Promise; /** 只改状态,不动定义 —— state 在列上与 definition 里各存一份,两处要一起改 */ setPackageState(id: string, version: number, state: 'active' | 'retired'): Promise; getPackage(id: string, version?: number): Promise; listPackages(): Promise; insertWorkflow(record: WorkflowRecord): Promise; getWorkflow(id: string): Promise; listWorkflows(limit: number): Promise; updateWorkflow(id: string, patch: Partial): Promise; listInstances(workflowId: string): Promise; insertInstance(workflowId: string, instance: NodeInstance & { taskId?: string; approvalId?: string }): Promise; updateInstance( workflowId: string, nodeId: string, instance: number, patch: Partial & { taskId?: string }, ): Promise; findInstanceByTask(taskId: string): Promise<{ workflowId: string; nodeId: string; instance: number } | undefined>; }; /** 活动契约面 —— app 注入 `activity-registry`(L4):编排校验与起单都要它 */ export type ActivityDirectory = { faces(): Promise>; }; /** 岗位与在岗人员 —— app 注入 `org`(L1):负责人四策略解析的候选集 */ export type OrgDirectory = { positions(): Promise>; candidates(position: string): Promise>; /** 某人的工作组绑定(ADR-011)—— 起单时按来源人取,取不到即不装载 */ workGroupBinding(staffId: string): Promise> | undefined>; /** 在岗与否 —— 绑定的人已离岗就不硬用,退回四策略 */ isActive(staffId: string): Promise; }; /** 起单与终态 —— app 注入 `task`(L6) */ export type TaskGateway = { start(input: { activityId: string; ownerId: StaffId; title: string; workflowId: string; nodeId: string; data: Record; message?: string; }): Promise<{ id: string }>; }; /** 审批点 —— app 注入 `human-tool`(L3):审批单卡到审批人工位 */ export type ApprovalGateway = { raise(input: { workflowId: string; nodeId: string; approverId: StaffId; subject: string; basis: ReadonlyArray<{ k: string; v: string }>; }): Promise<{ id: string }>; }; /** * 调用接口的入参校验 —— app 注入 ajv。 * 「凡单必有来源」的另一半是「凡单必合契约」:不合契约**不得起单**, * 且必须在**建工作流之前**判掉,否则会留下一条永远推不动的在途单。 */ export type SchemaValidator = { validate(schema: Record, value: unknown): { ok: boolean; errors: string[] }; }; /** S-FEEL —— app 注入 `@sfeel`:流转零 LLM */ export type Sfeel = { condition(expression: string, scope: Readonly>): boolean; expression(expression: string, scope: Readonly>): unknown; }; /** 流转记入事件 —— app 注入 `event`(L1) */ export type FlowEventPublisher = { publish(input: { workflowId: string; kind: string; detail: Record }): Promise; }; /** 终态回执 —— 登记人收消息 */ export type ReceiptNotifier = { notify(input: { to: StaffId; workflowId: string; subject: string; state: WorkflowState }): Promise; }; export type { TerminalState };