From 9a834df2c11eb22b724f28a4262886876a80d9f0 Mon Sep 17 00:00:00 2001 From: shunli Date: Wed, 13 May 2026 18:35:47 +0800 Subject: [PATCH] =?UTF-8?q?ORG8=20=E5=9B=BA=E5=8C=96=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E5=8F=AA=E8=AF=BB=E5=AE=A1=E8=AE=A1=E5=8F=A3?= =?UTF-8?q?=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/管理员手册.md | 103 ++++++++++++++++++ ...3_18-23-51-org8-master-data-permission.csv | 10 +- 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/docs/管理员手册.md b/docs/管理员手册.md index 8eb7d828..62d83725 100644 --- a/docs/管理员手册.md +++ b/docs/管理员手册.md @@ -60,6 +60,109 @@ OA 员工账号是权限、审批、业务数据和审计的主事实源;企 - 新员工账号创建必须同时确认直属主管、初始角色、账号状态和企业微信绑定路径。 - 离职或停用账号必须阻断登录、企业微信入口和新业务处理,但不得删除历史单据和审批记录。 +只读审计口径: + +所有 ORG8 主数据审计只允许使用只读账号执行 `SELECT`,输出仅保留工号、姓名、状态、角色摘要、业务类型和数量;不得导出手机号、邮箱、银行卡、身份证号、密码哈希、token 或企业微信真实标识。发现问题后只记录摘要和责任归属,不在审计 SQL 中修数据。 + +直属主管缺失: + +```sql +WITH role_summary AS ( + SELECT employee_id, string_agg(role_code::text, ',' ORDER BY role_code::text) AS roles + FROM employee_roles + GROUP BY employee_id +) +SELECT e.employee_no, e.name, e.status, COALESCE(r.roles, '') AS roles +FROM employees e +LEFT JOIN role_summary r ON r.employee_id = e.id +WHERE e.status = 'active' + AND e.direct_manager_id IS NULL + AND COALESCE(r.roles, '') !~ '(^|,)(ceo|admin)(,|$)' +ORDER BY e.employee_no; +``` + +主管停用或主管链断裂: + +```sql +SELECT e.employee_no, e.name, m.employee_no AS manager_no, m.name AS manager_name, m.status AS manager_status +FROM employees e +LEFT JOIN employees m ON m.id = e.direct_manager_id +WHERE e.status = 'active' + AND e.direct_manager_id IS NOT NULL + AND (m.id IS NULL OR m.status <> 'active' OR m.archived_at IS NOT NULL) +ORDER BY e.employee_no; +``` + +待办分配给停用审批人或无有效角色持有人: + +```sql +SELECT t.id AS task_id, wi.entity_type, a.employee_no AS assignee_no, a.name AS assignee_name, a.status AS assignee_status +FROM workflow_tasks t +JOIN workflow_instances wi ON wi.id = t.instance_id +LEFT JOIN employees a ON a.id = t.assignee_id +WHERE t.status = 'pending' + AND t.assignee_id IS NOT NULL + AND (a.id IS NULL OR a.status <> 'active' OR a.archived_at IS NOT NULL) +ORDER BY t.created_at; + +SELECT t.assignee_role, count(*) AS pending_count +FROM workflow_tasks t +WHERE t.status = 'pending' + AND t.assignee_role IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM employee_roles er + JOIN employees e ON e.id = er.employee_id + WHERE er.role_code = t.assignee_role + AND e.status = 'active' + AND e.archived_at IS NULL + ) +GROUP BY t.assignee_role +ORDER BY t.assignee_role; +``` + +`admin-only` 误用为业务审批: + +```sql +WITH role_summary AS ( + SELECT employee_id, string_agg(role_code::text, ',' ORDER BY role_code::text) AS roles + FROM employee_roles + GROUP BY employee_id +) +SELECT t.id AS task_id, wi.entity_type, e.employee_no, e.name, r.roles +FROM workflow_tasks t +JOIN workflow_instances wi ON wi.id = t.instance_id +JOIN employees e ON e.id = t.assignee_id +JOIN role_summary r ON r.employee_id = e.id +WHERE t.status = 'pending' + AND r.roles ~ '(^|,)admin(,|$)' + AND r.roles !~ '(^|,)(manager|ceo|finance|finance_mgr|hr)(,|$)' +ORDER BY t.created_at; + +SELECT id, name, level1_role, level2_role, level3_role +FROM approval_rules +WHERE enabled = true + AND 'admin' IN (level1_role::text, COALESCE(level2_role::text, ''), COALESCE(level3_role::text, '')) +ORDER BY priority; +``` + +财务和系统管理员混授: + +```sql +WITH role_summary AS ( + SELECT employee_id, string_agg(role_code::text, ',' ORDER BY role_code::text) AS roles + FROM employee_roles + GROUP BY employee_id +) +SELECT e.employee_no, e.name, e.status, r.roles +FROM employees e +JOIN role_summary r ON r.employee_id = e.id +WHERE e.status = 'active' + AND r.roles ~ '(^|,)admin(,|$)' + AND r.roles ~ '(^|,)(finance|finance_mgr)(,|$)' +ORDER BY e.employee_no; +``` + ## 4. 人员生命周期管理 ### 4.1 入职 1. 在 `人员管理` 创建员工账号。 diff --git a/issues/2026-05-13_18-23-51-org8-master-data-permission.csv b/issues/2026-05-13_18-23-51-org8-master-data-permission.csv index a3642f5d..1eb554cf 100644 --- a/issues/2026-05-13_18-23-51-org8-master-data-permission.csv +++ b/issues/2026-05-13_18-23-51-org8-master-data-permission.csv @@ -2,11 +2,11 @@ ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regr ORG8-0,ORG8 连续合同建档,"建立组织账号与权限主数据连续型合同,把组织、账号、主管、停用、角色、企业微信绑定和权限边界集中到同一 CSV。","1) 本 CSV 校验通过;2) 文档索引和状态矩阵指向本合同;3) 不改业务代码;4) 不绕过 R7E 人工确认;5) 后续组织权限问题优先进入本合同。","流程级验证:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-13_18-23-51-org8-master-data-permission.csv;rg -n 'ORG8|组织账号|权限主数据' docs/文档索引.md docs/文档事实源状态矩阵.md issues/README.md。",python3|rg|manual,DONE,DONE,DONE,issues/2026-05-13_18-23-51-org8-master-data-permission.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|issues/README.md,[],CSV validator 和索引 rg 均通过;本次仅合同建档和入口登记,未改业务代码,后续实现行仍需方案批准。 ORG8-1,组织账号需求规约更新,"把员工、主管、财务、管理员、停用和企业微信绑定的当前口径补入现有事实源或确认现有事实源已覆盖。","1) 组织账号主数据口径清楚;2) 不把管理员角色当作业务审批人;3) 企业微信只做身份和入口绑定;4) 冻结项不进入。","流程级验证:rg -n '组织|账号|直属主管|停用|角色|企业微信绑定|管理员' docs/管理员手册.md docs/需求-企业微信基础设施规约.md docs/海音达OA-MVP需求规格说明书.md。",rg|manual,DONE,DONE,DONE,docs/管理员手册.md|docs/需求-企业微信基础设施规约.md|docs/海音达OA-MVP需求规格说明书.md,"[""ORG8-0""]",已在管理员手册补 ORG8 组织账号主数据口径;rg 复核管理员手册、企业微信规约和 PRD 通过;未执行账号数据变更。 ORG8-2,角色边界设计,"设计员工、直属主管、审批人、财务和管理员的边界,明确最小权限和不兼容角色组合。","1) 角色能力矩阵清楚;2) 财务与系统管理混授风险可识别;3) admin-only 不进入业务审批;4) 有回滚和审计口径。","流程级验证:人工审查角色矩阵;rg -n '员工|主管|审批人|财务|管理员|角色边界|最小权限' docs/管理员手册.md docs/开发交付与变更管理规约.md。",rg|manual,DONE,DONE,DONE,docs/管理员手册.md|docs/开发交付与变更管理规约.md,"[""ORG8-1""]",管理员手册已补角色能力矩阵和不兼容组合;admin-only 不作为业务审批人,财务和系统管理员混授需人工确认;后续权限实现仍需方案批准。 -ORG8-3,直属主管缺失审计,"建立直属主管缺失的只读审计口径,识别会影响审批链的员工账号。","1) 缺直属主管的员工可列出摘要;2) 不打印隐私和密码;3) 不直接写生产数据;4) 缺口进入修复分流。","流程级验证:在只读环境执行员工和主管关系核验;无环境时记录可复现 SQL 或脚本步骤。",manual|node,TODO,TODO,TODO,scripts/qa|server/prisma,"[""ORG8-2""]",生产核验必须遵守 audit-readonly 边界。 -ORG8-4,主管停用影响审计,"识别直属主管被停用后对请假、报销、采购审批链的影响。","1) 停用主管关联员工可追溯;2) 受影响流程明确;3) 不自动改审批链;4) 有人工处理建议。","流程级验证:只读核验停用主管和下属关系;流程核对员工提交请假或报销时审批链是否可解释。",manual|node,TODO,TODO,TODO,scripts/qa|server/src,"[""ORG8-3""]",不在审计中修数据。 -ORG8-5,审批人停用影响审计,"识别审批人停用后待办、历史记录和新流程分派的影响。","1) 待办不分配给停用审批人;2) 历史审批记录不丢失;3) 新流程有替代规则;4) 异常可追溯。","流程级验证:提交或模拟审批流 -> 停用审批人场景 -> 检查待办归属和历史记录。",manual|node,TODO,TODO,TODO,server/src|scripts/qa,"[""ORG8-4""]",涉及状态机或待办迁移时需 reviewer。 -ORG8-6,admin-only 误用为审批人审计,"审计 admin-only 账号是否被配置为业务审批人或财务处理人。","1) admin-only 不承担业务审批;2) 误配能被发现;3) 不影响管理员系统管理入口;4) 修复路径明确。","流程级验证:只读查询角色和审批链配置;流程核对报销或请假审批人不是 admin-only。",manual|node,TODO,TODO,TODO,scripts/qa|server/src,"[""ORG8-2""]",如发现误配先记录,不直接改生产。 -ORG8-7,财务和管理员混授审计,"审计财务和系统管理员角色混授风险,明确是否允许同人双角色及审计要求。","1) 混授账号可列摘要;2) 财务付款和系统管理权限边界清楚;3) 高风险组合进入人工确认;4) 不泄露敏感字段。","流程级验证:只读核验用户角色集合;流程核对财务台账和系统管理入口权限。",manual|node,TODO,TODO,TODO,scripts/qa|server/src|client/src,"[""ORG8-2""]",真实名单只记录账号标识和角色摘要。 +ORG8-3,直属主管缺失审计,"建立直属主管缺失的只读审计口径,识别会影响审批链的员工账号。","1) 缺直属主管的员工可列出摘要;2) 不打印隐私和密码;3) 不直接写生产数据;4) 缺口进入修复分流。","流程级验证:在只读环境执行员工和主管关系核验;无环境时记录可复现 SQL 或脚本步骤。",manual|rg,DONE,DONE,DONE,docs/管理员手册.md|server/prisma/schema.prisma,"[""ORG8-2""]",已根据 Prisma schema 在管理员手册补直属主管缺失只读 SQL;未执行生产查询或数据修复;后续有只读环境时输出摘要再分流。 +ORG8-4,主管停用影响审计,"识别直属主管被停用后对请假、报销、采购审批链的影响。","1) 停用主管关联员工可追溯;2) 受影响流程明确;3) 不自动改审批链;4) 有人工处理建议。","流程级验证:只读核验停用主管和下属关系;流程核对员工提交请假或报销时审批链是否可解释。",manual|node,TODO,TODO,TODO,scripts/qa|server/src,"[""ORG8-3""]",只读 SQL 口径已在管理员手册补充;实际数据核验和流程核对待只读环境或人工窗口。 +ORG8-5,审批人停用影响审计,"识别审批人停用后待办、历史记录和新流程分派的影响。","1) 待办不分配给停用审批人;2) 历史审批记录不丢失;3) 新流程有替代规则;4) 异常可追溯。","流程级验证:提交或模拟审批流 -> 停用审批人场景 -> 检查待办归属和历史记录。",manual|node,TODO,TODO,TODO,server/src|scripts/qa,"[""ORG8-4""]",只读 SQL 口径已在管理员手册补充;实际 workflow 核验待只读环境或非生产流程窗口。 +ORG8-6,admin-only 误用为审批人审计,"审计 admin-only 账号是否被配置为业务审批人或财务处理人。","1) admin-only 不承担业务审批;2) 误配能被发现;3) 不影响管理员系统管理入口;4) 修复路径明确。","流程级验证:只读查询角色和审批链配置;流程核对报销或请假审批人不是 admin-only。",manual|node,TODO,TODO,TODO,scripts/qa|server/src,"[""ORG8-2""]",只读 SQL 口径已在管理员手册补充;实际误配核验待只读环境或非生产流程窗口。 +ORG8-7,财务和管理员混授审计,"审计财务和系统管理员角色混授风险,明确是否允许同人双角色及审计要求。","1) 混授账号可列摘要;2) 财务付款和系统管理权限边界清楚;3) 高风险组合进入人工确认;4) 不泄露敏感字段。","流程级验证:只读核验用户角色集合;流程核对财务台账和系统管理入口权限。",manual|node,TODO,TODO,TODO,scripts/qa|server/src|client/src,"[""ORG8-2""]",只读 SQL 口径已在管理员手册补充;实际混授名单待只读环境核验且只记录账号标识摘要。 ORG8-8,新员工账号流程,"定义新员工账号创建、角色分配、直属主管配置和企业微信绑定的操作流程。","1) 新员工从创建到可用路径清楚;2) 必填主数据明确;3) 缺主管或缺绑定有提示;4) 不记录密码明文。","流程级验证:管理员创建员工 -> 分配角色和主管 -> 员工登录或进入企业微信入口 -> 权限正确。",manual|playwright,TODO,TODO,TODO,docs/管理员手册.md|server/src|client/src,"[""ORG8-3"",""ORG8-7""]",若涉及 UI 改动需读产品设计规则并补视觉验证。 ORG8-9,企业微信绑定流程,"收敛企业微信用户标识、OA 账号和绑定状态的流程和异常处理。","1) 绑定状态可解释;2) 未绑定提示清楚;3) 解绑或变更有审计;4) 企业微信只做入口和身份基础设施。","流程级验证:企业微信入口 -> 身份绑定检查 -> OA 角色入口 -> deeplink 返回目标页面。",manual|playwright,TODO,TODO,TODO,docs/需求-企业微信基础设施规约.md|server/src|client/src,"[""ORG8-8""]",不做企业微信原生审批。 ORG8-10,账号禁用和离职流程,"定义账号禁用、离职和权限回收流程,保护历史单据和审批记录。","1) 禁用账号不能新登录或处理新任务;2) 历史记录保留;3) 待办有转交或暂停策略;4) 回滚路径清楚。","流程级验证:禁用账号 -> 尝试登录和处理审批 -> 检查历史单据可读但不可越权操作。",manual|node|playwright,TODO,TODO,TODO,server/src|client/src|docs/管理员手册.md,"[""ORG8-5""]",涉及数据变更必须先写方案和回滚路径。