Skip to content

Release 3.6.1 to main#268

Merged
snehar-nd merged 60 commits into
mainfrom
release-3.6.1
Apr 24, 2026
Merged

Release 3.6.1 to main#268
snehar-nd merged 60 commits into
mainfrom
release-3.6.1

Conversation

@snehar-nd
Copy link
Copy Markdown
Contributor

@snehar-nd snehar-nd commented Apr 24, 2026

📋 Description

JIRA ID:

Amm-2279

✅ Type of Change

Summary by CodeRabbit

Release Notes - Version 3.6.1

  • New Features

    • Added ABHA care context linking support.
    • Enabled Elasticsearch search functionality.
    • Added doctor signature capability.
  • Improvements

    • Enhanced session expiry handling and timeout management.
    • Improved prescription form validation with clearer error messages.
    • Updated UI translations across multiple languages.
    • Enhanced dialog styling for better user experience.
  • Chores

    • Updated API endpoints and configurations across environments.

helenKaryamsetty and others added 30 commits October 6, 2025 13:47
* fix(bug): saving abdm facilityid in session storage

* fix(bug): saving abdm facilityid in session storage

* feat: abdm M2 V3

---------

Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
* fix(bug): saving abdm facilityid in session storage

* fix(bug): saving abdm facilityid in session storage

* feat: abdm M2 V3

* feat: latest common-ui commit

---------

Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
* fix(bug): saving abdm facilityid in session storage

* fix(bug): saving abdm facilityid in session storage

* feat: abdm M2 V3

* feat: latest common-ui commit

* feat: added abha m2 APIs

---------

Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
* feat: amm-1811 edge cases handled

* fix: amm:1307 healthId, healthIdNumber mismatch issue fix
* fix(bug): saving abdm facilityid in session storage

* fix(bug): saving abdm facilityid in session storage

* feat: abdm M2 V3

* feat: latest common-ui commit

* feat: added abha m2 APIs

* fix: closed dialog after linking

---------

Co-authored-by: Karyamsetty Helen Grace <ka40094929@wipro.com>
fix: amm-1990, 1985, 1972, 1982, 1989, 1983, 1987,1986
fix: amm-1986, 1990 - common-ui reference update and version update
Elastic search implementaion.
fix: comma was missing in ci file
helenKaryamsetty and others added 25 commits December 30, 2025 12:17
Elastic seach API integration.
fix: pushing the common ui code of 3.6.1 to hwc ui
fix: pushed the common ui elastic search code to HWC UI
fix: amm-2038 addind common ui changes to hwc
fix: amm-2038 updated the advancesearch api end point
fix: amm-1931 JWT error handling issue
* fix: aam-2159 changed text from advancesearch to advanced search

* fix: amm-1979 validation for prescription

* Correct spelling in 'advanceBeneficiarySearch'

---------

Co-authored-by: 5Amogh <amoghavarsh@navadhiti.com>
Co-authored-by: Amoghavarsh <93114621+5Amogh@users.noreply.github.com>
fix: amm-2192 remove mandatory for prescription
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
7.6% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

📝 Walkthrough

Walkthrough

This PR updates build version metadata, refactors HTTP session-expiry handling with explicit state management, threads a doctor signature flag through service APIs, removes HTML template required constraints from prescription fields, adds corresponding synchronous validation logic, and extends environment configurations with Elasticsearch and ABHA care-context API endpoints alongside comprehensive UI translation updates.

Changes

Cohort / File(s) Summary
Submodule & Build
Common-UI, pom.xml
Submodule pointer updated to new commit; Maven version bumped from 3.6.0 to 3.6.1.
Core Services
src/app/app-modules/core/services/confirmation.service.ts
MatDialog dependency changed from private to public to allow external access.
HTTP Interceptor Refactoring
src/app/app-modules/core/services/http-interceptor.service.ts
Session-expiry state now managed explicitly via sessionTimeoutRef, pendingRequests counter, and isHandlingSessionExpiry flag. Spinner toggled based on request count. Error handling refactored to conditionally trigger session-expiry once. New handleSessionExpiry(), getErrorMessage(), extendSession(), and isSessionExpiryInProgress() methods added. Session state reset on login and router navigation.
Prescription Validation
src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/prescription.component.html, prescription.component.ts
HTML required attributes removed from medicine form, medicine name, dosage, frequency, quantity fields. New validateCurrentPrescription() method performs synchronous validation, accumulating field-specific errors and blocking submission with alert display.
Quick Consult Template
src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.html
HTML required constraints removed from form, medicine, dose, frequency, duration, unit, and quantity fields.
Doctor Signature Flag Integration
src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts, src/app/app-modules/nurse-doctor/workarea/workarea.component.ts, src/app/app-modules/nurse-doctor/case-sheet/general-case-sheet/doctor-diagnosis-case-sheet/doctor-diagnosis-case-sheet.component.ts
doctorSignatureFlag parameter added to six doctor submission methods and update method in service. WorkareaComponent initializes flag from checkUsersignatureExist() endpoint and threads it through submission calls. Diagnosis case-sheet now conditionally skips signature download unless flag enabled.
Nurse Workflow Updates
src/app/app-modules/nurse-doctor/nurse-worklist-wrapper/nurse-worklist/nurse-worklist.component.ts, src/app/app-modules/nurse-doctor/doctor-worklist/doctor-worklist.component.ts
Confirmation dialog now supplies explicit localized button labels. Doctor worklist redirect changed from same-tab window.location.href to new-tab window.open with noopener,noreferrer.
Lab & Layout Components
src/app/app-modules/lab/workarea/workarea.component.ts, src/app/app-modules/registrar/family-tagging/create-family-tagging/create-family-tagging.component.html
Lab workarea: formatting/indentation restructured. Family tagging: dialog action container now uses Flexbox layout with justify-content: flex-end and gap: 12px.
Environment Configuration
src/environments/environment.*.ts, src/environments/environment.ci.ts.template
All environment files extended with isEnableES: true flag and multiple new endpoint URLs: Elasticsearch search endpoints (elasticSearchUrl, advanceElasticSearchUrl), user signature check (checkUsersignExistUrl), care-context linking APIs (generateLinkTokenForCareContext, linkCareContext), and user ID lookup (getUserId). Development environment updates FHIR_API base path to fhir-api-abdm/.
Translation & UI Strings
src/assets/Assamese.json, src/assets/English.json, src/assets/Hindi.json, src/assets/Kannada.json, src/assets/language.json
Comprehensive updates to UI text across multiple languages: added new ro.abhaInfo section and tc.accept action label; updated registrar/bendetails/common keys with localized strings; corrected English phrasing ("Advanced Search"). Assamese file replaced MISSING_WORDS block with retranslated equivalents.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A signature flag dances through the doctor's flow,
Elasticsearch now whispers where to go,
Prescriptions validate with methodical care,
Session timers reset with proper flair,
From Assamese to Kannada, translations bloom bright—
These changes compose a symphony of might! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes a release action (version 3.6.1) targeting the main branch, which aligns with the changeset's pom.xml version bump and the PR's stated release objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release-3.6.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/environments/environment.prod.ts (1)

