169 lines
5.1 KiB
Markdown
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 -`.
|