47 lines
4.8 KiB
Markdown
47 lines
4.8 KiB
Markdown
# 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 30–60 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
|