71-88: ⚠️ Potential issue | 🟠 Major

Use the production ABHA suffix here before enabling the new prod ABHA flows.

Line 87 still sets abhaExtension to @sbx. With the new production ABHA/care-context endpoints in this file, that keeps prod traffic on the sandbox namespace and will break or mismatch ABHA identifiers in production. This should be @abdm for environment.prod.ts.

Suggested fix
-  abhaExtension: `@sbx`,
+  abhaExtension: `@abdm`,

Based on learnings, in this project abhaExtension is set to sbx in development/test and to abdm in environment.prod.ts for production.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/environments/environment.prod.ts` around lines 71 - 88, The
environment.prod.ts file's environment object wrongly sets abhaExtension to
'@sbx' which keeps production ABHA identifiers in the sandbox namespace; update
the environment constant's abhaExtension property (abhaExtension) to '@abdm' so
production ABHA/care-context endpoints use the correct production suffix and
avoid mismatched identifiers when prod ABHA flows are enabled.
🧹 Nitpick comments (6)
src/app/app-modules/registrar/family-tagging/create-family-tagging/create-family-tagging.component.html (1)

117-117: Consider moving inline styles to component stylesheet.

The inline styles added to <mat-dialog-actions> would be better maintained in the component's CSS file. This improves reusability and makes it easier to maintain consistent styling across the application.

Additionally, the pull-right class becomes redundant when display: flex is applied, as flexbox layout ignores float-based positioning.

♻️ Proposed refactor

In the component's CSS/SCSS file, add:

.dialog-actions-flex {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

Then update the template:

-    <mat-dialog-actions class="padding15 margin15 pull-right" style="display: flex;justify-content: flex-end;gap:12px">
+    <mat-dialog-actions class="padding15 margin15 dialog-actions-flex">

Minor formatting note: The inline style could use spaces after semicolons for consistency (flex; justify-content instead of flex;justify-content).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/app-modules/registrar/family-tagging/create-family-tagging/create-family-tagging.component.html`
at line 117, Move the inline styles from the <mat-dialog-actions> tag into the
component stylesheet: create a reusable CSS class (e.g., dialog-actions-flex) in
CreateFamilyTaggingComponent's stylesheet that sets display:flex,
justify-content:flex-end and gap:12px, add that class to the
<mat-dialog-actions> element and remove the inline style and the redundant
pull-right class; ensure spacing/formatting in the stylesheet is consistent.
src/app/app-modules/core/services/http-interceptor.service.ts (2)

152-184: getErrorMessage can be simplified; also called with a plain string at L197.

Three things worth cleaning up here:

  1. SonarCloud flags cognitive complexity 16 (>15) on this function.
  2. The happy path in handleSessionExpiry already builds errorMessage: string before calling this.getErrorMessage(errorMessage) — the helper only guards empty/whitespace, which is cheap to inline.
  3. The two return blocks producing the fallback string are duplicated between the try path and the catch path.

A small extraction of the fallback and a narrower signature (string | Error | { message?; errorMessage?; error? }) will make the function easier to follow and drop its complexity below the Sonar threshold.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/app-modules/core/services/http-interceptor.service.ts` around lines
152 - 184, Refactor getErrorMessage to reduce complexity: extract the fallback
string into a single constant used everywhere, narrow the parameter type to
string | Error | { message?: string; errorMessage?: string; error?: string },
and remove the outer try/catch and duplicated return paths so the function
simply checks types in order (string non-empty, then Error.message, then
object.message/errorMessage/error) and returns the fallback if none match; then
inline the trivial string-guard logic from handleSessionExpiry (i.e. don't call
getErrorMessage with an already-built non-empty string) so callers only pass
payloads that need parsing.

278-286: Minor cleanups flagged by SonarCloud.

  • L278: prefer url.includes('user/userAuthenticate') over indexOf(...) >= 0.
  • L282: url && url.toLowerCase().includes('/platform-feedback')url?.toLowerCase().includes('/platform-feedback').
  • L286: sessionStorage.getItem('authenticationToken') ? true : false!!sessionStorage.getItem('authenticationToken').
  • L65 (same file): same optional-chain suggestion as L282.

All behavior-preserving.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/app-modules/core/services/http-interceptor.service.ts` around lines
278 - 286, Update the URL and token checks in HttpInterceptorService: replace
url.indexOf('user/userAuthenticate') >= 0 with
url?.includes('user/userAuthenticate'); change url &&
url.toLowerCase().includes('/platform-feedback') to
url?.toLowerCase().includes('/platform-feedback'); replace
sessionStorage.getItem('authenticationToken') ? true : false with
!!sessionStorage.getItem('authenticationToken'); also apply the same
optional-chaining change noted at the earlier occurrence (around L65) where url
is checked. These changes preserve behavior while using modern idioms for
'user/userAuthenticate', '/platform-feedback', and 'authenticationToken' checks.
src/environments/environment.dev.ts (1)

