App Sitemap & Navigation Reachability β
Generated from the 2026-07-12 full reachability audit (both repos). The enforcement twin of this document is
test/navigation/route_reachability_test.dartβ everyAppRoutesconstant must be linked from a navigation surface or explicitly allowlisted there. The React web repo has the equivalent guardrail atsrc/test/layout/routeNavCoverage.test.ts.
Route zones β
| Zone | Prefixes | Shell | Auth |
|---|---|---|---|
| Auth / onboarding | /, /sign-in, /phone-otp, /onboarding | none | public |
| Public visitor | /public, /catalog, /tools/*, /about, /services, /contact, /terms, /privacy, /area-guides, /submit-property, /verify, /request-valuation, /p/:id | PublicVisitorShell (4 tabs) | public |
| Token portals | /bundle/, /deal/, /owner/, /client/, /valuation/portal/, /valuation/pay/, /brokerage/pay/, /sign/, /inspector/ | none | token-authorized |
| Client shell | /client/* | ClientAppShell (4 tabs) | client account |
| Staff shell | /dashboard, /brokerage/*, /valuation/*, /clients/*, /comms/* | AppShell (5 branches) | staff |
| Cross-cutting staff | /tasks, /documents, /finance, /reports/*, /ai/*, /admin/*, /network/*, /transactions/*, /settings/*, β¦ | pushed over AppShell | staff (some admin-only) |
Role gating: role_route_policy.dart (client-only accounts β client shell; finance routes β admin/accountant; /residents + /admin/offices β admin). v1 gating: kV1HiddenRoutes in routes.dart (currently empty).
Navigation surfaces (what links where) β
Programmatic catalogues (checked by the reachability test):
staff_bottom_nav_policy.dartβ per-persona 4 tabs + overflow (Agentic OS at/dashboard, brokerage/valuation, clients, comms/tasks/settings + persona variants).shell_tools_sheet.dartβ the center tools drawer: 19 shared shortcuts + admin shortcuts (residents, property registry, tahdeed, Hermes dashboard, send email).tool_catalog.dartβ global-search launcher (~60 tools; empty query = browsable list). The safety net: every staff tool, including Reports Hub and the agent KPI dashboard, must appear here.clientBottomNavConfigβ client shell tabs + support shortcuts.
Widget hubs (allowlisted with their surface in the reachability test):
- Side drawers:
brokerage_drawer.dart(11 entries),khobara_drawer.dart(5). - Reports hub (19 tiles), AI tools menu (9), WhatsApp tools menu (13), Comms tab, Network hub, Settings, Agentic OS menu.
- Public: visitor shell tabs, landing + footer, public tools hub (13 tiles).
- Contextual: valuations-list ops menu (data quality, coordinates, bulk, completeness, stats, appraiser/evaluator dashboards, templates, kanban), transactions-explorer staff menu (analytics, anomaly, predictive), properties-list tools menu (price heatmap, property alerts), documents-list actions (file manager, document manager), visit-detail "Site inspection" CTA (β which carries the Comparables CTA).
Deliberately deep-link-only (do not "fix") β
- Redirect/alias shapes:
/sign-up,/password-reset,/ai,/admin/whatsapp/marketing,/admin/party-registry,/brokerage/sales/requests*,/brokerage/properties/heatmap(web shape),/valuation/valuations/kanban,/finance/invoices|quotations(mode shortcuts β the brand paths are the linked ones). - Token portals β shared as links, never browsed to.
/admin/widget-galleryβ dev-only design gallery./settings/language,/settings/themeβ Settings has inline pickers./brokerage/properties/newβ superseded by/properties/new(AddPropertyScreen, the properties-list FAB)./valuation/clientsβ duplicated by the unified Contacts tab.
Dead code found by the audit was removed rather than wired: the never-routed ClientsListScreen (superseded by ClientsTabScreen) and the standalone IndividualDetailScreen wrapper (its IndividualProfileTab body lives on inside PartyDetailScreen).
Cross-repo path bridge (web β mobile) β
Deep links use the web-canonical shapes (DB/notification convention); inbound_route_normalizer.dart maps them to mobile routes (static alias table + dynamic :id patterns), and kWebInboundRedirects entries are also mounted as redirect GoRoutes. The web handles mobile-ish shapes via redirects in SharedRoutes.tsx (/transactions, /mailbox, β¦). Divergent pairs already bridged include:
| Web canonical | Mobile route |
|---|---|
/admin/activity-feed | /dashboard/activity |
/market/analytics Β· /market/anomaly-detection Β· /analytics/predictive | /transactions/analytics Β· /transactions/anomaly Β· /transactions/predictive |
/valuation/reports/{performance, evaluator-dashboard, valuation-stats} | /valuation/valuations/{appraiser-performance, evaluator-dashboard, stats} |
/ai/hermes-dashboard | /admin/hermes |
/tools/documents Β· /tools/workspace | /documents/dashboard Β· /documents/manager |
/brokerage/crm/call-logs | /call-logs |
/leaderboard Β· /kpi Β· /sla Β· /lead-source-roi | /reports/{leaderboard, kpi, sla, lead-source} |
When adding a route on either surface: keep the path identical if possible; otherwise add the alias to the normalizer (mobile) or SharedRoutes.tsx (web) in the same PR, and record the pair here.
2026-07-12 audit outcome β
23 mobile routes (19 staff + 4 public) were shipped with zero navigation entries; all are now wired (tool catalog + reports hub + contextual homes + public tools tiles). The web repo was audited the same day and is covered by its own guardrail; its intentional exemptions (/verify = QR entry, /admin/paci-areas = duplicate alias, buyers β filtered Contacts) are documented in routeNavCoverage.test.ts.
