/** * module: org —— 对外类型(编码规范 §10.1)。只有类型和常量,没有实现。 */ import type { DisableCheck, Grant, GrantAction, GrantObject, Position, Session, Staff, StaffId, WorkGroup, WorkGroupBinding } from '@contracts'; export type { DisableCheck, Grant, GrantAction, GrantObject, Position, Session, Staff, WorkGroup, WorkGroupBinding }; /** 员工连同其岗位的读模型 —— 治理台员工管理列表用 */ export type StaffWithPosition = Staff & { readonly position: Position; }; export type CreateStaffInput = { readonly account: string; readonly name: string; readonly positionId: string; }; export declare class StaffNotFoundError extends Error { readonly staffId: StaffId; constructor(staffId: StaffId); } export declare class PositionNotFoundError extends Error { readonly positionCode: string; constructor(positionCode: string); } export declare class AccountTakenError extends Error { readonly account: string; constructor(account: string); } /** 停用前置检查未过:在途任务与待答卡须先改派完毕(OS 02) */ export declare class DisableBlockedError extends Error { readonly check: DisableCheck; constructor(check: DisableCheck); } /** 登录结果 —— token 交给 app 层种 cookie;失败一律 undefined,不区分原因 */ export type IssuedSession = { readonly token: string; readonly expiresAt: string; }; export type OrgService = { listStaff(): Promise<{ staff: StaffWithPosition[]; positions: Position[]; }>; getStaff(staffId: StaffId): Promise; findByAccount(account: string): Promise; createStaff(input: CreateStaffInput): Promise; /** 停用前置检查 —— 只读,治理台先看再点 */ checkDisable(staffId: StaffId): Promise; /** 停用 —— 前置检查不过即抛 DisableBlockedError,不做部分执行 */ disableStaff(staffId: StaffId): Promise; listGrants(positionId: string): Promise; setGrants(positionId: string, grants: readonly Grant[]): Promise; /** 岗位权限校验 —— app 层鉴权中间件读它 */ authorize(staffId: StaffId, object: GrantObject, action: GrantAction): Promise; loadSession(account: string): Promise; /** 口令核验通过即签发会话;账号不存在 / 已停用 / 未设口令 / 口令错,一律 undefined */ login(account: string, password: string): Promise; /** 登出:该 token 立刻作废(服务端表,不是签名 cookie) */ logout(token: string): Promise; /** 解析会话 —— 命中即滑动续期;过期或已作废返回 undefined */ resolveSession(token: string): Promise; /** 设定口令 —— 明文只在此处停留一瞬,落库前即散列 */ setPassword(staffId: StaffId, password: string): Promise; /** 建组 / 改组;id 留空即新建 */ saveWorkGroup(input: { id?: string; name: string; ownerId: StaffId; members: Readonly>; }): Promise; /** 某人的工作组 —— 起单时按来源人取,取不到即不装载(全走四策略) */ workGroupOf(staffId: StaffId): Promise; /** 装进工作流的快照:改组不改已起的单 */ bindingOf(staffId: StaffId): Promise; /** 岗位在岗人员 —— 负责人四策略解析的候选集来源(由 process 调用) */ staffOfPosition(positionCode: string): Promise; ensureSeeded(): Promise; }; /** 从 token 或 Admin API 归一出来的一个人 —— `sub` 即 Staff.id */ export type Identity = { readonly sub: string; /** preferred_username */ readonly account: string; /** name claim,缺则回退 account */ readonly name: string; readonly email?: string; /** realm 角色,噪声角色已滤、已排序 */ readonly roles: readonly string[]; }; /** 验签没过 —— message 是手册 4.4 的人话,中间件原样回 401 */ export declare class TokenRejectedError extends Error { constructor(message: string); } /** 名册同步标了停用 —— 即使 token 还有效也拒(403);Keycloak 恢复后再同步一次 */ export declare class AccountDisabledError extends Error { readonly account: string; constructor(account: string); } /** 角色→端改完之后没有任何在册员工能进运营中心 —— 那张表就再也没人改得了 */ export declare class AccessLockoutError extends Error { constructor(); }