577-580: Consider renaming getUserId to getUserIdUrl for consistency.

The key getUserId holds a URL endpoint but uses different naming from neighbouring URL keys (downloadSignUrl, checkUsersignExistUrl, elasticSearchUrl, advanceElasticSearchUrl). Renaming to getUserIdUrl would clarify it's a URL value and match the naming convention throughout the file.

Note: All new keys (isEnableES, generateLinkTokenForCareContext, linkCareContext, getUserId, checkUsersignExistUrl, elasticSearchUrl, advanceElasticSearchUrl) are properly present across all environment files (dev, development, local, prod, test, ci).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/environments/environment.dev.ts` around lines 577 - 580, Rename the key
getUserId to getUserIdUrl to match the URL naming convention used nearby (e.g.,
downloadSignUrl, checkUsersignExistUrl, elasticSearchUrl) and update all
references to this constant across the codebase (including other environment
files and any imports/usages) so they point to getUserIdUrl; ensure the value
remains `${COMMON_API}user/userName/` and that tests/builds are updated to
reflect the new key.
src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts (2)

379-384: Inconsistent shape for doctorSignatureFlag in postQuickConsultDetails compared with the other save methods.

All other methods place doctorSignatureFlag directly inside the main payload object (e.g., alongside tcRequest, isSpecialist in NCDScreeningDetails, ancVisitDetails, etc.). Here it is merged via a separate Object.assign fragment. The result is functionally equivalent but the divergent shape is an easy source of future confusion when grepping/diffing payloads. Consider folding it into temp for consistency.

♻️ Proposed refactor
     const temp = {
       beneficiaryRegID: this.sessionstorage.getItem('beneficiaryRegID'),
       ...
       tcRequest: tcRequest,
       isSpecialist: isSpecialist,
+      doctorSignatureFlag: doctorSignatureFlag,
     };
     const quickConsultation = Object.assign(
       {},
       consultationData.quickConsultation,
       temp,
-      { doctorSignatureFlag: doctorSignatureFlag },
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts` around
lines 379 - 384, The construction of quickConsultation in
postQuickConsultDetails uses a separate Object.assign fragment for
doctorSignatureFlag which makes the payload shape diverge from other save
methods; instead fold doctorSignatureFlag into the same base object (e.g., merge
it into temp or include it directly when building the main payload) so
quickConsultation is built consistently (same top-level placement alongside
tcRequest/isSpecialist). Update the code around quickConsultation and temp in
postQuickConsultDetails to include doctorSignatureFlag in temp (or the primary
payload creation) rather than as a separate Object.assign entry.

3990-3992: Guard against a missing/undefined userID and consider encoding.

environment.checkUsersignExistUrl ends with a trailing / (e.g. …/signature1/signexist/), so if userID is ever null/undefined this will silently hit …/signexist/undefined and return a misleading response. Also, while current userID is numeric, using encodeURIComponent future-proofs the concatenation if the identifier shape ever changes.

🛡️ Proposed hardening
-  checkUsersignatureExist(userID: any) {
-    return this.http.get(environment.checkUsersignExistUrl + userID);
-  }
+  checkUsersignatureExist(userID: any) {
+    if (userID === null || userID === undefined || userID === '') {
+      return throwError(() => new Error('userID is required'));
+    }
+    return this.http.get(
+      environment.checkUsersignExistUrl + encodeURIComponent(String(userID)),
+    );
+  }

(Requires importing throwError from rxjs if adopted.)

Also worth typing the response (e.g. Observable<{ data: { signStatus: boolean } }>) since workarea.component.ts reads res.data.signStatus — it would give the call site compile-time safety.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts` around
lines 3990 - 3992, checkUsersignatureExist currently concatenates userID
directly which allows null/undefined to request ".../undefined" and misses
URL-encoding; update the method checkUsersignatureExist(userID: any) to first
validate userID (return an observable error via throwError if null/undefined)
and then append encodeURIComponent(String(userID)) to
environment.checkUsersignExistUrl; also add a typed return Observable matching
the expected shape (e.g. Observable<{ data: { signStatus: boolean } }>) so
callers reading res.data.signStatus get compile-time safety (import throwError
from rxjs if using it).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/app-modules/core/services/http-interceptor.service.ts`:
- Around line 319-323: The session-warning message is hardcoded in
confirmationService.alert; replace the English literal with the i18n lookup used
elsewhere (e.g., use currentLanguageSet?.sessionAboutToExpire with a safe
fallback to currentLanguageSet?.sessionExpired or a default string) and remove
the stray space before the question mark; update the confirmationService.alert
call in http-interceptor.service.ts and add the new i18n key
(sessionAboutToExpire) to your translations so the prompt is localized
consistently.
- Around line 43-48: The router subscription currently calls resetSessionState()
on any router event with url === '/login', which races with
handleSessionExpiry() and allows duplicate dialogs; fix by preventing reset when
navigation was initiated by the expiry flow—add a boolean flag (e.g.,
isNavigatingAfterExpiry) set in handleSessionExpiry() before calling
router.navigate(['/login']) and check that flag in the router.events handler to
skip resetSessionState() when true, or alternately set logoutMessageShown = true
before router.navigate and only clear it on explicit login/logout; update
references to isHandlingSessionExpiry, logoutMessageShown,
handleSessionExpiry(), resetSessionState(), and ConfirmationService.alert
accordingly so a second concurrent 401/403 cannot reopen the dialog.
- Around line 354-366: extendSession currently swallows errors by returning
of(null) in the catchError and then always calling resetSessionTimeoutTimer() in
subscribe; change extendSession so that resetSessionTimeoutTimer() is only
called when the backend call actually succeeds: have the catchError rethrow or
return throwError (or return of a failure sentinel and check it), and in the
subscribe success handler call resetSessionTimeoutTimer() only for a successful
response (e.g., test for non-null/ok response), while handling errors in the
error handler (or finalize) to avoid extending the client timer when the server
rejected/invalidated the session; update the logic around
this.http.post(environment.extendSessionUrl, {}) / catchError(...) /
subscribe(...) accordingly.

