This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BPOS-TMP-REPO/api-report/packages/contracts/src/org.d.ts
T
xcsandClaude Fable 5 8556432dba feat(org): 成员目录 —— Keycloak 读写面穿透、治理台成员/组织/权限三页、姓在前 personName、Staff.kind
后端:`KeycloakDirectory` 端口(users / groups / roles 读写;写直接穿透 Keycloak —— 这里建的人立刻能登录、
删的人立刻消失,停用与收权之后 logout 踢掉会话)、`keycloak-directory.ts` + `keycloak-admin-http.ts` 适配器、
org-directory 契约与 /api/gov 路由、`sync-roster` CLI(ops 路由够不着时整册照过来),
容器按 provisioning 服务账号有无决定注不注入(没配就如实说不可用)。
`personName` 姓在前:汉字直拼「柴浩」、否则留一个空格「Admin Amy」,token 与名册同步两条路同一把尺;
`staffKindOf` 按 Keycloak 固定前缀 service-account- 认服务账号,员工那一屏不摆它(`Staff.kind` 不落库,按账号名现判)。
前端:员工那一屏重做成成员 / 组织 / 权限三页签(member-page 下钻),页签栏右端一句话说清这一格管什么。
契约变更:contracts org.ts / api/http.ts / api/org-directory.ts;api-report 已刷新;org CONTRACT.md 与 ADR-012 同步。
2026-08-26 做的,一直留在工作树没入库。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0167qWjeyBwvfdGovd7FWbCu
2026-08-27 11:44:36 +08:00

314 lines
12 KiB
TypeScript

