Compare commits
2 Commits
1143e58929
...
3afd009420
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3afd009420 | ||
|
|
690adfbd5b |
129
docs/superpowers/specs/2026-10-14-服务机构端-C1待遇档案-design.md
Normal file
129
docs/superpowers/specs/2026-10-14-服务机构端-C1待遇档案-design.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
# 服务机构端 · C1 待遇档案 · 设计文档
|
||||||
|
|
||||||
|
> 日期:2026-10-14
|
||||||
|
> 范围:待遇档案域——老人档案(elder)+ 十态待遇状态机 + 状态变更留痕(elder_status_log)+ 评估结论副本上传。
|
||||||
|
> 依据:P0 PRD §3.2/§5.2/§5.5.1/§7.2/§7.4/§8.2;C0 设计 `2026-10-14-服务机构端-C0基础骨架-design.md`。
|
||||||
|
> 后续:C2 派单工单(含 `elder_svc` 老人个人项目库 + 服务计划)。
|
||||||
|
|
||||||
|
## 1. 背景与目标
|
||||||
|
|
||||||
|
在 C0 基础骨架(机构=租户、RBAC、目录四层、菜单、多租户过滤)之上,落地「待遇档案」域。C1 只做:老人档案建档、十态待遇状态机与变更留痕、评估结论副本上传。承接 C2 的状态机消费(L1 硬锁)与 `elder_svc`。
|
||||||
|
|
||||||
|
## 2. 已定决策(用户 2026-10-14 拍板)
|
||||||
|
|
||||||
|
- 评估结论承载=**上传副本 + 存字段**(等级唯一来源=评估结论,禁止建档人自行填写)。
|
||||||
|
- OCR 后置(C1 手工录入身份证 + 18 位校验位校验)。
|
||||||
|
- 批量导入后置(C1 先单条建档)。
|
||||||
|
- `elder_svc` 放 C2(与「制定计划时带入」一起做)。
|
||||||
|
- 文件存 MinIO(`http://localhost:9000`,bucket `carelink`,S3 兼容,后续切腾讯云 COS 只换配置)。
|
||||||
|
|
||||||
|
## 3. 数据模型(新增 2 张表)
|
||||||
|
|
||||||
|
通用字段:`created_at`/`created_by`/`updated_at`/`deleted_at`。主键 UUID v7。
|
||||||
|
|
||||||
|
**`elder` 老人档案表**(`@@map("sys_elder")`):
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| id | uuid | 主键 |
|
||||||
|
| tenant_code | varchar(64) | 机构(多租户隔离) |
|
||||||
|
| loc_code | varchar(12) | 参保地/统筹区(取目录依据) |
|
||||||
|
| prev_loc_code | varchar(12)? | 跨统筹区转移前参保地 |
|
||||||
|
| transfer_confirm_at | datetime? | 转移确认时间 |
|
||||||
|
| name | varchar(30) | 姓名 |
|
||||||
|
| gender | char(1) | M/F |
|
||||||
|
| birth_date | date | 出生日期(系统算年龄) |
|
||||||
|
| id_card_no | varchar(255) | 身份证号(加密预留;本期明文+TODO,掩码见 §7) |
|
||||||
|
| phone | varchar(15)? | 联系电话 |
|
||||||
|
| address | varchar(200) | 居住地址 |
|
||||||
|
| guardian_name | varchar(30)? | 紧急联系人 |
|
||||||
|
| guardian_phone | varchar(15)? | 紧急联系人电话 |
|
||||||
|
| insur_no | varchar(30) | 医保参保号 |
|
||||||
|
| insur_type | varchar(10) | employee/resident |
|
||||||
|
| insur_years | int? | 缴费年限 |
|
||||||
|
| insur_verify_status | varchar(20)? | verified/unverified(本期线下确认) |
|
||||||
|
| insur_verify_date | date? | 参保核验日期 |
|
||||||
|
| assess_level | varchar(20) | 失能等级 sev_1(重度一级·最高级)/sev_2/sev_3 |
|
||||||
|
| care_level | varchar(20) | 护理等级 care_1(一级·最高级)/care_2/care_3 |
|
||||||
|
| assess_date | date | 评估结论日期 |
|
||||||
|
| assess_org | varchar(100)? | 评估机构名称 |
|
||||||
|
| assess_evidence_file | varchar(255)? | 评估结论副本(MinIO key)【补】 |
|
||||||
|
| benefit_start | date | 待遇有效期起 |
|
||||||
|
| benefit_end | date | 待遇有效期止 |
|
||||||
|
| treat_status | varchar(20) | 待遇状态(§4) |
|
||||||
|
| status_source | varchar(10) | manual(恒)/api 预留 |
|
||||||
|
| status_change_date | date? | 状态最后变更日 |
|
||||||
|
| hosp_start / hosp_end | date? | 住院起止 |
|
||||||
|
| photo_tier_override | json? | 拍照分档加严覆盖 |
|
||||||
|
| need_assess | json? | 上门需求评估五块信息(建表留结构,采集交互后置 C2) |
|
||||||
|
| note | text? | 备注(含「注意事项」区块) |
|
||||||
|
| biz_line | varchar(20) | 恒 ltci |
|
||||||
|
|
||||||
|
索引:`tenant_code`、`tenant_code+id_card_no`(唯一,身份证防重)。
|
||||||
|
|
||||||
|
**`elder_status_log` 待遇状态变更日志**(`@@map("sys_elder_status_log")`):
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| id | uuid | 主键 |
|
||||||
|
| elder_id | varchar(36) | 老人 |
|
||||||
|
| from_status / to_status | varchar(20) | 变更前后 |
|
||||||
|
| change_reason | varchar(200) | 变更原因(必填) |
|
||||||
|
| source | varchar(10) | manual |
|
||||||
|
| operator_id | varchar(36) | 操作人 |
|
||||||
|
| evidence_file | varchar(255)? | 佐证材料 |
|
||||||
|
| changed_at | datetime | 变更时间 |
|
||||||
|
|
||||||
|
## 4. 十态待遇状态机
|
||||||
|
|
||||||
|
`treat_status` 十态与语义(可否派单/计费/恢复,PRD §7.4):
|
||||||
|
|
||||||
|
| 状态 | 值 | 可否派单 | 可否计费 | 恢复 |
|
||||||
|
|---|---|:---:|:---:|---|
|
||||||
|
| 待建档 | pending_file | ❌ | ❌ | 建档完成→active |
|
||||||
|
| 待起付(等待期/垫付期) | waiting_period | ✅(垫付台账) | ❌ | 待遇生效→结转 active |
|
||||||
|
| 正常享受 | active | ✅ | ✅ | — |
|
||||||
|
| 住院暂停 | hosp_pause | ❌ | ❌ | 出院人工确认→active |
|
||||||
|
| 复评等待期 | review_waiting | ❌ | ❌ | 复评结论出 |
|
||||||
|
| 跨统筹区转移中 | transferring | ❌ | ❌ | 新参保地确认 |
|
||||||
|
| 死亡 | dead | ❌ | ❌ | 不可恢复 |
|
||||||
|
| 长期异地居住 | long_away | ❌ | ❌ | 回迁确认 |
|
||||||
|
| 待遇到期 | benefit_expired | ❌ | ❌ | 续评通过 |
|
||||||
|
| 已终止 | terminated | ❌ | ❌ | 不可恢复 |
|
||||||
|
|
||||||
|
- 变更接口 `/elder/status/change`:`to_status` + `change_reason`(必填) + 可选 `evidence_file`;写 `elder_status_log` + 审计。
|
||||||
|
- 建档初始状态:待遇有效期覆盖今天 → `active`;否则 → `waiting_period`。
|
||||||
|
- L1 硬锁(无有效待遇不可服务)在 C2 派单时消费;C1 只实现状态机数据层与变更语义。
|
||||||
|
|
||||||
|
## 5. 接口(A 组 + 上传)
|
||||||
|
|
||||||
|
| 接口 | 方法 | 权限 | 说明 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `/elder/list` | GET | elder:list | 状态/等级/姓名筛选;身份证服务端掩码 |
|
||||||
|
| `/elder/create` | POST | elder:create | 建档;18 位校验、防重、等级来自评估结论 |
|
||||||
|
| `/elder/detail` | GET | elder:detail | 详情;admin/qc 可看身份证明文+留痕 |
|
||||||
|
| `/elder/status/change` | POST | elder:status-change | 变更状态,change_reason 必填 |
|
||||||
|
| `/elder/status/log` | GET | elder:detail | 状态变更历史 |
|
||||||
|
| `/elder/assess-evidence/upload` | POST | elder:create | 上传评估结论副本到 MinIO,返回 file key |
|
||||||
|
|
||||||
|
统一响应沿用 `{code,message,data,hint}`(hint 为硬锁提示,本期多数接口不触发)。
|
||||||
|
|
||||||
|
## 6. 前端
|
||||||
|
|
||||||
|
- 服务对象列表页(`ltc/elder`):状态筛选(全部/正常享受/住院暂停/待建档/待遇到期)、列表(姓名/护理等级带「(最高级)」/状态/计划/下次服务/操作)。
|
||||||
|
- 建档表单:必填校验(身份证 18 位+校验位、出生日期自动带出、参保地默认取机构属地、待遇止>起)、身份证防重提示、参保核验(线下确认字段)、**等级区块=上传评估结论副本(必做,禁止手填等级)**。
|
||||||
|
- 档案详情:完整信息 + 状态变更(下拉十态 + 原因必填)+ 状态日志时间线 + 身份证明文查看(admin/qc,留痕)。
|
||||||
|
|
||||||
|
## 7. 横切
|
||||||
|
|
||||||
|
- **身份证防重**:同机构 `id_card_no` 唯一;命中已有档案提示「已有档案,是否查看」。
|
||||||
|
- **掩码在服务端**:列表返回 `5301**********1234`;前端不做掩码。
|
||||||
|
- **明文查看留痕**:`/elder/detail` 请求明文身份证时落审计(谁/何时/看了谁的)。
|
||||||
|
- **等级唯一来源**:`/elder/create` 不接受前端传 `assess_level/care_level`;等级由「上传评估结论副本」后由机构/质控录入(走 `assess_*` 字段),或由后续官方接口带出。禁止建档表单直接填等级。
|
||||||
|
- **id_card_no 存储层加密后置**:C1 存明文 + TODO(与 staff 一起走统一 security change);掩码 + 明文查看留痕 C1 做。
|
||||||
|
- **审计**:建档、改状态、明文查看身份证落审计(复用脚手架 audit-log)。
|
||||||
|
- **MinIO 配置**:`.env` 新增 `MINIO_ENDPOINT/MINIO_ACCESS_KEY/MINIO_SECRET_KEY/MINIO_BUCKET`(默认 carelink),S3 兼容,后续切 COS 只换配置。
|
||||||
|
|
||||||
|
## 8. 非目标(本期不做)
|
||||||
|
|
||||||
|
OCR 回填、Excel 批量导入、`elder_svc`、评估结论打水印、`id_card_no` 存储层加密、官方接口拉取评估结论(B 路径)、`need_assess` 采集交互。
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
schema: spec-driven
|
||||||
|
created: 2026-10-14
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
## Context
|
||||||
|
|
||||||
|
服务机构端 P0 在 sysmgr 脚手架(ec-nest + ec-admin)上落地。脚手架已提供:多租户过滤(tenant_code)、RBAC(resource 树 + 权限码)、审计日志、软删(deleted_at)、错误码注册表。C0 只做映射 + 建业务表 + 配角色/权限/菜单/错误码,不侵入脚手架。
|
||||||
|
|
||||||
|
## Goals / Non-Goals
|
||||||
|
|
||||||
|
**Goals:**
|
||||||
|
|
||||||
|
- 定死机构=租户映射,业务表复用脚手架多租户过滤。
|
||||||
|
- `staff` 持 `user_id` 关联账号,不动 `sys_user`。
|
||||||
|
- C0 建 9 张业务表 + 复用 `sys_user`。
|
||||||
|
- 5 业务角色 + 权限码 + 菜单 + 错误码 + 审计落地。
|
||||||
|
|
||||||
|
**Non-Goals:**
|
||||||
|
|
||||||
|
- 不实现 C1–C4 业务(待遇档案/派单/留痕/质控)。
|
||||||
|
- 不接真实 COS 上传(占位)。
|
||||||
|
- 不做护理员 APP、家属端。
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
1. **机构=租户,tenant_code 作全局键**(备选:扩展 sys_tenant → 弃,污染框架)。
|
||||||
|
2. **staff.user_id 关联 user,不动 sys_user**(备选:user.staff_id → 弃,动框架;user.ext_type/ext_id 多态 → 弃,YAGNI + 无外键保障)。
|
||||||
|
3. **业务角色用脚手架角色 + 权限码**(PRD 的 `user.role` 逗号分隔不照搬,用 user↔role 多对多实现多角色并集)。
|
||||||
|
4. **主键 UUID v7**(备选 varchar32 → 弃,跟随脚手架)。
|
||||||
|
5. **软删 deleted_at**(备选 is_deleted 布尔 → 弃,跟随脚手架)。
|
||||||
|
6. **菜单:脚手架菜单树冻结,业务归「长护服务」分组**。脚手架四个分组(工作台/权限管理/系统管理/系统监控)不修改、不扩展;新增顶级分组「长护服务」=服务对象/排班派单/工单留痕/质控中心/文书档案 + 二级组「服务机构设置」(机构信息/属地与目录/服务项目与配价/拍照分档配置/质控提醒配置/对接档位)。账号与权限复用脚手架「用户管理/角色管理」,不重复建。
|
||||||
|
|
||||||
|
## 数据模型(DDL 概览)
|
||||||
|
|
||||||
|
通用字段:`created_at`/`created_by`/`updated_at`/`updated_by`/`deleted_at`。
|
||||||
|
|
||||||
|
- **org**:org_code(PK, 与 tenant_code 同值)、org_name、org_type、credit_code、loc_code、loc_name、svc_source、license_no、address、contact_name、contact_phone、bed_count、sign_date
|
||||||
|
- **staff**:staff_id(PK uuid)、tenant_code、user_id(unique 可空 → user.id)、name、id_card_no(加密)、person_code、phone、job_type、work_type、entry_date、leave_date、employ_status、cert_type/cert_no/cert_level/cert_expire/cert_status、cert_verify_url、group_leader_id
|
||||||
|
- **svc_national**(L1):nat_id、nat_code(unique 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**:code、name、sort;**dict_photo_tier**:code、name、tier
|
||||||
|
- **loc_config**:loc_code(PK)、loc_name、svc_source、item_count_rule(预留)
|
||||||
|
|
||||||
|
索引:`staff.user_id` 唯一、`staff.tenant_code`、`svc_national.nat_code` 唯一、`svc_local.loc_code`、`svc_org.tenant_code`。
|
||||||
|
|
||||||
|
## Risks / Trade-offs
|
||||||
|
|
||||||
|
- [org 表与 sys_tenant 1:1 但分表] → 以 `code = tenant_code` 同值保证一致;创建机构时事务内同步建 tenant。
|
||||||
|
- [staff.user_id 无法用 DB 外键到不同库] → 同库内仍可建外键;业务层再校验 user 存在 + 唯一。
|
||||||
|
- [目录四层数据初始化量大] → seed 提供 L1 36 项 + 昆明 L2 45 项 + L3 映射;州市按需插入 loc_config + svc_local。
|
||||||
|
|
||||||
|
## Migration Plan
|
||||||
|
|
||||||
|
- 新增 Prisma 迁移建 9 张表;seed 初始化目录(L1/L2/L3)、默认角色与权限码;不迁移旧数据(新库)。
|
||||||
|
- 回滚:删除本次迁移即可(纯新增,无破坏性改动)。
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
## Why
|
||||||
|
|
||||||
|
投云长护险「服务机构端」P0 要在 sysmgr 脚手架(ec-nest + ec-admin)上落地四块业务(待遇档案/派单工单/履约留痕/质控闸门)。C0 是地基:先定死「机构=租户」映射、账号/人员/角色、数据模型基线、审计与错误码,否则 C1–C4 各自为政、必然返工。
|
||||||
|
|
||||||
|
## What Changes
|
||||||
|
|
||||||
|
- 新增业务数据模型基线:`org`、`staff`、服务目录四层(`svc_national/svc_local/svc_mapping/svc_org`)、业务字典(`dict_abnormal_type/dict_photo_tier`)、属地配置 `loc_config`。
|
||||||
|
- 定死机构=租户映射:机构唯一标识 = 脚手架 `tenant_code`;`org` 独立业务表,不扩展 `sys_tenant`。
|
||||||
|
- 定死账号/人员分离:`staff`(业务新表)持 `user_id` 外键关联脚手架 `sys_user`(**不动 sys_user**);业务角色 nurse/leader/qc/admin/director 建成脚手架角色。
|
||||||
|
- 复用脚手架多租户过滤、RBAC、审计、错误码机制,落地服务机构端权限码与业务错误码。
|
||||||
|
- 后台新增业务菜单骨架(服务对象/排班派单/工单留痕/质控中心/文书/系统设置业务配置)。
|
||||||
|
- 照片存储(腾讯云 COS)本期只占位,不接真实上传。
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
### New Capabilities
|
||||||
|
|
||||||
|
- `shared/data-model`: 服务机构端 C0 数据模型字段字典(org/staff/目录四层/字典/loc_config + 枚举 + 多租户键约定)
|
||||||
|
- `shared/api-contract`: 统一响应(含 hint)+ 业务错误码(1001–4001)+ C0 接口契约
|
||||||
|
- `backend/org`: 机构(org)与人员(staff)域——机构=租户、staff.user_id 关联账号、角色权限、审计
|
||||||
|
- `backend/catalog`: 服务目录四层(L1–L4)+ 属地配置(loc_config)+ 业务字典
|
||||||
|
- `frontend/ad/svc-org-base`: 机构管理后台基础骨架——登录落地、业务菜单、权限控制、属地提示
|
||||||
|
|
||||||
|
### Modified Capabilities
|
||||||
|
|
||||||
|
(无)
|
||||||
|
|
||||||
|
## Impact
|
||||||
|
|
||||||
|
- 后端 ec-nest:新增 org/staff/catalog 业务模块(纯新增,不侵入脚手架)。
|
||||||
|
- 前端 ec-admin:新增业务菜单与页面骨架(纯新增)。
|
||||||
|
- 数据:新增 9 张业务表(迁移);复用脚手架 `sys_user`(不加列)。
|
||||||
|
- 部署:SaaS 多租户,每机构 = 一个 tenant。
|
||||||
|
- 契约锚点:`shared/data-model`、`shared/api-contract` 先行。
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
## Purpose
|
||||||
|
|
||||||
|
定义服务机构端服务目录四层(L1–L4)与属地配置、业务字典的后端行为——按属地加载目录、机构不可改目录、国家新增项显式提示。
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 属地目录加载
|
||||||
|
后端 MUST 按机构 `loc_code` 加载对应目录:昆明加载本地 45 项,新建制州市加载国家 36 项。
|
||||||
|
|
||||||
|
#### Scenario: 昆明机构加载
|
||||||
|
- **WHEN** 昆明机构请求目录
|
||||||
|
- **THEN** 返回本地 45 项(系统内置 L3 映射)
|
||||||
|
|
||||||
|
### Requirement: 机构不可改目录
|
||||||
|
机构 MUST 只能对 L4 勾选 + 配价(改 `is_enabled`/`price`),不可新增/修改 L1–L3 目录。
|
||||||
|
|
||||||
|
#### Scenario: 机构改目录被拒
|
||||||
|
- **WHEN** 机构尝试新增或修改目录项
|
||||||
|
- **THEN** 返回 403
|
||||||
|
|
||||||
|
### Requirement: 国家新增项显式提示
|
||||||
|
国家目录有而昆明本地目录没有的 5 项 MUST 在昆明机构勾选界面显式列出并标注「过渡期新增·建议纳入」。
|
||||||
|
|
||||||
|
#### Scenario: 昆明机构看到新增项
|
||||||
|
- **WHEN** 昆明机构请求可勾选项
|
||||||
|
- **THEN** 返回国家新增 5 项并标记 is_new_national
|
||||||
|
|
||||||
|
### Requirement: 属地配置驱动
|
||||||
|
新增州市 MUST 仅需插入 `loc_config` + `svc_local` 数据即生效,不改代码。
|
||||||
|
|
||||||
|
#### Scenario: 新增州市零代码
|
||||||
|
- **WHEN** 插入某新州市的 loc_config 与 svc_local
|
||||||
|
- **THEN** 该州市机构登录即加载新目录,无需发版
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
## Purpose
|
||||||
|
|
||||||
|
定义服务机构端机构(org)与人员(staff)域的后端行为——机构=租户映射、staff.user_id 关联账号、角色权限与审计。
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 机构与租户绑定
|
||||||
|
后端 MUST 以脚手架 `tenant_code` 作为机构唯一标识,业务表统一带 `tenant_code` 并继承脚手架多租户过滤。
|
||||||
|
|
||||||
|
#### Scenario: 跨机构数据隔离
|
||||||
|
- **WHEN** A 机构账号查询业务数据
|
||||||
|
- **THEN** 只返回本机构(本 tenant)数据,访问他机构返回 4001
|
||||||
|
|
||||||
|
### Requirement: 人员账号关联
|
||||||
|
`staff` 实体 MUST 持 `user_id` 关联脚手架 user;护理员/组长账号通过 `staff.user_id` 定位本人人员档案;院长/质控/管理员账号无 staff 记录。
|
||||||
|
|
||||||
|
#### Scenario: 护理员定位人员
|
||||||
|
- **WHEN** 护理员登录后请求本人信息
|
||||||
|
- **THEN** 系统按 `staff.user_id = 当前 user.id` 返回唯一 staff 记录
|
||||||
|
|
||||||
|
### Requirement: 角色与权限
|
||||||
|
业务角色 nurse/leader/qc/admin/director MUST 建成脚手架角色并按权限码授权;权限取角色并集;仅持 director 的账号写接口 MUST 返回 403。
|
||||||
|
|
||||||
|
#### Scenario: 仅院长写接口被拒
|
||||||
|
- **WHEN** 仅持 director 的账号调用写接口
|
||||||
|
- **THEN** 返回 403;若同时持 qc/admin,则按并集放行
|
||||||
|
|
||||||
|
### Requirement: 完整审计
|
||||||
|
建档、改状态、派单、放行、导入、导出、明文查看身份证等业务动作 MUST 全量落审计日志(谁/何时/动作/对象/前后值)。
|
||||||
|
|
||||||
|
#### Scenario: 改状态落审计
|
||||||
|
- **WHEN** 质控员变更老人待遇状态
|
||||||
|
- **THEN** 写入一条审计日志,含操作人、时间、前后值
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
## Purpose
|
||||||
|
|
||||||
|
定义机构管理后台基础骨架——登录后落地、业务菜单、权限控制与属地提示,作为服务机构端后台页面的容器。
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 登录落地
|
||||||
|
机构后台登录后 MUST 直接落地「服务对象」列表页,不做看板首页。
|
||||||
|
|
||||||
|
#### Scenario: 登录落地
|
||||||
|
- **WHEN** 机构账号登录成功
|
||||||
|
- **THEN** 进入服务对象列表页
|
||||||
|
|
||||||
|
### Requirement: 业务菜单
|
||||||
|
后台 MUST 保留脚手架菜单(工作台/权限管理/系统管理/系统监控)且不修改、不扩展,并新增顶级分组「长护服务」承载业务菜单:服务对象/排班派单/工单留痕/质控中心/文书档案,以及二级分组「服务机构设置」(机构信息/属地与目录/服务项目与配价/拍照分档配置/质控提醒配置/对接档位)。账号与权限复用脚手架「用户管理/角色管理」,不重复建。
|
||||||
|
|
||||||
|
#### Scenario: 菜单可见
|
||||||
|
- **WHEN** 登录后台
|
||||||
|
- **THEN** 脚手架菜单与「长护服务」业务菜单同时可见,按角色控制可见性;「长护服务」下含 5 个直接菜单项 + 「服务机构设置」二级组
|
||||||
|
|
||||||
|
### Requirement: 属地提示
|
||||||
|
登录页 MUST 显示机构属地与加载的目录(如「属地:昆明市 · 目录:昆明市 45 项」)。
|
||||||
|
|
||||||
|
#### Scenario: 属地可见
|
||||||
|
- **WHEN** 打开登录页
|
||||||
|
- **THEN** 显示机构属地与目录信息
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
## Purpose
|
||||||
|
|
||||||
|
定义服务机构端 C0 的统一响应契约与业务错误码,作为前后端接口交互的唯一约定。
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 统一响应结构
|
||||||
|
所有接口 MUST 返回统一响应结构 `{code, message, data, hint}`;`code=0` 成功,非 0 失败;硬锁拒绝时 `hint` MUST 提供用户可读的「怎么解」提示。
|
||||||
|
|
||||||
|
#### Scenario: 硬锁拒绝带 hint
|
||||||
|
- **WHEN** 接口因硬锁拒绝(如无有效待遇)
|
||||||
|
- **THEN** 返回非 0 code 与可读 message,且 `hint` 说明「先做什么才能做」
|
||||||
|
|
||||||
|
### Requirement: 业务错误码
|
||||||
|
业务错误码 MUST 落地为 5 位码 [域码2][序3],并覆盖:1001 无有效待遇、1002 无有效计划、1003 无有效工单、1004 留痕不完整、1005 未质控、1006 资质不匹配(提示级)、2001 时间冲突(硬拒)、2002 项数不满足(提示)、3001 必拍未拍(硬拒)、3002 定位失败(非错误)、3003 扑空登记、3004 垫付不计费、4001 越权或自审自放行。
|
||||||
|
|
||||||
|
#### Scenario: 资质不匹配提示级
|
||||||
|
- **WHEN** 派单时护理员资质不匹配
|
||||||
|
- **THEN** 返回 1006,前端仅提示、允许继续(本期不拦截,二期改硬拒)
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
## Purpose
|
||||||
|
|
||||||
|
定义服务机构端 C0 的数据模型字段字典——机构/人员/服务目录四层/字典/属地配置的实体、字段、枚举与多租户键约定,作为前后端字段命名的唯一锚点。
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 多租户键约定
|
||||||
|
服务机构端所有业务实体 MUST 携带 `tenant_code` 字段作为多租户隔离键,其值为机构唯一标识(= 脚手架租户 code)。
|
||||||
|
|
||||||
|
#### Scenario: 跨机构隔离
|
||||||
|
- **WHEN** 业务表写入一条记录
|
||||||
|
- **THEN** 该记录 MUST 带 `tenant_code`,且读操作按当前租户自动过滤,不返回其他租户数据
|
||||||
|
|
||||||
|
### Requirement: 机构实体 org
|
||||||
|
`org` 表 MUST 存在,主键为机构 code(与 `tenant_code` 同值),承载机构业务字段:org_name、org_type、credit_code、loc_code、loc_name、svc_source、license_no、address、contact_name、contact_phone、bed_count、sign_date。
|
||||||
|
|
||||||
|
#### Scenario: 机构唯一标识
|
||||||
|
- **WHEN** 创建一个机构
|
||||||
|
- **THEN** 其 code 与脚手架的 tenant code 一致且全局唯一
|
||||||
|
|
||||||
|
### Requirement: 人员实体 staff
|
||||||
|
`staff` 表 MUST 存在,承载人员/资质字段(name、id_card_no、phone、job_type、work_type、employ_status、cert_type/cert_no/cert_level/cert_expire/cert_status、group_leader_id),并 MUST 带 `user_id` 关联脚手架 `user.id`(可空、1:1)。
|
||||||
|
|
||||||
|
#### Scenario: 账号关联人员
|
||||||
|
- **WHEN** 护理员登录并定位本人 staff
|
||||||
|
- **THEN** 通过 `staff.user_id = user.id` 唯一定位到一条 staff 记录
|
||||||
|
|
||||||
|
### Requirement: 软删约定
|
||||||
|
服务机构端业务实体 MUST 采用脚手架 `deleted_at`(时间戳)软删,不物理删除。
|
||||||
|
|
||||||
|
#### Scenario: 软删保留
|
||||||
|
- **WHEN** 删除一条业务记录
|
||||||
|
- **THEN** 记录置 `deleted_at`,读操作默认排除,物理数据保留
|
||||||
|
|
||||||
|
### Requirement: 主键约定
|
||||||
|
业务实体主键 MUST 采用脚手架 UUID v7;业务码(机构 code、项目代码)MUST 建唯一索引。
|
||||||
|
|
||||||
|
#### Scenario: 主键唯一
|
||||||
|
- **WHEN** 新增业务记录
|
||||||
|
- **THEN** 生成 UUID v7 主键,业务码唯一索引防重复
|
||||||
|
|
||||||
|
### Requirement: 目录四层实体
|
||||||
|
`svc_national`(L1)、`svc_local`(L2)、`svc_mapping`(L3)、`svc_org`(L4) 四表 MUST 存在,字段按 PRD §7.2 定义;L3 映射表不提供机构侧接口。
|
||||||
|
|
||||||
|
#### Scenario: 目录分层
|
||||||
|
- **WHEN** 加载某机构属地目录
|
||||||
|
- **THEN** 按 L1/L2 取目录、L4 取机构勾选与配价、L3 仅内部映射
|
||||||
|
|
||||||
|
### Requirement: 字典与属地配置实体
|
||||||
|
`dict_abnormal_type`、`dict_photo_tier`、`loc_config` 三表 MUST 存在,承载异常分类、拍照分档、属地目录来源与项数规则配置。
|
||||||
|
|
||||||
|
#### Scenario: 属地配置驱动目录
|
||||||
|
- **WHEN** 新增一个州市
|
||||||
|
- **THEN** 插入一条 `loc_config` + 一批 `svc_local` 即生效,无需改代码
|
||||||
36
openspec/changes/archive/2026-10-14-svc-org-c0-base/tasks.md
Normal file
36
openspec/changes/archive/2026-10-14-svc-org-c0-base/tasks.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Tasks — svc-org-c0-base
|
||||||
|
|
||||||
|
## 1. 契约先行(shared)
|
||||||
|
|
||||||
|
- [ ] 1.1 定稿 `shared/data-model`:org/staff/目录四层/字典/loc_config 实体 + 枚举 + 多租户键(本 change 的 spec 已列,补全枚举值)。
|
||||||
|
- [ ] 1.2 定稿 `shared/api-contract`:统一响应(含 hint)+ 错误码 1001–4001 + C0 接口清单。
|
||||||
|
|
||||||
|
## 2. 后端数据层(ec-nest)
|
||||||
|
|
||||||
|
- [ ] 2.1 `schema.prisma` 新增 9 个业务模型(org/staff/svc_national/svc_local/svc_mapping/svc_org/dict_abnormal_type/dict_photo_tier/loc_config),staff.user_id 关联 User。
|
||||||
|
- [ ] 2.2 `prisma migrate dev --name c0_base` + `prisma generate`。
|
||||||
|
- [ ] 2.3 seed:L1 36 项、昆明 L2 45 项、L3 映射、默认角色 + 权限码 + 示例机构。
|
||||||
|
|
||||||
|
## 3. 后端业务域(ec-nest,纯新增)
|
||||||
|
|
||||||
|
- [ ] 3.1 权限码注册:`permissions.ts` 加 elder/plan/order/record/abnormal/qc/svc-org/staff/export 权限码。
|
||||||
|
- [ ] 3.2 `org` 模块(controller/service/dto):机构信息读写、机构=租户创建。
|
||||||
|
- [ ] 3.3 `staff` 模块:人员 CRUD、user_id 关联账号、group_leader_id 归属。
|
||||||
|
- [ ] 3.4 `catalog` 模块:属地目录加载(按 loc_code)、机构项目库勾选/配价、国家新增项、字典与 loc_config。
|
||||||
|
- [ ] 3.5 统一响应补 `hint` 字段 + 业务错误码注册(error-codes.ts)。
|
||||||
|
- [ ] 3.6 审计:org/staff/catalog 写操作挂 `@AuditLog`。
|
||||||
|
|
||||||
|
## 4. 前端后台(ec-admin,纯新增)
|
||||||
|
|
||||||
|
- [ ] 4.1 业务菜单骨架:服务对象/排班派单/工单留痕/质控中心/文书档案 + 系统设置业务配置项。
|
||||||
|
- [ ] 4.2 登录后落地服务对象列表页(占位页)。
|
||||||
|
- [ ] 4.3 登录页属地提示(机构属地 + 目录)。
|
||||||
|
- [ ] 4.4 角色权限控制(按权限码隐藏菜单/按钮)。
|
||||||
|
|
||||||
|
## 5. 验证
|
||||||
|
|
||||||
|
- [ ] 5.1 跨机构隔离:A 机构账号查不到 B 机构数据(4001)。
|
||||||
|
- [ ] 5.2 角色并集 + 仅 director 写接口 403。
|
||||||
|
- [ ] 5.3 昆明机构加载 45 项 + 国家新增 5 项显式提示。
|
||||||
|
- [ ] 5.4 审计动作全量落日志。
|
||||||
|
- [ ] 5.5 前端 Mock 验收通过(前端先于后端按 api-contract 联调)。
|
||||||
2
openspec/changes/svc-org-c1-elder/.openspec.yaml
Normal file
2
openspec/changes/svc-org-c1-elder/.openspec.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
schema: spec-driven
|
||||||
|
created: 2026-10-14
|
||||||
54
openspec/changes/svc-org-c1-elder/design.md
Normal file
54
openspec/changes/svc-org-c1-elder/design.md
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
## Context
|
||||||
|
|
||||||
|
C0 已落地机构=租户、RBAC、目录四层、菜单、多租户过滤(PrismaService 注入 tenantCode)。C1 新增待遇档案域(elder + elder_status_log),纯新增、不侵入脚手架。设计背景见 `docs/superpowers/specs/2026-10-14-服务机构端-C1待遇档案-design.md`。
|
||||||
|
|
||||||
|
## Goals / Non-Goals
|
||||||
|
|
||||||
|
**Goals:**
|
||||||
|
- elder 建档(身份证校验/防重、参保核验留痕、评估结论承载)。
|
||||||
|
- 十态待遇状态机 + elder_status_log 变更留痕。
|
||||||
|
- 评估结论副本上传(MinIO)+ 等级唯一来源约束。
|
||||||
|
- 身份证服务端掩码 + 明文查看留痕。
|
||||||
|
|
||||||
|
**Non-Goals:**
|
||||||
|
- OCR、Excel 批量导入、elder_svc、评估结论打水印、id_card_no 存储层加密、官方接口拉评估结论、need_assess 采集交互。
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
1. **文件存储用 MinIO**(`http://localhost:9000`,bucket `carelink`,minioadmin/minioadmin)。抽象 `StorageService.upload(buffer, key)` 接口,内部用 `minio` 官方包;后续切腾讯云 COS 只换实现与配置。
|
||||||
|
2. **等级唯一来源=「评估结论副本 + 评估结论字段」绑定**:建档时 `assess_level/care_level/assess_date/assess_org` 与 `assess_evidence_file` 绑定——有副本才能填等级,填等级必须有副本。前端不提供「直接填等级」的自由入口,等级区块 = 上传副本 + 录入评估结论字段。
|
||||||
|
3. **身份证掩码在服务端**:`maskIdCard()` 返回 `前4 + 10个* + 后4`(18 位)/`前3+*+后4`(15 位兜底)。列表用掩码;详情仅 admin/qc 可明文 + 落审计。
|
||||||
|
4. **id_card_no 存储层加密后置**(与 staff 统一走 security change);C1 明文存 + TODO。掩码/查看留痕 C1 做。
|
||||||
|
5. **建档初始状态**:`benefit_start ≤ today ≤ benefit_end` → `active`;否则 `waiting_period`。
|
||||||
|
|
||||||
|
## 数据模型(DDL 概览)
|
||||||
|
|
||||||
|
通用字段 `created_at/by`、`updated_at`、`deleted_at`;主键 UUID v7;`@@map` snake_case;软删。
|
||||||
|
|
||||||
|
- **elder**(`sys_elder`):id、tenant_code、loc_code、prev_loc_code、transfer_confirm_at、name、gender(char1)、birth_date、id_card_no(varchar255)、phone、address、guardian_name、guardian_phone、insur_no、insur_type、insur_years、insur_verify_status、insur_verify_date、assess_level、care_level、assess_date、assess_org、assess_evidence_file、benefit_start、benefit_end、treat_status、status_source、status_change_date、hosp_start、hosp_end、photo_tier_override(json)、need_assess(json)、note(text)、biz_line。唯一索引 `(tenant_code, id_card_no)`。
|
||||||
|
- **elder_status_log**(`sys_elder_status_log`):id、elder_id、from_status、to_status、change_reason(必填)、source、operator_id、evidence_file、changed_at。
|
||||||
|
|
||||||
|
PrismaService:`elder`/`elder_status_log` 均为租户级模型(带 tenantCode,自动过滤);`elder` 加入 SOFT_DELETE。
|
||||||
|
|
||||||
|
## 接口(`@Controller('elder')`)
|
||||||
|
|
||||||
|
| 方法/路径 | 权限 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| GET `/elder` | elder:list | 分页 + 状态/等级/姓名筛选;身份证掩码 |
|
||||||
|
| POST `/elder` | elder:create | 建档(18 位校验、防重、等级与副本绑定) |
|
||||||
|
| GET `/elder/:id` | elder:detail | 详情;admin/qc 明文 + 审计 |
|
||||||
|
| POST `/elder/:id/status` | elder:status-change | 变更状态,change_reason 必填,写日志 |
|
||||||
|
| GET `/elder/:id/status/log` | elder:detail | 状态日志 |
|
||||||
|
| POST `/elder/assess-evidence` | elder:create | 上传副本到 MinIO,返回 key |
|
||||||
|
|
||||||
|
权限码 `elder:list/create/detail/status-change` 已在 C0 permissions.ts 预留;APIS 数组登记 6 条资源(parent=elder 菜单)。
|
||||||
|
|
||||||
|
## Risks / Trade-offs
|
||||||
|
|
||||||
|
- [评估结论副本是合规证据,本地 MinIO 单点] → 副本 key 存 elder 表、MinIO 数据卷已挂本机;生产切 COS(异地冗余)。
|
||||||
|
- [等级唯一来源依赖「有副本」约束,机构可能绕过] → 后端强制校验 assess_evidence_file 与 assess_level 绑定,前端不提供自由填等级入口。
|
||||||
|
- [明文查看留痕依赖审计拦截器] → `/elder/:id` 明文分支显式写 audit-log。
|
||||||
|
|
||||||
|
## Migration Plan
|
||||||
|
|
||||||
|
新增迁移建 `sys_elder` + `sys_elder_status_log`(utf8mb4_general_ci,迁移 SQL 手改 collation)。回滚=删除迁移。
|
||||||
30
openspec/changes/svc-org-c1-elder/proposal.md
Normal file
30
openspec/changes/svc-org-c1-elder/proposal.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
## Why
|
||||||
|
|
||||||
|
C0 已落地服务机构端基础骨架(机构=租户、RBAC、目录、菜单)。C1 交付 PRD 的第一块业务「待遇档案」:老人档案建档、十态待遇状态机与变更留痕、评估结论副本上传——为 C2 派单(消费 L1 硬锁)与 C3 留痕提供老人数据与状态基础。
|
||||||
|
|
||||||
|
## What Changes
|
||||||
|
|
||||||
|
- 新增 `elder` 老人档案表 + `elder_status_log` 状态变更日志表(含评估结论副本字段)。
|
||||||
|
- 十态待遇状态机(pending_file/waiting_period/active/hosp_pause/review_waiting/transferring/dead/long_away/benefit_expired/terminated)+ 变更接口(change_reason 必填、留痕)。
|
||||||
|
- 评估结论副本上传到 MinIO(bucket carelink);**等级唯一来源=评估结论,禁止建档人自行填写**。
|
||||||
|
- 身份证服务端掩码 + 明文查看留痕;同机构身份证防重。
|
||||||
|
- 前端「服务对象」列表/建档/详情/状态变更页。
|
||||||
|
|
||||||
|
## Capabilities
|
||||||
|
|
||||||
|
### New Capabilities
|
||||||
|
|
||||||
|
- `backend/elder`: 待遇档案后端域——老人档案 CRUD、十态状态机、评估结论上传、身份证防重与掩码。
|
||||||
|
- `frontend/ad/elder`: 服务对象页面——列表/建档表单/详情/状态变更。
|
||||||
|
|
||||||
|
### Modified Capabilities
|
||||||
|
|
||||||
|
- `shared/data-model`: 新增 `elder` 老人档案实体、`elder_status_log` 状态日志实体。
|
||||||
|
- `shared/api-contract`: 新增 elder 接口(list/create/detail/status-change/status-log/assess-evidence-upload)。
|
||||||
|
|
||||||
|
## Impact
|
||||||
|
|
||||||
|
- 后端 ec-nest:新增 `elder` 模块 + MinIO 存储模块(纯新增,不侵入脚手架)。
|
||||||
|
- 前端 ec-admin:服务对象页面 + api。
|
||||||
|
- 数据:新增 2 张表(迁移,utf8mb4_general_ci)。
|
||||||
|
- 依赖:MinIO(本机 Docker,bucket carelink)。
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
## Purpose
|
||||||
|
|
||||||
|
定义服务机构端待遇档案(elder)域的后端行为——老人建档、十态状态机、评估结论承载、身份证防重与掩码。
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 老人建档
|
||||||
|
`POST /elder/create` MUST 校验身份证 18 位+校验位、出生日期由身份证带出、同机构 id_card_no 唯一、待遇止 > 起;建档后按待遇有效期置初始状态(active 或 waiting_period)。
|
||||||
|
|
||||||
|
#### Scenario: 身份证防重
|
||||||
|
- **WHEN** 同机构重复录入同一 id_card_no
|
||||||
|
- **THEN** 提示「已有档案」,不创建重复档案
|
||||||
|
|
||||||
|
### Requirement: 等级唯一来源
|
||||||
|
建档 MUST 不接受前端传入 assess_level/care_level;等级只能来自评估结论(assess_org/assess_date + 上传的评估结论副本)。
|
||||||
|
|
||||||
|
#### Scenario: 禁止手填等级
|
||||||
|
- **WHEN** 建档请求携带 assess_level
|
||||||
|
- **THEN** 忽略该字段,等级由评估结论字段决定
|
||||||
|
|
||||||
|
### Requirement: 十态状态机
|
||||||
|
`elder.treat_status` MUST 支持十态;状态变更 MUST 写 elder_status_log 且 change_reason 必填。
|
||||||
|
|
||||||
|
#### Scenario: 状态变更留痕
|
||||||
|
- **WHEN** 变更状态缺 change_reason
|
||||||
|
- **THEN** 拒绝并返回校验错误
|
||||||
|
|
||||||
|
### Requirement: 评估结论副本上传
|
||||||
|
`POST /elder/assess-evidence/upload` MUST 上传文件到 MinIO 并返回 file key。
|
||||||
|
|
||||||
|
#### Scenario: 上传成功
|
||||||
|
- **WHEN** 上传评估结论副本
|
||||||
|
- **THEN** 返回 file key,供建档引用
|
||||||
|
|
||||||
|
### Requirement: 身份证明文查看留痕
|
||||||
|
仅 admin/qc 可查看身份证明文,且每次明文查看 MUST 落审计。
|
||||||
|
|
||||||
|
#### Scenario: 明文查看留痕
|
||||||
|
- **WHEN** qc 查看老人身份证明文
|
||||||
|
- **THEN** 写一条审计日志
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
## Purpose
|
||||||
|
|
||||||
|
定义服务机构端「服务对象」页面——老人档案列表、建档表单、详情与状态变更的交互。
|
||||||
|
|
||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 服务对象列表
|
||||||
|
列表 MUST 显示姓名/护理等级(带「(最高级)」)/状态/计划/下次服务,支持状态筛选。
|
||||||
|
|
||||||
|
#### Scenario: 状态筛选
|
||||||
|
- **WHEN** 按「住院暂停」筛选
|
||||||
|
- **THEN** 只显示该状态的老人
|
||||||
|
|
||||||
|
### Requirement: 建档表单
|
||||||
|
建档表单 MUST 含身份证校验、出生日期自动带出、参保地默认取机构属地、参保核验字段、评估结论副本上传(禁止手填等级)。
|
||||||
|
|
||||||
|
#### Scenario: 等级不可手填
|
||||||
|
- **WHEN** 打开建档表单
|
||||||
|
- **THEN** 等级字段不可编辑,只能通过上传评估结论副本带出
|
||||||
|
|
||||||
|
### Requirement: 状态变更
|
||||||
|
详情页 MUST 支持十态状态变更(原因必填)+ 状态日志时间线。
|
||||||
|
|
||||||
|
#### Scenario: 变更需原因
|
||||||
|
- **WHEN** 变更状态未填原因
|
||||||
|
- **THEN** 不允许提交
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 老人档案接口
|
||||||
|
`/elder/list`、`/elder/create`、`/elder/detail`、`/elder/status/change`、`/elder/status/log`、`/elder/assess-evidence/upload` MUST 存在,遵循统一响应 `{code,message,data,hint}`。
|
||||||
|
|
||||||
|
#### Scenario: 状态变更必填原因
|
||||||
|
- **WHEN** 调用 `/elder/status/change` 且缺 change_reason
|
||||||
|
- **THEN** 返回校验错误,拒绝变更
|
||||||
|
|
||||||
|
### Requirement: 身份证服务端掩码
|
||||||
|
`/elder/list` MUST 返回掩码后的身份证(如 `5301**********1234`);明文仅在 `/elder/detail` 且 admin/qc 授权时返回,并 MUST 落审计。
|
||||||
|
|
||||||
|
#### Scenario: 列表掩码
|
||||||
|
- **WHEN** 调用 `/elder/list`
|
||||||
|
- **THEN** id_card_no 返回掩码值,非明文
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: 老人档案实体 elder
|
||||||
|
`elder` 表 MUST 存在,承载老人档案字段(tenant_code、loc_code、name、gender、birth_date、id_card_no、insur_no/type、assess_level/care_level、assess_date/org、assess_evidence_file、benefit_start/end、treat_status、hosp_start/end、note 等),主键 UUID v7,`tenant_code` 多租户隔离,`tenant_code + id_card_no` 唯一。
|
||||||
|
|
||||||
|
#### Scenario: 老人档案归属机构
|
||||||
|
- **WHEN** 创建一条老人档案
|
||||||
|
- **THEN** 带 tenant_code,读操作按当前租户自动过滤
|
||||||
|
|
||||||
|
#### Scenario: 同机构身份证唯一
|
||||||
|
- **WHEN** 同机构重复录入同一 id_card_no
|
||||||
|
- **THEN** 命中唯一约束,提示「已有档案」
|
||||||
|
|
||||||
|
### Requirement: 待遇状态日志实体 elder_status_log
|
||||||
|
`elder_status_log` 表 MUST 存在;每次待遇状态变更 MUST 写一条日志,含 from_status/to_status/change_reason(必填)/operator_id/changed_at。
|
||||||
|
|
||||||
|
#### Scenario: 状态变更留痕
|
||||||
|
- **WHEN** 变更老人待遇状态
|
||||||
|
- **THEN** 写入一条 elder_status_log,change_reason 非空
|
||||||
41
openspec/changes/svc-org-c1-elder/tasks.md
Normal file
41
openspec/changes/svc-org-c1-elder/tasks.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# Tasks — svc-org-c1-elder
|
||||||
|
|
||||||
|
## 1. 数据层
|
||||||
|
|
||||||
|
- [ ] 1.1 `schema.prisma` 新增 `Elder`、`ElderStatusLog` 模型(含唯一索引 tenant_code+id_card_no)。
|
||||||
|
- [ ] 1.2 `prisma.service.ts`:`Elder` 加入 SOFT_DELETE。
|
||||||
|
- [ ] 1.3 迁移 `c1_elder`(utf8mb4_general_ci,手改 collation)+ `prisma generate`。
|
||||||
|
|
||||||
|
## 2. 权限码 + 错误码 + 资源
|
||||||
|
|
||||||
|
- [ ] 2.1 确认 `permissions.ts` 已有 `elder.list/create/detail/status-change`(C0 预留);补 `elder:*` 缺项。
|
||||||
|
- [ ] 2.2 `error-codes.ts` 补 elder 域错误码(域 43):ELDER_NOT_FOUND、ELDER_ID_CARD_EXISTS、ELDER_STATUS_REASON_REQUIRED、ELDER_LEVEL_REQUIRES_EVIDENCE。
|
||||||
|
- [ ] 2.3 `tenant-template.ts` APIS 登记 6 条 elder 接口资源(parent=elder 菜单)。
|
||||||
|
|
||||||
|
## 3. MinIO 存储模块
|
||||||
|
|
||||||
|
- [ ] 3.1 安装 `minio` 依赖;`.env` 加 `MINIO_ENDPOINT/ACCESS_KEY/SECRET_KEY/BUCKET`。
|
||||||
|
- [ ] 3.2 新建 `src/storage/storage.module.ts` + `storage.service.ts`(`upload(buffer, key)` + 生成 key),`app.module.ts` 注册。
|
||||||
|
|
||||||
|
## 4. elder 后端模块
|
||||||
|
|
||||||
|
- [ ] 4.1 新建 `src/elder/{module,controller,service,dto,service.spec}.ts`。
|
||||||
|
- [ ] 4.2 建档:18 位校验、出生日期带出、防重、等级与副本绑定、初始状态判定。
|
||||||
|
- [ ] 4.3 十态状态机 + `/elder/:id/status`(change_reason 必填 + 写日志)。
|
||||||
|
- [ ] 4.4 掩码(列表)+ 明文查看(detail,admin/qc + 审计)。
|
||||||
|
- [ ] 4.5 评估结论上传接口(调 StorageService)。
|
||||||
|
- [ ] 4.6 TDD:建档防重、等级绑定、状态变更留痕、掩码;`pnpm test -- elder` + `tsc --noEmit`。
|
||||||
|
|
||||||
|
## 5. 前端
|
||||||
|
|
||||||
|
- [ ] 5.1 `src/api/elder.ts`(类型 + list/create/detail/statusChange/statusLog/uploadEvidence)。
|
||||||
|
- [ ] 5.2 服务对象列表页(`ltc/elder`,替换占位):状态筛选 + 表格。
|
||||||
|
- [ ] 5.3 建档表单(JSON Schema + ty-form):身份证校验、评估结论上传、参保核验字段、等级只读。
|
||||||
|
- [ ] 5.4 档案详情 + 状态变更弹窗 + 状态日志时间线。
|
||||||
|
- [ ] 5.5 `pnpm type-check` 通过。
|
||||||
|
|
||||||
|
## 6. 验证
|
||||||
|
|
||||||
|
- [ ] 6.1 冒烟:登录 → 建档 → 列表掩码 → 详情明文(qc)→ 状态变更留痕 → 审计落库。
|
||||||
|
- [ ] 6.2 等级绑定校验:无副本不能填等级;有等级必须有副本。
|
||||||
|
- [ ] 6.3 身份证防重:同机构重复建档被拦。
|
||||||
34
openspec/specs/backend/catalog/spec.md
Normal file
34
openspec/specs/backend/catalog/spec.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# backend/catalog Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
定义服务机构端服务目录四层(L1–L4)与属地配置、业务字典的后端行为——按属地加载目录、机构不可改目录、国家新增项显式提示。
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: 属地目录加载
|
||||||
|
后端 MUST 按机构 `loc_code` 加载对应目录:昆明加载本地 45 项,新建制州市加载国家 36 项。
|
||||||
|
|
||||||
|
#### Scenario: 昆明机构加载
|
||||||
|
- **WHEN** 昆明机构请求目录
|
||||||
|
- **THEN** 返回本地 45 项(系统内置 L3 映射)
|
||||||
|
|
||||||
|
### Requirement: 机构不可改目录
|
||||||
|
机构 MUST 只能对 L4 勾选 + 配价(改 `is_enabled`/`price`),不可新增/修改 L1–L3 目录。
|
||||||
|
|
||||||
|
#### Scenario: 机构改目录被拒
|
||||||
|
- **WHEN** 机构尝试新增或修改目录项
|
||||||
|
- **THEN** 返回 403
|
||||||
|
|
||||||
|
### Requirement: 国家新增项显式提示
|
||||||
|
国家目录有而昆明本地目录没有的 5 项 MUST 在昆明机构勾选界面显式列出并标注「过渡期新增·建议纳入」。
|
||||||
|
|
||||||
|
#### Scenario: 昆明机构看到新增项
|
||||||
|
- **WHEN** 昆明机构请求可勾选项
|
||||||
|
- **THEN** 返回国家新增 5 项并标记 is_new_national
|
||||||
|
|
||||||
|
### Requirement: 属地配置驱动
|
||||||
|
新增州市 MUST 仅需插入 `loc_config` + `svc_local` 数据即生效,不改代码。
|
||||||
|
|
||||||
|
#### Scenario: 新增州市零代码
|
||||||
|
- **WHEN** 插入某新州市的 loc_config 与 svc_local
|
||||||
|
- **THEN** 该州市机构登录即加载新目录,无需发版
|
||||||
34
openspec/specs/backend/org/spec.md
Normal file
34
openspec/specs/backend/org/spec.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# backend/org Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
定义服务机构端机构(org)与人员(staff)域的后端行为——机构=租户映射、staff.user_id 关联账号、角色权限与审计。
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: 机构与租户绑定
|
||||||
|
后端 MUST 以脚手架 `tenant_code` 作为机构唯一标识,业务表统一带 `tenant_code` 并继承脚手架多租户过滤。
|
||||||
|
|
||||||
|
#### Scenario: 跨机构数据隔离
|
||||||
|
- **WHEN** A 机构账号查询业务数据
|
||||||
|
- **THEN** 只返回本机构(本 tenant)数据,访问他机构返回 4001
|
||||||
|
|
||||||
|
### Requirement: 人员账号关联
|
||||||
|
`staff` 实体 MUST 持 `user_id` 关联脚手架 user;护理员/组长账号通过 `staff.user_id` 定位本人人员档案;院长/质控/管理员账号无 staff 记录。
|
||||||
|
|
||||||
|
#### Scenario: 护理员定位人员
|
||||||
|
- **WHEN** 护理员登录后请求本人信息
|
||||||
|
- **THEN** 系统按 `staff.user_id = 当前 user.id` 返回唯一 staff 记录
|
||||||
|
|
||||||
|
### Requirement: 角色与权限
|
||||||
|
业务角色 nurse/leader/qc/admin/director MUST 建成脚手架角色并按权限码授权;权限取角色并集;仅持 director 的账号写接口 MUST 返回 403。
|
||||||
|
|
||||||
|
#### Scenario: 仅院长写接口被拒
|
||||||
|
- **WHEN** 仅持 director 的账号调用写接口
|
||||||
|
- **THEN** 返回 403;若同时持 qc/admin,则按并集放行
|
||||||
|
|
||||||
|
### Requirement: 完整审计
|
||||||
|
建档、改状态、派单、放行、导入、导出、明文查看身份证等业务动作 MUST 全量落审计日志(谁/何时/动作/对象/前后值)。
|
||||||
|
|
||||||
|
#### Scenario: 改状态落审计
|
||||||
|
- **WHEN** 质控员变更老人待遇状态
|
||||||
|
- **THEN** 写入一条审计日志,含操作人、时间、前后值
|
||||||
27
openspec/specs/frontend/ad/svc-org-base/spec.md
Normal file
27
openspec/specs/frontend/ad/svc-org-base/spec.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# frontend/ad/svc-org-base Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
定义机构管理后台基础骨架——登录后落地、业务菜单、权限控制与属地提示,作为服务机构端后台页面的容器。
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: 登录落地
|
||||||
|
机构后台登录后 MUST 直接落地「服务对象」列表页,不做看板首页。
|
||||||
|
|
||||||
|
#### Scenario: 登录落地
|
||||||
|
- **WHEN** 机构账号登录成功
|
||||||
|
- **THEN** 进入服务对象列表页
|
||||||
|
|
||||||
|
### Requirement: 业务菜单
|
||||||
|
后台 MUST 保留脚手架菜单(工作台/权限管理/系统管理/系统监控)且不修改、不扩展,并新增顶级分组「长护服务」承载业务菜单:服务对象/排班派单/工单留痕/质控中心/文书档案,以及二级分组「服务机构设置」(机构信息/属地与目录/服务项目与配价/拍照分档配置/质控提醒配置/对接档位)。账号与权限复用脚手架「用户管理/角色管理」,不重复建。
|
||||||
|
|
||||||
|
#### Scenario: 菜单可见
|
||||||
|
- **WHEN** 登录后台
|
||||||
|
- **THEN** 脚手架菜单与「长护服务」业务菜单同时可见,按角色控制可见性;「长护服务」下含 5 个直接菜单项 + 「服务机构设置」二级组
|
||||||
|
|
||||||
|
### Requirement: 属地提示
|
||||||
|
登录页 MUST 显示机构属地与加载的目录(如「属地:昆明市 · 目录:昆明市 45 项」)。
|
||||||
|
|
||||||
|
#### Scenario: 属地可见
|
||||||
|
- **WHEN** 打开登录页
|
||||||
|
- **THEN** 显示机构属地与目录信息
|
||||||
20
openspec/specs/shared/api-contract/spec.md
Normal file
20
openspec/specs/shared/api-contract/spec.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# shared/api-contract Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
定义服务机构端 C0 的统一响应契约与业务错误码,作为前后端接口交互的唯一约定。
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: 统一响应结构
|
||||||
|
所有接口 MUST 返回统一响应结构 `{code, message, data, hint}`;`code=0` 成功,非 0 失败;硬锁拒绝时 `hint` MUST 提供用户可读的「怎么解」提示。
|
||||||
|
|
||||||
|
#### Scenario: 硬锁拒绝带 hint
|
||||||
|
- **WHEN** 接口因硬锁拒绝(如无有效待遇)
|
||||||
|
- **THEN** 返回非 0 code 与可读 message,且 `hint` 说明「先做什么才能做」
|
||||||
|
|
||||||
|
### Requirement: 业务错误码
|
||||||
|
业务错误码 MUST 落地为 5 位码 [域码2][序3],并覆盖:1001 无有效待遇、1002 无有效计划、1003 无有效工单、1004 留痕不完整、1005 未质控、1006 资质不匹配(提示级)、2001 时间冲突(硬拒)、2002 项数不满足(提示)、3001 必拍未拍(硬拒)、3002 定位失败(非错误)、3003 扑空登记、3004 垫付不计费、4001 越权或自审自放行。
|
||||||
|
|
||||||
|
#### Scenario: 资质不匹配提示级
|
||||||
|
- **WHEN** 派单时护理员资质不匹配
|
||||||
|
- **THEN** 返回 1006,前端仅提示、允许继续(本期不拦截,二期改硬拒)
|
||||||
55
openspec/specs/shared/data-model/spec.md
Normal file
55
openspec/specs/shared/data-model/spec.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# shared/data-model Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
定义服务机构端 C0 的数据模型字段字典——机构/人员/服务目录四层/字典/属地配置的实体、字段、枚举与多租户键约定,作为前后端字段命名的唯一锚点。
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Requirement: 多租户键约定
|
||||||
|
服务机构端所有业务实体 MUST 携带 `tenant_code` 字段作为多租户隔离键,其值为机构唯一标识(= 脚手架租户 code)。
|
||||||
|
|
||||||
|
#### Scenario: 跨机构隔离
|
||||||
|
- **WHEN** 业务表写入一条记录
|
||||||
|
- **THEN** 该记录 MUST 带 `tenant_code`,且读操作按当前租户自动过滤,不返回其他租户数据
|
||||||
|
|
||||||
|
### Requirement: 机构实体 org
|
||||||
|
`org` 表 MUST 存在,主键为机构 code(与 `tenant_code` 同值),承载机构业务字段:org_name、org_type、credit_code、loc_code、loc_name、svc_source、license_no、address、contact_name、contact_phone、bed_count、sign_date。
|
||||||
|
|
||||||
|
#### Scenario: 机构唯一标识
|
||||||
|
- **WHEN** 创建一个机构
|
||||||
|
- **THEN** 其 code 与脚手架的 tenant code 一致且全局唯一
|
||||||
|
|
||||||
|
### Requirement: 人员实体 staff
|
||||||
|
`staff` 表 MUST 存在,承载人员/资质字段(name、id_card_no、phone、job_type、work_type、employ_status、cert_type/cert_no/cert_level/cert_expire/cert_status、group_leader_id),并 MUST 带 `user_id` 关联脚手架 `user.id`(可空、1:1)。
|
||||||
|
|
||||||
|
#### Scenario: 账号关联人员
|
||||||
|
- **WHEN** 护理员登录并定位本人 staff
|
||||||
|
- **THEN** 通过 `staff.user_id = user.id` 唯一定位到一条 staff 记录
|
||||||
|
|
||||||
|
### Requirement: 软删约定
|
||||||
|
服务机构端业务实体 MUST 采用脚手架 `deleted_at`(时间戳)软删,不物理删除。
|
||||||
|
|
||||||
|
#### Scenario: 软删保留
|
||||||
|
- **WHEN** 删除一条业务记录
|
||||||
|
- **THEN** 记录置 `deleted_at`,读操作默认排除,物理数据保留
|
||||||
|
|
||||||
|
### Requirement: 主键约定
|
||||||
|
业务实体主键 MUST 采用脚手架 UUID v7;业务码(机构 code、项目代码)MUST 建唯一索引。
|
||||||
|
|
||||||
|
#### Scenario: 主键唯一
|
||||||
|
- **WHEN** 新增业务记录
|
||||||
|
- **THEN** 生成 UUID v7 主键,业务码唯一索引防重复
|
||||||
|
|
||||||
|
### Requirement: 目录四层实体
|
||||||
|
`svc_national`(L1)、`svc_local`(L2)、`svc_mapping`(L3)、`svc_org`(L4) 四表 MUST 存在,字段按 PRD §7.2 定义;L3 映射表不提供机构侧接口。
|
||||||
|
|
||||||
|
#### Scenario: 目录分层
|
||||||
|
- **WHEN** 加载某机构属地目录
|
||||||
|
- **THEN** 按 L1/L2 取目录、L4 取机构勾选与配价、L3 仅内部映射
|
||||||
|
|
||||||
|
### Requirement: 字典与属地配置实体
|
||||||
|
`dict_abnormal_type`、`dict_photo_tier`、`loc_config` 三表 MUST 存在,承载异常分类、拍照分档、属地目录来源与项数规则配置。
|
||||||
|
|
||||||
|
#### Scenario: 属地配置驱动目录
|
||||||
|
- **WHEN** 新增一个州市
|
||||||
|
- **THEN** 插入一条 `loc_config` + 一批 `svc_local` 即生效,无需改代码
|
||||||
Loading…
x
Reference in New Issue
Block a user