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

21 KiB
Raw Blame History

迭代1总体设计 —— API/接口设计hr-webocai 口径)

  • 版本v2.0迭代1-总体设计,取代 v1 Spring Boot/JWT RESTful 口径v1 已归档至 docs/_archive/01-design-v1-old/api-design.md
  • 状态评审通过主agent评审基线冻结
  • 规范依据ocai 技能集 module-development-spec、dspy-file-implementation-spec、crud-definition-spec架构基线 docs/01-design/architecture.md

1. 接口范式与通用约定(取代 v1 RESTful/JWT

  1. 端点形态:全部接口为 .dspy 端点(受控 Python路径 /{module}/api/{name}.dspy,由 ahserver wwwroot 自动路由无需注册GET query 与 POST body 统一解析进 params_kw。dspy 必须显式 return,且不得在 async with db.sqlorContext 块内 returnNoneType 陷阱)。
  2. 鉴权session cookieRedis 会话)+ rbac 路径级角色控制;每条路径经各模块 scripts/load_path.py 注册,角色:admin / hr / manager / employee / logined;未注册路径默认拒绝。不使用 JWT。
  3. 数据范围:查询类接口强制叠加 get_data_scope(user_id)hr-system 提供),范围外数据不可见。
  4. CRUD 列表/表单接口:由 json/*.json 经 xls2ui 自动生成列表查询、add/update/delete 包装 dspy不在本文逐一列出本文列出业务自定义端点。CRUD 自动生成部分约定 new_data_url/update_data_url/delete_data_url 位于 params 顶层。
  5. 统一响应结构
    • 列表:{"status":"success","data":{"rows":[...],"total":N}}DataViewer 强制格式)
    • 业务:{"status":"success"|"error","message":"...","data":{...}}
    • 错误返回 HTTP 200 + status=errorbricks 前端惯例),鉴权失败由框架返回 401/403。
  6. 错误码规范status=error 时 data.code
code 含义 典型场景
PARAM_INVALID 参数缺失/格式错误 必填项为空、日期格式错
NOT_FOUND 对象不存在 id 无效
DUPLICATE 唯一冲突 工号/编码重复
NO_PERMISSION 数据范围外/角色不足 越权访问他人档案
BLACKLIST_HIT 黑名单命中 入职校验拦截
STATUS_CONFLICT 状态不允许 已离职再调动、重复审批
FLOW_NOT_MATCH 无匹配审批流 该员工类型/部门未配置流程
SCOPE_OVERDRAFT 编制/范围超限 预留(编制管理范围外)
INTERNAL_ERROR 服务异常 兜底
  1. 审计:所有写接口成功后调用 write_audit_log(module,target_type,target_id,op,before,after)hr-system

2. 端点清单(按模块)

角色列A=adminH=hrM=managerE=employeeL=任意登录。数据范围=是 表示叠加数据范围过滤。 CRUD 列:该表的标准增删改查由 json/*.json 自动生成,路径为 /{module}/{tblname}_list(页面) + add_/update_/delete_{tblname}.dspy

2.1 hr-org/hrorgF01/F02/F04~F08

端点 方法 功能 关键请求参数 响应 data 角色 CRUD
/hrorg/api/org_tree.dspy GET 组织树(支持 as_of 历史日期、status 过滤) as_of?, status?, keyword? 树形节点数组(id,name,parent_id,children,status,leader_name) L
/hrorg/api/org_unit_create.dspy POST 新建组织(编码唯一校验、写 org_unit_change org_code,org_name,parent_id,org_type,leader_id,effective_date,自定义字段kv {id} A,H org_unit
/hrorg/api/org_unit_update.dspy POST 编辑组织(留痕) id,... {} A,H org_unit
/hrorg/api/org_unit_move.dspy POST 移动组织(变更上级) id,new_parent_id,effective_date {} A,H
/hrorg/api/org_unit_disable.dspy POST 停用组织(校验无在职员工引用) id {} A,H
/hrorg/api/org_change_timeline.dspy GET 组织时间轴 org_id {rows:[{change_type,before_json,after_json,operator,created_at}]} L
/hrorg/api/org_import.dspy POST Excel 批量导入组织(后台任务+结果文件) file(上传) {task_id} A,H
/hrorg/api/org_import_result.dspy GET 导入结果(成功/失败行下载) task_id {rows,total,error_file} A,H
/hrorg/api/org_chart_export.dspy GET 架构图导出(图片/XMind as_of?, root_id?, fmt=png/xmind 文件下载 A,H
/hrorg/api/org_field_def_save.dspy POST 组织字段自定义 fields[] {} A,H org_field_def
/hrorg/api/job_import.dspy / job_export.dspy POST/GET 职务批量导入导出 file / 筛选条件 {task_id} / 文件 A,H org_job
/hrorg/api/position_import.dspy / position_export.dspy POST/GET 职位批量导入导出 file / dept_id?,status? {task_id} / 文件 A,H org_position
/hrorg/api/job_options.dspy / position_options.dspy / grade_options.dspy / rank_options.dspy / sequence_options.dspy / org_options.dspy / company_options.dspy GET 主数据下拉选项(状态=active供花名册/异动表单引用) 无/keyword {rows:[{id,name}]} L org_job 等
/hrorg/api/entry_approval.dspy POST 发起入职审批(单个,匹配审批流) name,id_number,employee_type,org_id,position_id,hire_date,... {instance_id} 或 BLACKLIST_HIT/FLOW_NOT_MATCH A,H org_entry
/hrorg/api/entry_manual.dspy POST 手动入职(批量,直接入花名册或待入职) entries[]:{...}, to=pending/roster {entered:[],pending:[],blocked:[]} A,H
/hrorg/api/entry_invite_register.dspy POST 邀请待入职填写登记表(站内消息) entry_ids[] {} A,H
/hrorg/api/entry_register_submit.dspy POST 待入职员工提交登记表 entry_id,字段kv {} E(本人)
/hrorg/api/entry_blacklist_check.dspy GET 黑名单校验 id_number 或 name {hit:bool,blacklist_id?} A,H
/hrorg/api/entry_notify.dspy POST 入职通知/欢迎(模板填充发送) entry_ids[],template_id {} A,H
/hrorg/api/regular_apply.dspy POST 发起转正审批(自助/代发) employee_id,regular_date {instance_id} E(自助),H,M org_regularization
/hrorg/api/regular_manual.dspy POST 手动转正(直接更新花名册) employee_id,regular_date {} A,H
/hrorg/api/transfer_apply.dspy POST 发起调动审批(支持批量人员) transfer_type,effective_date,details[]:{employee_id,to_org_id,to_position_id,...} {instance_id} A,H,M org_transfer
/hrorg/api/transfer_cancel.dspy POST 取消调动(保留历史不改现职) transfer_id {} A,H
/hrorg/api/leave_apply.dspy POST 发起离职审批(自助/代发) employee_id,leave_type,leave_reason,leave_date {instance_id} E(自助),H,M org_leave
/hrorg/api/leave_manual.dspy POST 手动离职(直接入待离职/已离职) employee_id,leave_date,leave_reason {} A,H
/hrorg/api/leave_handover_save.dspy POST 离职交接项保存 leave_id,items[] {} A,H,M org_leave_handover
/hrorg/api/leave_certificate.dspy GET 离职证明生成下载 employee_id 文件 E(本人),A,H
/hrorg/api/blacklist_add.dspy POST 一键加入黑名单 leave_id 或 id_number_hash,reason {} A,H org_blacklist
/hrorg/api/concurrent_apply.dspy POST 发起兼岗审批 employee_id,org_id,position_id,start_date,end_date {instance_id} A,H,M org_concurrent_post
/hrorg/api/workbench_transfer.dspy GET 工作台入转调离汇总(经理/管理员视图) scope=team/all {entry_n,regular_n,transfer_n,leave_n,rows} M,H,A

2.2 hr-roster/hrrosterF03

端点 方法 功能 关键请求参数 响应 data 角色 CRUD
/hrroster/api/roster_list.dspy GET 花名册列表(主表条件分页 + EAV 拼装 + 范围过滤 + 脱敏) keyword?,org_id?,status?,type?,field_filters?,page,size {rows,total} A,H(范围),M(团队) roster_employee
/hrroster/api/roster_employee_create.dspy POST 新增员工(自动生成工号、写时间轴) 主档字段+自定义字段kv {id,employee_no} A,H roster_employee
/hrroster/api/roster_employee_update.dspy POST 更新员工(含自助修改路径:可改范围+可选审核) id,字段kv {} 或 {need_audit:true,instance_id} A,H,E(本人受限) roster_employee
/hrroster/api/employee_detail.dspy GET 员工档案详情(主档+分组字段+兼岗+合同摘要,按角色脱敏/字段可见) id {main,groups:[{group_name,fields:[...]}],concurrent,contracts} L(按范围)
/hrroster/api/roster_field_def_save.dspy POST 字段定义维护(类型/必填/敏感/自助/审核/适用类型/排序) fields[] {} A,H roster_field_def
/hrroster/api/roster_field_group_save.dspy POST 分组维护(含拖拽排序持久化) groups[] {} A,H roster_field_group
/hrroster/api/roster_type_rule_save.dspy POST 员工类型字段规则 employee_type,field_rules_json {} A,H roster_type_rule
/hrroster/api/empno_rule_save.dspy POST 工号规则维护 rules[] {} A,H roster_empno_rule
/hrroster/api/check_employee_no.dspy GET 工号查重 employee_no,exclude_id? {exists} A,H
/hrroster/api/roster_import.dspy POST 自定义导入(批量新增/批量修改,模板按当前字段定义生成) file,mode=new/update {task_id} A,H
/hrroster/api/roster_import_template.dspy GET 导入模板下载(按字段定义+类型规则) employee_type? 文件 A,H
/hrroster/api/roster_export.dspy GET 自定义导出(指定数据日期/字段/顺序) as_of?,field_ids[],filters {task_id}→文件 A,H
/hrroster/api/timeline.dspy GET 员工时间轴(全周期记录) employee_id,event_type? {rows:[{event_type,event_date,title,content_json}]} L(按范围)
/hrroster/api/timeline_add.dspy POST 时间轴记录编辑 employee_id,event_type,event_date,title,content {} A,H
/hrroster/api/file_preview_url.dspy GET 附件在线预览 URLfiles/ 受控访问) file_id {url} L(按范围)
/hrroster/api/roster_writeback.dspy 内部 异动回写入口(仅 hr-org/hr-flow 服务内调用,注册于 ServerEnv不注册 HTTP 路径) biz_type,biz_id,instance_id {} 服务内

2.3 hr-flow/hrflowF10

端点 方法 功能 关键请求参数 响应 data 角色 CRUD
/hrflow/api/form_def_save.dspy POST 表单定义维护(引用花名册字段) form_code,form_name,biz_type,fields_json {id} A,H flow_form_def
/hrflow/api/flow_def_save.dspy POST 流程定义(匹配条件、版本) flow_code,form_id,biz_type,match_cond_json {id} A,H flow_def
/hrflow/api/flow_node_save.dspy POST 节点维护(审批人/通过规则/字段权限/抄送) flow_id,nodes[] {} A,H flow_node_def
/hrflow/api/flow_role_save.dspy POST 审批角色(流程范围/操作权限/数据范围) role_name,flow_scope_json,op_perm_json,data_scope_json {id} A flow_role
/hrflow/api/flow_match.dspy GET 按员工类型/部门匹配流程 biz_type,employee_type,org_id {flow_id,flow_name} 或 FLOW_NOT_MATCH 服务内/HR
/hrflow/api/flow_start.dspy POST 发起审批(通用:业务模块统一入口) biz_type,biz_id,form_data_json {instance_id,inst_no} L
/hrflow/api/task_todo.dspy GET 我的待办 page,size {rows,total} L
/hrflow/api/task_done.dspy GET 已办 page,size {rows,total} L
/hrflow/api/inst_mine.dspy GET 我发起的 status?,page,size {rows,total} L
/hrflow/api/inst_received.dspy GET 我收到的(抄送/知会) page,size {rows,total} L
/hrflow/api/inst_detail.dspy GET 审批单详情(表单数据+流转记录+字段权限) instance_id {form_data,nodes:[{op,operator,time,comment}],status} L(参与者)
/hrflow/api/task_approve.dspy POST 同意 task_id,comment? {} L(任务归属)
/hrflow/api/task_reject.dspy POST 驳回 task_id,comment {} L(任务归属)
/hrflow/api/task_forward.dspy POST 转交 task_id,to_user_id {} L(任务归属)
/hrflow/api/inst_withdraw.dspy POST 撤回(发起人,仅首节点未处理) instance_id {} L(发起人)
/hrflow/api/inst_query.dspy GET 审批数据查询(表单/状态/发起人/编号/时间) form_name?,status?,initiator?,inst_no?,date_range {rows,total} A,H
/hrflow/api/inst_export.dspy GET 审批数据导出 同上 文件 A,H
/hrflow/api/inst_print.dspy GET 审批单打印视图 instance_id 打印 HTML L(参与者)

2.4 hr-contract/hrcontractF09

端点 方法 功能 关键请求参数 响应 data 角色 CRUD
/hrcontract/api/contract_list.dspy GET 合同台账列表(范围过滤) employee_id?,status?,type_id?,end_before? {rows,total} A,H contract_info
/hrcontract/api/contract_create.dspy POST 新增合同(模板引用) employee_id,type_id,company_id,start_date,end_date,file {id} A,H contract_info
/hrcontract/api/contract_import.dspy POST 批量导入 file {task_id} A,H
/hrcontract/api/contract_apply.dspy POST 合同审批(新签/续签/变更/终止) contract_id?,biz_type=contract_sign/renew/change/stop,form_data_json {instance_id} A,H
/hrcontract/api/contract_remind_rule_save.dspy POST 到期提醒规则 rule_name,days_before,target_role,content_template {id} A,H contract_remind_rule
/hrcontract/api/contract_template_save.dspy POST 模板维护 template_name,type_id,file,field_marks_json {id} A,H contract_template
/hrcontract/api/contract_expire_soon.dspy GET 即将到期列表(工作台/提醒) days {rows} A,H
/hrcontract/api/esign_stub.dspy POST 电子签预留桩(返回未启用提示) contract_id {status:'error',code:'NOT_ENABLED'} A,H

2.5 hr-report/hrreportF13全部只读

端点 方法 功能 关键请求参数 响应 data 角色
/hrreport/api/roster_analysis.dspy GET 花名册多维分布(维度可自定义) dim=type/status/age/edu/location/gender/custom_field_id {rows:[{dim_value,count}],total} A,H,M(范围)
/hrreport/api/entry_analysis.dspy GET 入职数量与趋势 dim=org/location/position,period=month/quarter {trend:[],rows:[]} A,H,M
/hrreport/api/regular_analysis.dspy GET 转正分析与近期待转正 period? {trend:[],upcoming:[]} A,H,M
/hrreport/api/transfer_analysis.dspy GET 近期调动分析 date_range? {rows:[{type,count}]} A,H,M
/hrreport/api/leave_analysis.dspy GET 离职分析(待离职数/原因/离职率/同环比) period? {pending_n,reasons:[],rate:{cur,yoy,mom}} A,H,M
/hrreport/api/team_stats.dspy GET 团队人事统计(经理工作台卡片) org_id? {headcount,entry_n,leave_n,...} M,H,A

2.6 hr-system/hrsystemF11/F12/F14/F15

端点 方法 功能 关键请求参数 响应 data 角色 CRUD
/hrsystem/api/role_save.dspy POST 管理角色创建与权限设置rbac 角色+路径) role_name,paths[] {id} A sys_role(rbac)
/hrsystem/api/data_scope_save.dspy POST 人员范围(组织维度/花名册字段维度) admin_user_id,scope_type,org_ids[]/field_ids[] {} A sys_data_scope
/hrsystem/api/admin_save.dspy POST 管理员管理(创建/调整权限) user_id,roles[] {} A
/hrsystem/api/get_data_scope.dspy 内部 数据范围查询ServerEnv 注册,供各模块查询叠加) user_id {scope_type,org_ids,field_ids} 服务内
/hrsystem/api/audit_log_list.dspy GET 操作日志查询(时间/类型/模块) module?,operation?,date_range,target? {rows,total} A sys_audit_log
/hrsystem/api/audit_log_detail.dspy GET 日志详情(前后对比) id {before_json,after_json,operator,ip,time} A
/hrsystem/api/workbench_employee.dspy GET 员工工作台聚合(档案摘要/待办数/可发起流程) {profile,todo_n,flows:[...]} E
/hrsystem/api/workbench_manager.dspy GET 经理工作台聚合(团队统计/待审批/关怀提醒) {stats,todos:[],care:[...]} M
/hrsystem/api/workbench_admin.dspy GET 管理员工作台聚合(人事统计/合同到期/提醒) {stats,contracts:[],care:[...]} A,H
/hrsystem/api/remind_rule_save.dspy POST 通用提醒规则(多场景自定义) scene_code,rule_name,days_before,content_template,target_role {id} A,H sys_remind_rule
/hrsystem/api/care_config_save.dspy POST 生日/周年关怀文案配置 care_type,template,enable {} A,H sys_care_config
/hrsystem/api/announcement_save.dspy POST 公告发布 title,content,publish_scope_json {id} A,H sys_announcement
/hrsystem/api/policy_save.dspy POST 政策发布(查阅范围/下载权限) title,file,view_scope_json,downloadable {id} A,H sys_policy
/hrsystem/api/message_list.dspy GET 我的站内消息 is_read?,msg_type? {rows,total} L
/hrsystem/api/message_read.dspy POST 标记已读 ids[] {} L
/hrsystem/api/remind_scan.dspy 内部 提醒扫描cron/启动任务:转正/合同/生日等到期扫描推送) {sent_n} 服务内

2.7 appbase/rbac 沿用(不自研)

登录/登出、用户管理、字典 appcodes 维护、rbac 角色路径绑定由 appbase/rbac 包自带页面与端点承载(/appbase/*/rbac/*迭代1仅在各模块 init/data.json 中初始化字典与角色。

3. 典型调用链示例

3.1 转正审批F05 流程2

  1. POST /hrorg/api/regular_apply.dspy {employee_id, regular_date} → hr-org 校验员工状态probation
  2. 内部调用 flow_match(biz_type=regular, employee_type, org_id)POST /hrflow/api/flow_start.dspy {biz_type:'regular', biz_id:regularization_id, form_data_json} → 生成 flow_instance + 首节点 flow_task发站内消息给审批人
  3. 审批人 POST /hrflow/api/task_approve.dspy → 全部节点通过 → flow_instance.inst_status=approved
  4. hr-flow 完成回调 → hr-org regular_confirm → hr-roster roster_writebackroster_employee.employee_status=regular、regular_date 更新,写 roster_timeline
  5. 各步均写 sys_audit_log转正提醒由 remind_scan 按预计日期提前推送管理员与直属主管。

3.2 花名册列表F03

GET /hrroster/api/roster_list.dspy?keyword=张&org_id=..&status=regular&page=1&size=50 → 权限校验(数据范围 org_ids/field_ids→ 主表条件分页 → 值表批量拼装显示字段 → 敏感字段按角色脱敏 → {"status":"success","data":{"rows":[...],"total":N}}

3.3 入职黑名单拦截F04

POST /hrorg/api/entry_approval.dspy → id_number 哈希匹配 org_blacklist → 命中返回 {"status":"error","data":{"code":"BLACKLIST_HIT"}},前端待入职列表高亮标注;手动入职返回 blocked 名单。

4. 与 v1 接口的替代关系(衔接 staff-mgr

v1 端点JWT RESTful 迭代1替代
POST /api/v1/staff /hrorg/api/entry_manual.dspy 或 /hrroster/api/roster_employee_create.dspy
GET /api/v1/staff /hrroster/api/roster_list.dspy+ CRUD 列表页)
GET /api/v1/staff/{id} /hrroster/api/employee_detail.dspy
PUT /api/v1/staff/{id} /hrroster/api/roster_employee_update.dspy
DELETE /api/v1/staff/{id}、batch-delete 离职流程 /hrorg/api/leave_manual.dspy迭代1不做删除语义裁决 Q6
GET /api/v1/staff/{id}/change-logs /hrroster/api/timeline.dspy
GET /api/v1/staff/audit-logs /hrsystem/api/audit_log_list.dspy
GET /api/v1/staff/check/employee-no /hrroster/api/check_employee_no.dspy
GET /api/v1/staff/departments /hrorg/api/org_tree.dspy

5. 安全设计要点

  1. 所有路径 load_path.py 注册;未注册即拒绝(含 .css/.js 静态资源)。
  2. 敏感字段身份证全角色脱敏前3后3手机前3后4职级/薪资类字段仅 admin/hr由 roster_field_def.sensitive + 角色矩阵驱动,服务端脱敏后返回。
  3. 全部 SQL 经 sqlor 绑定参数(${var}$ 占位),禁止拼接用户输入。
  4. 审批操作校验任务归属人;员工自助类接口校验本人(或白名单字段)。
  5. 导入导出、登录、权限变更全量写 sys_audit_log含 IP