touyun-elderly-care/docs/superpowers/specs/2026-10-14-服务机构端-C0基础骨架-design.md
liuyun ab32bb2634 docs: 修正 C0 设计——staff.user_id 关联账号,不动 sys_user
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 10:58:47 +08:00

119 lines
7.8 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.

# 服务机构端 · C0 基础骨架 · 设计文档
> 日期:2026-10-14
> 范围:服务机构端 P0 的「地基」——机构=租户映射、账号/人员/角色、数据模型基线、审计、错误码。
> 依据:`docs/requirements/P0 PRD(交付开发·V1)`、`docs/refs/` 数据字典、脚手架 sysmgr(ec-nest/ec-admin)。
> 后续:C1 待遇档案、C2 派单工单、C3 履约留痕、C4 质控闸门(各自另出 spec)。
## 1. 背景与目标
在 sysmgr 脚手架(ec-nest + ec-admin)之上实现服务机构端 P0。C0 只做地基,定死全局规则,供 C1–C4 复用,避免各块各自为政。
**已定决策**(用户 2026-10-14 拍板):
- 每个服务机构 = 脚手架一个独立租户(tenant)。
- 业务角色(nurse/leader/qc/admin/director)用脚手架角色,按业务角色配置权限。
- 保留脚手架菜单 + 新增服务机构端业务菜单。
- 本期只做机构管理后台 + 后端接口;护理员 APP(Flutter)、家属端(UniAPP)后续另开 change。
- 照片存储用腾讯云 COS,本期占位。
- 完整审计。
## 2. 机构↔租户映射
- 机构 = 租户。用脚手架 `tenant_code` 作为**机构唯一标识**(承载 PRD 的 `org_id` 语义)。
- `org` 独立业务表:主键 = 机构 code(与 `tenant_code` 同值),存机构业务字段;**不扩展 `sys_tenant`**(守 fork「框架只读」铁律)。
- 业务表统一带 `tenant_code`,继承脚手架 PrismaService 的自动多租户过滤 + 软删过滤。
- 备选(弃用):机构字段塞进 `sys_tenant` —— 污染脚手架,升级上游时易冲突。
`org` 关键字段:机构 code(主键)、org_name、org_type(medical_care/nursing_home/home_care/home_individual)、credit_code、loc_code、loc_name、svc_source(national/local)、license_no、address、contact_name/contact_phone、bed_count、sign_date。
## 3. 账号 / 人员 / 角色
分工(用户确认):
- **登录/鉴权/RBAC → `user`**:复用脚手架 `sys_user` + user-role + resource,**不加任何列**。
- **人员/HR/资质 → `staff`**:业务新表,是被派单、被质控、挂资质的对象,**不参与鉴权**。
- **关联**:`staff.user_id → user.id`,1:1,**外键放 staff 侧、可空**——不动 `sys_user`(守「框架只读」铁律)。院长/质控/管理员无 staff 记录;护理员/组长的 staff 记录 `user_id` 指向其账号。
> PRD 的 `user.staff_id` 落地为 `staff.user_id`(语义等价、方向镜像),字段字典以 `shared/data-model` 为准。
`staff` 关键字段:staff_id、tenant_code、name、id_card_no(加密)、person_code(预留)、phone、job_type(nurse/nurse_medical/manager)、work_type、entry_date/leave_date、employ_status、cert_type/cert_no/cert_level/cert_expire/cert_status、cert_verify_url(预留)、group_leader_id。
「多角色」落地:PRD 的「`user.role` 逗号分隔」**不照搬**,用脚手架 user↔role 多对多实现(权限并集天然支持)。「本组」在业务 service 层按 `staff.group_leader_id` 计算,不走脚手架 org 树。
## 4. 角色与权限码
5 个脚手架角色:nurse / leader / qc / admin / director。权限码走脚手架 Permissions + tenant-template 资源注册机制。
权限码清单(domain:action,最终清单随 `data-model`/`api-contract` 收口):
| 域 | 权限码 |
|---|---|
| elder | list / detail / create / update / status-change / import / svc-save |
| plan | create / change / detail / confirm |
| order | generate / assign / reassign / cancel / detail / today |
| record | checkin / checkout / item-save / photo-upload / detail |
| abnormal | report / list / handle |
| qc | pending-list / detail / pass / return / exception-link |
| svc-org | list / config / new-national |
| staff | list / create / update / group-assign |
| export | export |
角色→权限(并集;业务 service 层补「本组 / 自审自放行」校验):
- **nurse**:order.today、record.*、abnormal.report
- **leader**:nurse 全部 + 本组 order.assign/reassign/cancel、本组 qc.pass/return
- **qc**:elder.*、plan.*、order.*(全部)、record.detail、abnormal.handle、qc.*(全部)、svc-org.config、export
- **admin**:staff.*、svc-org.config、系统设置;不碰业务数据
- **director**:只读查看;**仅持 director 时写接口 403**
## 5. 数据模型基线(C0 建表)
C0 建 9 张业务表:`org`、`staff`、`svc_national`、`svc_local`、`svc_mapping`、`svc_org`、`dict_abnormal_type`、`dict_photo_tier`、`loc_config`。`user` 复用 `sys_user`(**不加任何列**);`staff.user_id` 关联 `user.id`。
- svc_national(L1):nat_id、nat_code(varchar20)、nat_name、nat_category、nat_sub_category、recommend_staff、recommend_duration、is_medical、version
- svc_local(L2):loc_id、loc_code、local_item_name、local_category、svc_time、min_freq、staff_qual、is_medical、source_doc、map_status
- svc_mapping(L3,机构不可见):map_id、loc_id、nat_id(可空)、map_type、map_note、status
- svc_org(L4):org_svc_id、tenant_code、src_type、src_id、is_enabled、price(预留)、price_effective(预留)、is_new_national
- dict_abnormal_type:9 宫格异常分类;dict_photo_tier:必拍/免拍/可拍配置
- loc_config:loc_code、loc_name、目录来源(national/local)、项数规则(预留)
> 字段字典唯一锚点:`shared/data-model`(实现时先行,本 spec 不重复完整字段定义)。
**与脚手架约定对齐点**(data-model 里定死):
1. 主键:脚手架 UUID v7(varchar36)vs PRD varchar(32) → 倾向跟随脚手架 UUID v7;业务码(机构编码/项目代码)作唯一索引。
2. 软删:脚手架 `deleted_at`(时间戳)vs PRD `is_deleted`(布尔)→ 跟脚手架 `deleted_at`。
3. 通用字段:`created_at/by`、`updated_at/by` 沿用脚手架。
## 6. 审计清单(完整审计)
复用脚手架 audit-log,以下业务动作全量落审计(谁 / 何时 / 动作 / 对象 / 前后值):
建档、改待遇状态、改等级、制定/变更计划、派单/调单/取消、签到/签退、上传照片、异常上报、质控放行/退回、异常处理/联动改计划、Excel 导入、导出文书、明文查看身份证、结转垫付。
## 7. 业务错误码
PRD 错误码映射到脚手架 error-codes.ts(业务码 5 位 [域2][序3]),统一响应补 `hint` 字段(脚手架现为 {code,message,data}):
1001 无有效待遇(L1) / 1002 无有效计划(L2) / 1003 无有效工单(L3) / 1004 留痕不完整(L4) / 1005 未质控(L5) / 1006 资质不匹配(提示级) / 2001 时间冲突(硬拒) / 2002 项数不满足(提示) / 3001 必拍未拍(硬拒) / 3002 定位失败(非错误) / 3003 扑空登记 / 3004 垫付不计费 / 4001 越权或自审自放行。
## 8. 横切产品缺口约定(C3/C4 引用)
- **推送**:P0 只做后台站内待办实时刷新(WebSocket/短轮询);APP push、公众号模板消息后置。
- **离线并发**:client_md5 幂等 + 留痕「补正链」;补传撞已退回 → 标「待重新质控」。
- **照片 COS**:record_photo.file_path 结构 + 上传接口占位(不接 COS SDK),COS 配置留 .env 占位。
- **身份核验(P-9)**:本期兜底 = 拍照留痕 + 护理员实名账号 + 家属可选确认;record 预留核验方式字段;扫脸/人证后置。
## 9. 非目标(本期不做)
护理员 APP、家属端、二期三块(结算/资质/看板)、评估机构端、医保接口对接、真实 COS 上传、身份扫脸核验。
## 10. 验收
- 一机构一租户隔离:跨机构数据不可见(4001)。
- 5 角色权限并集 + 仅持 director 时写接口 403。
- 业务菜单出现、脚手架菜单保留。
- 审计动作全量落日志。
- C0 建表经 `prisma migrate` 生成,`shared/data-model` 字段字典先行。