Skip to content

fix(ZMSKVR-1121): citizen view hash routing and deep-link test stability#2245

Open
ThomasAFink wants to merge 8 commits into
mainfrom
bugfix-zmskvr-1121-citizenview-hash-deep-links
Open

fix(ZMSKVR-1121): citizen view hash routing and deep-link test stability#2245
ThomasAFink wants to merge 8 commits into
mainfrom
bugfix-zmskvr-1121-citizenview-hash-deep-links

Conversation

@ThomasAFink
Copy link
Copy Markdown
Member

@ThomasAFink ThomasAFink commented Apr 24, 2026

  • Sync hash routes on hashchange and clear stale params in zms-appointment.ce.vue
  • Watch confirmAppointmentHash and appointmentHash in AppointmentView for same-tab navigation
  • Reset confirm success when loading appointment deep link
  • ATAF: use in-page location for same-document citizen view URLs (Safari timeout); drop redundant refresh
  • CLI: remove stray skip_gateway_trust callback param; gitignore .venv for local Python venv

Pull Request Checklist (Feature Branch to next):

  • Ich habe die neuesten Änderungen aus dem next Branch in meinen Feature-Branch gemergt.
  • Relevante Tests wurden mit zmsautomation ausgeführt.
  • Das Code-Review wurde abgeschlossen.
  • Fachliche Tests wurden durchgeführt und sind abgeschlossen.

Summary by CodeRabbit

  • Bug Fixes

    • Improved deep-link navigation reliability and performance for appointment and confirmation flows.
    • More robust same-tab hash routing so UI updates correctly on hash changes.
  • Refactor

    • Centralized and simplified deep-link initialization and routing logic; reduced in-mount work and added stale-result guards.
    • Consolidated route sync and lifecycle handling with proper teardown.
  • Tests

    • Refactored citizen view deep-link navigation tests.
  • Chores

    • Updated .gitignore to ignore local Python virtual environments.

Review Change Stack

- Sync hash routes on hashchange and clear stale params in zms-appointment.ce.vue
- Watch confirmAppointmentHash and appointmentHash in AppointmentView for same-tab navigation
- Reset confirm success when loading appointment deep link
- ATAF: use in-page location for same-document citizen view URLs (Safari timeout); drop redundant refresh
- CLI: remove stray skip_gateway_trust callback param; gitignore .venv for local Python venv
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3d616dec-091b-42f5-a07f-3bcefd8e94e0

📥 Commits

Reviewing files that changed from the base of the PR and between ded75c4 and 8d2fc59.

📒 Files selected for processing (1)
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (1)
  • .gitignore

📝 Walkthrough

Walkthrough

This pull request refactors deep-link navigation and initialization across the citizen view stack. Navigation logic in Java now uses same-document checks before updating URLs. Route state initialization is centralized into a single sync function. Vue components migrate initialization from mount hooks to hash-driven watchers with concurrency guards to prevent stale results.

Changes

Deep-Link Navigation & Initialization Refactoring

Layer / File(s) Summary
Navigation Helper
zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java
Adds navigateCitizenViewUrl() to intelligently navigate deep links using same-document hash updates when possible, with helpers isSameDocumentCitizenViewNavigation(), hostKey(), and normalizedPath() for robust URL comparison. Replaces direct WebDriver navigation in openConfirmationDeepLinkInBrowser() and openAppointmentViewDeepLinkInBrowser() with the new helper, reducing post-navigate waits to 2 seconds.
Route State Sync
zmscitizenview/src/zms-appointment.ce.vue
Introduces a centralized syncRouteFromLocation() function that clears and re-parses hash and query params from the current location. Simplifies onMounted to unconditionally sync route state and add a hashchange event listener for same-tab updates, with cleanup via onUnmounted().
Hash-Driven Initialization
zmscitizenview/src/components/Appointment/AppointmentView.vue
Moves deep-link initialization from onMounted into dedicated immediate watchers for appointmentHash and confirmAppointmentHash. Introduces runAppointmentInitializationFromHash() that orchestrates fetching services, parsing hashes, and routing to the appropriate view. Adds concurrency guards (latestAppointmentHash, latestConfirmAppointmentHash) and updates nextConfirmAppointment() to accept requestHash for skipping stale responses. Reduces onMounted to localStorage restoration and focus/cleanup logic.
Configuration
.gitignore
Adds .venv/ to ignore Python virtual environments.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as User Browser
  participant View as AppointmentView
  participant API as Backend API
  participant Router as Client Router
  Browser->>View: hashchange / appointmentHash set
  View->>View: runAppointmentInitializationFromHash(hash)
  View->>API: fetch services/providers
  API-->>View: services/providers
  View->>API: fetch appointment
  API-->>View: appointment data
  View->>Router: route to init/reschedule/cancel
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested reviewers

  • MoDaae

