# Validate Notification Deep Links

Use this checklist to verify that tapping notifications opens the correct in-app destination, especially on iOS/Android native builds.

## Before You Start

* Use a non-production environment.
* Sign in with a user that can access `Dashboard > Notifications`.
* Enable push notifications for the test device.
* For preference simulation, use a user with `manageUsers` permission.

## Setup

1. Open `Dashboard > Notifications`.
2. Enable push if needed.
3. Enable the preference(s) you will test.
4. Keep note of current app state for each run:
   * App foreground
   * App background
   * App terminated (cold start)

## How To Trigger Test Notifications

### A) Preference-level simulation (recommended)

Use `POST /api/push/simulate`:

```json
{
  "preferenceKey": "mfa_policy_changed"
}
```

If the preference is disabled and you still need to test routing:

```json
{
  "preferenceKey": "mfa_policy_changed",
  "bypassPreference": true
}
```

### B) Route override for plumbing checks

Use `POST /api/push/fcm/test` or `POST /api/push/test` with:

```json
{
  "url": "/app/locus?date=2030-04-10"
}
```

This validates tap routing mechanics but does not validate preference-key mapping.

## Expected Destination Matrix

* `mfa_policy_changed` -> `/dashboard/settings?section=security`
* `team_assigned`, `team_lead_changed` -> `/dashboard/teams`
* `invite_accepted` -> `/dashboard/users`
* `role_changed_for_me`, `module_access_changed` -> `/dashboard`
* `org_changes`, `trial_ending`, `payment_failed`, `invoice_ready`, `seat_limit_reached` -> `/dashboard/billing`
* `locus_day_before`, `locus_day_of`, `locus_booking_cancelled_by_admin`, `locus_resource_availability` -> `/app/locus` (prefer `?date=YYYY-MM-DD` when included)
* `locus_week_start_no_bookings`, `locus_booking_window_opening_soon`, `locus_booking_window_changes`, `locus_exclusive_zone_changed` -> `/app/locus`
* `orbis_no_bookings_next_window`, `orbis_conflict_detected`, `orbis_zone_override`, `orbis_series_published`, `orbis_series_updated`, `orbis_series_cancelled`, `orbis_conflict_resolved` -> `/app/orbis`
* `atlas_floor_published`, `atlas_element_schema_changed`, `atlas_headquarters_updated` -> `/app/atlas`
* `civitas_ticket_submitted`, `civitas_ticket_status_changed`, `civitas_ticket_needs_my_review`, `civitas_ticket_commented`, `civitas_pto_booking_cancelled`, `civitas_attachment_saved_to_profile`, `civitas_certificate_ready` -> `/app/civitas` (prefer `?ticket=<ticketId>` when included)
* `civitas_request_overdue` -> `/app/civitas`

## Execution Checklist

* [ ] iOS foreground tap opens expected route.
* [ ] iOS background tap opens expected route.
* [ ] iOS cold-start tap opens expected route.
* [ ] Android foreground tap opens expected route.
* [ ] Android background tap opens expected route.
* [ ] Android cold-start tap opens expected route.
* [ ] Web (service worker) click opens expected route.
* [ ] No notification tap falls back to unrelated `/app` home for tested keys.
* [ ] Date-based links preserve `date` query when present.
* [ ] Ticket-based links preserve `ticket` query when present.

## Evidence To Capture

* Notification payload used (`preferenceKey`, `data.url`).
* Device/platform/build version.
* App state during tap (foreground/background/cold start).
* Resulting route after tap.
* Screen recording for failures.

## Failure Triage

* If payload has valid `data.url` but route is wrong:
  * Check native listener handling in `NativeRuntimeGate`.
* If payload is missing/invalid `data.url`:
  * Check notification sender mapping for that preference key.
* If web opens wrong route:
  * Check `public/sw.js` `notificationclick` fallback mapping.
* If only cold-start fails:
  * Re-test with app fully terminated and confirm native plugin action event delivery.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xdbx.gitbook.io/axon/task-guides/validate-notification-deep-links.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
