65 Commits

Author SHA1 Message Date
liuyun
66da809a2e fix(c2): 属地项数提示级 + assign L2 放松 + reassign 守卫 + 时区标准化
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 23:41:20 +08:00
liuyun
8791ca494b fix(c2): 个人项目库允许保存空库(清空)
- R12: PutElderSvcDto.svcIds 移除 @ArrayNotEmpty,空数组=清空
- 补测 put 空 svcIds 清空项目库

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 23:07:02 +08:00
liuyun
00c8fa4d4c feat(c2): 工单按日列表接口(排班日视图 R11)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 23:06:03 +08:00
liuyun
9c4fd6f4ca feat(c2): 工单模块(派单/调单/冲突/批量推荐)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 22:42:15 +08:00
liuyun
161a1253ee fix(c2): plan create 置 active + confirm 不改状态 + change 校验同老人
- R7: create 置 planStatus=active(spec 权威);confirm 仅写确认字段不改状态
- R8: change 校验 oldPlan.elderId === dto.elderId,不匹配拒绝

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 22:32:59 +08:00
liuyun
418dfb9dae feat(c2): 服务计划 + 老人个人项目库模块
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 22:27:34 +08:00
liuyun
515e22453c feat(c2): plan/order 权限码/错误码/APIS 2026-10-14 22:13:53 +08:00
liuyun
766d8c7218 feat(c2): plan/plan_item/order/elder_svc 数据模型
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 22:08:40 +08:00
liuyun
312712f86c chore(c1): .env.example 修正 MinIO 端口 9010 与凭据 admin/admin111
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 22:01:19 +08:00
liuyun
64c3efd931 fix(c1): elder 日期用 UTC 零点,修复 @db.Date 提前一天的 off-by-one
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 21:27:26 +08:00
liuyun
a949acbc3b fix(c1): elder 建档日期字段转 Date 落库(修复 50000)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 21:23:21 +08:00
liuyun
0cbdb7f825 fix(c1): elder 十态校验/不可逆态守卫/待遇止>起 + statusLog 单测
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 17:29:41 +08:00
liuyun
1308675f80 feat(c1): elder 待遇档案模块(建档/状态机/掩码/上传)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 17:19:07 +08:00
liuyun
465057cce0 feat(c1): MinIO 存储模块
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 17:03:12 +08:00
liuyun
f3c775cea9 feat(c1): elder 权限码/错误码/接口资源
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 16:57:55 +08:00
liuyun
b83c59611c feat(c1): elder + elder_status_log 数据模型
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 16:54:45 +08:00
liuyun
239dec912c refactor(c0): 业务表去 sys_ 前缀改业务领域命名,字典复用脚手架
- ltc_agency/ltc_staff;svc_national/svc_local/svc_mapping/svc_org;loc_config
- 删 sys_dict_abnormal_type/sys_dict_photo_tier,异常分类/拍照分档改为内置字典(abnormal_type/photo_tier)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 14:44:58 +08:00
liuyun
aa95586a55 fix(c0): 接线业务 RBAC 与补齐服务机构设置菜单
- APIS 登记 agency/staff/svc-org 业务接口资源(code=权限码)
- syncTenantResources 为业务租户预置 5 个业务角色并授权
- MENUS 补齐 svc-config-loc(属地与目录)与 svc-config-docking(对接档位)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 13:47:55 +08:00
liuyun
945fe5daa3 feat(c0): catalog 目录模块(属地加载 + 机构项目库)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 13:08:47 +08:00
liuyun
0be521bd72 fix(c0): staff 绑定 userId 前校验账号在本租户存在
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 13:01:32 +08:00
liuyun
5a3beb4923 feat(c0): staff 人员模块(user_id 关联账号 + 归属组长)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 12:56:07 +08:00
liuyun
856e906740 feat(c0): agency 机构模块(按租户读写机构信息)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 12:48:27 +08:00
liuyun
198517bde4 feat(c0): 长护服务菜单组 + 目录 seed 骨架
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 12:42:53 +08:00
liuyun
b5eb94d3ae feat(c0): 服务机构端权限码与业务错误码 2026-10-14 12:39:42 +08:00
liuyun
6f32875295 feat(c0): 服务机构端基础数据模型(9 表 + 多租户/软删清单)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-10-14 12:36:43 +08:00
liuyun
8fca4a1b1e chore(db): 业务表统一字符集为 utf8mb4_general_ci
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-14 09:56:16 +08:00
liuyun
6618137da5 feat(auth): 平台超管租户切换(super 标志 + switch-tenant)
- JWT 加 super 标志,sub 保持超管真实 userId,tenantCode 随切换
- isSuper 解析/checkUserActive/PermissionsGuard 支持跨租户超管
- POST /auth/switch-tenant

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 00:00:38 +08:00
liuyun
477f35293e fix(security): 若干越权/健壮性修复
- assignOrgs 校验 orgCodes 存在性(对齐 assignResources)
- lock/kick 保护保留角色账号(super_admin/tenant_super_admin)
- BatchDeleteDto 加 @ArrayMaxSize(100)
- 待改密门禁显式放行 /auth/logout
- 分配部门改用独立权限码 role:assign-org

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 22:56:12 +08:00
liuyun
8eefa7fa44 feat(error): 业务错误码注册表(业务域+错误序)+ BusinessException
- error-codes 单一注册表 + BusinessException + 过滤器识别
- 迁移登录/锁定/待改密/用户名冲突/租户/会话等关键错误

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 22:42:12 +08:00
liuyun
f747ad5442 feat(tenant): 租户品牌定制(brand_name/logo_url/theme_color/copyright + GET /auth/brand)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 22:32:14 +08:00
liuyun
bad8639175 feat(notice): 站内通知(公告 + 已读追踪)
- Notice/NoticeRead 实体;管理侧 CRUD + 用户侧 mine/unread-count/read/read-all
- 资源注册 notice 菜单 + 接口

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 22:25:19 +08:00
liuyun
9869974d4c feat(auth): 首登强制改密 + 待改密门禁
- User 新增 must_change_password;创建(默认强制)/重置/createTenant 置 true
- 登录响应返回 mustChangePassword,改密成功清除
- JwtAuthGuard 待改密门禁:仅放行 PATCH /auth/me/password

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 21:54:38 +08:00
liuyun
86832ce32d feat(session): 在线会话强踢 + 账号锁定/解锁
- JWT 引入 sid,单会话精确强退(sid 黑名单)与按用户踢全部(tokenVersion)
- User 新增 lockedAt/lockReason,登录/刷新/守卫统一拒绝锁定
- sessions 模块:活跃会话列表 + 单会话强退;users 新增 lock/unlock/kick-sessions
- 资源注册 + syncTenantResources 存量租户补齐脚本

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 21:35:43 +08:00
liuyun
127707ffde feat(rbac): 批量删除 + 数据权限自定义闭环 + 若干修复
- users/orgs/resources 新增 POST /batch-delete(事务 + 失败汇总 + 用户踢下线)
- 角色数据权限自定义:GET/PUT /roles/:roleCode/orgs(roleOrg 写入路径)
- assignResources 校验 resourceCodes 存在性;角色 :id 语义改 :roleCode
- createTenant 补 createdBy;登录锁定双层阈值(IP+用户名 / 用户名全局)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 17:42:05 +08:00
liuyun
200cedeb59 fix: 第二轮残留问题
- 资源变更清权限缓存(H4 残留)
- 菜单聚合过滤已删角色(与 resolveAuth 一致)
- removeRole 事务化;removeTenant 清 Redis(userState/perm)
- createTenant 事务化 + 未提供密码时生成随机密码
- 登录失败锁定加 IP 维度;register 禁止平台租户
- refresh token 落 ip/userAgent;e2e 用独立账号避免锁死
- .env.example 补 CORS_ORIGIN/NODE_ENV、脱敏默认密码

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 17:22:10 +08:00
liuyun
9a9435e665 ci: 后端 Dockerfile
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 17:02:18 +08:00
liuyun
6937f9ece0 test: 修复 e2e + 补单元测试
- e2e 改为登录链路(成功返回 token / 密码错误 401)
- 补 maskSensitive、resolveDataScope 单测

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 17:01:30 +08:00
liuyun
ebc0797424 chore: 移除 @nestjs/mau + deploy 脚本;补 package 元数据与 MIT 许可
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:57:46 +08:00
liuyun
ba1ae43e39 feat(security): helmet + CORS 白名单 + 限流 + 定时清理 + 时间契约 Unix 毫秒
- helmet 安全头 + CORS_ORIGIN 白名单 + Swagger 仅非生产
- @nestjs/throttler 全局限流(60s/100 次)
- @nestjs/schedule 定时清理过期 token 与旧日志
- API 时间统一 Unix 毫秒(TransformInterceptor 递归转换)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:54:08 +08:00
liuyun
606585c3bd feat(security): 登录失败锁定 + 密码长度策略 + refresh token 哈希校验
- 登录连续失败 5 次锁定 15 分钟(Redis 计数)
- 密码字段 @MinLength(6)
- refresh 校验 tokenHash

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:46:13 +08:00
liuyun
5c1f2992b5 fix: created_by 注入 + 登出审计记录真实 username
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:43:31 +08:00
liuyun
6553b4c5c7 feat(auth): 登录按用户名自动探测租户 + 多租户选择
- LoginDto tenantCode 改为可选,缺省按用户名跨租户探测
- 单匹配自动登录,多匹配返回候选租户
- 前端登录页新增租户选择弹窗

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:41:19 +08:00
liuyun
6578db51c7 feat(auth): PATCH /auth/me/password 修改本人密码
- 校验原密码 + 更新后 tokenVersion 吊销其它会话

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:34:51 +08:00
liuyun
13510ee216 feat(tenant): 租户 onboarding 模板 + 级联删除
- 抽取 seed 资源/字典到 tenant-template.ts,initTenant 幂等初始化租户
- 创建租户自动初始化管理员/根组织/角色/资源/字典
- 删除租户级联清理全部业务数据
- 修复 BaseCrudService 对 Tenant 模型的 tenantCode 大小写注入 bug

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:32:46 +08:00
liuyun
53dbc38bab feat(auth): 注册接口 POST /auth/register
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:29:11 +08:00
liuyun
537ec4fd91 feat(rbac): 数据权限扩展至组织树与审计/登录日志
- orgs: 列表按可见部门过滤
- audit-logs/login-logs: 按操作人所属部门过滤(self 按 userId/username)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:24:51 +08:00
liuyun
78e537fa73 feat(rbac): 用户-角色分配 + 权限码下发接口
- users: GET/PUT /users/:id/roles(事务化替换 + 过滤无效角色 + 清权限缓存)
- auth: GET /auth/permissions 返回 {super, permissions}
- permissions/seed: 新增 user:assign-role 权限码与资源

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:19:11 +08:00
liuyun
513688a5e6 fix(security): P0 安全越权堵漏(C1/H1-H6/H10/H11/H13/M1/M4/M6/M8-M11/M22)
- 平台管理员模型:super_admin=平台超管、tenant_super_admin=租户顶层(保留码),tenant:* 仅平台可授予
- 软删改名回收唯一键 + P2002→409
- 删除角色级联清理关联 + 聚合过滤已删/停用角色资源
- tokenVersion 会话吊销(重置密码/停用/删除即时踢下线)
- data_scope self 按 userId 过滤 + 详情数据权限校验
- 组织树防环、seed 不重置密码、日志脱敏补 phone/email
- JWT 密钥强校验、pageSize 上限、DTO 枚举校验、Prisma 错误映射、授权事务化

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:10:00 +08:00
liuyun
73ed067a82 feat: dict-driven enums — built-in dicts + protection + aggregate query
- dict_type/dict_item 增加 built_in/color_type 字段与唯一约束
- seed 预置 5 个内置枚举字典(幂等)
- 内置类型/项删除与内置项 value 修改保护
- 新增 GET /dicts 聚合接口(登录态)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 14:29:18 +08:00
liuyun
0823c750b2 feat: tenant list search filter
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 12:50:23 +08:00