In
`@src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/prescription.component.ts`:
- Around line 392-446: The alert heading and all hardcoded validation labels in
submitForUpload() / validateCurrentPrescription() should be replaced with i18n
keys from current_language_set (e.g., current_language_set?.Prescription or
other existing keys); update the heading string ('Please fill the following
required fields:') to use a language key such as
current_language_set?.Prescription?.mandatoryFields (or add that key), and
replace each error label ('Medicine Form', 'Medicine Name', 'Dosage',
'Frequency', 'Duration', 'Unit', 'Quantity') with the corresponding
current_language_set?.Prescription?.* entries (use
nurseData?.chiefComplaintsDetails?.* if appropriate for any shared labels) so
the confirmationService.alert(errorMessage, 'error') shows fully localized text;
ensure validateCurrentPrescription() builds its errors array with those i18n
values and submitForUpload() composes the numbered message from them.

In
`@src/app/app-modules/nurse-doctor/doctor-worklist/doctor-worklist.component.ts`:
- Around line 119-127: In redirectToCHOReport(), guard against missing or
invalid dhistoken by safely parsing
this.sessionstorage.getItem('loginDataResponse') (catch JSON.parse errors) and
verifying the extracted dhistoken is a non-empty string before constructing the
URL and calling window.open; if the token is missing/invalid, do not call
window.open and instead handle the case (e.g., log via a logger or show a
user-facing message) so you avoid opening `${environment.dhisURL}undefined`.

In `@src/assets/Assamese.json`:
- Line 1959: The Assamese translations object contains duplicate "selfcare"
keys, causing the later value to override the earlier one; locate both
"selfcare" entries and either remove the redundant one or rename one to a
context-specific key (e.g., "selfcare_profile" or "selfcare_section") so both
translations are preserved, then update any consumers to use the new key if you
rename it.
- Around line 1800-1802: The locale object contains duplicate keys
"hypertension", "breastCancer", and "cervicalCancer" (appearing twice), causing
the earlier entries to be overwritten; remove the duplicate entries so each
concept has a single canonical key, or if the duplicated values are intended for
different screens rename one set (e.g., hypertension_screen vs
hypertension_summary) to unique keys; update only the entries for
"hypertension", "breastCancer", and "cervicalCancer" (and the other duplicates
noted around the later section) to eliminate duplication and keep the correct
translated string for each unique key.

In `@src/assets/Hindi.json`:
- Around line 1905-1907: The JSON contains a duplicate key "immunizationService"
(two entries with different Hindi/English values); remove the duplicate and keep
the intended translation or rename one key to a distinct identifier (e.g.,
"immunizationServiceLabel" vs "immunizationServiceAlt") if they represent
different UI contexts, then update any consumers that read the key (components
or i18n lookup calls) to use the chosen/renamed key so no translation is
silently overwritten at runtime.

---

Outside diff comments:
In `@src/environments/environment.prod.ts`:
- Around line 71-88: The environment.prod.ts file's environment object wrongly
sets abhaExtension to '@sbx' which keeps production ABHA identifiers in the
sandbox namespace; update the environment constant's abhaExtension property
(abhaExtension) to '@abdm' so production ABHA/care-context endpoints use the
correct production suffix and avoid mismatched identifiers when prod ABHA flows
are enabled.

---

Nitpick comments:
In `@src/app/app-modules/core/services/http-interceptor.service.ts`:
- Around line 152-184: Refactor getErrorMessage to reduce complexity: extract
the fallback string into a single constant used everywhere, narrow the parameter
type to string | Error | { message?: string; errorMessage?: string; error?:
string }, and remove the outer try/catch and duplicated return paths so the
function simply checks types in order (string non-empty, then Error.message,
then object.message/errorMessage/error) and returns the fallback if none match;
then inline the trivial string-guard logic from handleSessionExpiry (i.e. don't
call getErrorMessage with an already-built non-empty string) so callers only
pass payloads that need parsing.
- Around line 278-286: Update the URL and token checks in
HttpInterceptorService: replace url.indexOf('user/userAuthenticate') >= 0 with
url?.includes('user/userAuthenticate'); change url &&
url.toLowerCase().includes('/platform-feedback') to
url?.toLowerCase().includes('/platform-feedback'); replace
sessionStorage.getItem('authenticationToken') ? true : false with
!!sessionStorage.getItem('authenticationToken'); also apply the same
optional-chaining change noted at the earlier occurrence (around L65) where url
is checked. These changes preserve behavior while using modern idioms for
'user/userAuthenticate', '/platform-feedback', and 'authenticationToken' checks.

In `@src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts`:
- Around line 379-384: The construction of quickConsultation in
postQuickConsultDetails uses a separate Object.assign fragment for
doctorSignatureFlag which makes the payload shape diverge from other save
methods; instead fold doctorSignatureFlag into the same base object (e.g., merge
it into temp or include it directly when building the main payload) so
quickConsultation is built consistently (same top-level placement alongside
tcRequest/isSpecialist). Update the code around quickConsultation and temp in
postQuickConsultDetails to include doctorSignatureFlag in temp (or the primary
payload creation) rather than as a separate Object.assign entry.
- Around line 3990-3992: checkUsersignatureExist currently concatenates userID
directly which allows null/undefined to request ".../undefined" and misses
URL-encoding; update the method checkUsersignatureExist(userID: any) to first
validate userID (return an observable error via throwError if null/undefined)
and then append encodeURIComponent(String(userID)) to
environment.checkUsersignExistUrl; also add a typed return Observable matching
the expected shape (e.g. Observable<{ data: { signStatus: boolean } }>) so
callers reading res.data.signStatus get compile-time safety (import throwError
from rxjs if using it).

In
`@src/app/app-modules/registrar/family-tagging/create-family-tagging/create-family-tagging.component.html`:
- Line 117: Move the inline styles from the <mat-dialog-actions> tag into the
component stylesheet: create a reusable CSS class (e.g., dialog-actions-flex) in
CreateFamilyTaggingComponent's stylesheet that sets display:flex,
justify-content:flex-end and gap:12px, add that class to the
<mat-dialog-actions> element and remove the inline style and the redundant
pull-right class; ensure spacing/formatting in the stylesheet is consistent.

In `@src/environments/environment.dev.ts`:
- Around line 577-580: Rename the key getUserId to getUserIdUrl to match the URL
naming convention used nearby (e.g., downloadSignUrl, checkUsersignExistUrl,
elasticSearchUrl) and update all references to this constant across the codebase
(including other environment files and any imports/usages) so they point to
getUserIdUrl; ensure the value remains `${COMMON_API}user/userName/` and that
tests/builds are updated to reflect the new key.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fa8c2136-ab25-474a-ab7d-d75c38592ff8

📥 Commits

Reviewing files that changed from the base of the PR and between b742399 and c9e9bc4.

📒 Files selected for processing (25)
  • Common-UI
  • pom.xml
  • src/app/app-modules/core/services/confirmation.service.ts
  • src/app/app-modules/core/services/http-interceptor.service.ts
  • src/app/app-modules/lab/workarea/workarea.component.ts
  • src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/prescription.component.html
  • src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/prescription.component.ts
  • src/app/app-modules/nurse-doctor/case-sheet/general-case-sheet/doctor-diagnosis-case-sheet/doctor-diagnosis-case-sheet.component.ts
  • src/app/app-modules/nurse-doctor/doctor-worklist/doctor-worklist.component.ts
  • src/app/app-modules/nurse-doctor/nurse-worklist-wrapper/nurse-worklist/nurse-worklist.component.ts
  • src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.html
  • src/app/app-modules/nurse-doctor/shared/services/doctor.service.ts
  • src/app/app-modules/nurse-doctor/workarea/workarea.component.ts
  • src/app/app-modules/registrar/family-tagging/create-family-tagging/create-family-tagging.component.html
  • src/assets/Assamese.json
  • src/assets/English.json
  • src/assets/Hindi.json
  • src/assets/Kannada.json
  • src/assets/language.json
  • src/environments/environment.ci.ts.template
  • src/environments/environment.dev.ts
  • src/environments/environment.development.ts
  • src/environments/environment.local.ts
  • src/environments/environment.prod.ts
  • src/environments/environment.test.ts
💤 Files with no reviewable changes (2)
  • src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/prescription.component.html
  • src/app/app-modules/nurse-doctor/quick-consult/quick-consult.component.html

Comment on lines +43 to +48
this.router.events.subscribe((event: any) => {
if (event.url === '/login') {
this.resetSessionState();
}
});
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Race between /login router event and the post-navigate dialog — duplicate "session expired" dialogs possible.

resetSessionState() is invoked on every router event whose url === '/login' (NavigationStart, RoutesRecognized, NavigationEnd, etc.), flipping both isHandlingSessionExpiry and logoutMessageShown back to false. The expiry flow runs:

  1. catchError sets isHandlingSessionExpiry = true and calls handleSessionExpiry().
  2. handleSessionExpiry triggers router.navigate(['/login']).
  3. Router events fire → resetSessionState() runs → both flags cleared.
  4. Navigation Promise .then finally sets logoutMessageShown = true and schedules the dialog after 300 ms.

Between step 3 and step 4 there is a window where any in-flight 401/403 (typical when several parallel requests fail simultaneously) will re-enter handleSessionExpiry and open a second dialog — ConfirmationService.alert has no dedup (see confirmation.service.ts L67-86), so both dialogs will stack on top of each other.

Two ways to close the hole:

  • Skip resetSessionState() when the navigation was initiated by the expiry flow (e.g. read a this.isNavigatingAfterExpiry flag), or
  • Set logoutMessageShown = true before calling router.navigate, and only clear state on a real login success / user-initiated logout rather than on every /login URL visit.
🔒 Sketch of one fix
   private handleSessionExpiry(errorMessage: string): void {
     if (this.isHandlingSessionExpiry && this.logoutMessageShown) {
       return;
     }

     this.isHandlingSessionExpiry = true;
+    this.logoutMessageShown = true; // claim dialog slot before navigating
     this.clearSessionTimeoutTimer();

     sessionStorage.clear();
     this.sessionstorage.clear();

     const displayMessage = this.getErrorMessage(errorMessage);

     try {
       this.router
         .navigate(['/login'])
         .then((navigated: boolean) => {
           if (!navigated) {
             console.error('Navigation to login failed');
           }
-          if (!this.logoutMessageShown) {
-            this.logoutMessageShown = true;
-            setTimeout(() => {
+          setTimeout(() => {
               try {
                 this.confirmationService
                   .alert(displayMessage, 'error')
                   .afterClosed()
                   .subscribe(
                     () => {
                       console.log('Session expiry dialog closed');
                     },
                     (dialogError: any) => {
                       console.error('Error in dialog:', dialogError);
                     },
                   );
               } catch (dialogErr) {
                 console.error(
                   'Failed to show session expiry dialog:',
                   dialogErr,
                 );
               }
-            }, 300);
-          }
+          }, 300);
         })

And narrow the router subscription so it only resets on a real login, not every visit:

-    this.router.events.subscribe((event: any) => {
-      if (event.url === '/login') {
-        this.resetSessionState();
-      }
-    });
+    // Reset is driven by successful login response in `onSuccess`
+    // (already handled via `isLoginRequest && event.status === 200`).

Also applies to: 186-237

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/app-modules/core/services/http-interceptor.service.ts` around lines
43 - 48, The router subscription currently calls resetSessionState() on any
router event with url === '/login', which races with handleSessionExpiry() and
allows duplicate dialogs; fix by preventing reset when navigation was initiated
by the expiry flow—add a boolean flag (e.g., isNavigatingAfterExpiry) set in
handleSessionExpiry() before calling router.navigate(['/login']) and check that
flag in the router.events handler to skip resetSessionState() when true, or
alternately set logoutMessageShown = true before router.navigate and only clear
it on explicit login/logout; update references to isHandlingSessionExpiry,
logoutMessageShown, handleSessionExpiry(), resetSessionState(), and
ConfirmationService.alert accordingly so a second concurrent 401/403 cannot
reopen the dialog.

Comment on lines +319 to +323
this.confirmationService
.alert(
'Your session is about to Expire. Do you need more time ? ',
'sessionTimeOut',
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hardcoded English in the session-about-to-expire prompt.

The "timeout"/"error" branches below use currentLanguageSet?.sessionExpired fallbacks, but the primary prompt on line 321 is an English-only literal (and also has a stray space before ?). Align with the rest of the service and add an i18n key with a safe fallback.

🌐 Suggested fix
     this.confirmationService
       .alert(
-        'Your session is about to Expire. Do you need more time ? ',
-        'sessionTimeOut',
+        this.currentLanguageSet?.sessionAboutToExpire ||
+          'Your session is about to expire. Do you need more time?',
+        'sessionTimeOut',
       )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
this.confirmationService
.alert(
'Your session is about to Expire. Do you need more time ? ',
'sessionTimeOut',
)
this.confirmationService
.alert(
this.currentLanguageSet?.sessionAboutToExpire ||
'Your session is about to expire. Do you need more time?',
'sessionTimeOut',
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/app-modules/core/services/http-interceptor.service.ts` around lines
319 - 323, The session-warning message is hardcoded in
confirmationService.alert; replace the English literal with the i18n lookup used
elsewhere (e.g., use currentLanguageSet?.sessionAboutToExpire with a safe
fallback to currentLanguageSet?.sessionExpired or a default string) and remove
the stray space before the question mark; update the confirmationService.alert
call in http-interceptor.service.ts and add the new i18n key
(sessionAboutToExpire) to your translations so the prompt is localized
consistently.

Comment on lines +354 to +366
private extendSession(): void {
this.http
.post(environment.extendSessionUrl, {})
.pipe(
catchError((error: any) => {
console.error('Failed to extend session:', error);
return of(null);
}),
)
.subscribe(() => {
this.resetSessionTimeoutTimer();
});
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

extendSession silently extends the timer even when the backend call fails.

catchError returns of(null) and the subscribe unconditionally runs resetSessionTimeoutTimer(). If the extend endpoint returns 4xx/5xx (or the token has already been invalidated server-side), the client will keep scheduling another 27‑minute window as if the session was renewed — the user keeps working until the next authenticated call 401s, at which point all their in-progress input is lost.

🛡️ Suggested fix
   private extendSession(): void {
-    this.http
-      .post(environment.extendSessionUrl, {})
-      .pipe(
-        catchError((error: any) => {
-          console.error('Failed to extend session:', error);
-          return of(null);
-        }),
-      )
-      .subscribe(() => {
-        this.resetSessionTimeoutTimer();
-      });
+    this.http.post(environment.extendSessionUrl, {}).subscribe({
+      next: () => this.resetSessionTimeoutTimer(),
+      error: (err: any) => {
+        console.error('Failed to extend session:', err);
+        // Treat as expiry; let the standard flow surface the message.
+        this.handleSessionExpiry(
+          this.currentLanguageSet?.sessionExpiredPleaseLogin ||
+            'Session has expired, please login again.',
+        );
+      },
+    });
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/app-modules/core/services/http-interceptor.service.ts` around lines
354 - 366, extendSession currently swallows errors by returning of(null) in the
catchError and then always calling resetSessionTimeoutTimer() in subscribe;
change extendSession so that resetSessionTimeoutTimer() is only called when the
backend call actually succeeds: have the catchError rethrow or return throwError
(or return of a failure sentinel and check it), and in the subscribe success
handler call resetSessionTimeoutTimer() only for a successful response (e.g.,
test for non-null/ok response), while handling errors in the error handler (or
finalize) to avoid extending the client timer when the server
rejected/invalidated the session; update the logic around
this.http.post(environment.extendSessionUrl, {}) / catchError(...) /
subscribe(...) accordingly.

Comment on lines 392 to +446
submitForUpload() {
const validationErrors = this.validateCurrentPrescription();

if (validationErrors.length > 0) {
const errorMessage =
'Please fill the following required fields:\n' +
validationErrors.map((e, i) => `${i + 1}. ${e}`).join('\n');
this.confirmationService.alert(errorMessage, 'error');
return;
}

this.addMedicine();
this.clearCurrentaddDetails();
}

validateCurrentPrescription(): string[] {
const errors: string[] = [];

if (!this.currentPrescription.formName) {
errors.push('Medicine Form');
}
if (!this.currentPrescription.drugName || !this.tempDrugName) {
errors.push('Medicine Name');
}
if (!this.currentPrescription.dose) {
errors.push('Dosage');
}
if (!this.currentPrescription.frequency) {
errors.push('Frequency');
}

// Conditional validations
if (
this.currentPrescription.frequency &&
this.currentPrescription.frequency !== 'SOS'
) {
if (!this.currentPrescription.duration) {
errors.push('Duration');
}
if (!this.currentPrescription.unit) {
errors.push('Unit');
}
}

// Quantity required for non-liquid forms
if (
this.currentPrescription.formID &&
this.currentPrescription.formID > 2 &&
!this.currentPrescription.qtyPrescribed
) {
errors.push('Quantity');
}

return errors;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find which language keys the prescription form labels already use
rg -nP --type=html -C1 'current_language_set\?\.Prescription\?\.' src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/
rg -nP --type=html -C1 'nurseData\?\.chiefComplaintsDetails\?\.duration' src/app/app-modules/nurse-doctor/
# Confirm no existing "fillRequiredFields" key before introducing a new one
fd -t f -e json . src/assets | head -20
rg -nP '"fillRequiredFields"|"alerts"\s*:' -g '*.json' | head

Repository: PSMRI/HWC-UI

Length of output: 10209


🏁 Script executed:

# Check the structure of alerts in the main language JSON file
head -100 src/assets/English.json | tail -50

# Find the alerts section
rg -A20 '"alerts"' src/assets/English.json | head -40

# Check if medicineName or medicine is used in JSON
rg -i '"medicine' src/assets/English.json | head -10

# Check Prescription section in JSON
rg -A30 '"Prescription"' src/assets/English.json | head -50

Repository: PSMRI/HWC-UI

Length of output: 6135


i18n gap: validation error strings are hardcoded in English.

The rest of this component renders field labels from current_language_set?.Prescription?.* / nurseData?.chiefComplaintsDetails?.*, but the heading "Please fill the following required fields:" and the error labels (Medicine Form, Medicine Name, Dosage, Frequency, Duration, Unit, Quantity) are plain English. Non-English users will see a mixed-language alert. Source each label and the heading from current_language_set.

🌐 Example fix using existing language keys
   validateCurrentPrescription(): string[] {
     const errors: string[] = [];

+    const lang = this.current_language_set;
     if (!this.currentPrescription.formName) {
-      errors.push('Medicine Form');
+      errors.push(lang?.Prescription?.form || 'Medicine Form');
     }
     if (!this.currentPrescription.drugName || !this.tempDrugName) {
-      errors.push('Medicine Name');
+      errors.push(lang?.Prescription?.medicine || 'Medicine Name');
     }
     if (!this.currentPrescription.dose) {
-      errors.push('Dosage');
+      errors.push(lang?.Prescription?.dosage || 'Dosage');
     }
     if (!this.currentPrescription.frequency) {
-      errors.push('Frequency');
+      errors.push(lang?.Prescription?.frequency || 'Frequency');
     }

     if (
       this.currentPrescription.frequency &&
       this.currentPrescription.frequency !== 'SOS'
     ) {
       if (!this.currentPrescription.duration) {
-        errors.push('Duration');
+        errors.push(lang?.nurseData?.chiefComplaintsDetails?.duration || 'Duration');
       }
       if (!this.currentPrescription.unit) {
-        errors.push('Unit');
+        errors.push(lang?.Prescription?.unit || 'Unit');
       }
     }

     if (
       this.currentPrescription.formID &&
       this.currentPrescription.formID > 2 &&
       !this.currentPrescription.qtyPrescribed
     ) {
-      errors.push('Quantity');
+      errors.push(lang?.Prescription?.quantity || 'Quantity');
     }

     return errors;
   }

For the heading, use an existing language key such as mandatoryFields or add one consistent with your i18n schema.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/app-modules/nurse-doctor/case-record/general-case-record/prescription/prescription.component.ts`
around lines 392 - 446, The alert heading and all hardcoded validation labels in
submitForUpload() / validateCurrentPrescription() should be replaced with i18n
keys from current_language_set (e.g., current_language_set?.Prescription or
other existing keys); update the heading string ('Please fill the following
required fields:') to use a language key such as
current_language_set?.Prescription?.mandatoryFields (or add that key), and
replace each error label ('Medicine Form', 'Medicine Name', 'Dosage',
'Frequency', 'Duration', 'Unit', 'Quantity') with the corresponding
current_language_set?.Prescription?.* entries (use
nurseData?.chiefComplaintsDetails?.* if appropriate for any shared labels) so
the confirmationService.alert(errorMessage, 'error') shows fully localized text;
ensure validateCurrentPrescription() builds its errors array with those i18n
values and submitForUpload() composes the numbered message from them.

Comment on lines 119 to 127
redirectToCHOReport() {
window.location.href = `${environment.dhisURL}${JSON.parse(this.sessionstorage.getItem('loginDataResponse'))?.dhistoken}`;
const token = JSON.parse(
this.sessionstorage.getItem('loginDataResponse'),
)?.dhistoken;

const url = `${environment.dhisURL}${token}`;

window.open(url, '_blank', 'noopener,noreferrer');
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Guard against a missing dhistoken before opening the URL.

If loginDataResponse is absent or the parsed payload has no dhistoken, token will be undefined and the method will still open ${environment.dhisURL}undefined in a new tab, leading to a confusing broken page. A simple guard avoids this edge case. Opening _blank with noopener,noreferrer looks good otherwise.

🛡️ Proposed fix
   redirectToCHOReport() {
-    const token = JSON.parse(
-      this.sessionstorage.getItem('loginDataResponse'),
-    )?.dhistoken;
-
-    const url = `${environment.dhisURL}${token}`;
-
-    window.open(url, '_blank', 'noopener,noreferrer');
+    const loginData = this.sessionstorage.getItem('loginDataResponse');
+    const token = loginData ? JSON.parse(loginData)?.dhistoken : undefined;
+
+    if (!token) {
+      this.confirmationService.alert(
+        this.currentLanguageSet?.alerts?.info?.somethingWentWrong ||
+          'Unable to open CHO report: missing session token.',
+        'error',
+      );
+      return;
+    }
+
+    const url = `${environment.dhisURL}${token}`;
+    window.open(url, '_blank', 'noopener,noreferrer');
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/app-modules/nurse-doctor/doctor-worklist/doctor-worklist.component.ts`
around lines 119 - 127, In redirectToCHOReport(), guard against missing or
invalid dhistoken by safely parsing
this.sessionstorage.getItem('loginDataResponse') (catch JSON.parse errors) and
verifying the extracted dhistoken is a non-empty string before constructing the
URL and calling window.open; if the token is missing/invalid, do not call
window.open and instead handle the case (e.g., log via a logger or show a
user-facing message) so you avoid opening `${environment.dhisURL}undefined`.

Comment thread src/assets/Assamese.json
Comment on lines +1800 to +1802
"hypertension": "উচ্চ ৰক্তচাপ স্ক্ৰীণিং",
"breastCancer": "স্তনৰ কেঞ্চাৰ স্ক্ৰীণিং",
"cervicalCancer": "গৰ্ভাশয়ৰ মুখৰ কেঞ্চাৰ স্ক্ৰীণিং",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove the duplicated disease keys from this locale object.

These hypertension, breastCancer, and cervicalCancer entries are declared twice in the same JSON object, so one set is overwritten at parse time and becomes unreachable. Please keep one canonical key per concept, or rename them if these labels are meant for different screens.

Also applies to: 2033-2036

🧰 Tools
🪛 Biome (2.4.12)

[error] 1800-1800: The key hypertension was already declared.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1801-1801: The key breastCancer was already declared.

(lint/suspicious/noDuplicateObjectKeys)


[error] 1802-1802: The key cervicalCancer was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/assets/Assamese.json` around lines 1800 - 1802, The locale object
contains duplicate keys "hypertension", "breastCancer", and "cervicalCancer"
(appearing twice), causing the earlier entries to be overwritten; remove the
duplicate entries so each concept has a single canonical key, or if the
duplicated values are intended for different screens rename one set (e.g.,
hypertension_screen vs hypertension_summary) to unique keys; update only the
entries for "hypertension", "breastCancer", and "cervicalCancer" (and the other
duplicates noted around the later section) to eliminate duplication and keep the
correct translated string for each unique key.

Comment thread src/assets/Assamese.json
"count": "গণনা",
"information": "তথ্য",
"dosDont": "কৰিবলগীয়া আৰু নকৰিবলগীয়া",
"selfcare": "নিজে যত্ন লোৱা",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

selfcare is declared twice in the same object.

The later declaration overrides the earlier one, so one translation is effectively dead. Keep a single selfcare key or split the contexts into distinct names.

Also applies to: 2091-2091

🧰 Tools
🪛 Biome (2.4.12)

[error] 1959-1959: The key selfcare was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/assets/Assamese.json` at line 1959, The Assamese translations object
contains duplicate "selfcare" keys, causing the later value to override the
earlier one; locate both "selfcare" entries and either remove the redundant one
or rename one to a context-specific key (e.g., "selfcare_profile" or
"selfcare_section") so both translations are preserved, then update any
consumers to use the new key if you rename it.

Comment thread src/assets/Hindi.json
Comment on lines 1905 to +1907
"immunizationService": "Immunization Services",
"birthImmunizationHistory" :"Birth & Immunization History",
"birthImmunizationHistory": "जन्म एवं टीकाकरण का इतिहास",
"immunizationService": "टीकाकरण सेवाएँ",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

immunizationService is duplicated here.

Lines 1905 and 1907 define the same key in the same object, so only the last value survives at runtime. Please keep one key or rename them if they are intended for different UI contexts.

🧰 Tools
🪛 Biome (2.4.12)

[error] 1905-1905: The key immunizationService was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/assets/Hindi.json` around lines 1905 - 1907, The JSON contains a
duplicate key "immunizationService" (two entries with different Hindi/English
values); remove the duplicate and keep the intended translation or rename one
key to a distinct identifier (e.g., "immunizationServiceLabel" vs
"immunizationServiceAlt") if they represent different UI contexts, then update
any consumers that read the key (components or i18n lookup calls) to use the
chosen/renamed key so no translation is silently overwritten at runtime.

@snehar-nd snehar-nd merged commit 621b77d into main Apr 24, 2026
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants