From 19cfedfddf720ff94e800cf2764208eb0a210732 Mon Sep 17 00:00:00 2001 From: ducoterra Date: Sat, 17 Oct 2026 19:32:36 -0400 Subject: [PATCH] phase: 08_events_paging_and_copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All green. Final report: **Verified (phase 08 — both task files already in `complete/`; this was the final verification pass)** - `Dash.eventsPager()` in `app.js` (50/page, `1–50 of N` strip, aria-labelled `‹ prev`/`next ›` disabled at the ends, `WeakMap` page state, reset only when the event *set* changes, `EVENT_FEED_LIMIT`=200) with three call sites; `ul.events` bounded to 320px + `overflow-y:auto`; `/api/events` untouched (`le=500`, no silent clamp). - Live browser against the real fleet: `/system` `1–50 of 121`, `/llm` `1–50 of 200`, `/ups` `1–50 of 200`; container 320px vs scrollHeight 1543/2368; page 2 → `51–100 of 200` and survived two polls; no empty `.sub`/`.faint` container visible on any page; footers carry only measurements (`rates over Δ11.9s · poll 10s`). Fresh artifacts: `data/logs/08-final-{system-head,llm-page,index-page,ups-feed-page2}.png` (32 phase screenshots already present). - Grep of live served bytes for all 13 deleted flavour fragments + `actions = -`: none survive in HTML or JS. - `AGENTS.md` carries both new UI-convention rules (flavour-text rule with the `TODO.md:7` cited examples; the event-feed-window rule) and the updated test count. **Tests / lint (full project 100% green)** - `bash .agents/validate.sh` → **EXIT=0**: `uv run pytest --cov --cov-fail-under=94` → **624 passed, 9 skipped, coverage 97.91%**; `ruff check src tests agent` → All checks passed; `pyright` → 0 errors; `node --check` ×5 clean; repo hygiene clean. - `uv run pytest -m live --live` (`.env.dev` sourced) → **9 passed**; `uv pip list --outdated` → empty. Re-ran pytest/ruff/pyright/node after the doc edits → all exit 0. **Completion criteria**: bounded scroll + 50/page + count footer ✅ (all three feeds, live) · no removed flavour string ✅ · AGENTS.md rule ✅ · `validate.sh` green + screenshots in `data/logs/` ✅. **Documentation**: full README/AGENTS review against code (env table vs `config.py`/`.env*.example`, script flags, Containerfile uid 10001/8090, chart heights 120/110/160, test count, coverage) — one inaccuracy fixed: README said "Every page's event feed" (the overview has none) → now "The three event feeds (`/system`, `/llm`, `/ups`)"; also restored the missing trailing newline in `TODO.md`. Everything else verified consistent. **Notes**: paging stays client-side (no API change); the task-02 defect fix in `/ups` setup copy (`NUT_HOST`/`NUT_PORT`, `LISTEN 127.0.0.1`, one `instcmds` per command, never `actions = -`) re-verified against README and live bytes. Pre-existing items intentionally left to their own phases: `ups.test.result: "Done and passed"` rated `warn` (operator's `TODO.md` entry) and the dev-DB `database is locked` retention issue. **Next pending phase**: `.agents/phases/todo/09_disks_smartctl/` --- .../08_events_paging_and_copy/00_phase.md | 0 .../01_paginate_event_feeds.md | 0 .../02_strip_flavor_text.md | 0 ...08_events_paging_and_copy__00_phase.a1.err | 0 .../08_events_paging_and_copy__00_phase.a1.md | 19 ++ ...nts_paging_and_copy__00_phase.a1.md.status | 1 + ...ents_paging_and_copy__00_phase.a1.validate | 48 ++++ ...g_and_copy__01_paginate_event_feeds.a1.err | 0 ...ng_and_copy__01_paginate_event_feeds.a1.md | 14 ++ ...copy__01_paginate_event_feeds.a1.md.status | 1 + ..._copy__01_paginate_event_feeds.a1.validate | 48 ++++ ...ging_and_copy__02_strip_flavor_text.a1.err | 0 ...aging_and_copy__02_strip_flavor_text.a1.md | 20 ++ ...nd_copy__02_strip_flavor_text.a1.md.status | 1 + ...and_copy__02_strip_flavor_text.a1.validate | 48 ++++ AGENTS.md | 42 +++- README.md | 11 +- TODO.md | 2 + src/dashboards/web/pages/index.html | 5 +- src/dashboards/web/pages/llm.html | 9 +- src/dashboards/web/pages/system.html | 8 +- src/dashboards/web/pages/ups.html | 16 +- src/dashboards/web/static/app.js | 166 ++++++++++++- src/dashboards/web/static/dash.css | 22 +- src/dashboards/web/static/page-index.js | 3 +- src/dashboards/web/static/page-llm.js | 30 +-- src/dashboards/web/static/page-system.js | 23 +- src/dashboards/web/static/page-ups.js | 32 +-- tests/test_api.py | 226 +++++++++++++++++- 29 files changed, 721 insertions(+), 74 deletions(-) rename .agents/phases/{todo => complete}/08_events_paging_and_copy/00_phase.md (100%) rename .agents/phases/{todo => complete}/08_events_paging_and_copy/01_paginate_event_feeds.md (100%) rename .agents/phases/{todo => complete}/08_events_paging_and_copy/02_strip_flavor_text.md (100%) create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.err create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md.status create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.validate create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.err create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md.status create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.validate create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__02_strip_flavor_text.a1.err create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__02_strip_flavor_text.a1.md create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__02_strip_flavor_text.a1.md.status create mode 100644 .agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__02_strip_flavor_text.a1.validate diff --git a/.agents/phases/todo/08_events_paging_and_copy/00_phase.md b/.agents/phases/complete/08_events_paging_and_copy/00_phase.md similarity index 100% rename from .agents/phases/todo/08_events_paging_and_copy/00_phase.md rename to .agents/phases/complete/08_events_paging_and_copy/00_phase.md diff --git a/.agents/phases/todo/08_events_paging_and_copy/01_paginate_event_feeds.md b/.agents/phases/complete/08_events_paging_and_copy/01_paginate_event_feeds.md similarity index 100% rename from .agents/phases/todo/08_events_paging_and_copy/01_paginate_event_feeds.md rename to .agents/phases/complete/08_events_paging_and_copy/01_paginate_event_feeds.md diff --git a/.agents/phases/todo/08_events_paging_and_copy/02_strip_flavor_text.md b/.agents/phases/complete/08_events_paging_and_copy/02_strip_flavor_text.md similarity index 100% rename from .agents/phases/todo/08_events_paging_and_copy/02_strip_flavor_text.md rename to .agents/phases/complete/08_events_paging_and_copy/02_strip_flavor_text.md diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.err b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md new file mode 100644 index 0000000..6b4489c --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md @@ -0,0 +1,19 @@ +All green. Final report: + +**Verified (phase 08 — both task files already in `complete/`; this was the final verification pass)** +- `Dash.eventsPager()` in `app.js` (50/page, `1–50 of N` strip, aria-labelled `‹ prev`/`next ›` disabled at the ends, `WeakMap` page state, reset only when the event *set* changes, `EVENT_FEED_LIMIT`=200) with three call sites; `ul.events` bounded to 320px + `overflow-y:auto`; `/api/events` untouched (`le=500`, no silent clamp). +- Live browser against the real fleet: `/system` `1–50 of 121`, `/llm` `1–50 of 200`, `/ups` `1–50 of 200`; container 320px vs scrollHeight 1543/2368; page 2 → `51–100 of 200` and survived two polls; no empty `.sub`/`.faint` container visible on any page; footers carry only measurements (`rates over Δ11.9s · poll 10s`). Fresh artifacts: `data/logs/08-final-{system-head,llm-page,index-page,ups-feed-page2}.png` (32 phase screenshots already present). +- Grep of live served bytes for all 13 deleted flavour fragments + `actions = -`: none survive in HTML or JS. +- `AGENTS.md` carries both new UI-convention rules (flavour-text rule with the `TODO.md:7` cited examples; the event-feed-window rule) and the updated test count. + +**Tests / lint (full project 100% green)** +- `bash .agents/validate.sh` → **EXIT=0**: `uv run pytest --cov --cov-fail-under=94` → **624 passed, 9 skipped, coverage 97.91%**; `ruff check src tests agent` → All checks passed; `pyright` → 0 errors; `node --check` ×5 clean; repo hygiene clean. +- `uv run pytest -m live --live` (`.env.dev` sourced) → **9 passed**; `uv pip list --outdated` → empty. Re-ran pytest/ruff/pyright/node after the doc edits → all exit 0. + +**Completion criteria**: bounded scroll + 50/page + count footer ✅ (all three feeds, live) · no removed flavour string ✅ · AGENTS.md rule ✅ · `validate.sh` green + screenshots in `data/logs/` ✅. + +**Documentation**: full README/AGENTS review against code (env table vs `config.py`/`.env*.example`, script flags, Containerfile uid 10001/8090, chart heights 120/110/160, test count, coverage) — one inaccuracy fixed: README said "Every page's event feed" (the overview has none) → now "The three event feeds (`/system`, `/llm`, `/ups`)"; also restored the missing trailing newline in `TODO.md`. Everything else verified consistent. + +**Notes**: paging stays client-side (no API change); the task-02 defect fix in `/ups` setup copy (`NUT_HOST`/`NUT_PORT`, `LISTEN 127.0.0.1`, one `instcmds` per command, never `actions = -`) re-verified against README and live bytes. Pre-existing items intentionally left to their own phases: `ups.test.result: "Done and passed"` rated `warn` (operator's `TODO.md` entry) and the dev-DB `database is locked` retention issue. + +**Next pending phase**: `.agents/phases/todo/09_disks_smartctl/` diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md.status b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md.status new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.md.status @@ -0,0 +1 @@ +ok diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.validate b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.validate new file mode 100644 index 0000000..36b642f --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__00_phase.a1.validate @@ -0,0 +1,48 @@ +== uv run pytest --cov (hermetic: no network, live tests skip) == +........................................................................ [ 11%] +........................................................................ [ 22%] +........................................................................ [ 34%] +........................................................................ [ 45%] +...........................sssssssss.................................... [ 56%] +........................................................................ [ 68%] +........................................................................ [ 79%] +........................................................................ [ 90%] +......................................................... [100%] +=============================== warnings summary =============================== +.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1 + /var/home/ducoterra/Projects/Personal/dashboards/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead. + from starlette.testclient import TestClient as TestClient # noqa + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +================================ tests coverage ================================ +_______________ coverage: platform linux, python 3.14.4-final-0 ________________ + +Name Stmts Miss Cover Missing +------------------------------------------------------------------ +src/dashboards/__init__.py 3 0 100% +src/dashboards/__main__.py 14 1 93% 28 +src/dashboards/alerts.py 166 0 100% +src/dashboards/api.py 193 0 100% +src/dashboards/app.py 107 6 94% 50-51, 56, 58, 60, 127 +src/dashboards/collectors.py 142 5 96% 97-98, 102-103, 120 +src/dashboards/config.py 113 0 100% +src/dashboards/debug.py 14 0 100% +src/dashboards/poller.py 165 3 98% 192-194, 279 +src/dashboards/prom.py 105 5 95% 107, 144, 158, 161, 164 +src/dashboards/rates.py 37 1 97% 51 +src/dashboards/severity.py 49 0 100% +src/dashboards/sources/__init__.py 0 0 100% +src/dashboards/sources/host.py 199 1 99% 147 +src/dashboards/sources/llm.py 150 1 99% 228 +src/dashboards/sources/nut.py 389 20 95% 128, 142, 148, 160, 166, 178, 186, 199, 270-271, 273, 489, 501, 536, 569, 573, 630-631, 636, 648 +src/dashboards/sources/nut_sim.py 134 0 100% +src/dashboards/store.py 178 2 99% 243-244 +------------------------------------------------------------------ +TOTAL 2158 45 98% +Required test coverage of 94% reached. Total coverage: 97.91% +624 passed, 9 skipped, 1 warning in 53.90s +== uv run ruff check src tests agent == +All checks passed! +== uv run pyright == +0 errors, 0 warnings, 0 informations +== node --check src/dashboards/web/static/*.js == diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.err b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.err new file mode 100644 index 0000000..e69de29 diff --git a/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md new file mode 100644 index 0000000..4e2b74c --- /dev/null +++ b/.agents/reports/08_events_paging_and_copy/08_events_paging_and_copy__01_paginate_event_feeds.a1.md @@ -0,0 +1,14 @@ +**Implemented (task 01 — event feeds: scrollable and paginated)** +- `Dash.eventsPager(el, events, opts)` in `app.js`: one shared pager — 50 rows/page, `1–50 of N` footer with `‹ prev` / `next ›` (aria-labelled for direction, `disabled` at the ends), strip hidden when the feed fits, page state in a `WeakMap` keyed by the `