Files
zyt/artifacts/prescription-ai-visibility-backend-implementation.md
T
2026-10-17 16:51:48 +08:00

5.6 KiB
Raw Blame History

处方 AI 一致度授权:后端实施记录

日期:2026-10-17。仅修改 server 后端及本报告;未提交、未部署、未连接生产数据库或模型服务。

行为

  • 新服务 server/app/common/service/prescriptionai/PrescriptionAiVisibility.php 使用 ConfigService 一条 JSON:type=prescription_ai_visibility / name=agreement_policy,字段仅 role_ids:int[]、admin_ids:int[]。
  • 默认空、缺失或格式错误策略全部不可查看一致度。角色或单用户命中任一即可;查看没有 root、通配符或管理权限豁免。
  • 账号每次重新检查 disable=0、delete_time IS NULL;角色关系实时查询并排除软删除角色。配置读取无长期缓存,授权或撤销下次请求立即生效。
  • 独立管理权限为 tcm.prescriptionAi/manageVisibility。root 可管理,其余账号须持此权限;三个管理入口均在服务端统一验证,防止未注册路由中间件默认放行产生越权。所有入口仍由控制器重载有效账号,拒绝未知参数与错误 HTTP 方法。
  • statuses 顶层及各 item、reports 顶层及各 batch、detail 顶层均返回 agreement_visible。未授权时共享 Logic 投影删除整个 comparison、扁平 score/herb_score、比较状态/原因/版本、比较类型/基线等派生数据;失败模型生成错误原因保留。
  • full 模型正文使用固定字段及嵌套结构投影,拒绝历史正文未知 raw/result/score、调试对象、伪造 progress 等旁路。报告、候选方案、来源与覆盖说明、进度、医生原方、复核意见保留。
  • statistics 在扫描/聚合之前拒绝没有白名单资格的账号;原有动作 RBAC 和处方/患者/来源范围校验仍执行。后台分析、比较、手动重试与复核的既有权限流程未加指标限制。

固定接口

HTTP tcm.prescriptionAi/ 后 action 数据
GET capabilities {agreement_visible:boolean, can_manage_visibility:boolean},登录账号自查
GET getVisibilityConfig {role_ids:number[],admin_ids:number[]},仅管理者
POST setVisibilityConfig 接收且仅接收上述两数组,返回去重排序后的策略;仅管理者
GET visibilityOptions {roles:[{id,name}],admins:[{id,name,account}]},仅管理者

选项及保存列表上界:500 个角色、5000 个后台用户。选项只返回活跃记录,超过上界明确报错,不静默截断。保存只验证新提交的名单,因此失效 ID 可从旧名单中删除后保存,不会被旧数据阻塞。角色无 disable/status 列,按软删除判断。

迁移

新增 server/database/migrations/2026_10_17_prescription_ai_agreement_visibility.sql:

  • 幂等创建系统设置下 type C 的“处方AI一致度授权”菜单,perms 为 tcm.prescriptionAi/manageVisibility,component 为 setting/prescription_ai_visibility/index。
  • 幂等预置一条空 JSON 策略,不自动授权任何非 root 角色,不填入查看白名单。
  • 不新增业务表,不改变既有报告或队列数据。上线时需要先执行该迁移;本次仅在隔离测试数据库中执行并重放验证。

修改文件

  1. server/app/common/service/prescriptionai/PrescriptionAiVisibility.php(新):策略、管理校验、实时匹配、有限选项、输出投影。
  2. server/app/adminapi/controller/tcm/PrescriptionAiController.php:四个接口。
  3. server/app/adminapi/logic/tcm/PrescriptionAiLogic.php:统一能力标记、指标裁剪、统计授权、正文投影。
  4. server/database/migrations/2026_10_17_prescription_ai_agreement_visibility.sql(新):幂等菜单及空策略。
  5. server/tests/PrescriptionAiVisibilityTest.php(新):无应用初始化的纯离线策略/投影回归。
  6. server/tests/PrescriptionAiQueueTest.php:隔离真实 ORM、Cipher、Logic、Controller 及迁移回归。

验证结果

PHP 8.2.9;新增/修改的 5 个 PHP 文件全部 php -l 通过。git diff --check -- server 通过。全仓 diffcheck 中另有并行桌面端文件换行问题,已通知主代理,本任务未修改 app 文件。

纯离线:

  • php server/tests/PrescriptionAiVisibilityTest.php:22 checks。
  • php server/tests/PrescriptionAiProgressTest.php:38 checks。
  • php server/tests/PrescriptionAiComparisonTest.php:266 checks。
  • php server/tests/PrescriptionAiStatisticsTest.php:64 checks。
  • php server/tests/PrescriptionAiConfigurationTest.php:通过。

隔离 MySQL:主代理建立的 127.0.0.1:33447,root 空密码,显式 ZYT_AI_TEST_MYSQL_PORT=33447。这些脚本不 App::initialize,不读生产 .env,创建并最终删除各自唯一 prescription_ai_test_* 临时库:

  • php server/tests/PrescriptionAiQueueTest.php:113 checks。
  • php server/tests/PrescriptionAiQueueTest.php --legacy-progress-schema:111 checks。
  • php server/tests/PrescriptionAiPipelineTest.php:125 checks。

新增集成覆盖:默认空名单含 root 拒绝查看、root 管理与查看分离、独立非 root 管理权限、GET/POST/未知字段、伪 root/星号 token、配置越权拒绝、角色/个人任一授权、多角色、即时撤销、软删除角色、禁用/删除账号、无效策略、活跃最小选项与超限、菜单禁用即时撤销、allowlist 不替代动作 RBAC、真实加密旧正文注入及嵌套旁路、三个读取出口完整裁剪、统计拒绝、保留报告/候选/原方/复核/失败原因、限制指标后仍可重试/复核、迁移执行两次。

报告是实现交付,不表示生产迁移已经执行。测试 MySQL 进程由主代理负责最终关闭。