This commit is contained in:
Your Name
2026-11-09 10:02:27 +08:00
parent 0c43d54c08
commit 8466acef9f
35 changed files with 3584 additions and 111 deletions
@@ -55,6 +55,11 @@ namespace app\adminapi\logic\tcm {
self::$events[] = ['read', $params];
return self::$records;
}
public static function saveLocalAudioTranscript(array $params): array
{
self::$events[] = ['recover', $params];
return ['call_record_id' => 1102, 'transcription_status' => 'completed', 'saved' => true];
}
public static function getError(): string { return self::$error; }
}
}
@@ -79,6 +84,7 @@ namespace {
public object $controllerObject;
public string $actionName = 'getCallRecords';
public string $controllerName = 'tcm.Diagnosis';
public bool $postRequest = false;
public function __construct(public array $query = [], bool $root = false)
{
$this->adminInfo = ['admin_id' => 91, 'root' => $root ? 1 : 0,
@@ -92,6 +98,8 @@ namespace {
return $name === null ? $this->query : ($this->query[$name] ?? $default);
}
public function param(string $name, $default = null) { return $default; }
public function post($name = '', $default = null, $filter = '') { return $this->query; }
public function isPost(): bool { return $this->postRequest; }
public function controller(): string { return $this->controllerName; }
public function action(): string { return $this->actionName; }
public function ip(): string { return '192.0.2.91'; }
@@ -207,5 +215,45 @@ namespace {
$empty = transcriptAuthorizationInvoke(['diagnosis_id' => 701], ['tcm.diagnosis/getCallRecords']);
transcriptAuthorizationExpect($empty['code'] === 1 && $empty['data'] === [], 'authorized empty history retains the original array response');
$recoveryGrants = ['tcm.diagnosis/startCallTranscription', 'tcm.diagnosis/upsertCallTranscriptSegments',
'tcm.diagnosis/finishCallTranscription'];
foreach ([[], ['tcm.diagnosis/huifang'], ['tcm.diagnosis/edit'], ['tcm.diagnosis/video-call'],
['tcm.diagnosis/saveLocalAudioTranscript'], [$recoveryGrants[0]], array_slice($recoveryGrants, 0, 2),
[$recoveryGrants[0], $recoveryGrants[1], $recoveryGrants[2] . 'Other']] as $permissions) {
$request = new ConsultationTranscriptRequest();
$request->actionName = 'SaVeLoCaLaUdIoTrAnScRiPt';
$GLOBALS['consultation_transcript_request'] = $request;
AdminAuthCache::$permissions = $permissions;
AdminAuthCache::$allUriReads = 0;
$continued = false;
$denied = (new AuthMiddleware())->handle($request, static function () use (&$continued): array {
$continued = true; return ['code' => 1];
});
transcriptAuthorizationExpect($denied['code'] === 0 && !$continued, 'recovery requires all exact realtime grants');
transcriptAuthorizationExpect(AdminAuthCache::$allUriReads === 0, 'recovery never uses unregistered route bypass');
}
foreach ([false, true] as $root) {
$payload = ['diagnosis_id' => 701, 'call_record_id' => 1102, 'admin_id' => 9999,
'recovery_id' => 'audio-' . str_repeat('a', 32), 'expected_session_id' => 'session',
'expected_status' => 'partial', 'audio_url' => 'https://audio.invalid/test.webm',
'transcript_text' => "原文 <test> &\n结尾"];
$request = new ConsultationTranscriptRequest($payload, $root);
$request->actionName = 'saveLocalAudioTranscript';
$request->postRequest = true;
$GLOBALS['consultation_transcript_request'] = $request;
$controller = new ConsultationTranscriptController($request);
$request->controllerObject = $controller;
AdminAuthCache::$permissions = $root ? [] : array_map('strtoupper', $recoveryGrants);
DiagnosisLogic::$events = [];
$saved = (new AuthMiddleware())->handle($request, static fn () => $controller->saveLocalAudioTranscript());
transcriptAuthorizationExpect($saved['code'] === 1 && $saved['data']['saved'] === true, 'granted actor can invoke recovery');
$payload['admin_id'] = 91;
transcriptAuthorizationExpect(DiagnosisLogic::$events === [['recover', $payload]], 'controller uses login actor and preserves transcript text');
$request->postRequest = false;
DiagnosisLogic::$events = [];
transcriptAuthorizationExpect($controller->saveLocalAudioTranscript()['code'] === 0 && DiagnosisLogic::$events === [],
'recovery rejects GET before persistence');
}
echo "Consultation transcript authorization: {$assertions} assertions passed (no DB or network)\n";
}