Files
musicdl-catalog-sync-suite/catalog-sync/docs/superpowers/plans/2026-04-18-task-center-bandwidth-summary.md

169 lines
5.1 KiB
Markdown

# Task Center Bandwidth Summary Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Show real-time aggregate download speed next to the Task Center heading, while rendering upload speed as a placeholder.
**Architecture:** Reuse existing per-worker `speed_bytes_per_sec` values already stored in `job_workers`, aggregate them in the dashboard payload as `transfer_stats`, and render/update a single Task Center header node from server-rendered HTML plus dashboard refreshes. Upload remains explicitly unimplemented and is shown as a placeholder string.
**Tech Stack:** FastAPI, Jinja2, vanilla JavaScript, `unittest`
---
### Task 1: Lock the API and page contract with tests
**Files:**
- Modify: `tests/catalogsync/test_ops_api.py`
- [ ] **Step 1: Write the failing API test**
Add coverage that seeds a running download worker with `speed_bytes_per_sec=2 * 1024 * 1024`, calls `/api/dashboard`, and asserts:
```python
self.assertEqual("2.0 MB/s", payload["transfer_stats"]["download_speed_text"])
self.assertEqual("-", payload["transfer_stats"]["upload_speed_text"])
```
Also render `/dashboard` and assert the Task Center area includes:
```python
self.assertIn("Task Center", html)
self.assertIn("Down 2.0 MB/s", html)
self.assertIn("Up -", html)
```
- [ ] **Step 2: Run test to verify it fails**
Run: `python -m unittest tests.catalogsync.test_ops_api.OperationsApiTests.test_dashboard_transfer_stats_exposes_download_speed_and_upload_placeholder -v`
Expected: FAIL because `transfer_stats` and the new header text do not exist yet.
### Task 2: Lock the browser refresh behavior with a frontend test
**Files:**
- Modify: `tests/catalogsync/test_ops_frontend.py`
- [ ] **Step 1: Write the failing frontend test**
Expose `updateDashboard`, create a fake `[data-task-center-transfer]` node, call:
```javascript
api.updateDashboard({
transfer_stats: {
download_speed_text: "2.0 MB/s",
upload_speed_text: "-"
}
});
```
and assert the node text becomes:
```javascript
"Down 2.0 MB/s | Up -"
```
- [ ] **Step 2: Run test to verify it fails**
Run: `python -m unittest tests.catalogsync.test_ops_frontend.OperationsFrontendTests.test_update_dashboard_refreshes_task_center_transfer_summary -v`
Expected: FAIL because no Task Center transfer node is updated yet.
### Task 3: Implement backend aggregation and initial render
**Files:**
- Modify: `musicdl/catalogsync/ops/web.py`
- Modify: `musicdl/catalogsync/templates/ops/dashboard.html`
- [ ] **Step 1: Add backend transfer aggregation**
In `musicdl/catalogsync/ops/web.py`, extend worker serialization to include numeric speed fields and add a helper that returns:
```python
{
"download_speed_bytes_per_sec": ...,
"download_speed_text": ...,
"upload_speed_bytes_per_sec": 0,
"upload_speed_text": "-",
}
```
using the sum of active download worker `speed_bytes_per_sec`.
- [ ] **Step 2: Add the server-rendered Task Center summary node**
In `musicdl/catalogsync/templates/ops/dashboard.html`, change the Task Center heading area to include:
```html
<span class="muted" data-task-center-transfer>Down {{ transfer_stats.download_speed_text }} | Up {{ transfer_stats.upload_speed_text }}</span>
```
- [ ] **Step 3: Run the API test to verify it passes**
Run: `python -m unittest tests.catalogsync.test_ops_api.OperationsApiTests.test_dashboard_transfer_stats_exposes_download_speed_and_upload_placeholder -v`
Expected: PASS
### Task 4: Implement live refresh wiring
**Files:**
- Modify: `musicdl/catalogsync/static/ops/app.js`
- [ ] **Step 1: Update the dashboard refresh path**
In `updateDashboard(payload)`, look up `[data-task-center-transfer]` and set:
```javascript
"Down " + downloadSpeedText + " | Up " + uploadSpeedText
```
with defaults of `"0 B/s"` for missing download speed and `"-"` for upload.
- [ ] **Step 2: Run the frontend test to verify it passes**
Run: `python -m unittest tests.catalogsync.test_ops_frontend.OperationsFrontendTests.test_update_dashboard_refreshes_task_center_transfer_summary -v`
Expected: PASS
### Task 5: Regression verification
**Files:**
- Modify: none
- [ ] **Step 1: Run focused regression**
Run:
```bash
python -m unittest tests.catalogsync.test_ops_api tests.catalogsync.test_ops_frontend -v
node -e "new Function(require('fs').readFileSync('musicdl/catalogsync/static/ops/app.js','utf8')); console.log('app.js syntax ok')"
```
Expected: all selected tests PASS and `app.js syntax ok` prints.
- [ ] **Step 2: Sync to NAS and restart**
Sync these files to `/volume4/Music_Cloud/catalogsync/app/...`:
```text
musicdl/catalogsync/ops/web.py
musicdl/catalogsync/templates/ops/dashboard.html
musicdl/catalogsync/static/ops/app.js
```
Then restart:
```bash
nohup bash /volume4/Music_Cloud/catalogsync/bin/serve_console.sh >/dev/null 2>&1 &
```
- [ ] **Step 3: Verify deployed page**
Check:
```bash
http://127.0.0.1:18080/dashboard
http://127.0.0.1:18080/api/dashboard?include_task_rows=false
```
Expected: the Task Center heading shows `Down ... | Up -`.