3.6 KiB
module: org
职责: 员工与岗位(ADR-012):验签后的人是谁(名册即时更新)、他能进哪几个端(角色→端)、 岗位指派与在岗人员查询(负责人四策略解析的候选集来源)、名册同步(Admin API)、 在途工作(只读)、工作组(ADR-011)、种子(岗位 + 缺省角色→端) 不负责: 验签之外的 HTTP 语义(401/403 由 app 层中间件按路由归属判)、 负责人解析算法本身(见 process)、任务与卡的在途判定(经 InFlightWorkProbe 由 app 注入)
公开出口: index.ts
- 类型:
OrgServiceStaffWithPositionIdentity与 @contracts 的Staff/Position/Principal/RoleAccess/RosterSyncOutcome/InFlightWork/Surface/WorkGroup/WorkGroupBinding转出 - 错误:
TokenRejectedError(→401)AccountDisabledError(→403)AccessLockoutError(→409)StaffNotFoundErrorPositionNotFoundError - 端口类型:
TokenVerifierVerifiedClaimsRosterSourceRosterUserIdentityPatchPositionRepositoryStaffRepositoryStaffRecordRoleAccessRepositoryWorkGroupRepositoryInFlightWorkProbeClockIdGenerator - 用例工厂:
createOrgService(deps: OrgServiceDeps): OrgService - 纯函数:
identityOfisNoiseRolenormalizeRolesendsOfassertNotLockedOutnormalizeEndsbuildInFlightWork - 常量:
POSITION_SEEDNONE_POSITION_CODETEST_POSITION_CODEDEFAULT_ROLE_ACCESS - adapter 工厂(供 app 装配):
createKeycloakTokenVerifier(jose,配置型KeycloakVerifierOptions)createKeycloakRoster(Admin API,配置型KeycloakRosterOptions)createPositionRepositorycreateStaffRepositorycreateRoleAccessRepositorycreateWorkGroupRepository - 错误译文(供 app 拼 401 message):
explainJoseError(jose 错误 → 人话,手册 4.4) - Drizzle 表:
positionTablestaffTableroleAccessTableworkGroupTable
层级: L1(编码规范 §4)
依赖: @contracts;@shared/db(Drizzle 句柄与 sys schema);jose(仅 adapter)
port:InFlightWorkProbe(app 注入 task / human-tool 的只读用例)、IdGenerator、
TokenVerifier(app 给 jose 远程 JWKS;测试给本地密钥对)、RosterSource(可缺省)
被依赖: process(负责人解析的候选集)、message(治理台收件人 = staffWithEnd('ops'))、
app(鉴权中间件与 /api/gov/staff、/api/gov/access 路由组装)
不变量:
Staff.id就是 Keycloaksub;account只作显示,永不当键state只由名册同步置disabled;authenticate/principalOf对 disabled 一律抛 AccountDisabledError, 有效 token 不能把它翻回 active(撤权在同步之后即时生效)- 名册即时更新只写变了的列;
last_seen_at60 秒内不重写 - 角色→端:
setRoleAccess/deleteRoleAccess先算新表再验锁死不变量(名册为空不算锁死) staffOfPosition只回 active;哨兵岗 NONE 恒回 []ensureSeeded幂等:岗位按 code 判存在;缺省角色→端只在表空时播;测试账号策略只补不覆盖- 工作组是绑定不是策略(ADR-011):
bindingOf只出成员表快照,在岗与否由调用方核
影响半径(2026-08-25,ADR-012):contract / port / index 全面重写 —— 退役 login logout resolveSession
setPassword authorize loadSession listGrants setGrants createStaff checkDisable
disableStaff findByAccount 与 SessionRepository PasswordHasher GrantRepository;
下游 app(中间件 / 装配 / 路由)与 message 装配同批改,depcruise 已反查确认。