Add Method 1 (fetch by request_id) for self/current-session data + fix latest-consent-anchor drift bug
- M3HiuWorkflowService: data_fetch now supports fetch_by_request_id=1, sending request_id (not consent_id) per bridge Method 1 -- targets the current/self consent request's own session, distinct from Method 2 (consent_id, which can resolve to a stale session sharing the same artifact). - Patient::abdm_content_fetch_only(): tries Method 2 (consent_id) -> Method 1 (request_id, self data) -> Method 3 (abha_address, historical fallback) in order, stopping as soon as real documents are found. - Fixed a real pre-existing bug this surfaced: getLatestAbdmSyncSnapshot() used the same flawed 'status=SUCCESS implies COMPLETED' check (without requiring workflow_state=DATA_RECEIVED) already fixed elsewhere in computeConsentSessionDetail(). This let broad/historical data_fetch rows (status=success, but decrypted_data=[]) hijack priority-500 'best' selection and silently drift the resolved 'latest granted consent' to an unrelated historical consent_id after Method 3 fallback ran. Now requires workflow_state=DATA_RECEIVED, matching the earlier fix.
This commit is contained in:
parent
c87928c2bc
commit
ad98afbe57
|
|
@ -2070,6 +2070,39 @@ class Patient extends BaseController
|
|||
$documentsPersisted = (int) ($fetchResult['documents_persisted'] ?? 0);
|
||||
$documentsUpdated = (int) ($fetchResult['documents_updated'] ?? 0);
|
||||
|
||||
// The consent-artifact-scoped fetch above (bridge "Method 2") may resolve
|
||||
// to a stale/different session sharing the same consent artifact id. Per
|
||||
// the bridge gateway team, GET /v1/hiu/data/fetch?request_id=... ("Method
|
||||
// 1") targets the ONE specific consent request instead -- this is the
|
||||
// "self"/current session's own data. Try it before falling back to the
|
||||
// broader by-ABHA-address historical lookup (Method 3).
|
||||
if ($documentsPersisted + $documentsUpdated === 0 && $consentRequestRef !== '') {
|
||||
try {
|
||||
$requestIdFetchResult = $service->runOperation('data_fetch', [
|
||||
'abha_address' => $abhaContext['abha_address'],
|
||||
'consentRequestId' => $consentRequestRef,
|
||||
'fetch_by_request_id' => 1,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
$requestIdFetchResult = null;
|
||||
}
|
||||
|
||||
if (is_array($requestIdFetchResult) && (int) ($requestIdFetchResult['ok'] ?? 0) === 1) {
|
||||
$reqDocumentsPersisted = (int) ($requestIdFetchResult['documents_persisted'] ?? 0);
|
||||
$reqDocumentsUpdated = (int) ($requestIdFetchResult['documents_updated'] ?? 0);
|
||||
if ($reqDocumentsPersisted + $reqDocumentsUpdated > 0) {
|
||||
return $this->response->setJSON([
|
||||
'ok' => 1,
|
||||
'phase' => 'COMPLETED',
|
||||
'message' => 'Records fetched successfully using existing granted consent.',
|
||||
'documents_persisted' => $reqDocumentsPersisted,
|
||||
'documents_updated' => $reqDocumentsUpdated,
|
||||
'data' => ['data_fetch' => $fetchResult, 'data_fetch_by_request_id' => $requestIdFetchResult],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The consent-artifact-scoped fetch above (bridge "Method 1/2") only
|
||||
// returns data for the ONE consent/request we targeted. Per the bridge
|
||||
// gateway team, GET /v1/hiu/data/fetch?abha_address=... ("Method 3")
|
||||
|
|
@ -3552,7 +3585,16 @@ class Patient extends BaseController
|
|||
$phase = 'REQUESTED';
|
||||
$priority = 120;
|
||||
|
||||
if (($operation === 'DATA_FETCH' || $operation === 'HI_DATA_PUSH_CALLBACK') && $status === 'SUCCESS') {
|
||||
// NOTE: `status` only reflects whether the bridge API call itself
|
||||
// succeeded (no HTTP/transport error) -- it does NOT mean the HIP
|
||||
// actually sent any health records (see M3HiuWorkflowService::
|
||||
// resolveState()/runOperation(), which always set status=success for
|
||||
// any error-free response, even one reporting decrypted_data=[]).
|
||||
// Whether data truly arrived is tracked separately via workflow_state
|
||||
// (DATA_PENDING vs DATA_RECEIVED); require that here too, otherwise a
|
||||
// broad/historical data_fetch attempt with empty decrypted_data can
|
||||
// wrongly hijack "latest consent" resolution with a stale consent_id.
|
||||
if (($operation === 'DATA_FETCH' || $operation === 'HI_DATA_PUSH_CALLBACK') && $status === 'SUCCESS' && $state === 'DATA_RECEIVED') {
|
||||
$phase = 'COMPLETED';
|
||||
$priority = 500;
|
||||
} elseif (in_array($rawConsentStatus, ['GRANTED', 'APPROVED', 'ACTIVE'], true)) {
|
||||
|
|
|
|||
|
|
@ -998,6 +998,35 @@ class M3HiuWorkflowService
|
|||
];
|
||||
}
|
||||
|
||||
// Method 1 (per bridge gateway team, 2026-07-29): GET /v1/hiu/data/fetch
|
||||
// ?request_id=... fetches data for the ONE specific consent request that
|
||||
// request_id belongs to -- this is the "self"/current session's own data,
|
||||
// distinct from Method 2 (consent_id, which can resolve to a different/
|
||||
// stale session sharing the same consent artifact) and Method 3 (abha_address,
|
||||
// which returns unrelated historical sessions across every past consent).
|
||||
// Callers opt in explicitly via fetch_by_request_id=1.
|
||||
$fetchByRequestId = (int) ($clean['fetch_by_request_id'] ?? 0) === 1;
|
||||
if ($fetchByRequestId) {
|
||||
$requestIdOnly = trim((string) (
|
||||
$clean['abdm_consent_request_id']
|
||||
?? $clean['consentRequestId']
|
||||
?? $clean['consent_request_id']
|
||||
?? ''
|
||||
));
|
||||
if ($requestIdOnly === '') {
|
||||
return [
|
||||
'ok' => 0,
|
||||
'http_code' => 422,
|
||||
'error_text' => 'consent_request_id is required to fetch data by request_id (Method 1).',
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'ok' => 1,
|
||||
'payload' => ['request_id' => $requestIdOnly],
|
||||
];
|
||||
}
|
||||
|
||||
$requestFallback = '';
|
||||
if (! $requestIdGenerated) {
|
||||
$requestFallback = trim((string) (
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user