面诊文字对话：后端授权回归验证
日期：2026-10-20

结果：本轮要求的测试与语法检查全部通过。

新增测试文件
server/tests/ConsultationTranscriptAuthorizationTest.php

测试方法
- 通过 Composer autoload 加载并执行实际 DiagnosisController::getCallRecords 与 AuthMiddleware::handle。
- 控制器派生类只提供合成 request、管理员身份及 JSON 包装；不替换待测动作。
- DiagnosisLogic 的授权/读取依赖、AdminAuthCache、LoginLogic 与 JsonService 使用进程内替身；所有记录和身份均为合成数据。
- middleware 的 request() 使用固定测试IP；env() 替身一旦调用即抛错。因此本测试不初始化框架、不读取 .env、不访问数据库或网络。
- 无菜单注册的替身 getAllUri 返回 []，并记录调用次数；专门断言该敏感路由完全不落入 legacy 未登记绕过路径。
- 本测试验证控制器会调用既有行级策略并在拒绝时停止读取；行级策略本身的语义继续由 DiagnosisWorkspaceRowAuthorizationTest 覆盖。本轮没有访问真实患者或数据库。

新增测试覆盖（57个断言）
1. 菜单中未注册 getCallRecords 时，无功能权限仍拒绝。
2. 仅有 edit/detail/video-call 或相似前缀权限不能读取面诊记录。
3. huifang 或 getCallRecords 任一精确权限单独即可读取，无需 edit；两者同时存在可用。
4. 路由与直接权限的大小写规范化不形成绕过。
5. root 保留原中间件权限豁免，且控制器仍调用诊单行级校验。
6. 诊单无权读取/不存在时，在 getCallRecords 读取依赖执行前拒绝，错误为空时使用统一兜底文案。
7. 缺失、null、0、负数、空串、非数字字符串 ID 被拒绝，不执行行级策略或读取。
8. 合法数字字符串 ID 规范成整数；实际行级授权收到可信 adminId/adminInfo。
9. 外部 call_record_id/appointment_id/caller_id 参数不会透传为额外的读取控制项。
10. 正常返回保留两个不同通话 ID、不同 caller_id（均非当前用户）、session、状态、全文及顺序，不强加 caller 限制。
11. 全文里的换行、中文与 <test>/& 保持原样；partial 记录的已保存文字不会被清除。
12. 已授权空记录仍返回原契约 data: []。

已执行命令及结果
php server/tests/ConsultationTranscriptAuthorizationTest.php
  PASS: Consultation transcript authorization: 57 assertions passed (no DB or network)
php server/tests/DiagnosisWorkspaceRowAuthorizationTest.php
  PASS: Diagnosis workspace row authorization: OK
php server/tests/CallRecordLifecycleIdentityContractTest.php
  PASS: Call-record lifecycle identity contract: OK
php -l server/app/adminapi/controller/tcm/DiagnosisController.php
  PASS: No syntax errors detected
php -l server/app/adminapi/http/middleware/AuthMiddleware.php
  PASS: No syntax errors detected
php -l server/tests/ConsultationTranscriptAuthorizationTest.php
  PASS: No syntax errors detected
以上进程退出码均为0。

已向主线程说明的校验边界
本轮控制器版本先将 diagnosis_id 强转为 (int)，再检查 >0。因此它拒绝上面第7项的输入，但尚不是严格正整数字符串/整数形状校验。
例如 '701suffix'、'701.5' 或 true 可被 PHP 强转为正整数。这些最终仍须通过诊单行级可见性验证，不构成跳过授权；但不应将当前输入形状表述为“已严格拒绝所有非法ID”。
主线程已知悉，并计划在本轮终态之后收紧形状验证，随后复跑本测试。严格形状校验当前不计入57项通过断言，尚未声称已完成。

变更范围
本轮仅新增上述后端测试与本验证报告；未修改业务代码、已有测试、部署文件或用户脏文件。

主线程最终补充验收
- 已将 diagnosis_id 收紧为整数或字符串输入，再经 FILTER_VALIDATE_INT/min_range=1 验证；小数、尾缀字符串、布尔、数组和对象均被拒绝。
- 已将这些输入形状加入同一无数据库控制器/中间件测试。最终重新执行输出：Consultation transcript authorization: 73 assertions passed (no DB or network)，退出码0。
- 因此上文“整数强转”边界描述仅对应首次验证快照，最终交付代码已处理该问题。
