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);
|
$documentsPersisted = (int) ($fetchResult['documents_persisted'] ?? 0);
|
||||||
$documentsUpdated = (int) ($fetchResult['documents_updated'] ?? 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
|
// The consent-artifact-scoped fetch above (bridge "Method 1/2") only
|
||||||
// returns data for the ONE consent/request we targeted. Per the bridge
|
// returns data for the ONE consent/request we targeted. Per the bridge
|
||||||
// gateway team, GET /v1/hiu/data/fetch?abha_address=... ("Method 3")
|
// gateway team, GET /v1/hiu/data/fetch?abha_address=... ("Method 3")
|
||||||
|
|
@ -3552,7 +3585,16 @@ class Patient extends BaseController
|
||||||
$phase = 'REQUESTED';
|
$phase = 'REQUESTED';
|
||||||
$priority = 120;
|
$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';
|
$phase = 'COMPLETED';
|
||||||
$priority = 500;
|
$priority = 500;
|
||||||
} elseif (in_array($rawConsentStatus, ['GRANTED', 'APPROVED', 'ACTIVE'], true)) {
|
} 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 = '';
|
$requestFallback = '';
|
||||||
if (! $requestIdGenerated) {
|
if (! $requestIdGenerated) {
|
||||||
$requestFallback = trim((string) (
|
$requestFallback = trim((string) (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user