77 lines
4.3 KiB
PHP
77 lines
4.3 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||
require __DIR__ . '/fixtures/CompleteTcmCase.php';
|
||
|
||
use app\adminapi\logic\tcm\PatientAiReportLogic;
|
||
use app\adminapi\service\AiRequiredSource;
|
||
use app\adminapi\service\TcmClinicalFactStateGuard as Guard;
|
||
use app\adminapi\service\TcmClinicalReportStream;
|
||
|
||
$snapshot = (new ReflectionMethod(PatientAiReportLogic::class, 'buildSourceSnapshotFromRows'))
|
||
->invoke(null, CompleteTcmCase::rows());
|
||
$submission = (new ReflectionMethod(PatientAiReportLogic::class, 'sanitizeSnapshotForUpstream'))
|
||
->invoke(null, AiRequiredSource::submission($snapshot));
|
||
$ledger = Guard::build(CompleteTcmCase::current(), $submission);
|
||
$checks = 0;
|
||
$expect = static function (bool $condition, string $message) use (&$checks): void {
|
||
++$checks;
|
||
if (!$condition) throw new RuntimeException($message);
|
||
};
|
||
$tongueSource = array_values(array_filter($ledger['sources'], static fn (array $row): bool => $row['field'] === 'tongue'))[0];
|
||
$original = '舌象:2026-10-23“' . $tongueSource['quote'] . '”(' . $tongueSource['id']
|
||
. ')。本次无舌照附件,以文字记录为限。' . "\n\n";
|
||
$expect(Guard::validate($ledger, $original)['valid'], 'The original retained tongue paragraph has no clinical state conflict.');
|
||
foreach ([1, 2, 7, 31] as $size) {
|
||
$visible = '';
|
||
$stream = new TcmClinicalReportStream($ledger, static function (string $delta) use (&$visible): bool {
|
||
$visible .= $delta;
|
||
return true;
|
||
});
|
||
foreach (str_split($original, $size) as $chunk) $stream->push($chunk);
|
||
$expect($stream->finish() && $visible === $original, 'The original paragraph preserves every accepted source/metadata byte.');
|
||
}
|
||
foreach (['本次', '此次', '当前', '目前'] as $scope) {
|
||
foreach (['无舌照附件', '未提供图片附件'] as $missing) {
|
||
$metadata = $scope . $missing . ',以文字记录为限。';
|
||
$expect(Guard::validate($ledger, $metadata)['valid'], 'Missing material is metadata, not an absent tongue examination.');
|
||
foreach ([1, 2, 7, 31] as $size) {
|
||
$visible = '';
|
||
$wire = $metadata . "\r\n\r\n";
|
||
$stream = new TcmClinicalReportStream($ledger, static function (string $delta) use (&$visible): bool {
|
||
$visible .= $delta;
|
||
return true;
|
||
});
|
||
foreach (str_split($wire, $size) as $chunk) $stream->push($chunk);
|
||
$expect($stream->finish() && $visible === $wire, 'Metadata forwards exact original UTF-8/CRLF bytes.');
|
||
}
|
||
foreach (['患者有固定刺痛。', '患者无固定刺痛。', '口干未记录。', '舌象未记录。', '舌红绛。', '脉滑。'] as $actual) {
|
||
foreach ([',', '且'] as $join) {
|
||
$text = $scope . $missing . $join . $actual;
|
||
$expect(!Guard::validate($ledger, $text)['valid'], 'A material prefix cannot exempt an adjacent patient assertion.');
|
||
$visible = '';
|
||
$stream = new TcmClinicalReportStream($ledger, static function (string $delta) use (&$visible): bool {
|
||
$visible .= $delta;
|
||
return true;
|
||
});
|
||
foreach (str_split($text . "\n\n", 7) as $chunk) $stream->push($chunk);
|
||
$expect(!$stream->finish() && $visible === '', 'Unsupported findings remain withheld before delivery.');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$expect(!Guard::validate($ledger, '本次无舌照附件(s999999),以文字记录为限。')['valid'],
|
||
'The metadata role cannot waive an invalid source annotation.');
|
||
$expect(!Guard::validate($ledger, '本次无舌象。')['valid'], 'Missing tongue examination is not missing tongue image.');
|
||
foreach (['舌象', '脉象'] as $exam) {
|
||
foreach (['本次', '此次', '当前', '目前'] as $scope) {
|
||
foreach (['无', '没有', '未提供'] as $absence) {
|
||
$result = Guard::validate($ledger, $scope . $absence . $exam . '。');
|
||
$expect(!$result['valid'] && in_array('RECORDED_TO_UNKNOWN', array_column($result['issues'], 'code'), true),
|
||
'An existing named tongue/pulse examination cannot be erased by a bare missing-result claim.');
|
||
}
|
||
}
|
||
}
|
||
echo "TCM scoped attachment availability: {$checks} assertions passed (offline).\n";
|