fix(client): back navigation follows history, not always the landing screen #374

Merged
james merged 1 commit from fix-drawer-back-history into main 2026-06-29 15:17:41 +00:00
Owner

Bug: back always returned to Chat regardless of where you came from.

Root cause: the (app) Drawer left backBehavior at its default. The vendored drawer/tab router defaults to backBehavior: "firstRoute" (confirmed in BaseTabRouter({ …, backBehavior = 'firstRoute' })), which sends every back action — Android hardware back, browser back, and the in-app back buttons via router.back() — to the first/landing route, ignoring history. After the default landing moved to Chat (#373), that surfaced as "back always goes to Chat."

Fix: set the Drawer's backBehavior="history" so back pops to the actual previous screen. One line in app/(app)/_layout.tsx.

This makes the network detail screens' existing goBackOr(router, "/network") behave correctly — router.back() now returns to the prior screen when there's history, and still falls back to the logical parent (/network) on a cold start / deep link (so you also get "up categorically" for free in the no-history case).

Verification (local)

  • typecheck ✓ (confirms backBehavior is a valid <Drawer> prop) · lint ✓ · test ✓ 172 · semgrep ✓ 0 findings

⚠️ Needs maintainer verification

Navigation behavior isn't covered by the node-env tests — please confirm on device/web: from a person/org detail → back returns to Network (not Chat); from Network → back returns to the previous tab; and a cold-start/deep-link straight onto a detail screen still lands "up" on Network.

Direct bug report (no ticket).

🤖 Generated with Claude Code

**Bug:** back always returned to Chat regardless of where you came from. **Root cause:** the `(app)` Drawer left `backBehavior` at its default. The vendored drawer/tab router defaults to `backBehavior: "firstRoute"` (confirmed in `BaseTabRouter({ …, backBehavior = 'firstRoute' })`), which sends **every** back action — Android hardware back, browser back, and the in-app back buttons via `router.back()` — to the first/landing route, ignoring history. After the default landing moved to Chat (#373), that surfaced as "back always goes to Chat." **Fix:** set the Drawer's `backBehavior="history"` so back pops to the actual previous screen. One line in `app/(app)/_layout.tsx`. This makes the network detail screens' existing `goBackOr(router, "/network")` behave correctly — `router.back()` now returns to the prior screen when there's history, and still falls back to the logical parent (`/network`) on a cold start / deep link (so you also get "up categorically" for free in the no-history case). ## Verification (local) - `typecheck` ✓ (confirms `backBehavior` is a valid `<Drawer>` prop) · `lint` ✓ · `test` ✓ 172 · semgrep ✓ 0 findings ## ⚠️ Needs maintainer verification Navigation behavior isn't covered by the `node`-env tests — please confirm on device/web: from a person/org detail → back returns to Network (not Chat); from Network → back returns to the previous tab; and a cold-start/deep-link straight onto a detail screen still lands "up" on Network. Direct bug report (no ticket). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(client): back navigation follows history, not always the landing screen
Some checks failed
Commits / Conventional Commits (pull_request) Successful in 10s
PR / Static analysis (pull_request) Successful in 2m27s
PR / OpenAPI (pull_request) Successful in 3m44s
PR / Lint (pull_request) Successful in 4m17s
PR / Typecheck (pull_request) Successful in 4m27s
PR / Client (web export smoke) (pull_request) Successful in 4m32s
PR / Test (sqlite) (pull_request) Successful in 4m31s
PR / pnpm audit (pull_request) Successful in 2m29s
PR / Test (postgres) (pull_request) Successful in 5m0s
Secrets / gitleaks (pull_request) Successful in 41s
PR / Build (pull_request) Successful in 4m58s
PR / OSV-Scanner (pull_request) Successful in 1m49s
PR / Package age policy (soft) (pull_request) Successful in 45s
PR / E2E (Playwright) (pull_request) Failing after 5m59s
PR / Trivy (image) (pull_request) Successful in 2m21s
PR / Coverage (soft) (pull_request) Successful in 1m56s
39f734691d
The (app) Drawer left backBehavior at its default ("firstRoute"), so every
back action — system back, browser back, and the in-app back buttons via
router.back() — jumped to the first/landing route regardless of where you
came from. After the default landing moved to Chat (#373) that meant back
always went to Chat.

Set the Drawer's backBehavior to "history" so back pops to the actual
previous screen. The network detail screens' goBackOr(router, "/network")
now genuinely returns to the prior screen when there's history, and still
falls back to the logical parent on a cold start / deep link.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

📊 Test coverage

Patch coverage: no testable lines changed.

Overall (app/, lib/, db/, excluding UI per ADR-0019):

Metric Value Soft target
Lines 79.4% ≥ 50%
Branches 71.2% ⚠️ ≥ 75%
Functions 80.5% informational

Soft thresholds per ADR-0019. Coverage is informational and does not block merge.

<!-- coverage-comment --> ## 📊 Test coverage **Patch coverage:** no testable lines changed. **Overall** (`app/`, `lib/`, `db/`, excluding UI per ADR-0019): | Metric | Value | Soft target | |---|---|---| | Lines | 79.4% ✅ | ≥ 50% | | Branches | 71.2% ⚠️ | ≥ 75% | | Functions | 80.5% | informational | Soft thresholds per [ADR-0019](docs/adr/0019-coverage-soft-targets.md). Coverage is informational and does not block merge.
james merged commit 903571804c into main 2026-06-29 15:17:41 +00:00
james deleted branch fix-drawer-back-history 2026-06-29 15:17:41 +00:00
Sign in to join this conversation.
No description provided.