This commit is contained in:
Your Name
2026-08-03 09:51:53 +08:00
parent 81d6a38e26
commit 22a371a733
10 changed files with 215 additions and 96 deletions
@@ -23,6 +23,10 @@ $assertTrue(
str_contains($controllerSource, 'confirmGancaoSubmission'),
'admin API must expose an actionable Gancao reconciliation endpoint'
);
$assertTrue(
str_contains($controllerSource, 'public function ddcode()'),
'admin API must expose a dedicated tracking correction endpoint'
);
$assertTrue(
str_contains($migrationSource, '`lease_expires_at`'),
'pharmacy submission claims must persist an explicit lease expiry'
+47 -3
View File
@@ -799,14 +799,14 @@ $assertTrue(
'remote payload must reload the canonical order after acquiring the durable claim'
);
$assertTrue(
substr_count($prescriptionOrderLogicSource, 'LockedPharmacySnapshotMutation::execute(') >= 7,
'order edit, patient, ship, withdraw, audit revoke, ship-mode and usage mutations must run inside locked snapshot transactions'
substr_count($prescriptionOrderLogicSource, 'LockedPharmacySnapshotMutation::execute(') >= 8,
'order edit, logistics, patient, ship, withdraw, audit revoke, ship-mode and usage mutations must run inside locked snapshot transactions'
);
$assertTrue(
substr_count($prescriptionLogicSource, 'LockedPharmacySnapshotMutation::executeForPrescription(') >= 4,
'prescription edit, patient patch, delete and void must lock every linked order and claim before saving'
);
foreach (['patchPrescriptionPatient', 'edit', 'ship', 'withdraw', 'revokeRxAudit', 'setShipMode', 'patchPrescriptionUsage'] as $method) {
foreach (['patchPrescriptionPatient', 'edit', 'ddcode', 'ship', 'withdraw', 'revokeRxAudit', 'setShipMode', 'patchPrescriptionUsage'] as $method) {
$start = (int) strpos($prescriptionOrderLogicSource, 'public static function ' . $method . '(');
$end = (int) strpos($prescriptionOrderLogicSource, 'private static function ' . $method . 'Locked(', $start);
$wrapperSource = substr($prescriptionOrderLogicSource, $start, $end - $start);
@@ -844,6 +844,35 @@ $assertTrue(
!str_contains($shipLockedSource, '->ship_mode ='),
'shipping logistics must never overwrite the pharmacy target snapshot'
);
$ddcodeStart = (int) strpos($prescriptionOrderLogicSource, 'public static function ddcode(');
$ddcodeLockedStart = (int) strpos($prescriptionOrderLogicSource, 'private static function ddcodeLocked(', $ddcodeStart);
$ddcodeEnd = (int) strpos($prescriptionOrderLogicSource, 'public static function ship(', $ddcodeLockedStart);
$ddcodeWrapperSource = substr($prescriptionOrderLogicSource, $ddcodeStart, $ddcodeLockedStart - $ddcodeStart);
$ddcodeLockedSource = substr($prescriptionOrderLogicSource, $ddcodeLockedStart, $ddcodeEnd - $ddcodeLockedStart);
$assertTrue(
(bool) preg_match(
'/LockedPharmacySnapshotMutation::execute\(.*?self::ddcodeLocked\(.*?\),\s*false\s*\)/s',
$ddcodeWrapperSource
),
'tracking correction must keep row locks and transactions while bypassing only the remote snapshot mutability assertion'
);
preg_match_all('/\$order->([a-z_]+)\s*=/', $ddcodeLockedSource, $ddcodeAssignedFieldMatches);
$assertSame(
['tracking_number', 'express_company'],
array_values(array_unique($ddcodeAssignedFieldMatches[1] ?? [])),
'tracking correction must write only the tracking number and carrier fields'
);
$assertTrue(
!str_contains($ddcodeLockedSource, '$order->fulfillment_status')
&& !str_contains($ddcodeLockedSource, 'assertRemoteSnapshotMutable'),
'tracking correction must be available in every fulfillment state and for remotely submitted orders'
);
$assertTrue(
str_contains($ddcodeLockedSource, "'fill_tracking'")
&& str_contains($ddcodeLockedSource, "'修改快递信息:单号")
&& str_contains($ddcodeLockedSource, "\n true\n );"),
'tracking correction must append a strict operation log containing old and new logistics values'
);
$assertTrue(
substr_count($prescriptionLogicSource, 'remoteSnapshotLockErrorForPrescription') >= 2,
'consumer prescription edit and patient patch must enforce the linked order snapshot lock'
@@ -1459,6 +1488,9 @@ $assertTrue(
$tcmApi = (string) file_get_contents(dirname(__DIR__, 3) . '/admin/src/api/tcm.ts');
$desktopOrderPage = (string) file_get_contents(dirname(__DIR__, 3) . '/admin/src/views/consumer/prescription/order_list.vue');
$mobileOrderPage = (string) file_get_contents(dirname(__DIR__, 3) . '/admin/src/views/consumer/prescription/order_list_h5.vue');
$ddcodeMigration = (string) file_get_contents(
dirname(__DIR__, 2) . '/sql/1.9.20260803/add_prescription_order_ddcode_menu.sql'
);
$gancaoReconcileComponent = (string) file_get_contents(
dirname(__DIR__, 3) . '/admin/src/views/consumer/prescription/components/GancaoSubmissionReconcileButton.vue'
);
@@ -1486,6 +1518,18 @@ $assertTrue(
str_contains($tcmApi, "url: '/tcm.prescriptionOrder/uploadToPharmacy'"),
'unified pharmacy API client must use the independently registered upload URI'
);
$assertTrue(
str_contains($tcmApi, "url: '/tcm.prescriptionOrder/ddcode'")
&& str_contains($ddcodeMigration, "'tcm.prescriptionOrder/ddcode'"),
'tracking correction API and its dedicated permission must be registered together'
);
$assertTrue(
str_contains($desktopOrderPage, 'await prescriptionOrderDdcode({')
&& str_contains($mobileOrderPage, 'await prescriptionOrderDdcode({')
&& (bool) preg_match('/function canQuickTrackRow\([^)]*\)\s*\{\s*return true\s*\}/', $desktopOrderPage)
&& (bool) preg_match('/function canQuickTrackRow\([^)]*\)\s*\{\s*return true\s*\}/', $mobileOrderPage),
'desktop and mobile tracking correction must use the dedicated API in every fulfillment state'
);
$assertTrue(
str_contains($desktopOrderPage, "v-perms=\"['tcm.prescriptionOrder/uploadToPharmacy']\""),
'unified pharmacy buttons must require the new upload permission'