- Shortened template-scoped paper setting keys to avoid s_name length limits in legacy schemas
- Added legacy key fallback so existing saved settings still load
- Updated rename/delete/reset flows to handle both new and legacy key aliases safely
- Restored corrupted buildOpdLetterPrintData method that broke class structure
This fixes the 'Unable to save OPD paper print settings' error when saving new templates
- add new permissions:
template.opd_print, template.pathology_print, template.diagnosis_print,
template.document_print, template.ipd_document
- Template controller now accepts new permission keys (with backward-compatible fallbacks)
- IPD Document Master now has independent permission key (template.ipd_document)
- Template index tile visibility updated to use new granular keys
- OPD print template builder now honors template.opd_print permission
- preserve existing behavior via legacy permission fallbacks to avoid role breakage
- add formatAiReportHtml() in opd_prescription_basic to render labeled sections
- auto-format loaded patient scan history reports after AJAX load
- format updated report immediately after Run AI response
- keep raw report text for Use Report action while presenting readable UI blocks
- style history report container as light card for clearer visual structure
- new rx_group_delete(int rxId) method in Opd_prescription controller
- deletes linked medicines first (opd_prescrption_prescribed_template), then group row
- POST route: Opd_prescription/rx_group_delete/(:num)
- Delete button (red) added to each row in Rx-Group list table
- confirm dialog before delete (shows group name)
- reloads list after delete; clears form if deleted group was loaded
- cache session medicine rows in currentSessionMedicineRows on every renderMedicine() call
- when Create Rx-Group modal opens, show all current consult medicines as checkboxes
- all medicines pre-checked by default so they are included in the new Rx-Group
- uncheck any medicine to exclude it from the Rx-Group
- crgcMedicineList built from checked rows; manually added medicines preserved
- medicines listed as chips: Type Name (Dose When Freq) for quick readability
- expanded rxGroupCreateModal to modal-xl with two-column layout
- left column: group info (name, complaints, diagnosis, investigation, finding)
- right column: medicine form (name autocomplete, type, dose/when/freq/where, days/qty/remark)
- medicine name search uses medicine_search endpoint with datalist
- type auto-fills on datalist selection (same Chrome input-event fix as main form)
- dose/when/freq/where selects populated from medicineDoseMasterCache (already loaded)
- + Add Medicine adds to local crgcMedicineList array with live table display
- Remove button (x) on each row in the pending medicine table
- Save Rx-Group: creates group then batch-saves all medicines sequentially
- Save & Apply: same as above then applies group to current session
- added '+ Rx-Group' button beside Rx Group selector in medicine panel
- added rxGroupCreateModal with Name/Complaints/Diagnosis/Investigation/Finding fields
- pre-fills Complaints and Diagnosis from current consult textarea values
- Save: creates group and refreshes catalog (group appears in selector)
- Save & Apply: creates group and immediately applies it to current session
- error shown inline in modal, catalog reloads after successful create
- remove use_count/(0) decoration from datalist option value
- option value is now plain med_name, no star or count suffix
- extract applyMedicineSelection() helper to avoid code duplication
- detect datalist selection inside input callback (Chrome fires input not change)
- type, med-id, favorite button all fill immediately when exact name match found
- change handler simplified: matches against medicineSuggestRows array directly
- consult form medicine Dose/When/Freq changed to dropdowns from dose masters
- added Where dropdown in consult medicine editor and table display
- consult now loads options from Opd_prescription/rx_group_dose_masters
- medicine add/update payload now includes dosage_where
- medicine list now returns dosage_where_label for readable table output
- edit mode supports existing values not present in current master set
- quick chips now map into select options (with safe fallback)
- use namespaced delegated handlers in opd_rx_group_workspace
- call off(...namespace...) before on(...) for all click actions
- resolves multiple rx_group_get calls on single Edit click after panel reopen
- default speech mode preference changed to browser
- on consult load, preference is reset to browser and saved
- prevents automatic /stt-proxy calls until server STT is stabilized
- manual mode selector remains available for future server testing
- Added Mic Mode selector in consult header
- Apply one preference to both Complaints Mic and Med Mic
- Browser mode can be forced to bypass /stt-proxy 400 errors
- Preference persisted in localStorage
- Mode change stops active recordings safely before applying
- Med Mic now supports server mode and browser speech-recognition mode
- auto-select mode from STT server health: server -> browser -> off
- click behavior updated for both modes (start/stop on same button)
- server failure now auto-falls back to browser mode when supported
- Med Mic labels now reflect current mode (server/browser/off)
- sttProxy now returns detailed upload error info (code, error string, php limits)
- sttProxy accepts fallback upload field name 'file' in addition to 'audio'
- reject empty audio payloads with explicit message
- client: guard against very short/empty blobs before POST to /stt-proxy
Production runs HTTPS; browser blocks http://139.59.13.39:8000 (mixed content).
Solution: CI4 proxy endpoints forward audio/health check server-side (HTTP→HTTP).
- Home::sttProxy() POST stt-proxy - forwards audio to STT server
- Home::sttProxyHealth() GET stt-proxy/health - pings STT and returns {ok:bool}
- JS: auto-detect window.location.protocol; use proxy URLs on HTTPS,
direct IP URLs on HTTP (local/dev)
- checkComplaintsSttServer: parse {ok:bool} from proxy health response
When recording started, setMedicalMicButtonState() removed btn-medical-stt class
from the active button and the click handler (bound to .btn-medical-stt) never
fired on second click, so recording ran forever with no way to stop.
Fix: keep btn-medical-stt class always; only add/remove btn-danger for active state.
- initComplaintsSpeech() now calls checkComplaintsSttServer() async:
server up → mode 'server', browser fallback → mode 'browser', else 'off'
- click handler now handles both 'server' and 'browser' modes
(previously only 'browser' was handled, server mode click did nothing)
- show '…' while server health check is in progress to avoid confusion
- Add complaints Speech-to-Text (browser + server STT fallback) with interim preview
- Add Medical Mic (server STT) for examination, diagnosis, provisional diagnosis fields
- Add speech-test route + Home::speechTest() view for STT testing
- OPD prescription: resolve dosage/when/frequency labels from lookup tables
- OPD prescription: show generic/salt name below medicine name in print
- OPD prescription: translate complaints/diagnosis/advice/investigation to Hindi for patient
- Add translateToLocalPatientText() helper with English->Hindi medical term map
- Add 'Remove All' medicines button (btn_clear_medicine)
- Add template search box in Load Template modal
- Fix investigation batch add: dedup + guard against concurrent add
- Fix single investigation add: check duplicate before adding
- Fix rx status text overflow: ellipsis + title tooltip
- Remove unused FHIR History and Back to Invoice buttons from Rx header
- .gitignore: exclude public/uploads/* and writable/ayushman/*
- Redact AIzaSy Gemini key from clinical_audit_trail entries in seed JSON
- Add default never-export denylist to exportMasterSeedData() so that
clinical_audit_trail, lab_log, bridge_sync_queue and session tables are
always skipped when setup.seed.export_tables is not configured.
This prevents API keys set via the admin UI from leaking into git via
the audit trail even after being deleted from hospital_setting.
- Add migration 2026-03-18-000028_CreateCityAutoUTable.php to create
the missing city_auto_u table (city, district, state columns) used
by PatientModel::getCitySuggestions() — resolves 500 on /billing/patient/city
- Fix HospitalProfile::save() to check directory creation success before
moving uploaded logo files; returns clean JSON error instead of
throwing HTTPException when public/assets/images/ is not writable