fix(abdm): stamp consent status on its own request row
Reconciled status lived only on a separate reconcile row, whose correlation back to a session was rebuilt on every page load, so denied/expired requests reverted to REQUESTED after reopening. Write GRANTED/DENIED/EXPIRED/REVOKED onto the session's own consent_request row and treat a stamped terminal state as authoritative.
This commit is contained in:
parent
c6f415cfdc
commit
fb2bfb8a8c
|
|
@ -2697,7 +2697,7 @@ class Patient extends BaseController
|
|||
// older requests the patient later denied/expired in the PHR app keep
|
||||
// showing REQUESTED otherwise, because nothing ever re-checks them.
|
||||
$sessions = $this->getAbdmConsentRequestsList($abhaAddress);
|
||||
$reconcilePayloads = [];
|
||||
$reconcileJobs = [];
|
||||
foreach ($sessions['requests'] ?? [] as $consent) {
|
||||
if (in_array(strtoupper(trim((string) ($consent['status'] ?? ''))), ['EXPIRED', 'DENIED', 'REVOKED'], true)) {
|
||||
continue;
|
||||
|
|
@ -2708,16 +2708,19 @@ class Patient extends BaseController
|
|||
if ($sessionRequestId === '' && $sessionConsentRequestId === '' && $sessionConsentId === '') {
|
||||
continue;
|
||||
}
|
||||
$reconcilePayloads[] = [
|
||||
'abha_address' => $abhaAddress,
|
||||
'request_id' => $sessionRequestId,
|
||||
'abdm_consent_request_id' => $sessionConsentRequestId,
|
||||
'abdm_consent_artifact_id' => $sessionConsentId,
|
||||
'consent_id' => $sessionConsentId,
|
||||
$reconcileJobs[] = [
|
||||
'anchor_row_id' => (int) ($consent['id'] ?? 0),
|
||||
'payload' => [
|
||||
'abha_address' => $abhaAddress,
|
||||
'request_id' => $sessionRequestId,
|
||||
'abdm_consent_request_id' => $sessionConsentRequestId,
|
||||
'abdm_consent_artifact_id' => $sessionConsentId,
|
||||
'consent_id' => $sessionConsentId,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
if ($reconcilePayloads === []) {
|
||||
if ($reconcileJobs === []) {
|
||||
$snapshot = $this->getLatestAbdmSyncSnapshot($abhaAddress);
|
||||
$requestId = trim((string) ($snapshot['request_id'] ?? ''));
|
||||
$consentRequestId = trim((string) ($snapshot['consent_request_id'] ?? ''));
|
||||
|
|
@ -2728,12 +2731,15 @@ class Patient extends BaseController
|
|||
'error' => 'No consent request found for this patient to check.',
|
||||
]);
|
||||
}
|
||||
$reconcilePayloads[] = [
|
||||
'abha_address' => $abhaAddress,
|
||||
'request_id' => $requestId,
|
||||
'abdm_consent_request_id' => $consentRequestId,
|
||||
'abdm_consent_artifact_id' => $consentId,
|
||||
'consent_id' => $consentId,
|
||||
$reconcileJobs[] = [
|
||||
'anchor_row_id' => 0,
|
||||
'payload' => [
|
||||
'abha_address' => $abhaAddress,
|
||||
'request_id' => $requestId,
|
||||
'abdm_consent_request_id' => $consentRequestId,
|
||||
'abdm_consent_artifact_id' => $consentId,
|
||||
'consent_id' => $consentId,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -2745,7 +2751,8 @@ class Patient extends BaseController
|
|||
$dataUpdates = 0;
|
||||
$dataFailed = 0;
|
||||
|
||||
foreach ($reconcilePayloads as $reconcilePayload) {
|
||||
foreach ($reconcileJobs as $job) {
|
||||
$reconcilePayload = $job['payload'];
|
||||
try {
|
||||
$reconcile = $service->runOperation('consent_reconcile', $reconcilePayload);
|
||||
} catch (\Throwable $e) {
|
||||
|
|
@ -2758,6 +2765,7 @@ class Patient extends BaseController
|
|||
continue;
|
||||
}
|
||||
$reconcileOk = true;
|
||||
$this->persistConsentPhaseOnRequestRow((int) $job['anchor_row_id'], $reconcile);
|
||||
|
||||
$fetchSummary = ['granted' => false, 'data_updates' => 0, 'failed' => 0, 'artifact_ids' => []];
|
||||
try {
|
||||
|
|
@ -2782,7 +2790,7 @@ class Patient extends BaseController
|
|||
|
||||
return $this->response->setJSON([
|
||||
'ok' => 1,
|
||||
'sessions_checked' => count($reconcilePayloads),
|
||||
'sessions_checked' => count($reconcileJobs),
|
||||
'reconcile_ok' => $reconcileOk ? 1 : 0,
|
||||
'reconcile_error' => $reconcileOk ? '' : $reconcileError,
|
||||
'granted' => $granted ? 1 : 0,
|
||||
|
|
@ -2792,6 +2800,52 @@ class Patient extends BaseController
|
|||
] + $this->getAbdmConsentRequestsList($abhaAddress));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stamps a reconciled consent status onto the session's own CONSENT_REQUEST
|
||||
* row. Without this the status lives only on a separate reconcile row, whose
|
||||
* attribution back to a session depends on id correlation — so a reload could
|
||||
* show REQUESTED again for a request ABDM already reported as denied/expired.
|
||||
*
|
||||
* @param array<string, mixed> $reconcile consent_reconcile operation result
|
||||
*/
|
||||
private function persistConsentPhaseOnRequestRow(int $rowId, array $reconcile): void
|
||||
{
|
||||
if ($rowId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$status = strtoupper(trim((string) (
|
||||
$reconcile['consent']['status']
|
||||
?? $reconcile['consent_status']
|
||||
?? $reconcile['status']
|
||||
?? ''
|
||||
)));
|
||||
$state = match ($status) {
|
||||
'GRANTED', 'APPROVED', 'ACTIVE' => 'GRANTED',
|
||||
'DENIED' => 'DENIED',
|
||||
'EXPIRED' => 'EXPIRED',
|
||||
'REVOKED' => 'REVOKED',
|
||||
default => '',
|
||||
};
|
||||
if ($state === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$update = ['workflow_state' => $state, 'updated_at' => $now];
|
||||
if ($state === 'EXPIRED') {
|
||||
$update['expired_at'] = $now;
|
||||
} elseif ($state === 'REVOKED' || $state === 'DENIED') {
|
||||
$update['revoked_at'] = $now;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->db->table('abdm_hiu_workflows')->where('id', $rowId)->update($update);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Unable to persist ABDM consent status on row ' . $rowId . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function abdm_timeline(int $pno)
|
||||
{
|
||||
if (! $this->db->tableExists('patient_master')) {
|
||||
|
|
@ -4789,6 +4843,14 @@ class Patient extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
// A status stamped directly onto this request row by a live status check
|
||||
// is authoritative: it names this exact consent request, unlike separate
|
||||
// reconcile rows that have to be correlated back to a session.
|
||||
$anchorState = strtoupper(trim((string) (is_array($consentRequestRow) ? ($consentRequestRow['workflow_state'] ?? '') : '')));
|
||||
if (in_array($anchorState, ['EXPIRED', 'DENIED', 'REVOKED'], true)) {
|
||||
$phase = $anchorState;
|
||||
}
|
||||
|
||||
// A short, human-friendly identifier for this session (the "Request ID"
|
||||
// guid is too long to display in a table column) -- use the underlying
|
||||
// abdm_hiu_workflows row id of this session's own CONSENT_REQUEST row
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user