Archived
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
This commit is contained in:
@@ -19,6 +19,10 @@ export declare const listStaffRoute: {
|
||||
disabled: "disabled";
|
||||
}>>;
|
||||
roles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
kind: z.ZodDefault<z.ZodEnum<{
|
||||
person: "person";
|
||||
service: "service";
|
||||
}>>;
|
||||
position: z.ZodObject<{
|
||||
id: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
|
||||
code: z.ZodString;
|
||||
@@ -55,6 +59,10 @@ export declare const createStaffRoute: {
|
||||
disabled: "disabled";
|
||||
}>>;
|
||||
roles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
kind: z.ZodDefault<z.ZodEnum<{
|
||||
person: "person";
|
||||
service: "service";
|
||||
}>>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** @deprecated 随 ADR-012 退役,后端回 410;改用 staffInFlightRoute */
|
||||
@@ -266,6 +274,10 @@ export declare const setStaffPositionRoute: {
|
||||
disabled: "disabled";
|
||||
}>>;
|
||||
roles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
kind: z.ZodDefault<z.ZodEnum<{
|
||||
person: "person";
|
||||
service: "service";
|
||||
}>>;
|
||||
position: z.ZodObject<{
|
||||
id: z.core.$ZodBranded<z.ZodString, "PositionId", "out">;
|
||||
code: z.ZodString;
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ export type RouteContract<TParams extends z.ZodTypeAny = z.ZodTypeAny, TQuery ex
|
||||
export type RouteOutput<R extends RouteContract> = z.infer<R['output']>;
|
||||
export type RouteBody<R extends RouteContract> = R['body'] extends z.ZodTypeAny ? z.infer<R['body']> : never;
|
||||
/** 结构化错误:前端按 code 分辨,不解析文案。`gone` = 410,路由已随统一鉴权中心退役 */
|
||||
export declare const API_ERROR_CODES: readonly ["unauthenticated", "forbidden", "not-found", "validation-failed", "conflict", "precondition-failed", "internal", "gone"];
|
||||
export declare const API_ERROR_CODES: readonly ["unauthenticated", "forbidden", "not-found", "validation-failed", "conflict", "precondition-failed", "internal", "gone", "keycloak-misconfigured", "keycloak-unavailable"];
|
||||
export type ApiErrorCode = (typeof API_ERROR_CODES)[number];
|
||||
export type ApiError = {
|
||||
readonly code: ApiErrorCode;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from './http.ts';
|
||||
export * from './workbench.ts';
|
||||
export * from './governance.ts';
|
||||
export * from './org-directory.ts';
|
||||
export * from './ingest.ts';
|
||||
export * from './mail.ts';
|
||||
|
||||
@@ -0,0 +1,701 @@
|
||||
/**
|
||||
* 成员与组织(ADR-012 · 运营中心「员工」那一屏的三个页签)。
|
||||
*
|
||||
* **真源是 Keycloak**:读接口是它的投影,写接口**直接穿透**到 Admin API ——
|
||||
* 这里建的人立刻能登录、这里停的人立刻登不上、这里删的人从 Keycloak 消失。
|
||||
* 没有「先存本地草稿再同步」这回事,**也没有撤销**;界面上凡写必二次确认。
|
||||
*
|
||||
* 与本地名册的关系:`sys.staff` 是这份目录的投影 + 一列本地岗位(见 org/CONTRACT.md)。
|
||||
* 涉及身份的写(停用 / 删除 / 授收角色)之后,本地那一行当场跟手 —— 两屏不许说两句话。
|
||||
*
|
||||
* 三处口径与 Keycloak 的形状有关,写在这儿免得每条接口重复:
|
||||
* ① **服务账号一律不可见、不可写**:目录读剔除 `service-account-*`(它是身份不是人,
|
||||
* 见 `staffKindSchema`);写面对着服务账号的 sub 一律 403。
|
||||
* ② **组树是平表**:一行一个组,靠 `parentId` / `depth` 表达层级(按 `path` 升序已排好)。
|
||||
* 契约里不放递归结构 —— 递归 schema 到了声明文件那一层只会变成一坨 any。
|
||||
* ③ **列表无分页**:realm 不大,一次拉全;Keycloak 那一侧的 100 条上限由适配器分页兜住。
|
||||
*/
|
||||
import { z } from 'zod';
|
||||
export declare const orgUserSchema: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type OrgUser = z.infer<typeof orgUserSchema>;
|
||||
export declare const orgUserDetailSchema: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
firstName: z.ZodOptional<z.ZodString>;
|
||||
lastName: z.ZodOptional<z.ZodString>;
|
||||
emailVerified: z.ZodBoolean;
|
||||
groups: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
path: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export type OrgUserDetail = z.infer<typeof orgUserDetailSchema>;
|
||||
export declare const listOrgUsersRoute: {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/users";
|
||||
readonly access: "ops";
|
||||
readonly output: z.ZodObject<{
|
||||
users: z.ZodArray<z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
export declare const getOrgUserRoute: {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/users/:sub";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
firstName: z.ZodOptional<z.ZodString>;
|
||||
lastName: z.ZodOptional<z.ZodString>;
|
||||
emailVerified: z.ZodBoolean;
|
||||
groups: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
path: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/**
|
||||
* 新建成员 —— 建完立刻能登录。口令是**临时**的:本人首登必须改
|
||||
* (`temporary:true`,手册 §14.2);我们不存它,也不回显。
|
||||
*/
|
||||
export declare const createOrgUserRoute: {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users";
|
||||
readonly access: "ops";
|
||||
readonly body: z.ZodObject<{
|
||||
username: z.ZodString;
|
||||
firstName: z.ZodOptional<z.ZodString>;
|
||||
lastName: z.ZodOptional<z.ZodString>;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
password: z.ZodOptional<z.ZodString>;
|
||||
roles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** 改资料(姓名 / 邮箱)—— 用户名建后不可改,不在这里 */
|
||||
export declare const patchOrgUserRoute: {
|
||||
readonly method: "PATCH";
|
||||
readonly path: "/api/gov/org/users/:sub";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
firstName: z.ZodOptional<z.ZodString>;
|
||||
lastName: z.ZodOptional<z.ZodString>;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/**
|
||||
* 启用 / 停用。停用**立刻踢掉该用户全部会话** —— 不然他攥着的 token
|
||||
* 还能用到过期为止,而「已停用」这三个字在界面上已经写出去了(界面不撒谎)。
|
||||
*/
|
||||
export declare const setOrgUserEnabledRoute: {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/enabled";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
enabled: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** 重置口令 —— 一律临时口令,本人首登必须改;服务端不回显、不留痕 */
|
||||
export declare const resetOrgUserPasswordRoute: {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/reset-password";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
password: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** 删人 —— 从 Keycloak 消失,不可撤销;本地名册那一行同批停用(留痕与在途还挂着他) */
|
||||
export declare const deleteOrgUserRoute: {
|
||||
readonly method: "DELETE";
|
||||
readonly path: "/api/gov/org/users/:sub";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
export declare const orgRoleSchema: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
description: z.ZodOptional<z.ZodString>;
|
||||
composite: z.ZodBoolean;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
holders: z.ZodNumber;
|
||||
}, z.core.$strip>;
|
||||
export type OrgRole = z.infer<typeof orgRoleSchema>;
|
||||
export declare const listOrgRolesRoute: {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/roles";
|
||||
readonly access: "ops";
|
||||
readonly output: z.ZodObject<{
|
||||
roles: z.ZodArray<z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
description: z.ZodOptional<z.ZodString>;
|
||||
composite: z.ZodBoolean;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
holders: z.ZodNumber;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/**
|
||||
* 授 / 收一个 realm 角色。收权**立刻踢掉该用户全部会话**(手册 §17.3)——
|
||||
* 否则他手上那枚 token 还带着旧角色,收权要等到 token 过期才生效。
|
||||
* 不能收自己的最后一条进运营中心的路(409)—— 收完没人进得来,这扇门就锁死了。
|
||||
*/
|
||||
export declare const setOrgUserRoleRoute: {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/roles/:role";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
role: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
granted: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
export declare const orgGroupSchema: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
path: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
depth: z.ZodNumber;
|
||||
memberCount: z.ZodNumber;
|
||||
}, z.core.$strip>;
|
||||
export type OrgGroup = z.infer<typeof orgGroupSchema>;
|
||||
/** 组树平表,按 `path` 升序 —— 层级看 `parentId` / `depth` */
|
||||
export declare const listOrgGroupsRoute: {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/groups";
|
||||
readonly access: "ops";
|
||||
readonly output: z.ZodObject<{
|
||||
groups: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
path: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
depth: z.ZodNumber;
|
||||
memberCount: z.ZodNumber;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** 组的直属成员(含被停用的人 —— 这一屏管的是归属,不是能不能登录) */
|
||||
export declare const listOrgGroupMembersRoute: {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/groups/:id/members";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
members: z.ZodArray<z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** 建组:`parentId` 给了就是子组,不给就是顶层组。同级不得重名(Keycloak 那一侧拦,409) */
|
||||
export declare const createOrgGroupRoute: {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/groups";
|
||||
readonly access: "ops";
|
||||
readonly body: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
path: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
depth: z.ZodNumber;
|
||||
memberCount: z.ZodNumber;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
export declare const renameOrgGroupRoute: {
|
||||
readonly method: "PATCH";
|
||||
readonly path: "/api/gov/org/groups/:id";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
path: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
depth: z.ZodNumber;
|
||||
memberCount: z.ZodNumber;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** 删组 —— 连同子组一起没(Keycloak 语义);人不会被删,只是不再属于这个组 */
|
||||
export declare const deleteOrgGroupRoute: {
|
||||
readonly method: "DELETE";
|
||||
readonly path: "/api/gov/org/groups/:id";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/** 成员进 / 出组 */
|
||||
export declare const setOrgUserGroupRoute: {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/groups/:groupId";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
groupId: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
member: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
/**
|
||||
* 这一屏的全部路由 —— 归属一处列全,测试拿它逐条断言。
|
||||
* 逐个 import 去断言的写法,新增一条只要忘了加进名单就悄悄漏过去了。
|
||||
*/
|
||||
export declare const ORG_DIRECTORY_ROUTES: readonly [{
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/users";
|
||||
readonly access: "ops";
|
||||
readonly output: z.ZodObject<{
|
||||
users: z.ZodArray<z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/users/:sub";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
firstName: z.ZodOptional<z.ZodString>;
|
||||
lastName: z.ZodOptional<z.ZodString>;
|
||||
emailVerified: z.ZodBoolean;
|
||||
groups: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
path: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users";
|
||||
readonly access: "ops";
|
||||
readonly body: z.ZodObject<{
|
||||
username: z.ZodString;
|
||||
firstName: z.ZodOptional<z.ZodString>;
|
||||
lastName: z.ZodOptional<z.ZodString>;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
password: z.ZodOptional<z.ZodString>;
|
||||
roles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "PATCH";
|
||||
readonly path: "/api/gov/org/users/:sub";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
firstName: z.ZodOptional<z.ZodString>;
|
||||
lastName: z.ZodOptional<z.ZodString>;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/enabled";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
enabled: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/reset-password";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
password: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "DELETE";
|
||||
readonly path: "/api/gov/org/users/:sub";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/roles";
|
||||
readonly access: "ops";
|
||||
readonly output: z.ZodObject<{
|
||||
roles: z.ZodArray<z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
description: z.ZodOptional<z.ZodString>;
|
||||
composite: z.ZodBoolean;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
holders: z.ZodNumber;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/roles/:role";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
role: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
granted: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/groups";
|
||||
readonly access: "ops";
|
||||
readonly output: z.ZodObject<{
|
||||
groups: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
path: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
depth: z.ZodNumber;
|
||||
memberCount: z.ZodNumber;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "GET";
|
||||
readonly path: "/api/gov/org/groups/:id/members";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
members: z.ZodArray<z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
username: z.ZodString;
|
||||
displayName: z.ZodString;
|
||||
email: z.ZodOptional<z.ZodString>;
|
||||
enabled: z.ZodBoolean;
|
||||
roles: z.ZodArray<z.ZodString>;
|
||||
ends: z.ZodArray<z.ZodEnum<{
|
||||
design: "design";
|
||||
ops: "ops";
|
||||
workbench: "workbench";
|
||||
}>>;
|
||||
lastSeenAt: z.ZodOptional<z.ZodString>;
|
||||
positionCode: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/groups";
|
||||
readonly access: "ops";
|
||||
readonly body: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
path: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
depth: z.ZodNumber;
|
||||
memberCount: z.ZodNumber;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "PATCH";
|
||||
readonly path: "/api/gov/org/groups/:id";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
path: z.ZodString;
|
||||
parentId: z.ZodOptional<z.ZodString>;
|
||||
depth: z.ZodNumber;
|
||||
memberCount: z.ZodNumber;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "DELETE";
|
||||
readonly path: "/api/gov/org/groups/:id";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
}, {
|
||||
readonly method: "POST";
|
||||
readonly path: "/api/gov/org/users/:sub/groups/:groupId";
|
||||
readonly access: "ops";
|
||||
readonly params: z.ZodObject<{
|
||||
sub: z.ZodString;
|
||||
groupId: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly body: z.ZodObject<{
|
||||
member: z.ZodBoolean;
|
||||
}, z.core.$strip>;
|
||||
readonly output: z.ZodObject<{
|
||||
ok: z.ZodLiteral<true>;
|
||||
}, z.core.$strip>;
|
||||
}];
|
||||
@@ -20,6 +20,10 @@ export declare const sessionRoute: {
|
||||
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">;
|
||||
@@ -80,6 +84,10 @@ export declare const loginRoute: {
|
||||
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">;
|
||||
@@ -158,6 +166,10 @@ export declare const meRoute: {
|
||||
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">;
|
||||
@@ -891,6 +903,7 @@ export declare const taskDetailSchema: z.ZodObject<{
|
||||
cols: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>]>>;
|
||||
}, z.core.$strip>>;
|
||||
submitLabel: z.ZodOptional<z.ZodString>;
|
||||
gateLedgers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
||||
gate: z.ZodOptional<z.ZodObject<{
|
||||
ready: z.ZodBoolean;
|
||||
why: z.ZodString;
|
||||
@@ -1475,6 +1488,7 @@ export declare const taskDetailSchema: z.ZodObject<{
|
||||
cols: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>]>>;
|
||||
}, z.core.$strip>>;
|
||||
submitLabel: z.ZodOptional<z.ZodString>;
|
||||
gateLedgers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
||||
gate: z.ZodOptional<z.ZodObject<{
|
||||
ready: z.ZodBoolean;
|
||||
why: z.ZodString;
|
||||
@@ -2796,6 +2810,7 @@ export declare const taskDetailRoute: {
|
||||
cols: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>]>>;
|
||||
}, z.core.$strip>>;
|
||||
submitLabel: z.ZodOptional<z.ZodString>;
|
||||
gateLedgers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
||||
gate: z.ZodOptional<z.ZodObject<{
|
||||
ready: z.ZodBoolean;
|
||||
why: z.ZodString;
|
||||
@@ -3380,6 +3395,7 @@ export declare const taskDetailRoute: {
|
||||
cols: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>]>>;
|
||||
}, z.core.$strip>>;
|
||||
submitLabel: z.ZodOptional<z.ZodString>;
|
||||
gateLedgers: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
||||
gate: z.ZodOptional<z.ZodObject<{
|
||||
ready: z.ZodBoolean;
|
||||
why: z.ZodString;
|
||||
|
||||
+28
@@ -19,6 +19,22 @@ export declare const staffStateSchema: z.ZodEnum<{
|
||||
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;
|
||||
@@ -30,6 +46,10 @@ export declare const staffSchema: z.ZodObject<{
|
||||
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<{
|
||||
@@ -44,6 +64,10 @@ export declare const principalSchema: z.ZodObject<{
|
||||
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">;
|
||||
@@ -226,6 +250,10 @@ export declare const sessionSchema: z.ZodObject<{
|
||||
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">;
|
||||
|
||||
Reference in New Issue
Block a user