更新
This commit is contained in:
@@ -115,12 +115,42 @@ try {
|
||||
'source_diagnosis_ids' => [1], 'source_summary' => ['diagnosis_count' => 1], 'missing' => [],
|
||||
'baseline_eligible' => false, 'baseline_exclusion_reasons' => ['SOURCE_HISTORY_VERSIONS_UNAVAILABLE'],
|
||||
'comparison_type' => 'latest_context', 'cutoff_at' => time(), 'wait_for_transcript' => false];
|
||||
$rx = $fixture();
|
||||
$rx = $fixture(['patient_name' => 'Snapshot patient', 'gender' => 0, 'age' => 52,
|
||||
'clinical_diagnosis' => 'Saved clinical diagnosis', 'usage_instruction' => 'Saved usage',
|
||||
'times_per_day' => 2, 'usage_days' => 7,
|
||||
'aux_usage' => '{"prescription_name":"Saved auxiliary formula","dosage_amount":1.5,"dosage_bag_count":2,"need_decoction":0,"bags_per_dose":1,"times_per_day":1,"usage_days":3,"phone":"private-aux-contact","nested":{"phone":"private-aux-nested"}}',
|
||||
'phone' => 'private-contact', 'doctor_signature' => 'private-signature',
|
||||
'case_record' => '{"phone":"private-nested-contact","clinical_diagnosis":"other diagnosis"}']);
|
||||
$context['source_access_manifest'] = ['schema_version' => 'prescription-source-access-v1', 'patient_id' => 100,
|
||||
'target' => ['prescription_id' => (int) $rx['id'], 'diagnosis_id' => 1],
|
||||
'records' => [['source_kind' => 'diagnoses', 'id' => 1, 'source_id' => 'diagnoses:1', 'diagnosis_id' => 1, 'patient_id' => 100, 'staff' => []]]];
|
||||
$batchId = $save($rx);
|
||||
$expect($batchId > 0 && $save($rx) === $batchId, 'same clinical content enqueues once');
|
||||
$pendingDetail = Api::detail($batchId, 1, $root);
|
||||
$snapshot = $pendingDetail['doctor_snapshot'];
|
||||
$expect($pendingDetail['status'] === 'preparing' && $pendingDetail['models'] === []
|
||||
&& $snapshot['prescription']['herbs'][0]['name'] === '测试药材',
|
||||
'original prescription available before model preparation and results');
|
||||
$expect($snapshot['patient']['name'] === 'Snapshot patient' && $snapshot['patient']['gender_label'] === '女'
|
||||
&& (int) $snapshot['patient']['age'] === 52
|
||||
&& $snapshot['diagnosis']['clinical_diagnosis'] === 'Saved clinical diagnosis'
|
||||
&& $snapshot['prescription']['usage_instruction'] === 'Saved usage', 'saved patient diagnosis and usage projected');
|
||||
$expect((int) $snapshot['prescription']['times_per_day'] === 2 && (int) $snapshot['prescription']['usage_days'] === 7
|
||||
&& $snapshot['prescription']['aux_usage'] === ['prescription_name' => 'Saved auxiliary formula',
|
||||
'dosage_amount' => 1.5, 'dosage_bag_count' => 2, 'need_decoction' => 0, 'bags_per_dose' => 1,
|
||||
'times_per_day' => 1, 'usage_days' => 3],
|
||||
'saved main and auxiliary usage remain distinct and auxiliary private fields are excluded');
|
||||
$expect(!str_contains(json_encode($snapshot), 'private-') && !isset($snapshot['prescription']['herbs'][0]['medicine_id']),
|
||||
'detail original excludes contacts signatures nested records and internal medicine IDs');
|
||||
try { Api::detail($batchId, 0, []); $expect(false, 'unauthenticated caller cannot read original'); }
|
||||
catch (DomainException $e) { $checks++; }
|
||||
Db::name('tcm_diagnosis')->where('id', 1)->update(['delete_time' => time()]);
|
||||
try { Api::detail($batchId, 1, $root); $expect(false, 'revoked source access cannot read original'); }
|
||||
catch (DomainException $e) { $checks++; }
|
||||
Db::name('tcm_diagnosis')->where('id', 1)->update(['delete_time' => null]);
|
||||
$expect(!isset($snapshot['prescription']['herbs'][0]['unit'])
|
||||
&& !isset($snapshot['prescription']['herbs'][0]['dose_basis'])
|
||||
&& !isset($snapshot['diagnosis']['western_diagnosis']), 'missing source units and diagnosis split are not invented');
|
||||
$blank = $fixture(['is_system_auto' => 1, 'herbs' => '[]']);
|
||||
$expect($save($blank) === null, 'blank prescriptions do not enqueue');
|
||||
$expect((int) Db::name('prescription_ai_task')->count() === 0, 'no model call or task before snapshot');
|
||||
@@ -158,6 +188,8 @@ try {
|
||||
$liveStatus = Api::statuses([$rx['id']], 1, $root)['items'][0];
|
||||
$liveDetail = Api::detail($batchId, 1, $root);
|
||||
$liveReports = Api::reports(['prescription_id' => $rx['id']], 1, $root);
|
||||
$expect(!array_key_exists('doctor_snapshot', $liveStatus)
|
||||
&& !array_key_exists('doctor_snapshot', $liveReports['lists'][0]), 'summaries do not expose original clinical content');
|
||||
$captureModels = false;
|
||||
$expect($modelQueries !== [], 'list/detail/history task select queries observed');
|
||||
foreach ($modelQueries as $sql) {
|
||||
@@ -203,6 +235,10 @@ try {
|
||||
Db::name('prescription_ai_batch')->where('id', $batchId)->update(['baseline_eligible' => 1, 'baseline_exclusions_json' => '[]']);
|
||||
$eligibleStats = Api::statistics([], 1, $root);
|
||||
$expect($eligibleStats['doctors'][0]['models']['qwen']['mean'] === 80.0, 'synthetic qualified baseline has empty exclusion reason');
|
||||
// 分布直方图必须随统计一起返回,否则界面只能凭均值猜形状。
|
||||
$bins = $eligibleStats['doctors'][0]['models']['qwen']['distribution'] ?? null;
|
||||
$expect(is_array($bins) && array_sum($bins) === 1 && ($bins['[80,100]'] ?? 0) === 1,
|
||||
'statistics expose the agreement distribution bins');
|
||||
Db::name('prescription_ai_batch')->where('id', $batchId)->update(['baseline_eligible' => 0, 'baseline_exclusions_json' => '["SOURCE_HISTORY_VERSIONS_UNAVAILABLE"]']);
|
||||
$expect((int) Db::name('prescription_ai_attempt')->count() === 3, 'attempt history retained');
|
||||
$payload = ['request_key' => '12345678-abcd-1234-abcd-123456789012', 'herbs' => [['name' => 'fixture']]];
|
||||
@@ -221,11 +257,17 @@ try {
|
||||
});
|
||||
} catch (RuntimeException $e) {}
|
||||
$expect((int) Db::name('prescription_ai_batch')->count() === $countBefore, 'prescription and outbox roll back together');
|
||||
Db::name('tcm_prescription')->where('id', $rx['id'])->update(['herbs' => '[{"name":"changed","dosage":20}]']);
|
||||
Db::name('tcm_prescription')->where('id', $rx['id'])->update(['herbs' => '[{"name":"changed","dosage":20}]',
|
||||
'clinical_diagnosis' => 'Changed clinical diagnosis', 'patient_name' => 'Changed patient',
|
||||
'aux_usage' => '{"times_per_day":3,"usage_days":9}']);
|
||||
$newBatch = $save($rx);
|
||||
$expect($newBatch !== $batchId, 'clinical change creates immutable new batch');
|
||||
$expect(Db::name('prescription_ai_batch')->where('id', $batchId)->value('validity') === 'prescription_changed', 'previous version invalidated');
|
||||
$expect((int) Db::name('prescription_ai_result')->count() === 2, 'historic model results immutable');
|
||||
$expect(Api::detail($batchId, 1, $root)['doctor_snapshot'] === $snapshot,
|
||||
'historic report retains saved original after live prescription patient and diagnosis change');
|
||||
$expect(Api::detail($newBatch, 1, $root)['doctor_snapshot']['diagnosis']['clinical_diagnosis'] === 'Changed clinical diagnosis',
|
||||
'new pending revision carries its own updated original');
|
||||
$newClaim = Store::claimBatch();
|
||||
Store::finishPreparation($newClaim, $context);
|
||||
$lease = Store::claimTask('qwen');
|
||||
|
||||
Reference in New Issue
Block a user