Proxy routes now share one upstream-error adapter so client-actionable statuses such as auth, entitlement, validation, and rate limits survive the BFF instead of becoming opaque 502s. The scan terminal mobile overrides also load last and remove desktop rail constraints so phones get a single readable column.
Constraint: Mobile users reported the dashboard was unreadable, and BFF proxy errors were masking expected client states.
Rejected: Let every route keep bespoke error JSON | continued inconsistent status codes and production detail leakage.
Confidence: high
Scope-risk: moderate
Directive: Keep ScanTerminalMobile.module.css imported after desktop scan-terminal CSS so mobile breakpoints win.
Tested: npx tsc --noEmit --pretty false --project frontend/tsconfig.json
Tested: npm run build
Tested: npm run test:business
Tested: Chrome mobile smoke test at 390px with no horizontal overflow
Not-tested: Real device Safari/Android manual QA
The scan terminal had grown into overlapping CSS, request-state, AI-provider, and city-card data responsibilities. This refactor separates those boundaries without changing product behavior: CSS modules are split by surface, city AI prompt/provider/fallback logic is isolated, and scan terminal request state now has reusable RemoteData adapters plus business-state tests.
Constraint: Preserve existing global scan-terminal class names and API responses during the refactor
Constraint: No new dependencies; keep this as a file-boundary cleanup
Rejected: Introduce React Query now | higher migration risk than the requested lightweight query-client path
Rejected: Rewrite AI stream behavior | progressive/fallback states are product-sensitive and were only adapter-split
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep AI stream state changes covered by business snapshots before changing fallback/cache wording
Tested: npm run test:business; npx tsc --noEmit; npm run build; python pytest -q; ruff check; py_compile targeted city AI modules
Not-tested: Live DeepSeek provider network replay and browser visual QA