hr-system/docs/01-design/architecture.md

295 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 一期批次1总体设计 —— 系统架构与技术选型(hr-web)
- 版本:v2.0(批次1设计定稿;v2.0 变更:对齐 SRS v3.1 —— 批次1范围扩入编制管理(F16)/项目式组织(F17)、数据库口径修正 MariaDB/库hrs、部署端口统一 9182、新增降级项设计专章 §10、新增 API 开放接口规范 §9、F01~F15↔FEAT-B1 编号映射)
- 状态:**设计定稿(批次1评审修订版,随本批次冻结;契约变更须走设计评审)**
- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v3.1,2026-08-18)+ `docs/00-requirement/iteration1-function-detail.md`(F01~F15,81 条)+ `docs/00-requirement/approved-features.md`(FEAT-B1-01~12)
- 应用定义:`apps/hr-web.md`;模块定义:`modules/hr-org.md`、`hr-roster.md`、`hr-flow.md`、`hr-contract.md`、`hr-report.md`、`hr-system.md`
- 开发规范:ocai 技能集 —— web-application-spec、module-development-spec、database-table-definition-spec、crud-definition-spec、dspy-file-implementation-spec
## 0. 与需求基线的对齐说明
| # | 对齐项 | 结论 |
|---|---|---|
| 1 | 批次1范围 | SRS v3.1 §1.4 批次1 = 12 feature(FEAT-B1-01~12)。其中 FEAT-B1-10 编制管理、FEAT-B1-11 项目式组织在原 F01~F15(81 条验收项)基线之外,本设计新增 **F16 编制管理(6 条验收项)、F17 项目式组织(3 条验收项)**,批次1合计 **90 条可验收项** |
| 2 | 功能编号映射 | F01 组织↔FEAT-B1-02;F02 职位职级↔FEAT-B1-03;F03 花名册+F08 兼岗↔FEAT-B1-04;F04 入职↔FEAT-B1-05;F05 转正+F06 调动↔FEAT-B1-06;F07 离职↔FEAT-B1-07;F09 合同↔FEAT-B1-08;F14 工作台+F15 员工服务↔FEAT-B1-09;F10 流程审批+F11 权限+F12 日志↔FEAT-B1-01;F13 报表↔FEAT-B1-12;F16↔FEAT-B1-10;F17↔FEAT-B1-11 |
| 3 | 技术口径 | ocai 规范:前端 bricks + dspy;后端 ahserver(Python);数据层 apppublic/sqlor(MariaDB);应用 hr-web。与 SRS v3.1 头注一致 |
| 4 | 部署口径 | 测试/生产应用统一端口 **9182**、库名 **hrs**(SRS §8);v1.1 文档中 dev:9080/prod:443/库hr 口径作废 |
| 5 | 降级项 | 批次1涉及 D1 身份证读卡→手工录入、D3 钉钉交接→占位字段、D4 电子签→模板生成+桩、D9 短信→站内兜底、扫码入职→内网登记链接/二维码;专章见 §10,二期预留接口清单见 §10.4 |
## 1. 概述
批次1交付「Web 版人事系统(hr-web)」**组织人事底座 + 系统管理与权限基座**,功能范围 F01~F17:组织架构、职位职级体系、花名册、入职/转正/调动/离职/兼岗、合同台账(不含电子签)、流程审批、权限/日志、报表、工作台、员工服务与提醒、**编制管理、项目式组织**。规模规格 100 人账号。
设计原则:
1. **全栈遵循 ocai 规范**:前端 bricks 组件体系(.ui 纯 JSON 声明式页面 + dspy 驱动的 CRUD),后端 ahserver(Python/aiohttp),数据层 apppublic/sqlor(MariaDB),基础模块 appbase(字典/用户)+ rbac(角色权限)。
2. **配置驱动**:表结构(models/*.json)、CRUD 界面(json/*.json)、字典(appcodes)全部声明式定义,支撑 SRS 的"字段/流程/表单自定义"诉求(FEAT-B1-01 验收①不写代码配置 4 类审批流)。
3. **模块宿主无关**:每个模块仅依赖基础包与自己的数据表,通过 `load_{module}()` 注册 ServerEnv,可被任意宿主应用加载(module-development-spec)。
4. **单一事实来源**:花名册(roster_employee)是全系统员工数据唯一事实来源,入转调离审批通过后统一经 `roster_writeback` 回写(SRS §5.2-1)。
5. **降级留桩**:一期降级项(SRS §9)一律"字段/桩端点/流程位"预留,二期对接不改表结构主干。
## 2. 总体架构
```
┌────────────────────────────────────────────────────────────────────┐
│ 浏览器(PC Web 为主) │
│ bricks.js 渲染引擎:.ui(JSON) 页面 + DataViewer/Tree/Form/Chart │
└──────────────────────────────┬─────────────────────────────────────┘
│ HTTP session cookie(Redis 会话)
┌──────────────────────────────▼─────────────────────────────────────┐
│ ahserver 应用进程(hr-web,直接监听 9182,systemd 守护) │
│ (二期补齐域名/证书后可选引入 nginx:9182 HTTPS 反代,见 §7.3) │
│ 路由:wwwroot 自动路由 /{module}/{file}.ui|.dspy|.css|.js │
│ processors: .tmpl→tmpl, .ui→bui, .dspy→dspy │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 业务模块(load_xxx 注册 ServerEnv) │ │
│ │ hr-org | hr-roster | hr-flow | hr-contract | hr-report | │ │
│ │ hr-system │ │
│ ├─────────────────────────────────────────────────────────────┤ │
│ │ 基础模块:appbase(users/orgs/appcodes 字典)+ rbac(角色权限)│ │
│ │ bricks_for_python(UiWindow 等 pybricks) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ 后台任务:remind_scan(提醒扫描)/ headcount 联动校验 / 导入导出任务 │
└──────────┬───────────────────────────────┬─────────────────────────┘
│ sqlor 连接池(sor.C/U/D/R/I/sqlExe) │ Redis session
┌──────────▼──────────┐ ┌────────▼────────┐
│ MariaDB(库 hrs) │ │ Redis(会话) │
│ json2ddl 生成 DDL │ └─────────────────┘
└─────────────────────┘ files/ 目录:附件存储(合同文件、离职证明、导入导出文件、登记表二维码)
```
请求处理链路(以花名册列表为例):
1. 浏览器访问 `/hrroster/roster_list.ui`(由 json/roster_employee_list.json 经 xls2ui 生成的 DataViewer 页);
2. DataViewer 按 CRUD JSON 中的 `dataurl`/`new_data_url` 等调用 `/hrroster/api/xxx.dspy`;
3. ahserver 将 GET query + POST body 统一解析为 `params_kw` 注入 dspy 上下文;
4. dspy 调用 `load_hrroster()` 注册的业务函数(内部经 sqlor `sor.R` 查询,叠加 rbac 数据范围过滤与敏感字段脱敏);
5. dspy 显式 `return` JSON(列表必须 `{status:'success', data:{rows:[...], total:N}}`),bricks 渲染。
## 3. 技术选型与理由
| 层 | 选型 | 选型理由 |
|---|---|---|
| 前端 | bricks 组件体系 + .ui 纯 JSON 页面 | ocai 强制规范;CRUD JSON 自动生成列表/表单/树页面,批次1中 80% 的增删改查页面零 Vue 代码;DataViewer 自带筛选(data_filter)、子表(subtables)、工具栏 bind |
| 声明式页面脚本 | .dspy(受控 Python) | 后端 API 与页面逻辑统一语言栈(Python);ahserver 自动解析参数、自动 JSON 序列化;禁止 import/print,天然受控 |
| 后端框架 | ahserver(aiohttp 异步) | ocai 强制规范;内置会话/RBAC/文件上传/后台任务;wwwroot 自动路由免手写路由注册;100 人规模单实例足够 |
| 数据访问 | apppublic/sqlor | 异步连接池 + 绑定参数防注入;`sor.C/U/D/R/I/sqlExe` 六元 API 覆盖全部数据操作;与 models JSON 配套 |
| 表定义 | models/*.json + json2ddl | database-table-definition-spec 标准;数据库无关的抽象类型,DDL 自动生成,保证 collate utf8mb4_unicode_ci 一致 |
| CRUD 生成 | json/*.json + xls2ui | crud-definition-spec 标准;自动产出列表页 .ui 与 add/update/delete dspy 包装 |
| 字典 | appbase appcodes/appcodes_kv | 性别/员工类型/异动类型/离职原因/提醒场景/编制周期等枚举统一管理,CRUD 下拉直接引用(codes 段) |
| 权限 | rbac 模块 + 自研数据范围表 | rbac 管"功能权限(路径级)",hr-system 扩展"数据范围(组织维度/花名册字段维度)",满足 SRS §2.2 |
| 数据库 | **MariaDB(库 hrs)** | 任务明确口径(SRS §8);sqlor DDL 模板成熟;每日全量备份保留 ≥30 天 |
| 会话 | Redis + aiohttp_session | web-application-spec 推荐;服务重启不丢登录 |
| 附件 | ahserver files/ 文件存储 | 合同附件、离职证明、导入导出文件、入职登记表二维码图片;100 人规模本地目录足够,随应用数据一并备份(NFR-5) |
v1(Java/Spring Boot/JPA/JWT)口径已全部废弃归档(`docs/_archive/`),不保留双栈:鉴权由"自研 JWT Filter"改为"ahserver session + rbac",ORM 由 JPA 改为 sqlor,前端由"无"改为 bricks/dspy。
## 4. 模块划分与职责边界
### 4.1 批次1模块清单(6 个,均挂载于 hr-web 应用)
| 模块 | 路由前缀 | 职责 | 数据表前缀 | 批次1功能 |
|---|---|---|---|---|
| hr-org | /hrorg | 组织架构、职位职级体系、入转调离兼岗异动业务、黑名单、合同公司、**编制管理、项目式组织** | org_ | F01/F02/F04~F08/**F16/F17** |
| hr-roster | /hrroster | 花名册(字段定义/字段值 EAV/员工主档/时间轴/工号规则)、导入导出 | roster_ | F03 |
| hr-flow | /hrflow | 表单定义、流程定义、流程实例、审批任务(待办/已办/我发起/我收到) | flow_ | F10(FEAT-B1-01 流程引擎部分) |
| hr-contract | /hrcontract | 合同台账、合同类型/模板、到期提醒规则、合同审批、esign 桩 | contract_ | F09 |
| hr-report | /hrreport | 只读聚合报表(花名册/入职/转正/调岗/离职五类分析),无自有表 | — | F13 |
| hr-system | /hrsystem | 角色/管理员/数据范围、操作日志、工作台聚合、提醒规则、公告政策、站内消息 | sys_ | F11/F12/F14/F15(FEAT-B1-01 权限日志部分 + FEAT-B1-09) |
### 4.2 职责边界规则
1. **员工主数据唯一入口**:所有模块读写员工信息必须经 hr-roster 的注册函数(ServerEnv 暴露),禁止跨模块直接 SQL 写 roster_ 表。入转调离审批通过后由 hr-flow 回调 hr-org 的业务函数,再调用 hr-roster `roster_writeback` 更新员工主档与时间轴。
2. **审批引擎与业务解耦**:hr-flow 只管"表单+流程+实例+任务"的流转,不含业务语义;业务回写通过 `biz_type + biz_id` 关联 + 流程完成回调(ServerEnv 注册的 hook 函数)实现。考勤流程(桩位,FEAT-B1-01)仅允许建表单定义,biz_type=attendance_* 无回写 hook。
3. **权限横切**:功能权限(路径级 RBAC)由 rbac 模块统一拦截(各模块 scripts/load_path.py 注册路径与角色);数据范围由 hr-system 提供 `get_data_scope(user_id)` 公共函数,hr-org/hr-roster/hr-report 在查询、报表、**导出**时强制叠加(SRS §2.2-2)。
4. **操作日志横切**:所有写操作(sor.C/U/D)统一经 hr-system 的 `write_audit_log(...)` 记录前后值(before/after JSON),F12 查询页只读 sys_audit_log。
5. **编制联动**:入转调离回写成功后,hr-org 同步调用 `headcount_check(employee, event)` 重算所属编制方案占编并写快照/超编提醒(服务内同步执行,100 人规模满足"1 分钟内刷新"验收)。
6. **字典统一**:任何枚举值不得硬编码在 dspy 中,一律走 appcodes(init/data.json 初始化),CRUD 下拉用 models codes 段引用。
### 4.3 hr-system 与 staff-mgr 的职责边界
| 对象 | 性质 | 职责 | 状态 |
|---|---|---|---|
| **hr-system**(模块,repos/hr-system) | ocai 规范模块 | 系统支撑层:F11 权限管理、F12 操作日志、F14 工作台、F15 员工服务与提醒;并承载全应用横切能力(数据范围、审计、站内消息、提醒扫描) | 批次1新建(复用现有空仓 hr-system.git) |
| **staff-mgr**(遗留 Java 模块) | v1 遗留 | 旧员工 CRUD REST 服务(/api/v1/staff/*,Spring Boot + JPA + JWT) | **已归档,冻结不再开发**;仅作数据迁移来源与参考实现(见 §6) |
边界结论:
- 一期上线后 staff-mgr 不再承担任何线上职责;其员工数据一次性迁移至 hr-roster,部门缓存迁移至 hr-org,日志迁移至 hr-system(详见 database-design.md §8、任务 T23)。
- 旧模块的"员工 CRUD"职责由 **hr-roster** 承接(不是 hr-system);hr-system 只承接"操作日志/权限"类横切职责。
- v1 应用定义 `apps/hr-system.md`(Java 后端服务)已废弃,与模块 hr-system 仅重名,无继承关系。
- 迁移范围(仅在职/含历史)与切换时间点待 PM 确认(SRS §11-Q3),脚本按"可配置范围"实现,默认在职+离职保留档案。
## 5. 模块结构与依赖关系
### 5.1 标准模块目录(module-development-spec)
每个业务模块仓库结构一致:
```
{module}/
├── {module}/ # Python 包
│ ├── __init__.py # 导出全部公共函数(三处注册同步点之一)
│ ├── init.py # load_{module}():ServerEnv 注册
│ └── *.py # 业务实现(service 层)
├── wwwroot/ # index.ui、menu、业务页 .ui、api/*.dspy、css/js
├── models/ # 表定义 JSON(json2ddl → mysql.ddl.sql)
├── json/ # CRUD 定义 JSON(xls2ui → 列表页 + add/update/delete dspy)
├── init/data.json # 字典与初始化数据(appcodes Format B)
├── scripts/load_path.py # RBAC 路径注册(角色:logined/admin/hr/manager/employee)
├── skill/SKILL.md # 模块 AI 说明(数据模型/端点/坑位)
├── pyproject.toml
└── README.md
```
### 5.2 依赖关系图
```
┌─────────── rbac(功能权限) ◄──── appbase(users/orgs/appcodes)
│ ▲ ▲
│ │ 路径注册/数据范围 │ 字典/用户
┌─────────┴──┐ ┌──────┴─────┐ ┌──────┴─────┐
│ hr-system │◄─────│ hr-flow │◄──────────│ hr-contract │
│F11/12/14/15│ 审批回调/权限 │ 合同审批 │
└─────▲──────┘ └──────▲─────┘ └──────┬─────┘
│ 审计/数据范围 │ 入转调离/兼岗审批 │ 员工/公司引用
│ │ │
┌─────┴──────┐ ┌──────┴─────┐ │
│ hr-report │─────►│ hr-org │◄─────────────────┘
│ (只读聚合) │ 异动数据 │组织/职位/异动/编制/项目│
└─────▲──────┘ └──────┬─────┘
│ 花名册分析 │ 员工主数据读写(唯一入口)
│ ┌──────▼─────┐
└─────────────│ hr-roster │
│ 员工唯一事实源│
└────────────┘
依赖方向:箭头指向被依赖方。hr-report 只读,不被任何模块依赖。
```
依赖矩阵(行依赖列):
| ↓依赖→ | hr-org | hr-roster | hr-flow | hr-contract | hr-report | hr-system |
|---|---|---|---|---|---|---|
| hr-org | — | 回写花名册/黑名单 | 异动审批流转 | — | — | 权限/日志/提醒通道 |
| hr-roster | 组织/职位主数据 | — | 自助修改审核 | — | — | 字段级权限/脱敏/日志 |
| hr-flow | — | 表单引用字段/完成回调 | — | — | — | 审批角色权限/日志 |
| hr-contract | 合同公司主数据 | 员工关联 | 合同审批 | — | — | 提醒通道/日志 |
| hr-report | 异动/编制数据 | 花名册数据 | — | — | — | 数据范围 |
| hr-system | 工作台引用组织/异动/编制 | 工作台引用档案 | 工作台引用待办 | 工作台引用合同 | — | — |
### 5.3 应用装配
- 应用入口 `app/hr_web.py`:`init()` 中依次 `ServerEnv()` → 设置 `get_module_dbname`(返回 `hrs`)→ `load_appbase()` → `load_rbac()` → `load_pybricks()` → `load_hrsystem/load_hrorg/load_hrroster/load_hrflow/load_hrcontract/load_hrreport()`。
- `conf/config.json`:processors 必含 `[".tmpl","tmpl"], [".ui","bui"], [".dspy","dspy"]`;indexes 含 `index.ui`;databases 配置 **hrs** 库(测试环境 test/test123);Redis session(session_max_time/session_issue_time)。
- build.sh 顺序:建 venv → pip install apppublic/sqlor/ahserver/bricks/appbase/rbac → clone 6 个业务模块 pip install → 各模块 models/ 执行 `json2ddl mysql . > mysql.ddl.sql` 并导入 hrs 库 → init/data.json 导入(含四类流程模板、基础字段集、内置 admin 与角色,SRS §5.2-4)→ json/ 执行 `xls2ui` 生成 CRUD → symlink 各模块 wwwroot 与 bricks dist → systemd 服务。
## 6. 与现有 staff-mgr 员工管理模块的衔接方案
### 6.1 衔接定位
staff-mgr 是 v1 Java 口径下的员工 CRUD 模块(已通过端到端验证),与 ocai 规范冲突,不改造、不并行演进,采取**一次性数据迁移 + 接口替代 + 退役**策略。
### 6.2 职责与接口替代映射
| staff-mgr 旧接口(/api/v1/staff) | 批次1替代(hr-roster/hr-org/hr-system dspy) | 说明 |
|---|---|---|
| POST /(创建员工) | /hrroster/api/roster_employee_create.dspy(或手动入职 /hrorg/api/entry_manual.dspy) | 新建一律走入职流程或花名册新增 |
| GET /(分页列表) | /hrroster/roster_list(CRUD 列表 + data_filter) | 筛选能力增强(自定义字段) |
| GET /{id}(详情) | /hrroster/api/employee_detail.dspy | 档案 Tabs + 时间轴 |
| PUT /{id}(更新) | /hrroster/api/roster_employee_update.dspy | 可配置自助修改 + 审核 |
| DELETE /{id}、POST /batch-delete | 离职流程 /hrorg/api/leave_manual.dspy | 一期不做物理/逻辑删除员工,统一走离职 |
| GET /{id}/change-logs | /hrroster/api/timeline.dspy | 时间轴(含迁移进来的旧变更记录) |
| GET /audit-logs | /hrsystem/api/audit_log_list.dspy | 历史日志迁入 sys_audit_log |
| GET /check/employee-no | /hrroster/api/check_employee_no.dspy | 工号查重保留 |
| GET /departments | /hrorg/api/org_tree.dspy | 部门缓存表废弃,直接查 org_unit |
脱敏规则延续并按 SRS §2.2-4 加强:身份证号全角色脱敏(前3后3)、手机号(前3后4)、薪资职级类字段仅 admin/hr 可见——由 roster_field_def.sensitive 驱动,替代 staff-mgr 硬编码 MaskUtil。
### 6.3 数据迁移方案(详见 database-design.md §8)
- 迁移对象:staff_employee → roster_employee;staff_employee_extra → roster_field_value + contract_info;staff_department_cache → org_unit;staff_change_log → roster_timeline;staff_audit_log → sys_audit_log。
- 迁移工具:hr-system 仓内 `scripts/migrate_staff_mgr.py`(Python + sqlor,幂等、按 employee_no 去重、输出核对报告:总数/抽样一致,NFR-8)。
- 切换策略:UAT 通过后一次性切换;切换后 staff-mgr 服务下线、仓库冻结归档(保留只读访问一个迭代周期)。迁移范围待 PM 确认(SRS §11-Q3)。
### 6.4 风险与对策
| 风险 | 对策 |
|---|---|
| 旧数据字段语义不一致(如 status 枚举) | 迁移脚本内置映射表 + 人工核对报告;UAT 期间双库比对 |
| 旧 department_id 无组织主数据 | 先迁 staff_department_cache 建 org_unit,再按 department_id 关联 |
| 身份证号加密算法不同(AesCipher) | 迁移时解密后按 hr-web 统一加密方案重新落库(cipher+hash) |
## 7. 部署与运维设计(SRS §8 落地)
### 7.1 环境矩阵
| 项 | 测试环境 | 生产环境 |
|---|---|---|
| 主机 | hrstest@192.168.16.12:22(免密已验证) | hrs@192.168.16.10:22 |
| 应用端口 | **9182**(ahserver 直接监听,HTTP) | **9182**(同左;域名/证书补齐前接受 IP 直连,SRS §11-Q1) |
| 数据库 | MariaDB 本地,test/test123,库 hrs | MariaDB 本地,库 hrs(生产账号口令部署时安全配置,SRS §11-Q2) |
| 会话 | Redis 本地(仅内网监听) | Redis 本地(仅内网监听) |
| 进程守护 | systemd hr-web.service(异常自动重启,NFR-3) | 同左 |
| 备份 | 无要求 | MariaDB 每日全量备份(mysqldump+crontab),保留 ≥30 天;files/ 附件目录随应用数据备份(NFR-5) |
| 监控告警 | — | 进程存活 + 9182 端口探活 + 备份结果告警(基础三项;接收渠道待明确 SRS §11-Q8,默认本地日志+邮件占位) |
### 7.2 部署形态决策
一期采用**单实例直连形态**:ahserver 直接监听 9182,systemd 守护(`Restart=always`),满足 NFR-3(月度可用率 ≥99% 工作时间、异常自动重启)。不强制引入 nginx。
### 7.3 HTTPS 升级路径(预留)
生产域名与证书补齐后(SRS §11-Q1),引入 nginx 监听 9182(HTTPS)反代 ahserver 内部端口(如 127.0.0.1:9183),ahserver 改绑 loopback;配置变更仅涉及 conf/config.json 端口与 systemd unit,无代码改动。招聘官网对外(批次3 FEAT-B3-07)依赖此升级。
## 8. 安全设计
1. **鉴权**:ahserver session(Redis)+ rbac 角色。批次1角色:`admin`(系统管理员)、`hr`(人事)、`manager`(部门经理)、`employee`(员工自助);所有路径经 scripts/load_path.py 注册,**未注册路径默认拒绝**(SRS §2.2-1)。
2. **数据范围**(F11):sys_data_scope 支持两类范围——组织维度(org_id 集合,含子树)、花名册字段维度(field_id 可见集合),两类可叠加;查询、报表、导出层强制拼接范围条件。
3. **脱敏**(SRS §2.2-4):敏感字段(身份证/手机/薪资级)在 roster_field_def 标记 sensitive;身份证号全角色脱敏(前3后3)、手机号(前3后4)、薪资/职级等敏感字段仅 admin/hr 可见,dspy 返回前按角色矩阵脱敏。
4. **审计**(F12):全量写操作记录前后值 JSON、操作人、时间、IP;审批、导入导出、登录同样记录;可按时间/类型查询。
5. **SQL 注入**:全部经 sqlor 绑定参数;dspy 禁止拼接用户输入(sqlExe 使用 `${var}$` 占位)。
6. **口令**:密码加盐哈希存储(appbase users 既有机制,NFR-4)。
7. **API 开放接口鉴权**:一期仅规范(§9),桩路径不注册业务处理,注册即按"未启用"拒绝。
## 9. API 开放接口规范(一期预留,FEAT-B1-01⑦)
一期不交付第三方集成,仅交付**鉴权与端点规范**:
1. **端点形态**:`/openapi/v1/{resource}.dspy`,resource 规划 `employees|orgs|changes`(员工/组织/异动事件推送),与内部 dspy 同框架。
2. **鉴权方案(二期启用)**:app_key + app_secret 签名(HMAC-SHA256,含时间戳防重放);密钥由 admin 在系统管理页生成(sys_openapp 表已预留,见 database-design.md §4.5);限流默认 10 req/s/app。
3. **响应契约**:与内部接口一致的 `{status,message,data}` 结构;批量接口统一分页参数 `page/size`(size ≤200)。
4. **数据出口管控**:开放接口同样强制数据范围与脱敏规则,导出字段需在管理端显式授权。
5. **一期落位**:不注册业务端点;`/openapi/v1/ping.dspy` 返回 `{status:'error', code:'NOT_ENABLED'}` 作为桩位,验证路由与鉴权框架可达。
## 10. 降级项设计(批次1相关,SRS §9)
| # | 降级项 | 一期降级方案(设计落点) | 二期预留接口/字段 |
|---|---|---|---|
| D1 | 身份证硬件读卡 | 入职/档案**手工录入**证件信息:roster_employee 设 `id_type/id_number_cipher/id_number_hash/id_valid_from/id_valid_to/id_authority/id_source(='manual')`;入职审批单与登记表含证件信息分组;展示脱敏(前3后3) | `id_source` 枚举预留 `card_reader`;读卡硬件对接后经 `roster_employee_update` 回填同一组字段,无需改表 |
| D3 | 钉钉同步/离职资源交接 | 不同步;离职交接项 `org_leave_handover.item_type` 含 **`dingtalk_resource`(占位类型)**,交接内容手工登记;组织/人员无同步入口 | 交接项类型字典可扩展;二期钉钉开放平台对接后 item_type=dingtalk_resource 项改为自动拉取资源清单 |
| D4 | 电子签 | contract_template 按占位符生成合同文本(docx/pdf)供**打印/下载**(contract_text_gen.dspy);`contract_info.esign_status` 字段(not_enabled)+ `esign_stub.dspy` 桩端点返回 NOT_ENABLED | esign_status 状态机(not_enabled→signing→signed)已定义,二期对接电子签平台后流转 |
| D9 | 短信通知渠道 | sys_message.send_channel 一期仅 `site`(站内)生效;提醒/关怀/审批通知全部站内送达;未配置 SMTP 时不尝试邮件 | send_channel 枚举含 `sms/email` 预留位;二期短信网关/SMTP 接入仅扩展发送器 |
| —(扫码入职降级) | 对外渠道扫码入职 | 系统内生成**入职登记链接 + 二维码图片**(内网可访问):org_entry 增 `register_token/register_url/qrcode_file/register_expire`;候选人扫码填登记表进审批流 | register_url 域名部分走配置项,二期对外渠道启用后切换公网域名 |
| —(考勤流程桩位) | 考勤流程联动 | FEAT-B1-01:考勤类表单(换班/加班/请假等)可建表单定义(biz_type=attendance_*),无回写 hook、不联动考勤系统 | flow_def.biz_type 字典预留 attendance_* 值 |
| —(工作台绩效/考勤统计桩位) | 经理/管理员工作台绩效考勤卡片 | F14:工作台留"绩效/考勤"桩位卡片,显示"未接入"占位,不取数 | workbench 聚合端点预留 perf/attendance 空结构字段 |
## 11. 非功能设计响应(SRS §7)
| NFR | 指标 | 设计响应 |
|---|---|---|
| NFR-1 | 列表 ≤500ms;报表聚合 ≤3s;导入 500 行 ≤30s | 100 人规模 + 索引设计(database-design.md §6);列表默认分页 50;组织树一次性加载(≤200 节点);报表直接 SQL 聚合;导入走后台任务 + 结果文件 |
| NFR-2 | 100 账号/并发 30/简历 2 万/花名册 2000 | 单实例 ahserver 异步模型足够;花名册含离职档案 2000 行在索引覆盖下无压力 |
| NFR-3 | 月度可用率 ≥99%,异常自动重启 | systemd Restart=always;单实例无状态(会话在 Redis) |
| NFR-4 | session+rbac/默认拒绝/审计/脱敏/参数绑定/密码哈希 | §8 安全设计逐项覆盖 |
| NFR-5 | 每日全量备份 ≥30 天 | §7.1:mysqldump crontab + files/ 目录备份 |
| NFR-6 | Chrome/Edge 最近 2 版;员工自助移动端兼容 | bricks 标准组件兼容;员工自助页面(工作台/档案/待办/服务/消息)ResponsableBox 自适应 |
| NFR-7 | ocai 模块结构/配置化/load_xxx 装配 | §3/§5 全栈声明式;表单/流程/字段 JSON 化 |
| NFR-8 | staff-mgr 迁移核对报告 | §6.3 + database-design.md §8(总数/抽样一致) |
## 12. 配套设计文档
| 文档 | 版本 | 内容 |
|---|---|---|
| database-design.md | v3.0 | ER、**49 张表**结构(含编制/项目式 6 新表 + sys_openapp 预留)、索引、字典、models JSON、staff-mgr 迁移 |
| api-design.md | v3.0 | dspy 端点清单(约 120 个)、请求/响应契约、鉴权角色、错误码、降级桩端点汇总、开放接口规范 |
| ui-design.md | v3.0 | 页面结构、组件树、路由表、核心交互流程、降级项交互说明 |
| iteration1-task-breakdown.md | v2.0 | 可行性分析、风险、开发任务拆解(T01~T27,面向 develop 角色可直接建任务) |
| feature-list.md | v2.1 | F01~F17 功能清单与 FEAT-B1 映射(批次1范围基线) |