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:
+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