diff --git a/webui/docs/migration/page-migration-overview.md b/webui/docs/migration/page-migration-overview.md index 0d123551..01c96a57 100644 --- a/webui/docs/migration/page-migration-overview.md +++ b/webui/docs/migration/page-migration-overview.md @@ -1,16 +1,17 @@ -# WebUI Page Migration Analysis +# WebUI Page Migration Overview -Snapshot date: 2026-05-02 +Snapshot date: 2026-05-14 ## Summary - The shell route manifest now has 18 page ids. -- `issues` is still the only React-owned route. +- `issues` and `stats` are now React-owned routes. - Since the last snapshot, the biggest changes are: - `downloads` was renamed into `search`. - The live queue became `active-downloads`. - `watchlist` and `wishlist` became full sidebar pages. - `tools` was split off from `dashboard`. - `artists` is no longer a route id. +- Since the last migration review, `stats` has been fully moved to React, the legacy stats HTML/JS/CSS path has been removed, and the global `Chart.js` import has been dropped in favor of route-local `Recharts`. - The shell is also more modular now. The old monolithic `script.js` has been split across `core.js`, `init.js`, `shared-helpers.js`, and feature modules such as `search.js`, `api-monitor.js`, `pages-extra.js`, `stats-automations.js`, and `wishlist-tools.js`. - Current profile compatibility still normalizes old `downloads` and `artists` references to `search`, so the docs and the route ids are not always using the same historical language. @@ -28,7 +29,7 @@ Snapshot date: 2026-05-02 - `webui/static/core.js` now holds a lot of the shared global state that used to live in the old monolith. - `webui/static/init.js` still owns page activation, permission gating, nav highlighting, legacy routing, and the `window.SoulSyncWebRouter` bridge. - `webui/static/shell-bridge.js` and the TanStack Router adapter still decide whether a route is handled by the React host or handed back to the legacy shell. -- `issues` remains the reference pattern for React-owned pages: route manifest ownership, shell bridge integration, route-local data loading, and detail-modal behavior all live in the React subtree. +- `issues` remains the reference pattern for interactive React-owned pages, while `stats` now complements it as the reference for data-heavy read-only routes with route-local charts and explicit shell handoffs. - The legacy shell is now spread across feature modules rather than one giant coordinator file, which makes the migration seams a little clearer than they were a month ago. ### Route and Compatibility Notes @@ -48,6 +49,7 @@ Snapshot date: 2026-05-02 - Socket/WebSocket and polling behavior remain the biggest migration risks for live pages. - The help system, tours, and helper annotations still reference some historical route names, so route-migration work should use the manifest as the source of truth. - Visual effects such as `particles.js` and `worker-orbs.js` remain shell-global. +- Route migrations should actively scan for emerging shared UI or shell patterns. Do not force abstractions on the first occurrence, but do document overlap and prefer extracting a shared primitive once a second route clearly needs the same behavior. ## Scoring Rubric Each page is scored from 1 to 5 on five axes: @@ -74,10 +76,10 @@ Rollups: | Page | Owner | Scores (R/S/A/C/T) | Effort | Risk | Recommended Wave | | --- | --- | --- | --- | --- | --- | -| `issues` | React | 2 / 2 / 2 / 2 / 2 | Low | Low | Wave 0 | +| `issues` | React | 2 / 2 / 2 / 2 / 2 | Low | Low | Completed | +| `stats` | React | 2 / 2 / 2 / 2 / 2 | Low | Low | Completed | | `help` | Legacy | 3 / 2 / 1 / 1 / 2 | Low | Low | Wave 1 | | `hydrabase` | Legacy | 2 / 2 / 2 / 2 / 2 | Low | Low | Wave 1 | -| `stats` | Legacy | 2 / 2 / 2 / 2 / 2 | Low | Low | Wave 1 | | `import` | Legacy | 3 / 3 / 3 / 2 / 3 | Medium | Medium | Wave 1 | | `search` | Legacy | 4 / 4 / 4 / 3 / 4 | High | High | Wave 2 | | `watchlist` | Legacy | 4 / 4 / 4 / 3 / 4 | High | High | Wave 3 | @@ -104,6 +106,13 @@ Rollups: - Key coupling: shell page gating, shell nav badge refresh, bridge-controlled chrome, React Query cache. - Why it stays first: it is already the canonical React route pattern and the migration baseline. +#### `stats` +- Current owner: React. +- Primary files: `webui/src/routes/stats/*`, `webui/src/platform/shell/*`. +- Main surface: listening stats, charts, ranked lists, disk usage, database storage visualization. +- Key coupling: query invalidation, shell handoffs for playback and artist navigation, route-local chart composition. +- Why it matters now: it is the first completed data-heavy read-only migration and the current reference for route-local charting, explicit shell bridge usage, and legacy cleanup after cutover. + ### Wave 1: Safest wins #### `help` @@ -120,19 +129,12 @@ Rollups: - Key coupling: profile gating and a small amount of shell state. - Recommendation: low-risk route with a narrow surface. -#### `stats` -- Current owner: Legacy. -- Primary files: `webui/index.html`, `webui/static/stats-automations.js`. -- Main surface: listening stats, charts, ranked lists, database storage visualization. -- Key coupling: chart rendering, some deep links back into library routes. -- Recommendation: early migration candidate with good parity-test potential. - #### `import` - Current owner: Legacy. - Primary files: `webui/index.html`, `webui/static/stats-automations.js`, `webui/static/helper.js`. - Main surface: staging files, album and singles matching, suggestion cards, processing queue. - Key coupling: settings-derived staging path assumptions and downstream library state. -- Recommendation: still bounded enough for an early wave, though more workflow-heavy than `help` or `stats`. +- Recommendation: still bounded enough for an early wave, though more workflow-heavy than `help` or `hydrabase`. ### Wave 2: Search split @@ -244,6 +246,7 @@ Rollups: - Recommendation: save this for the final wave with the other complex authoring surfaces. ## Platform Unlocks +- `stats` now provides the baseline for route-local charting, explicit shell-bridge interop from React, and the pattern of cleaning out legacy assets once parity is confirmed. - `search` likely unlocks reusable search-controller and download-launch primitives for the global search widget and other search entry points. - `watchlist` likely unlocks artist-card, per-artist config, and scan-status primitives for `discover` and `wishlist`. - `wishlist` likely unlocks queue/cycle visualization, live polling, and retry-state handling for `active-downloads` and sync-driven download flows. @@ -252,6 +255,7 @@ Rollups: - `library` + `artist-detail` still unlock entity-detail patterns, bulk actions, and file-management workflows. ## Why Earlier Waves Are Safer +- `stats` validated that bounded data pages can move early without needing broad shell rewrites, while also surfacing a healthy reminder to watch for emerging shared primitives during migration work. - Wave 1 routes are either mostly static or bounded data UIs with limited cross-route side effects. - Wave 2 adds the renamed search surface without dragging in the full queue history. - Wave 3 introduces the new watchlist/wishlist split, which is important but still narrower than discovery or library management. @@ -260,8 +264,9 @@ Rollups: - Waves 6-10 defer the broadest, most coupled, or most orchestration-heavy surfaces until the team has the most leverage. ## Final Recommendation -- Keep `issues` as the reference implementation and preserve the existing bridge contract. +- Keep `issues` and `stats` as the current React reference implementations, and preserve the explicit bridge contract between React routes and legacy shell behavior. - Treat `search`, `watchlist`, `wishlist`, `active-downloads`, and `tools` as the current route ids, and keep `downloads` and `artists` only as compatibility history. -- Migrate the safe routes first: `help`, `hydrabase`, `stats`, and `import`. +- Migrate the remaining safe legacy routes first: `help`, `hydrabase`, and `import`. +- During each migration, actively look for small reuse opportunities across route slices and shared UI primitives, but only extract once the overlap is clearly real. - Use `search` as the next meaningful proving ground now that the download queue has been split out. - Avoid pulling `settings`, `sync`, `library`, `artist-detail`, or `automations` forward unless there is a separate product priority strong enough to justify the added regression risk. diff --git a/webui/docs/migration/stats-migration-plan.md b/webui/docs/migration/stats-migration-plan.md index d74215cc..bd582c2e 100644 --- a/webui/docs/migration/stats-migration-plan.md +++ b/webui/docs/migration/stats-migration-plan.md @@ -1,7 +1,16 @@ -# WebUI Stats React Migration Sketch +# WebUI Stats Migration Plan Snapshot date: 2026-05-14 +## Status + +- Completed on 2026-05-14. +- `stats` is now React-owned in the shell route manifest. +- The legacy stats HTML, JS, and CSS path has been removed. +- The global `Chart.js` import was removed and replaced with route-local `Recharts`. +- Legacy playback and artist-detail handoffs now go through the explicit shell bridge. +- A local seed script exists for realistic UI testing without production listening history: `tools/seed_stats_ui_scenarios.py`. + ## Goal - Migrate `stats` from the legacy shell to the React route host. @@ -16,6 +25,8 @@ Snapshot date: 2026-05-14 - The page is complex enough to validate query conventions, search-param state, and route-local chart components. - The page does not currently drive broad shell-global workflows. +This route has now validated those assumptions successfully. + ## Current Legacy Shape Page surface in `webui/index.html`: @@ -370,6 +381,7 @@ Playwright is optional for the first pass. - Extract shared chart colors into route-local constants or a small shared viz helper. - Consider a tiny `components/charts/` layer only after a second React page needs charts. - Revisit whether `stats/cached` should remain the primary page payload or whether the route should fan out to narrower endpoints later. +- Keep watching for overlap between route-local controls and shared UI primitives. The stats range selector is a good example of a pattern that should stay local for now, but should be reconsidered if another migrated route needs the same segmented-control behavior. ## Recommendation @@ -385,3 +397,12 @@ It should not optimize for: - visual redesign - a cross-app chart abstraction - backend reshaping + +## Outcome + +- The route now serves as the reference for data-heavy read-only React pages. +- The migration proved out route-local charts, route-search state, explicit shell-bridge interop, and post-cutover legacy cleanup. +- The work also reinforced a migration guideline for future routes: + - prefer local implementation on first use + - actively note overlap with shared primitives + - extract only once the second clear consumer appears