Commit Graph

111 Commits

Author SHA1 Message Date
2e7e33238b Fix fatal memory-exhaustion crash in Consent Request History: cap response_json to NULL for data_fetch/hi_data_push_callback rows
Those operations can store the entire decrypted FHIR bundle (incl. base64 scanned-document attachments, sometimes MB per row) in response_json. fetchAbdmWorkflowRows()/getLatestAbdmSyncSnapshot() only ever read small consent-status/hi_types fields out of response_json, which never appear in bulk data_fetch payloads anyway, so cap it at the SQL level instead of buffering it into PHP memory just to build a list view.
2026-07-29 03:35:46 +05:30
37dba1948e Redesign Consent Request History table columns and add Fetch/Show Data modal with FHIR section accordion 2026-07-29 03:16:24 +05:30
7129f6e17b Show Consent Request ID in Consent Request History and fetched-document list; persist consent_request_id per document 2026-07-29 03:05:02 +05:30
ad98afbe57 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.
2026-07-29 02:31:29 +05:30
c87928c2bc Support Method 3 (fetch by abha_address) as fallback to surface historical ABDM records
Per bridge gateway team guidance, GET /v1/hiu/data/fetch?abha_address=... returns ALL historical decrypted records across every past consent for a patient, unlike the consent/request-scoped Methods 1/2 previously used exclusively. Added M3HiuWorkflowService support for a fetch_by_abha_address flag on the data_fetch operation, and wired abdm_content_fetch_only() to automatically fall back to this broader lookup when the consent-scoped fetch finds nothing new -- this surfaced 14 previously-invisible historical documents (consultation reports, pathology/cytology) for the test patient that were never being fetched before.
2026-07-29 02:19:56 +05:30
690dbf9572 Fix misleading 'fetched successfully' message on Fetch Records when no documents were actually saved
abdm_content_fetch_only() always returned phase=COMPLETED and 'Records fetched successfully' whenever the data_fetch API call itself succeeded (fetchResult.ok===1), even when documents_persisted+documents_updated was 0 (bridge/HIP hasn't actually delivered any records yet -- decrypted_data still empty, session status 'requested'). Now check documents_persisted+documents_updated: if 0, report phase=GRANTED with a clear 'not sent any records yet' message instead of falsely claiming success.
2026-07-29 02:08:25 +05:30
afd1de04bf Fix ABDM consent status showing COMPLETED before data actually arrived
computeConsentSessionDetail() treated any data_fetch/hi_data_push_callback row with status=success as proof the session reached COMPLETED. But the DB 'status' column only reflects whether the underlying API call/poll succeeded (no HTTP/transport error) -- NOT whether data was actually received; that's tracked separately via workflow_state (DATA_PENDING vs DATA_RECEIVED). A data_fetch poll that succeeds at the HTTP level but returns decrypted_data=[] (bridge still processing) was incorrectly marked COMPLETED instead of staying at GRANTED. Now also require workflow_state === DATA_RECEIVED for the COMPLETED phase.
2026-07-29 01:55:15 +05:30
67daaf8894 Fix ABDM consent modal showing all HI types as DENIED when granted via async data push
When a consent session's overall phase resolves to GRANTED/COMPLETED via a data_fetch or hi_data_push_callback row (proof data was actually fetched), but no consent_reconcile/consent_status row in that session ever recorded which hi_types were granted (e.g. data arrives via async push before any reconcile poll runs), grantedHiTypes stayed empty and every requested HI type was incorrectly marked DENIED. Fall back to treating the full requested set as granted when we have positive proof of GRANTED/COMPLETED but no negative evidence of per-type denial.
2026-07-29 01:44:17 +05:30
0a19ccb425 Fix ABDM Consent Request History UI showing blank/orphaned COMPLETED row: fetchAbdmWorkflowRows() now always includes every consent_request anchor row for the ABHA (merged with recent-200 window), so heavy per-artifact data_fetch polling volume can no longer push a session's CONSENT_REQUEST row out of range and break groupWorkflowRowsIntoSessions() 2026-07-29 01:21:54 +05:30
1439ce0fcc Fix invalid ABDM HIType codes (HealthDocument->HealthDocumentRecord, Wellness->WellnessRecord) causing consent_request 400; fix extractErrorText for array-shaped bridge error responses 2026-07-28 22:16:22 +05:30
dec025d6bf ABDM Custom Request: default Expiry Date uses exact +1 year instead of +365 days 2026-07-28 16:57:34 +05:30
7256858562 ABDM Custom Request modal: Purpose as fixed dropdown + add Expiry Date field 2026-07-28 16:54:00 +05:30
25db2e5ddc ABDM OPD tab: replace flow buttons with per-patient Consent Request History list (Phase 3) 2026-07-28 16:42:20 +05:30
48d19f0ff7 ABDM: add manual Consent Request form with editable HI types + date range (Phase 2)
- New Patient::abdm_content_request_custom(int \) endpoint builds a custom
  consent{} block (purpose, hiTypes, permission.dateRange, dataEraseAt) from
  user-submitted hi_types[]/date_from/date_to/purpose form fields, instead of
  always using M3HiuWorkflowService::buildDefaultConsent()'s hardcoded
  OPConsultation+DiagnosticReport / 365-day defaults. Reuses the existing
  requester/hiu-id resolution and hiTypes normalization already built into
  preparePayloadForOperation() for the consent_request operation, so no
  M3HiuWorkflowService changes were needed.
- New route (POST) patient/abdm_content_request_custom/(:num).
- New 'Custom Request' button + '#abdmCustomConsentModal' form
  (Patient_Profile_Opd_V.php) with HI type checkboxes (OPConsultation,
  DiagnosticReport, Prescription, DischargeSummary, HealthDocument,
  ImmunizationRecord, Wellness, Invoice), Valid From/To date inputs
  (defaulted to today-365d..today), and a Purpose text field. On submit,
  reuses the existing auto-flow polling loop (runAutoFlowStep) with the
  returned request_id to track status through to data fetch.
- Live-verified end-to-end on patient 11 (Devender Singh): submitted a
  request for OPConsultation + DiagnosticReport + Prescription; sandbox
  granted only OPConsultation/DiagnosticReport, and the Phase 1 consent
  detail modal correctly showed Prescription as DENIED alongside the two
  GRANTED types, confirming the partial-grant per-HI-type breakdown works
  correctly end-to-end.
2026-07-28 16:23:47 +05:30
7f47045c55 ABDM: add per-HI-type Consent Detail view (Phase 1)
- New Patient::getAbdmConsentArtifactDetail() helper builds a requested-vs-granted
  HI type breakdown for a patient's current ABDM consent artifact, using the
  bridge-team-confirmed 'Option A' model: overall status is single-valued
  (GRANTED/REVOKED/EXPIRED/DENIED), per-type status is derived by comparing the
  requested hiTypes (from the saved consent_request request_json) against the
  granted hi_types array (already flattened onto responses by
  M3HiuGatewayClient). No bridge changes or DB migrations required.
- New Patient::abdm_consent_detail(int \) JSON endpoint + route
  patient/abdm_consent_detail/(:num).
- New 'View Consent' link + Bootstrap modal on the OPD ABDM tab
  (Patient_Profile_Opd_V.php) rendering a lifecycle stepper, consent metadata
  (Consent ID, Purpose, Valid From/To, Erase Date), and a per-HI-type table
  (Document Type / Permission / Status / Timestamp).
- Fixed a bug found during live testing: once a consent reaches COMPLETED
  (after a successful data_fetch), the highest-priority workflow row has no
  hi_types field (it's a FHIR data bundle), which was causing all granted
  types to show as DENIED. Now searches workflow history for the most recent
  row that actually carries the granted hi_types payload.
- Live-verified against patient 15 (Meera Bisht): both requested HI types
  (OPConsultation, DiagnosticReport) correctly show GRANTED with timestamps.
2026-07-28 16:17:10 +05:30
37c3592f69 ABDM: auto-expire stale pending consent requests after 1 hour
Previously, clicking 'Fetch ABDM Records' when a prior consent request was
stuck in REQUESTED/PENDING (no GRANTED/DENIED callback ever received from
the ABDM bridge/PHR - e.g. patient never opened/approved it in their PHR
app) would just resume/re-poll that same dead request indefinitely, since
getLatestAbdmSyncSnapshot() always prioritized the existing REQUESTED
request over starting a new one.

Now:
- getLatestAbdmSyncSnapshot() computes the age of a REQUESTED/PENDING
  snapshot's updated_at and marks restart_required = true once it has
  been pending for more than ABDM_PENDING_STALE_SECONDS (1 hour).
- abdm_content_auto_flow() honors this flag: when the last sync is stale,
  it no longer resumes the old request_id and instead falls through to
  create a brand-new consent_request against the bridge.

Verified locally: a 6h-old stale REQUESTED request for a test ABHA was
correctly abandoned and a fresh consent_request was created and granted
on the next 'Fetch ABDM Records' click, instead of re-polling the dead
request.
2026-07-28 14:36:15 +05:30
becff35929 ABDM OPD tab: fix duplicate fetched-document rows + add dedicated Fetch Records action
- M3HiuDocumentRepository::persistFromDataFetch no longer includes the
  per-call request_id in the document dedup hash. request_id is unique
  every time data_fetch runs, so it was causing a brand-new duplicate
  row to be inserted on every re-fetch of the exact same ABDM document.
  Now dedup key is transaction_id + consent_ref + care_context_reference
  + bundle_id, which stays stable across repeated fetches -> re-fetches
  UPDATE the existing row instead of duplicating it.
- Added Patient::abdm_content_fetch_only() + route
  billing/patient/abdm_content_fetch_only/(id): a lightweight action for
  when consent is already GRANTED/COMPLETED. It calls data_fetch directly
  using the saved consent reference, skipping consent_request + reconcile
  polling entirely, avoiding unnecessary bridge calls/noise.
- Patient_Profile_Opd_V.php: added a 'Fetch Records' button that only
  appears once consent phase is GRANTED or COMPLETED, wired to the new
  endpoint; on success it refreshes the document list in place. The
  original 'Fetch ABDM Records' button still owns the full consent
  request -> reconcile -> fetch flow and already stops/re-enables
  correctly on DENIED/FAILED (verified, no change needed there).
- One-time cleanup: deduped existing abdm_hiu_documents rows in dev DB
  (13 -> 3) and recomputed doc_hash with the new stable key.
2026-07-28 04:34:08 +05:30
716ad04d13 Fix duplicate ABDM consent requests: only treat consent_request submission failure as terminal FAILED 2026-07-28 02:36:27 +05:30
acc4e5c287 Prefer recent granted/completed over pending 404 snapshot 2026-07-28 02:28:57 +05:30
5c15424280 Promote granted consent status in snapshot ranking 2026-07-28 02:26:19 +05:30
98b25914d7 Include callback operations in ABDM sync snapshot 2026-07-28 02:15:34 +05:30
71e0c7cf24 Treat transient consent 404 as pending 2026-07-28 02:07:50 +05:30
c2a3e3054f Resolve fallback consent status in OPD flow 2026-07-28 01:53:44 +05:30
a15f5a0785 Handle failed ABDM consent reset and add status help 2026-07-28 01:05:25 +05:30
3b6ed76a3c Reset stale ABDM request flow after bridge 404 2026-07-27 15:21:42 +05:30
0048cb1eff Resume granted consent flow on reconcile 404 and attempt direct fetch 2026-07-27 15:01:36 +05:30
698b9cd520 Prefer granted/completed ABDM state over latest 404 reconcile rows 2026-07-27 14:40:39 +05:30
c77201ec96 Persist and resume ABDM sync state on profile reload 2026-07-27 14:32:47 +05:30
8086bfbeb6 Stop ABDM auto-sync polling on reconcile 404 2026-07-27 14:28:42 +05:30
49698a72d7 Handle ABDM reconcile not-found as pending state 2026-07-27 14:18:07 +05:30
92a954a4cd Fix ABDM HIU auto-flow duplicate consent handling 2026-07-27 14:12:56 +05:30
39b5fc7c3e Use opd_no on OPD history header 2026-07-25 21:20:10 +05:30
4e060b9b98 Add patient details to OPD history header 2026-07-25 21:03:06 +05:30
5d6acdd480 Implement ABDM bridge health record flows
- add facility QR support and OPD queue bridge fixes
- support care-context push warnings for lab, radiology, IPD and remaining HI types
- improve ABHA patient matching and diagnosis autocomplete performance
- clean up webcam streams on page navigation
2026-07-20 03:02:09 +05:30
2b53c05a68 Add ABDM documents and patient profile sync UI 2026-07-16 18:23:40 +05:30
540de8c76e Enhance camera capture/edit permissions and fix OPD AdviceBlock rendering 2026-07-08 15:24:39 +05:30
3d40642116 Add ABDM M3 HIU workflows, routes, UI, and runbook docs 2026-07-01 17:37:53 +05:30
985d476bc1 ABDM: finalize ABHA verify persistence, M2 routes/workflows, and location masters seeding 2026-06-24 03:15:22 +05:30
75e71c2343 Fix new patient create 500 from undefined ABHA lock flag 2026-06-22 08:30:36 +05:30
96c030b72d chore: checkpoint before discharge history panel refactor 2026-06-22 02:05:24 +05:30
1bac1f6e04 feat: update storestock flow and ABDM bridge handling 2026-06-18 17:38:20 +05:30
cad5a477bf Sync OPD history flow and discharge UI refinements 2026-06-11 19:30:02 +05:30
0d9ff81a97 Add DataTables search box support to patient search - now handles both initial search and live filtering 2026-06-06 14:56:02 +05:30
d82078c9ed Convert patient search to DataTables with AJAX server-side processing
- Updated Patient::search() to only render view with search query
- Created Patient::search_ajax() method for DataTables AJAX endpoint
- Implemented server-side processing with pagination, sorting, and filtering
- Results ordered by Last Visit DESC by default
- Retrieves all patient data from patient_master table
- Added proper SQL escaping to prevent injection
- Updated Patient_Search_V.php to use DataTables with AJAX remote data
- Added DataTables configuration with 25 rows per page default
- Supports dynamic length menu (10, 25, 50, 100, All)
- Added route for billing/patient/search_ajax endpoint
- Improved user experience with loading spinner and customized messages
2026-06-06 14:52:10 +05:30
8ef46cddb1 Add permission for Admin to edit patient name anytime
- Add billing.patient.edit-name-anytime permission to AuthGroups
- Update patient edit time restriction from 12 hours to 24 hours
- Modify Person_Edit_V to check for edit-name-anytime permission
- Admin can now edit patient name field (input_name) even after 24-hour window
2026-06-05 17:33:31 +05:30
45abd3ca76 Store ABHA ID and ABHA address separately 2026-06-02 06:00:35 +05:30
701111b75e fix(patient): avoid queue_no select on legacy opd_master schema 2026-05-31 21:02:55 +05:30
a56e8a5776 feat: SNOMED background coding pipeline + ABDM Coding Panel
- Add opd_coding_queue + opd_snomed_suggestions migrations
- Add ProcessSnomedCoding spark command (cron: snomed:process-coding)
  Extracts clinical phrases, matches local SNOMED FULLTEXT, saves suggestions
- Add AbdmCodingPanel controller: index/review/confirm/reject/correct/mark_fhir_ready/tip_check
- Add coding_panel + coding_panel_review views (Bootstrap 5, AJAX actions)
- Inject queue trigger in opd_prescription_save (fail-open, ON DUPLICATE KEY)
- Add consult form tip badge: polls tip_check 4s after save, shows review link
- Add AbdmCodingPanel routes behind abdm permission filter
- Various ABDM gateway, FHIR, ABHA, SNOMED library updates
2026-05-19 20:40:27 +05:30
0628f8f813 feat: ABDM OPD Queue + ABHA Register flow + patient ABHA search fix
ABDM OPD Queue (today):
- New EAtriaBridgeConnector: opdQueueFetch/opdTokenCreate/opdTokenUpdateStatus + patch() helper
- New AbdmOpdQueue controller: index/list/fetchQueue/createToken/updateTokenStatus/processScannedToken
  - fetchQueue syncs gateway tokens into abdm_opd_tokens (local DB) and enriches with HMS patient data
  - processScannedToken auto-finds/creates patient_master record from ABHA scan data, marks token CALLED
- New migration: abdm_opd_tokens table (gateway_token_id, source, status, patient_id, opd_id, processed_at)
- New view: abdm/opd_queue.php - reception screen with auto-refresh 30s, HMS Patient column (green row when OPD registered)
- Sidebar: ABDM OPD Queue nav link added
- Routes: AbdmOpdQueue with abdmPermFilter

ABHA Register tab (earlier this session):
- New Abha controller: initiate/verifyOtp/communication/verifyCommOtp/validateAbha/card + autoCreateOrFindPatient
- New views: abha/card.php, partials/abha_create_panel.php, partials/abha_otp_modal.php
- Patient_V.php: ABHA Register tab with 4-method wizard (ABHA number, QR scan, facility QR, mobile OTP)

Patient ABHA search fix:
- Patient::search() now detects ABHA column (abha_id/abha_no/abha/abha_address) and searches by it

ABDM Bridge infrastructure:
- EAtriaBridgeConnector: new connector for e-atria.in ABDM bridge gateway
- AbdmConnectorFactory/Interface updated
- AbdmGatewaySettings controller + view
- SNOMED/CSNOTK terminology service skeleton
- Finance payout OPD consult views
- Migration: AddAbdmPushFieldsToOpdAndPatient, CreateSnomedCoreTables
- Docs: abdm/ API specs, architecture, gateway guides
2026-05-16 04:21:31 +05:30
5d5c9656ea billing: improve patient name display on consult form and history page 2026-05-08 13:49:37 +05:30
fbb03a6abb billing: redesign ABHA wizard, enhance patient info panels and consult page photo/layout 2026-05-08 13:29:57 +05:30
baba5521dd Fix dashboard and OPD counts for DATETIME appointment_date 2026-04-28 11:23:06 +05:30
6ae9a3516f feat: add HealthPlix OPD sync flow with settings, diagnostics, and sync ID persistence 2026-04-27 08:32:51 +05:30
d02244444e finance/storestock: implement cash submission audits, bank settlements, and opd payout tracking 2026-04-22 10:53:20 +05:30
7e4903bd68 billing: add patient history action and legacy-style OPD history view 2026-04-22 10:33:29 +05:30
19db43762d Enhance OPD and patient workflows with live updates and UX improvements 2026-04-07 03:27:39 +05:30
062fc7ab32 feat: Add ABDM Task Board module with ABHA workflow
- Add ABDM sidebar heading and Task Board nav link
- Create migration 000040: abdm_work_tasks table
- Add AbdmTaskBoard controller with backfill methods
- Add AbdmWorkTaskService for task creation/deduplication
- Add AbdmGateway controller for ABDM API integration
- Separate task types: patient_abha_create vs patient_abha_update
- Add lab_report_publish and radiology_report_publish task types
- Patient.php: auto-create ABDM tasks on registration
- Diagnosis.php: auto-create tasks on report verify/finalize
- Task board UI: 7 filter buttons with default Unupdated ABHA view
- Fix SQL crash in backfillLabRadiologyTasks (dynamic column detection)
- Improve load_form AJAX error display with HTTP status + response text
- Add ABDM routes in Routes.php
- Add FHIR R4 builder library updates
- Add bridge sync service updates
2026-04-05 23:42:24 +05:30
9d88aaa2a6 Implement ABDM identity storage and align OPD consult/medicine dose masters 2026-04-04 17:26:40 +05:30
e282289227 Default new patient blood group to Not Define 2026-04-02 17:49:45 +05:30
aa845ac5ff Add report panel updates and related billing/discharge enhancements 2026-03-10 02:43:35 +05:30
614713f76b Implement OPD template builder, doctor template selection, and OPD print integration fixes 2026-02-27 19:44:36 +05:30