三面拆分⑩:工作组管理落员工区 —— ADR-011 欠账清账

建组/改组:逐岗位选人,留空即回落四策略。绑定先于策略,起单时快照进工作流;
实测改绑定后新起单的 work_group 快照即含新成员表,在途不受影响。

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 21:28:30 +08:00
co-authored by Claude Fable 5
parent a93f03f464
commit 6f36f8340a
8 changed files with 350 additions and 12 deletions
+30 -1
View File
@@ -4,7 +4,7 @@
*/
import { z } from 'zod';
import type { RouteContract } from './http.ts';
import { disableCheckSchema, grantSchema, positionSchema, staffSchema } from '../org.ts';
import { disableCheckSchema, grantSchema, positionSchema, staffSchema, workGroupSchema } from '../org.ts';
import { positionIdSchema, staffIdSchema, taskIdSchema } from '../id.ts';
import { closureReportSchema, processPackageSchema, triggerConfigSchema } from '../process-package.ts';
import { controlSemanticSchema, taskRuntimeStateSchema, terminalStateSchema, workflowStateSchema } from '../terminal.ts';
@@ -250,6 +250,34 @@ export const upsertTriggerRoute = {
output: z.object({ trigger: triggerConfigSchema }),
} as const satisfies RouteContract;
/* ── 员工管理 · 工作组(ADR-011) ───────────────────────────────────── */
/**
* 工作组 = 一组「岗位 → 员工」的绑定,**起单时装载、随工作流走**。
*
* 它是**绑定先于策略**,不是第五种负责人策略:起单人有组,整条流的岗位就按组指人;
* 没有组才回落四策略。装进工作流的是**快照** —— 改组不改已起的单。
*/
export const listWorkGroupsRoute = {
method: 'GET',
path: '/api/gov/work-groups',
/** `ownerName` 是组长姓名的呈现补充,读表时一并带出,免得前端再对一次 id */
output: z.object({ groups: z.array(workGroupSchema.extend({ ownerName: z.string() })) }),
} as const satisfies RouteContract;
/** 一人一组:按 `ownerId` 落,已有即更新、没有即新建 */
export const saveWorkGroupRoute = {
method: 'PUT',
path: '/api/gov/work-groups',
body: z.object({
ownerId: staffIdSchema,
name: z.string().min(1),
/** 岗位 code → 员工 id;留空的岗位不绑定,那一位仍走四策略 */
members: z.record(z.string().min(1), staffIdSchema),
}),
output: z.object({ group: workGroupSchema }),
} as const satisfies RouteContract;
/* ── 活动库管理:两维分类 × 包版本 × 资产版本 ─────────────────────────── */
export const listActivitiesRoute = {
@@ -427,6 +455,7 @@ export const govMetricsRoute = {
/* ── 出参类型:契约自己命名,消费方不再 `z.infer` ──────────────────────── */
export type GovTasksOutput = z.infer<typeof listGovTasksRoute.output>;
export type GovWorkGroupsOutput = z.infer<typeof listWorkGroupsRoute.output>;
export type GovApprovalsOutput = z.infer<typeof listApprovalsRoute.output>;
export type GovStaffOutput = z.infer<typeof listStaffRoute.output>;
export type GovGrantsOutput = z.infer<typeof listGrantsRoute.output>;