Poem

🐰 A rabbit hops through tangled webs,
Deep links now dance with hash-fueled steps,
Watchers guard against the stale,
Same-doc checks and syncs prevail,
Navigation flows—pristine and true! 🌿✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: fixing hash routing and deep-link test stability in citizen view, which is the primary focus across all modified files.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix-zmskvr-1121-citizenview-hash-deep-links

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: 3

Caution

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

⚠️ Outside diff range comments (2)
zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java (1)

1645-1645: ⚠️ Potential issue | 🟡 Minor

Stale javadoc: navigation no longer refreshes.

The comment still says "then refresh so the app loads it", but the refresh call was removed and replaced by navigateCitizenViewUrl(url) (which relies on the Vue hashchange listener in zms-appointment.ce.vue instead). Update the doc to reflect the new behavior, e.g. "hash updates are picked up by the app's hashchange listener — no refresh needed".

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

In
`@zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java`
at line 1645, Update the stale Javadoc on CitizenViewPage: replace the sentence
that says "then refresh so the app loads it" with a note that no refresh is
required because hash updates are picked up by the app's hashchange listener;
mention the method used (navigateCitizenViewUrl(url)) so readers know navigation
now relies on the Vue hashchange handler instead of a manual refresh.
zmscitizenview/src/components/Appointment/AppointmentView.vue (1)

1292-1345: ⚠️ Potential issue | 🟡 Minor

LocalStorage restoration runs even during confirm deep links.

The guard on line 1293 checks only !props.appointmentHash. When the user lands on a #/appointment/confirm/... URL, props.confirmAppointmentHash is truthy but props.appointmentHash is not, so this block still fires a second fetchServicesAndProviders call and restores stale selectedService / appointment / currentView from localStorage — which then races against nextConfirmAppointment's currentView.value = 5 (line 1109). The last then() to resolve wins, producing flaky UI state on the confirmation page (and is likely contributing to the deep-link test flakiness this PR is trying to fix).

