# module: org 职责: 员工与岗位:账号、口令与登录会话(ADR-010)、岗位授权(客体三类 × 动作三种)、 停用前置检查、岗位在岗人员查询(负责人四策略解析的候选集来源)、 工作组(ADR-011:起单时的岗位绑定)、种子数据播种 不负责: 负责人解析算法本身(见 process)、任务与卡的在途判定(经 InFlightWorkProbe 端口由 app 注入)、 鉴权中间件与 cookie 的读写(app 层:§4「中间件在 app 层,身份判定读 org 出口」) 公开出口: index.ts - 类型:`OrgService` `StaffWithPosition` `CreateStaffInput` `IssuedSession` 与 @contracts 的 `Staff` / `Position` / `Grant` / `GrantObject` / `GrantAction` / `DisableCheck` / `Session` 转出 - 错误:`StaffNotFoundError` `PositionNotFoundError` `AccountTakenError` `DisableBlockedError` - 端口类型:`PositionRepository` `StaffRepository` `GrantRepository` `SessionRepository` `WorkGroupRepository` `PasswordHasher` `InFlightWorkProbe` `Clock` `IdGenerator` - 用例工厂:`createOrgService(deps: OrgServiceDeps): OrgService` - 纯函数:`isAuthorized` `actionCovers` `objectCovers` - 常量:`POSITION_SEED` `STAFF_SEED` `DEFAULT_LOGIN_ACCOUNT` - adapter 工厂(供 app 装配):`createPositionRepository` `createStaffRepository` `createGrantRepository` `createSessionRepository` `createWorkGroupRepository` `objectKeyOf` - 口令散列(供 app 装 `PasswordHasher`):`hashPassword` `verifyPassword` `newSessionToken` - Drizzle 表(供 app 迁移与 join):`positionTable` `staffTable` `grantTable` `sessionTable` `workGroupTable` 层级: L1(编码规范 §4) 依赖: @contracts;@shared/db(Drizzle 句柄与 sys schema) port:`InFlightWorkProbe`(app 注入 task / human-tool 的只读用例)、`IdGenerator` 被依赖: process(负责人解析的候选集)、message、interaction、human-tool、report、 app(鉴权中间件与 /api/gov/staff 路由组装) 不变量: - 动作蕴含:治理 ⊃ 写 ⊃ 读;数据客体三级覆盖(域 ⊃ 对象 ⊃ 字段) - 停用是全有全无:前置检查未过即抛 `DisableBlockedError`,不做部分执行 - `authorize` 对停用员工恒 false - `ensureSeeded` 幂等:按 code / account 判存在,已存在则跳过,不覆盖人工改动; 唯一例外是**补种口令** —— 已存在但 `password_hash` 为空的员工会被补上初始口令, 否则 ADR-010 之前建的账号永远登不进(这不算覆盖人工改动:空不是改动) - **登录失败不区分原因**:账号不存在 / 已停用 / 未设口令 / 口令错,一律 `undefined`; 且无论账号是否存在都走一遍散列比对,免得响应时间泄漏账号是否存在 - **明文永不落库**:口令只在 `login` / `setPassword` 的入参上停留一瞬,落库前即散列 - **会话可即刻作废**:服务端表而非签名 cookie —— `logout` 立刻生效; `disableStaff` 连带 `revokeAllOf`,被停用的人拿旧 cookie 也办不了事 - **工作组是绑定不是策略**(ADR-011):它给出岗位的人选,四策略于是无从发问; `bindingOf` 只出成员表快照,在岗与否由调用方(process)核 —— 岗位候选集核不了跨岗位的绑定 影响半径: contract 增 `login` / `logout` / `resolveSession` / `setPassword` 与 `IssuedSession`; port 增 `SessionRepository` / `PasswordHasher`,`StaffRepository` 增两个口令读写方法; 下游只有 app(装配 + 鉴权中间件),depcruise 已反查确认 近变(2026-07-27):模块面**未变**。app 层新增工作组读写路由 (`GET|PUT /api/gov/work-groups`),组装既有的 `workGroupOf` / `saveWorkGroup` —— ADR-011 落地时欠的那个治理界面就此清账,一人一组的口径由 app 层按 ownerId 保证。