/**
* 员工、岗位与端(编码规范 §4 · `org`;语义出处 OS 02 员工管理;鉴权归统一鉴权中心,ADR-012)。
*
* 身份来自 Keycloak:`Staff.id` 就是 token 的 `sub`。权限只到「端」(design / ops / workbench),
* 角色 → 端由运营中心的表定;岗位仍是本系统的表(流程引擎按它解析负责人)。
* 旧的岗位授权(客体三类 × 动作三种)与口令会话已退役 —— 类型留一轮(@deprecated,下个迭代删)。
*/
import { z } from 'zod';
export declare const positionSchema: z.ZodObject<{
id: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
code: z.ZodString;
name: z.ZodString;
note: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
export type Position = z.infer<typeof positionSchema>;
export declare const STAFF_STATES: readonly ["active", "disabled"];
export declare const staffStateSchema: z.ZodEnum<{
active: "active";
disabled: "disabled";
}>;
export type StaffState = z.infer<typeof staffStateSchema>;
/**
* 人,还是服务账号。
*
* Keycloak 给每个开了 `serviceAccountsEnabled` 的 client 自动建一个用户,用户名恒为
* `service-account-<clientId>` —— 那是 Keycloak 自己的命名,不是我们的约定;它也不出现在
* 管理台的 Users 列表、Admin API 的 `GET /users` 里(名册同步的下限保护②为此存在)。
*
* 它是**真身份**(试跑与 e2e 就用它跑单,铁规矩 6),但**不是人**:
* 员工管理那一屏不摆它,试跑台的负责人下拉照旧摆。
* 这条判断归后端 —— 界面不该去猜账号名长什么样。
*/
export declare const staffKindSchema: z.ZodEnum<{
person: "person";
service: "service";
}>;
export type StaffKind = z.infer<typeof staffKindSchema>;
export declare const staffSchema: z.ZodObject<{
id: z.core.$ZodBranded<z.ZodString, "StaffId", "out">;
account: z.ZodString;
name: z.ZodString;
email: z.ZodOptional<z.ZodString>;
positionId: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
state: z.ZodDefault<z.ZodEnum<{
active: "active";
disabled: "disabled";
}>>;
roles: z.ZodDefault<z.ZodArray<z.ZodString>>;
kind: z.ZodDefault<z.ZodEnum<{
person: "person";
service: "service";
}>>;
}, z.core.$strip>;
export type Staff = z.infer<typeof staffSchema>;
export declare const principalSchema: z.ZodObject<{
staff: z.ZodObject<{
id: z.core.$ZodBranded<z.ZodString, "StaffId", "out">;
account: z.ZodString;
name: z.ZodString;
email: z.ZodOptional<z.ZodString>;
positionId: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
state: z.ZodDefault<z.ZodEnum<{
active: "active";
disabled: "disabled";
}>>;
roles: z.ZodDefault<z.ZodArray<z.ZodString>>;
kind: z.ZodDefault<z.ZodEnum<{
person: "person";
service: "service";
}>>;
}, z.core.$strip>;
position: z.ZodObject<{
id: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
code: z.ZodString;
name: z.ZodString;
note: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
roles: z.ZodArray<z.ZodString>;
ends: z.ZodArray<z.ZodEnum<{
design: "design";
ops: "ops";
workbench: "workbench";
}>>;
}, z.core.$strip>;
export type Principal = z.infer<typeof principalSchema>;
/** 角色 → 端:一行一个 realm 角色 */
export declare const roleAccessSchema: z.ZodObject<{
role: z.ZodString;
ends: z.ZodArray<z.ZodEnum<{
design: "design";
ops: "ops";
workbench: "workbench";
}>>;
}, z.core.$strip>;
export type RoleAccess = z.infer<typeof roleAccessSchema>;
/**
* 名册同步的结果 —— 没配 provisioning 就如实说没配,不摆零。
* 三个计数说的是**真落进库里的条数**,不是打算写几条:单条写失败时它不进计数,
* 而是点名进 `failed` —— 一次半途失败的同步不许报成一排绿数字。
*/
export declare const rosterSyncOutcomeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
configured: z.ZodLiteral<false>;
message: z.ZodString;
}, z.core.$strip>, z.ZodObject<{
configured: z.ZodLiteral<true>;
inserted: z.ZodNumber;
updated: z.ZodNumber;
disabled: z.ZodNumber;
total: z.ZodNumber;
failed: z.ZodArray<z.ZodObject<{
account: z.ZodString;
reason: z.ZodString;
}, z.core.$strip>>;
}, z.core.$strip>], "configured">;
export type RosterSyncOutcome = z.infer<typeof rosterSyncOutcomeSchema>;
export declare const inFlightWorkSchema: z.ZodObject<{
staffId: z.core.$ZodBranded<z.ZodString, "StaffId", "out">;
blocked: z.ZodBoolean;
openTasks: z.ZodDefault<z.ZodArray<z.ZodObject<{
taskId: z.ZodString;
title: z.ZodString;
}, z.core.$strip>>>;
openCards: z.ZodDefault<z.ZodArray<z.ZodObject<{
cardId: z.ZodString;
title: z.ZodString;
}, z.core.$strip>>>;
openApprovals: z.ZodDefault<z.ZodArray<z.ZodObject<{
approvalId: z.ZodString;
title: z.ZodString;
}, z.core.$strip>>>;
}, z.core.$strip>;
export type InFlightWork = z.infer<typeof inFlightWorkSchema>;
/** @deprecated 随 ADR-012 改名 `inFlightWorkSchema`;下个迭代删 */
export declare const disableCheckSchema: z.ZodObject<{
staffId: z.core.$ZodBranded<z.ZodString, "StaffId", "out">;
blocked: z.ZodBoolean;
openTasks: z.ZodDefault<z.ZodArray<z.ZodObject<{
taskId: z.ZodString;
title: z.ZodString;
}, z.core.$strip>>>;
openCards: z.ZodDefault<z.ZodArray<z.ZodObject<{
cardId: z.ZodString;
title: z.ZodString;
}, z.core.$strip>>>;
openApprovals: z.ZodDefault<z.ZodArray<z.ZodObject<{
approvalId: z.ZodString;
title: z.ZodString;
}, z.core.$strip>>>;
}, z.core.$strip>;
/** @deprecated 改用 `InFlightWork` */
export type DisableCheck = InFlightWork;
/** @deprecated 权限只到端,动作三分已退役 */
export declare const GRANT_ACTIONS: readonly ["read", "write", "govern"];
/** @deprecated */
export declare const grantActionSchema: z.ZodEnum<{
read: "read";
write: "write";
govern: "govern";
}>;
/** @deprecated */
export type GrantAction = z.infer<typeof grantActionSchema>;
/** @deprecated */
export declare const GRANT_ACTION_LABEL: Readonly<Record<GrantAction, string>>;
/** @deprecated 治理台九功能不再是授权客体 */
export declare const GOVERNANCE_FUNCTIONS: readonly ["task", "staff", "process", "trigger", "activity", "tool", "data", "memory", "system"];
/** @deprecated */
export declare const governanceFunctionSchema: z.ZodEnum<{
trigger: "trigger";
data: "data";
task: "task";
system: "system";
tool: "tool";
activity: "activity";
staff: "staff";
process: "process";
memory: "memory";
}>;
/** @deprecated */
export type GovernanceFunction = z.infer<typeof governanceFunctionSchema>;
/** @deprecated */
export declare const GOVERNANCE_FUNCTION_LABEL: Readonly<Record<GovernanceFunction, string>>;
/** @deprecated */
export declare const grantObjectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
kind: z.ZodLiteral<"data">;
domain: z.ZodString;
object: z.ZodString;
field: z.ZodOptional<z.ZodString>;
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"governance">;
function: z.ZodEnum<{
trigger: "trigger";
data: "data";
task: "task";
system: "system";
tool: "tool";
activity: "activity";
staff: "staff";
process: "process";
memory: "memory";
}>;
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"task">;
activityId: z.ZodOptional<z.ZodString>;
}, z.core.$strip>], "kind">;
/** @deprecated */
export type GrantObject = z.infer<typeof grantObjectSchema>;
/** @deprecated */
export declare const grantSchema: z.ZodObject<{
positionId: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
object: z.ZodDiscriminatedUnion<[z.ZodObject<{
kind: z.ZodLiteral<"data">;
domain: z.ZodString;
object: z.ZodString;
field: z.ZodOptional<z.ZodString>;
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"governance">;
function: z.ZodEnum<{
trigger: "trigger";
data: "data";
task: "task";
system: "system";
tool: "tool";
activity: "activity";
staff: "staff";
process: "process";
memory: "memory";
}>;
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"task">;
activityId: z.ZodOptional<z.ZodString>;
}, z.core.$strip>], "kind">;
action: z.ZodEnum<{
read: "read";
write: "write";
govern: "govern";
}>;
}, z.core.$strip>;
/** @deprecated */
export type Grant = z.infer<typeof grantSchema>;
/** @deprecated 改用 `principalSchema` / `GET /api/me` */
export declare const sessionSchema: z.ZodObject<{
staff: z.ZodObject<{
id: z.core.$ZodBranded<z.ZodString, "StaffId", "out">;
account: z.ZodString;
name: z.ZodString;
email: z.ZodOptional<z.ZodString>;
positionId: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
state: z.ZodDefault<z.ZodEnum<{
active: "active";
disabled: "disabled";
}>>;
roles: z.ZodDefault<z.ZodArray<z.ZodString>>;
kind: z.ZodDefault<z.ZodEnum<{
person: "person";
service: "service";
}>>;
}, z.core.$strip>;
position: z.ZodObject<{
id: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
code: z.ZodString;
name: z.ZodString;
note: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
grants: z.ZodArray<z.ZodObject<{
positionId: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
object: z.ZodDiscriminatedUnion<[z.ZodObject<{
kind: z.ZodLiteral<"data">;
domain: z.ZodString;
object: z.ZodString;
field: z.ZodOptional<z.ZodString>;
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"governance">;
function: z.ZodEnum<{
trigger: "trigger";
data: "data";
task: "task";
system: "system";
tool: "tool";
activity: "activity";
staff: "staff";
process: "process";
memory: "memory";
}>;
}, z.core.$strip>, z.ZodObject<{
kind: z.ZodLiteral<"task">;
activityId: z.ZodOptional<z.ZodString>;
}, z.core.$strip>], "kind">;
action: z.ZodEnum<{
read: "read";
write: "write";
govern: "govern";
}>;
}, z.core.$strip>>;
}, z.core.$strip>;
/** @deprecated 改用 `Principal` */
export type Session = z.infer<typeof sessionSchema>;
/**
* 工作组 —— 一组「岗位 → 员工」的绑定,起单时装载、随工作流走。
*
* **不是第五种负责人策略**(OS 03「策略封闭四选」不动):
* 四策略回答的是「这个岗位该派给谁」,工作组直接给出了答案,策略于是无从发问。
* 键是**岗位 code**(BD / PM / FAE …),与流程包 `owner.position` 同一口径。
*/
export declare const workGroupSchema: z.ZodObject<{
id: z.ZodString;
name: z.ZodString;
ownerId: z.core.$ZodBranded<z.ZodString, "StaffId", "out">;
members: z.ZodRecord<z.ZodString, z.core.$ZodBranded<z.ZodString, "StaffId", "out">>;
}, z.core.$strip>;
export type WorkGroup = z.infer<typeof workGroupSchema>;
/** 装进工作流的**快照**:改组不改已起的单(留痕不被改写) */
export declare const workGroupBindingSchema: z.ZodRecord<z.ZodString, z.core.$ZodBranded<z.ZodString, "StaffId", "out">>;
export type WorkGroupBinding = z.infer<typeof workGroupBindingSchema>;