🛡️ Proposed fix
 onMounted(() => {
-  if (!props.appointmentHash) {
+  if (!props.appointmentHash && !props.confirmAppointmentHash) {
     const localStorageAppointment = localStorage.getItem(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@zmscitizenview/src/components/Appointment/AppointmentView.vue` around lines
1292 - 1345, The localStorage restoration in onMounted runs whenever
props.appointmentHash is falsy, which also triggers during confirmation
deep-links; update the guard to also check props.confirmAppointmentHash (or
otherwise detect confirm deep-link state) and skip the localStorage
restore/fetch when confirmAppointmentHash is truthy to prevent the extra
fetchServicesAndProviders call and the race with nextConfirmAppointment's
currentView assignment; locate the onMounted block and adjust the initial if
condition (and any related early returns) so restoration only happens when
neither appointmentHash nor confirmAppointmentHash indicate a confirm deep-link.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java`:
- Around line 1668-1682: The navigateCitizenViewUrl method currently swallows
all exceptions and logs a vague warning; change it so navigation failures are
not silently ignored: catch only to log a detailed message (include the target
URL and the caught exception) using ScenarioLogManager.getLogger().error or
warn, then rethrow the exception (or wrap it in a RuntimeException) so callers
see the failure; retain the existing logic around
isSameDocumentCitizenViewNavigation and ensureAbsoluteCitizenViewUrl but do not
suppress errors from DriverUtil.getDriver(), driver.navigate().to(...) or
((JavascriptExecutor) driver).executeScript(...).

In `@zmscitizenview/src/components/Appointment/AppointmentView.vue`:
- Around line 1259-1290: The watchers for props.appointmentHash and
props.confirmAppointmentHash start async flows (via
runAppointmentInitializationFromHash and nextConfirmAppointment) without
guarding against stale responses; add a shared "latestAppointmentHash" (or
separate latestConfirmHash) variable that you set to the current hash at the
start of each watcher callback, then in runAppointmentInitializationFromHash
(and any async helpers like fetchServicesAndProviders and fetchAppointment)
check that the stored latest hash still equals the hash being processed after
each await/then and bail early if it does not so late-resolving promises cannot
overwrite services.value, offices.value, appointment.value, or currentView.value
for a newer hash.

In `@zmscitizenview/src/zms-appointment.ce.vue`:
- Around line 126-136: The debug statements currently emit sensitive base64
payloads (window.location.hash, appointmentHash.value,
confirmAppointmentHash.value) — replace these raw logs in the
syncRouteFromLocation/extractRouteParams area with non-sensitive indicators: log
only presence booleans or masked values (e.g.,
hasAppointmentHash/hasConfirmHash) and keep descriptive text, or remove the
after-sync log entirely; ensure no code paths call console.debug with the full
hash values.

---

Outside diff comments:
In
`@zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java`:
- Line 1645: Update the stale Javadoc on CitizenViewPage: replace the sentence
that says "then refresh so the app loads it" with a note that no refresh is
required because hash updates are picked up by the app's hashchange listener;
mention the method used (navigateCitizenViewUrl(url)) so readers know navigation
now relies on the Vue hashchange handler instead of a manual refresh.

In `@zmscitizenview/src/components/Appointment/AppointmentView.vue`:
- Around line 1292-1345: The localStorage restoration in onMounted runs whenever
props.appointmentHash is falsy, which also triggers during confirmation
deep-links; update the guard to also check props.confirmAppointmentHash (or
otherwise detect confirm deep-link state) and skip the localStorage
restore/fetch when confirmAppointmentHash is truthy to prevent the extra
fetchServicesAndProviders call and the race with nextConfirmAppointment's
currentView assignment; locate the onMounted block and adjust the initial if
condition (and any related early returns) so restoration only happens when
neither appointmentHash nor confirmAppointmentHash indicate a confirm deep-link.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b6501e60-e03f-4171-9795-7e27325c8aff

📥 Commits

Reviewing files that changed from the base of the PR and between 2a4f580 and 55c6792.

📒 Files selected for processing (5)
  • .gitignore
  • cli_test.py
  • zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java
  • zmscitizenview/src/components/Appointment/AppointmentView.vue
  • zmscitizenview/src/zms-appointment.ce.vue
💤 Files with no reviewable changes (1)
  • cli_test.py

Comment thread zmscitizenview/src/components/Appointment/AppointmentView.vue
Comment thread zmscitizenview/src/zms-appointment.ce.vue Outdated
…onsole

Replace syncRouteFromLocation console.debug payloads with segment count and presence flags only.
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.

🧹 Nitpick comments (3)
zmscitizenview/src/zms-appointment.ce.vue (3)

127-130: Optional: gate the console.debug behind a dev flag (or drop it).

Now that the payload is just a segment count plus presence booleans there's no credential leak, but an unconditional console.debug in a production component is still noise for downstream consumers embedding the custom element. Consider wrapping it in import.meta.env.DEV (Vite) or removing it before release.

♻️ Suggested tweak
-  console.debug("[ZMS] syncRouteFromLocation: segments=", urlElements.length, {
-    hasAppointmentHash: !!appointmentHash.value,
-    hasConfirmAppointmentHash: !!confirmAppointmentHash.value,
-  });
+  if (import.meta.env.DEV) {
+    console.debug("[ZMS] syncRouteFromLocation: segments=", urlElements.length, {
+      hasAppointmentHash: !!appointmentHash.value,
+      hasConfirmAppointmentHash: !!confirmAppointmentHash.value,
+    });
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@zmscitizenview/src/zms-appointment.ce.vue` around lines 127 - 130, The
console.debug call in syncRouteFromLocation is unconditional and should be gated
or removed for production; wrap the debug call (the console.debug that logs
urlElements.length and the appointmentHash/confirmAppointmentHash booleans) in a
dev-only guard such as checking import.meta.env.DEV (or remove the statement
entirely) so it only runs in development builds and avoids noisy logs for
consumers of the custom element.

93-116: Minor: extractRouteParams has a hidden dependency on window.location.

The function takes urlElements as input but silently reads window.location.href for the exclusiveLocation query param. That mixes two input sources and makes the function harder to test in isolation. Since syncRouteFromLocation is the sole caller, consider reading the query params there and passing them in (or folding both parses into syncRouteFromLocation). Non-blocking — pre-existing pattern, just now more visible.

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

In `@zmscitizenview/src/zms-appointment.ce.vue` around lines 93 - 116,
extractRouteParams mixes inputs by reading window.location.href internally for
query params (exclusiveLocation) while taking urlElements as an argument; make
it pure by moving the URLSearchParams creation and exclusiveLocation check out
of extractRouteParams and into its caller (syncRouteFromLocation), then pass the
extracted exclusiveLocation value (or a searchParams object) into
extractRouteParams so extractRouteParams only depends on its parameters and no
longer reads window.location.

118-145: Hash sync + hashchange wiring looks correct.

The clear-then-reparse approach works well with the appointmentHash / confirmAppointmentHash watchers in AppointmentView.vue (both early-return on empty), so transitioning between deep links won't trigger spurious initialization. Listener teardown in onUnmounted is in place.

One edge case to be aware of: when navigating same-tab from a confirm-success URL (/appointment/confirm/HASH) to a neutral URL with no appointment hash, syncRouteFromLocation will clear both refs, but confirmAppointmentSuccess will remain true because it only resets inside runAppointmentInitializationFromHash() (which runs only when a new appointment hash loads). If the user journey requires clearing success state on any hash change, consider resetting it during syncRouteFromLocation or whenever hash clears, rather than only on appointment-hash load.

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

In `@zmscitizenview/src/zms-appointment.ce.vue` around lines 118 - 145,
syncRouteFromLocation clears appointment-related refs but doesn't reset the
confirmAppointmentSuccess flag, so navigating from a confirm-success hash to a
neutral hash leaves confirmAppointmentSuccess true; update syncRouteFromLocation
to also reset confirmAppointmentSuccess (or invoke a clear function) when
confirmAppointmentHash and appointmentHash are cleared so the UI state matches
the absence of a hash, referencing syncRouteFromLocation,
confirmAppointmentHash, appointmentHash, confirmAppointmentSuccess and
runAppointmentInitializationFromHash to ensure consistency with existing
initialization behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@zmscitizenview/src/zms-appointment.ce.vue`:
- Around line 127-130: The console.debug call in syncRouteFromLocation is
unconditional and should be gated or removed for production; wrap the debug call
(the console.debug that logs urlElements.length and the
appointmentHash/confirmAppointmentHash booleans) in a dev-only guard such as
checking import.meta.env.DEV (or remove the statement entirely) so it only runs
in development builds and avoids noisy logs for consumers of the custom element.
- Around line 93-116: extractRouteParams mixes inputs by reading
window.location.href internally for query params (exclusiveLocation) while
taking urlElements as an argument; make it pure by moving the URLSearchParams
creation and exclusiveLocation check out of extractRouteParams and into its
caller (syncRouteFromLocation), then pass the extracted exclusiveLocation value
(or a searchParams object) into extractRouteParams so extractRouteParams only
depends on its parameters and no longer reads window.location.
- Around line 118-145: syncRouteFromLocation clears appointment-related refs but
doesn't reset the confirmAppointmentSuccess flag, so navigating from a
confirm-success hash to a neutral hash leaves confirmAppointmentSuccess true;
update syncRouteFromLocation to also reset confirmAppointmentSuccess (or invoke
a clear function) when confirmAppointmentHash and appointmentHash are cleared so
the UI state matches the absence of a hash, referencing syncRouteFromLocation,
confirmAppointmentHash, appointmentHash, confirmAppointmentSuccess and
runAppointmentInitializationFromHash to ensure consistency with existing
initialization behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 23ad858f-f2f6-4250-bf05-91fda444bf46

📥 Commits

Reviewing files that changed from the base of the PR and between 55c6792 and 4cee9dd.

📒 Files selected for processing (1)
  • zmscitizenview/src/zms-appointment.ce.vue

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.

Caution

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

⚠️ Outside diff range comments (2)
zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java (1)

1645-1661: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stale Javadoc — the "then refresh" wording no longer matches the implementation.

The method no longer issues driver.navigate().refresh(); it now routes through navigateCitizenViewUrl(...), which deliberately avoids a full reload for same-document hash changes (that's the whole point of the Safari fix). The current Javadoc misleads future readers and contradicts the helper's own Javadoc on Line 1663.

📝 Suggested doc fix
-    /** Navigate to the appointment view URL extracted from the confirmation mail (link without /confirm/), then refresh so the app loads it. */
+    /**
+     * Navigate to the appointment view URL extracted from the confirmation mail (link without /confirm/).
+     * Routes through {`@link` `#navigateCitizenViewUrl`(String)} so same-document hash changes update via
+     * {`@code` window.location.href} (Safari / eager page-load) instead of a full {`@code` navigate().to()}.
+     */

As per coding guidelines: "Comments rules — Don't be redundant" and "Use as clarification of code".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java`
around lines 1645 - 1661, The Javadoc for openAppointmentViewDeepLinkInBrowser
is stale— it says "then refresh" but the implementation calls
navigateCitizenViewUrl(...) (which intentionally avoids a full reload) and uses
ensureAbsoluteCitizenViewUrl(...) to normalize the URL; update the method
Javadoc to accurately describe that it navigates to the appointment view deep
link using navigateCitizenViewUrl and does not perform a full browser refresh,
and mention that it waits briefly for client-side routing to settle (the
Thread.sleep) and that the URL is obtained via
zms.ataf.rest.steps.CitizenApiSteps.getBookingAppointmentUrl().
zmscitizenview/src/components/Appointment/AppointmentView.vue (1)

1315-1373: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

onMounted localStorage restore can race with the confirm-hash flow.

The gate at Line 1316 only checks !props.appointmentHash. When a user opens a #/appointment/confirm/... deep link in a browser that still has fresh (<30 min) lhm-appointment-data from a prior session, both flows fire in parallel:

  • The confirmAppointmentHash watcher (Line 1292) calls nextConfirmAppointment, which sets appointment.value / currentView = 5 on success.
  • This onMounted block calls fetchServicesAndProviders and then overwrites appointment.value / currentView with the stored data.

Whichever resolves last wins, which can leave confirmAppointmentSuccess === true while appointment.value is the unrelated stored appointment, or pull the user back out of the success view.

🛡️ Suggested gate
 onMounted(() => {
-  if (!props.appointmentHash) {
+  if (!props.appointmentHash && !props.confirmAppointmentHash) {
     const localStorageAppointment = localStorage.getItem(
       LOCALSTORAGE_PARAM_APPOINTMENT_DATA
     );

As per coding guidelines: "Avoid logical dependency. Don't write methods which works correctly depending on something else in the same class." — the restore should explicitly opt out for any deep-link entry, not rely on the watchers winning the race.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@zmscitizenview/src/components/Appointment/AppointmentView.vue` around lines
1315 - 1373, The onMounted restore path races with the confirm-hash flow; change
the initial guard in the onMounted block so it explicitly opts out when any
deep-link confirm flow is present (not just props.appointmentHash). Add an early
return if props.appointmentHash or props.confirmAppointmentHash (the prop
watched by the confirmAppointmentHash watcher that calls nextConfirmAppointment)
is truthy, so the restore logic in onMounted will not call
fetchServicesAndProviders nor overwrite appointment.value or currentView when a
confirm deep-link is active.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java`:
- Around line 1645-1661: The Javadoc for openAppointmentViewDeepLinkInBrowser is
stale— it says "then refresh" but the implementation calls
navigateCitizenViewUrl(...) (which intentionally avoids a full reload) and uses
ensureAbsoluteCitizenViewUrl(...) to normalize the URL; update the method
Javadoc to accurately describe that it navigates to the appointment view deep
link using navigateCitizenViewUrl and does not perform a full browser refresh,
and mention that it waits briefly for client-side routing to settle (the
Thread.sleep) and that the URL is obtained via
zms.ataf.rest.steps.CitizenApiSteps.getBookingAppointmentUrl().

In `@zmscitizenview/src/components/Appointment/AppointmentView.vue`:
- Around line 1315-1373: The onMounted restore path races with the confirm-hash
flow; change the initial guard in the onMounted block so it explicitly opts out
when any deep-link confirm flow is present (not just props.appointmentHash). Add
an early return if props.appointmentHash or props.confirmAppointmentHash (the
prop watched by the confirmAppointmentHash watcher that calls
nextConfirmAppointment) is truthy, so the restore logic in onMounted will not
call fetchServicesAndProviders nor overwrite appointment.value or currentView
when a confirm deep-link is active.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b0f40933-cc57-4225-ae2c-d1ab83555051

📥 Commits

Reviewing files that changed from the base of the PR and between 4cee9dd and ded75c4.

📒 Files selected for processing (2)
  • zmsautomation/src/test/java/zms/ataf/ui/pages/citizenview/CitizenViewPage.java
  • zmscitizenview/src/components/Appointment/AppointmentView.vue

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant