Introduce AppRouter + getAppRouter() so Capacitor uses HashRouter (filesystem bundle, no nginx rewrite) while web keeps BrowserRouter
Isolate platform checks in nativePlatform (no Capacitor.isNativePlatform() sprinkled through the route tree)
Auth forced redirects (axiosApi → /signin/) use hash-safe redirectToAppPath on native
Leave CRA homepage / absolute PUBLIC_URL asset paths unchanged so /var/www/{env}.chat.aimloperations/html deploy stays intact; HashRouter keeps document URL at the bundle root so assets resolve
Test plan
Unit tests: AppRouter + nativePlatform (npm run test:ci)
Capacitor build: open nested route (/#/account/), force WebView reload — no blank/404
Browser back/forward + Android hardware back with HashRouter
Web deploy smoke: deep link reload at /account/ still works via nginx rewrite
Confirm login redirects after 401 still land on sign-in (web path + native hash)
## Summary
- Closes #24
- Introduce `AppRouter` + `getAppRouter()` so Capacitor uses `HashRouter` (filesystem bundle, no nginx rewrite) while web keeps `BrowserRouter`
- Isolate platform checks in `nativePlatform` (no `Capacitor.isNativePlatform()` sprinkled through the route tree)
- Auth forced redirects (`axiosApi` → `/signin/`) use hash-safe `redirectToAppPath` on native
- Leave CRA `homepage` / absolute `PUBLIC_URL` asset paths unchanged so `/var/www/{env}.chat.aimloperations/html` deploy stays intact; HashRouter keeps document URL at the bundle root so assets resolve
## Test plan
- [x] Unit tests: `AppRouter` + `nativePlatform` (`npm run test:ci`)
- [ ] Capacitor build: open nested route (`/#/account/`), force WebView reload — no blank/404
- [ ] Browser back/forward + Android hardware back with HashRouter
- [ ] Web deploy smoke: deep link reload at `/account/` still works via nginx rewrite
- [ ] Confirm login redirects after 401 still land on sign-in (web path + native hash)
Isolate BrowserRouter vs HashRouter in AppRouter so nested paths reload
cleanly from the Capacitor filesystem bundle without nginx rewrites, while
web deploy keeps BrowserRouter unchanged.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
AppRouter+getAppRouter()so Capacitor usesHashRouter(filesystem bundle, no nginx rewrite) while web keepsBrowserRouternativePlatform(noCapacitor.isNativePlatform()sprinkled through the route tree)axiosApi→/signin/) use hash-saferedirectToAppPathon nativehomepage/ absolutePUBLIC_URLasset paths unchanged so/var/www/{env}.chat.aimloperations/htmldeploy stays intact; HashRouter keeps document URL at the bundle root so assets resolveTest plan
AppRouter+nativePlatform(npm run test:ci)/#/account/), force WebView reload — no blank/404/account/still works via nginx rewrite