Files
lingniu-vehicle-ingest/vehicle-data-platform/docs/frontend-production-readiness.md

47 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Frontend production-readiness audit
This document records verified risks, the production controls that address them, and the next evidence to collect. It is intentionally operational: a passing build alone is not proof that the browser application is production-ready.
## 2026-07-15: route continuity and monitor memory
### Resolved in this round
| Risk | User-visible failure | Control | Evidence gate |
| --- | --- | --- | --- |
| A stale lazy route asset disappears during release | Navigation leaves the content area blank | Preserve the previous build's original hashed assets for one generation; isolate every route with a recoverable error boundary and one-shot reload | Request an old route asset after the symlink switch; navigate through every primary route without a blank shell |
| A pasted batch search temporarily shows the previous fleet | Operators may mistake stale vehicles for batch matches | Hide placeholder rows while `keywords` is changing; report matched and missing plates after the request resolves | Paste newline/comma-separated plates with a duplicate and an unknown plate; verify exact results and missing-count feedback |
| A route is first fetched only after click | Slow transitions and a longer loading flash | Deduplicated route import cache plus pointer, focus and pointer-down preload | Route module unit tests and rendered navigation loop |
| Rapid map pans retain large query payloads | Heap growth and eventual interaction jank | Consume React Query `AbortSignal` and immediately garbage-collect inactive map viewport queries | Query-cache churn test keeps exactly one map payload after repeated viewport changes |
| Superseded monitor requests continue in the background | Wasted server traffic and stale responses | Pass request cancellation signals through the API client | API client signal test and browser network/console smoke |
| QR generation resolves after the dialog unmounts | State update after lifecycle end | Cancel the asynchronous state write on cleanup | Monitor component test |
React documents that `lazy` caches the import promise and propagates a rejected module load to the nearest Error Boundary; this is why a route-level boundary is required rather than a loading fallback alone: <https://react.dev/reference/react/lazy>. React's Suspense documentation also distinguishes a loading fallback from error handling: <https://react.dev/reference/react/Suspense>.
The navigation and progressive-loading direction follows mature observability systems: persistent global controls, collapsible sections and loading only the content needed for the current task. Elastic documents these dashboard interaction and panel-organization patterns here: <https://www.elastic.co/docs/explore-analyze/dashboards/using> and <https://www.elastic.co/docs/explore-analyze/dashboards/arrange-panels>.
### Remaining audit queue
1. Capture a Chrome heap profile across at least 50 `monitor -> history -> statistics -> tracks` cycles and inspect retained AMap objects and detached DOM nodes.
2. Bound or explicitly evict other high-cardinality query families, especially arbitrary history windows and track playback ranges.
3. Retire or migrate the legacy `App.tsx` integration suite so production V2 regressions and obsolete legacy UI expectations are reported separately.
4. Reduce the shared CSS and Semi UI payload; preserve ExcelJS as an action-only dynamic import and consider moving large workbook generation off the main thread.
5. Add an automated release smoke that reads the previous `.release-assets` manifest and asserts every listed compatibility asset returns HTTP 200.
## 2026-07-15: query memory and vehicle-count semantics
Production reconciliation proved that the three visible vehicle counts represent different populations rather than a data loss: 1,035 service identities equal 1,024 bound master vehicles plus 11 realtime identities awaiting binding; 738 vehicles currently have a realtime location row and can enter the global-monitor map. The UI must name these populations explicitly instead of presenting them as interchangeable totals.
High-volume history rows, aggregated series, track playback and daily-mileage matrices consume the request `AbortSignal` and use zero inactive-cache retention. Small vehicle-option and summary results retain only a bounded 3060 second cache. This preserves responsive repeated lookups without retaining multiple large arbitrary date-window payloads after their observer is gone.
## Release evidence template
- Commit and release identifier
- All non-legacy frontend tests
- Production V2 route tests
- TypeScript/Vite production build sizes
- Authenticated health response and `data.runtime.platformRelease`
- New main asset HTTP status
- Previous route asset HTTP status
- Browser route loop, blank-page check and console warnings/errors
- Desktop and mobile viewport screenshots