M3 HIU: track every discovered consent artifact id per consent_request in new abdm_hiu_consent_artifacts registry, and re-poll each individually every cycle (merged fetch-by-request-id alone does not keep returning already-established artifact sessions)
This commit is contained in:
parent
e783a57c4d
commit
e803809506
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
/**
|
||||
* Tracks every distinct ABDM consent ARTIFACT id discovered under a consent
|
||||
* request. Needed because a multi-facility M3 consent produces one artifact
|
||||
* per linked HIP facility, and the bridge's merged "fetch by consent_request_id"
|
||||
* call does not reliably keep returning sessions for artifacts that were
|
||||
* already individually resolved earlier (verified 2026-07-28: a previously
|
||||
* "received" artifact stopped appearing in the merged sessions list, while
|
||||
* still returning real data when queried directly by its own artifact id).
|
||||
* So HMS must remember every artifact id it has ever seen for a consent
|
||||
* request and keep polling each one individually, in addition to the merged
|
||||
* request-id call (which is what discovers brand-new sibling artifacts).
|
||||
*/
|
||||
class CreateAbdmHiuConsentArtifacts extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->forge->addField([
|
||||
'id' => [
|
||||
'type' => 'BIGINT',
|
||||
'constraint' => 20,
|
||||
'unsigned' => true,
|
||||
'auto_increment' => true,
|
||||
],
|
||||
'consent_request_id' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 180,
|
||||
],
|
||||
'artifact_id' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 180,
|
||||
],
|
||||
'abha_address' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 120,
|
||||
'null' => true,
|
||||
],
|
||||
'hfr_id' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 60,
|
||||
'null' => true,
|
||||
],
|
||||
'last_status' => [
|
||||
'type' => 'VARCHAR',
|
||||
'constraint' => 40,
|
||||
'null' => true,
|
||||
],
|
||||
'last_polled_at' => [
|
||||
'type' => 'DATETIME',
|
||||
'null' => true,
|
||||
],
|
||||
'created_at' => [
|
||||
'type' => 'DATETIME',
|
||||
'null' => true,
|
||||
],
|
||||
'updated_at' => [
|
||||
'type' => 'DATETIME',
|
||||
'null' => true,
|
||||
],
|
||||
]);
|
||||
$this->forge->addKey('id', true);
|
||||
$this->forge->addUniqueKey(['consent_request_id', 'artifact_id'], 'uniq_request_artifact');
|
||||
$this->forge->addKey('abha_address');
|
||||
$this->forge->createTable('abdm_hiu_consent_artifacts', true);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$this->forge->dropTable('abdm_hiu_consent_artifacts', true);
|
||||
}
|
||||
}
|
||||
|
|
@ -277,6 +277,46 @@ class M3HiuWorkflowService
|
|||
} else {
|
||||
$summary['failed']++;
|
||||
}
|
||||
|
||||
// Merged-by-request-id fetch discovers NEW sibling artifacts, but
|
||||
// does not reliably keep returning sessions for artifacts already
|
||||
// established earlier (verified: an already-"received" artifact
|
||||
// stopped appearing in the merged list while still returning real
|
||||
// data when queried by its own artifact id). So remember every
|
||||
// artifact id ever seen for this consent request, and re-poll each
|
||||
// one individually every cycle too, for full coverage.
|
||||
$singleArtifactId = trim((string) (
|
||||
$consentResult['abdm_consent_artifact_id'] ?? ''
|
||||
));
|
||||
$fetchSessions = is_array($dataResult['sessions'] ?? null) ? $dataResult['sessions'] : [];
|
||||
$this->recordDiscoveredArtifacts(
|
||||
$resolvedConsentId,
|
||||
$fetchSessions,
|
||||
$payload['abha_address'],
|
||||
$payload['hfr_id']
|
||||
);
|
||||
if ($singleArtifactId !== '' && ! $this->isGatewayRequestIdPattern($singleArtifactId)) {
|
||||
$this->rememberArtifact($resolvedConsentId, $singleArtifactId, $payload['abha_address'], $payload['hfr_id']);
|
||||
}
|
||||
|
||||
foreach ($this->getKnownArtifactIds($resolvedConsentId) as $artifactId) {
|
||||
if ($artifactId === '' || $artifactId === $resolvedConsentId) {
|
||||
continue;
|
||||
}
|
||||
$artifactPayload = $payload;
|
||||
$artifactPayload['consent_id'] = $artifactId;
|
||||
$artifactPayload['consent_request_id'] = $artifactId;
|
||||
$artifactPayload['abdm_consent_artifact_id'] = $artifactId;
|
||||
$artifactPayload['abdm_consent_request_id'] = $artifactId;
|
||||
|
||||
$artifactResult = $this->runOperation('data_fetch', $artifactPayload);
|
||||
if ((int) ($artifactResult['ok'] ?? 0) === 1) {
|
||||
$summary['data_updates']++;
|
||||
$this->markArtifactPolled($resolvedConsentId, $artifactId, (string) ($artifactResult['consent_status'] ?? ''));
|
||||
} else {
|
||||
$summary['failed']++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$summary['failed']++;
|
||||
}
|
||||
|
|
@ -285,6 +325,98 @@ class M3HiuWorkflowService
|
|||
return $summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts and upserts every distinct artifact id found in a data_fetch
|
||||
* result's sessions[] array (each session's consent_id is typically
|
||||
* "artifactId:internalRequestId" or a bare artifact id) into the
|
||||
* abdm_hiu_consent_artifacts registry, so future poll cycles keep
|
||||
* checking each artifact individually.
|
||||
*/
|
||||
private function recordDiscoveredArtifacts(string $consentRequestId, array $sessions, string $abhaAddress, string $hfrId): void
|
||||
{
|
||||
foreach ($sessions as $session) {
|
||||
if (! is_array($session)) {
|
||||
continue;
|
||||
}
|
||||
$rawConsentId = trim((string) ($session['consent_id'] ?? ''));
|
||||
if ($rawConsentId === '') {
|
||||
continue;
|
||||
}
|
||||
$artifactId = strpos($rawConsentId, ':') !== false
|
||||
? trim(explode(':', $rawConsentId)[0])
|
||||
: $rawConsentId;
|
||||
if ($artifactId === '' || $this->isGatewayRequestIdPattern($artifactId)) {
|
||||
continue;
|
||||
}
|
||||
$this->rememberArtifact($consentRequestId, $artifactId, $abhaAddress, $hfrId, (string) ($session['status'] ?? ''));
|
||||
}
|
||||
}
|
||||
|
||||
private function rememberArtifact(string $consentRequestId, string $artifactId, string $abhaAddress, string $hfrId, string $status = ''): void
|
||||
{
|
||||
if (! $this->db->tableExists('abdm_hiu_consent_artifacts') || $consentRequestId === '' || $artifactId === '') {
|
||||
return;
|
||||
}
|
||||
$now = Time::now('Asia/Kolkata')->toDateTimeString();
|
||||
$existing = $this->db->table('abdm_hiu_consent_artifacts')
|
||||
->where('consent_request_id', $consentRequestId)
|
||||
->where('artifact_id', $artifactId)
|
||||
->get(1)
|
||||
->getRowArray();
|
||||
|
||||
if (! empty($existing)) {
|
||||
$update = ['updated_at' => $now];
|
||||
if ($status !== '') {
|
||||
$update['last_status'] = $status;
|
||||
}
|
||||
$this->db->table('abdm_hiu_consent_artifacts')->where('id', (int) $existing['id'])->update($update);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db->table('abdm_hiu_consent_artifacts')->insert([
|
||||
'consent_request_id' => $consentRequestId,
|
||||
'artifact_id' => $artifactId,
|
||||
'abha_address' => $abhaAddress !== '' ? $abhaAddress : null,
|
||||
'hfr_id' => $hfrId !== '' ? $hfrId : null,
|
||||
'last_status' => $status !== '' ? $status : null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
private function markArtifactPolled(string $consentRequestId, string $artifactId, string $status): void
|
||||
{
|
||||
if (! $this->db->tableExists('abdm_hiu_consent_artifacts')) {
|
||||
return;
|
||||
}
|
||||
$now = Time::now('Asia/Kolkata')->toDateTimeString();
|
||||
$update = ['last_polled_at' => $now, 'updated_at' => $now];
|
||||
if ($status !== '') {
|
||||
$update['last_status'] = $status;
|
||||
}
|
||||
$this->db->table('abdm_hiu_consent_artifacts')
|
||||
->where('consent_request_id', $consentRequestId)
|
||||
->where('artifact_id', $artifactId)
|
||||
->update($update);
|
||||
}
|
||||
|
||||
private function getKnownArtifactIds(string $consentRequestId): array
|
||||
{
|
||||
if (! $this->db->tableExists('abdm_hiu_consent_artifacts') || $consentRequestId === '') {
|
||||
return [];
|
||||
}
|
||||
$rows = $this->db->table('abdm_hiu_consent_artifacts')
|
||||
->select('artifact_id')
|
||||
->where('consent_request_id', $consentRequestId)
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
return array_values(array_unique(array_map(
|
||||
static fn (array $row): string => trim((string) ($row['artifact_id'] ?? '')),
|
||||
$rows
|
||||
)));
|
||||
}
|
||||
|
||||
public function listTimeline(array $filters, int $limit = 200): array
|
||||
{
|
||||
if (! $this->db->tableExists('abdm_hiu_workflows')) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user