toga-ai 1.0.435 → 1.0.436
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: session
|
|
3
|
+
slug: sprint-dashboard
|
|
4
|
+
title: TOGa IQ Sprint Dashboard prototype (React + Express stand-in)
|
|
5
|
+
author: kyalamarthi
|
|
6
|
+
repos: [test]
|
|
7
|
+
framework: "standalone"
|
|
8
|
+
client: shared
|
|
9
|
+
status: active
|
|
10
|
+
created: 2026-07-24
|
|
11
|
+
updated: 2026-07-24
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Session: sprint-dashboard
|
|
15
|
+
**Date:** 2026-07-24
|
|
16
|
+
**Project/Repo:** test (standalone Node/React prototype in `@krishna/React`; reads 2.0 TOGa IQ `Team` data)
|
|
17
|
+
**Task:** Build a Power BI-parity TOGa IQ sprint dashboard in `test/@krishna/React` — React (CDN, no build) frontend + Express/mysql2 backend that stands in for the api2 `/v2` engine — with KPI tiles, Status/Work Type pies, Sprint Burndown, Sprint Points By Dev, and a Time-Progression header, all auto-resolving the current sprint from the live `Team` schema.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What WORKED
|
|
22
|
+
- **`backend/server.js`** — Express + a single mysql2 pool, `MOCK_MODE` switch, api2 `/v2` envelope (`{transactionId,timestamp,isSuccess,status,error,messages,meta,data}`), and `express.static` serving the frontend with `Cache-Control: no-store`. Live-verified against the `Team` schema (core-cluster reader): server boots "LIVE (querying MySQL)".
|
|
23
|
+
- **Parameterized tile endpoint** `GET /v2/sprints/tile?category=committed|conditional|stretch|unplanned` driven by a `CATEGORIES` map (per-tile `column`+`value`+mock) and a `COLUMN_ALLOWLIST`. Injection-safe: `value`/`sprint` are bound `?` params, the work-type **column** is only ever taken from the server-side allowlist. Verified all four categories, a clean **400** on `category=bogus`, and the back-compat `/v2/sprints/committed-tile` alias.
|
|
24
|
+
- **Status rollup** (`/status-breakdown`) mirrors the Power BI "Status now Category Group" SWITCH (default→Review); returns **both `count` and `points`** per bucket. **Work Type pie** (`/worktype-breakdown`) = `SUM(sprintPointsNow) GROUP BY workTypeNow`. **Points-by-Dev** (`/points-by-dev`) joins `Tasks→Tasks_Developers→Developers` (many-to-many, full points per dev) with the "New Status" SWITCH (`dtCompleted`→Complete; else statusNow-not-in-active→In Review; else workTypeNow). **Burndown** (`/burndown`) = Target `CCU×(1−day/N)` + actual `total−done-to-date` (CCU vs CCUS) over Mon–Fri working days, actuals stop at today. All live-verified for sprint 83.
|
|
25
|
+
- **Current-sprint auto-resolution** — a `/v2/sprints` middleware defaults every endpoint to the sprint whose range contains today (`CURDATE() BETWEEN dateStart AND dateEnd`, else most recently started), and `GET /v2/sprints/current` feeds the header. Verified → auto-resolves to **sprint 83** (Jul 22–Aug 4); no hardcoded sprint anywhere.
|
|
26
|
+
- **`frontend/dashboard.html`** — 2×2 grid (tiles top; Status/Work Type left column `1fr`; Burndown/Points-by-Dev right column `2fr`), fits one viewport, no scroll. Reusable `Donut`/`PieChart`/`Legend`/`StackedBarChart`/`BurndownChart` + shared `fetchEnvelope`/`useApi`. Time-Progression header bar (business hours) + Full-screen button. Verified via browser screenshots and `evaluate_script` (10px row gaps, `docScrollH == viewportH`).
|
|
27
|
+
- **`frontend/dashboard1.html`** — copy of dashboard.html, since customized into a **donut** variant (center totals + value legend). `USE_MOCK=false` (live). Its **Status donut shows POINTS** (center "208 points", legend point values) via `b.points` + `unit="points"`.
|
|
28
|
+
- **Knowledge captured** — `/capture` UPDATED `knowledge/2.0/apps/worker2/features/team-sprint-management.md` with the full DAX→SQL metric definitions + Team-schema precision; **pushed to `_main`**.
|
|
29
|
+
|
|
30
|
+
## What did NOT work — DO NOT RETRY THESE
|
|
31
|
+
- **Layout attempt #1:** `.page { min-height:100vh }` + `.main-grid { grid-template-rows: minmax(240px,1fr) minmax(240px,1fr) }`. On a 768px viewport the grid grew to **750px** and the bottom row was clipped ~170px (`document.scrollHeight = 939 > 768`). Reason: `min-height` + the `minmax` row **minimums** let the grid exceed the viewport instead of shrinking.
|
|
32
|
+
- **Layout attempt #2:** `.page { height:100vh; overflow:hidden }` + `grid-template-rows: 1fr 1fr` **alone** → rows still **overlapped by exactly 20px** (row-1 cards ran 169→490, row-2 started at 470). Reason: cards were `box-sizing: content-box`, so their `14px×2` padding + `1px×2` border added **30px on top** of the computed `290.5px` track height → each card rendered **321px** and overflowed its grid row. **Root fix:** global `*, *::before, *::after { box-sizing: border-box }`.
|
|
33
|
+
- **Absolutely-positioning the chart SVGs** (`.chart-fill { position:absolute; inset:0 }`) did **not** fix the row overlap on its own — the overlap was the card padding (content-box), not the SVG's intrinsic height. (Kept the absolute-fill regardless — it's correct for scaling charts to their cell — but it was not the fix.)
|
|
34
|
+
- **`/committed-tile` alias via `app._router.handle(req,res)`** — reached into Express internals and was fragile. Refactored both routes to call a shared `serveTile()` function instead.
|
|
35
|
+
- **First full-content Write to each new file** was denied once by the fact-forcing gate (keys on path, ignores content). Use stub-first for large new files to avoid re-emitting the whole body.
|
|
36
|
+
|
|
37
|
+
## Not tried yet (candidates for next session)
|
|
38
|
+
- **Productionize the tiles as real api2 Record Scripts** (`_Model_Team_Sprint::sprintTile` on `_underscore`, registered via **dbchanges2**) to replace the Express stand-in. `sql/register_committed_tile_endpoint.sql` is the starting template. This is the natural next step (user asked how the real data path works: worker2 ingests → Team DB → api2 Record Script serves).
|
|
39
|
+
- **Auth** — `AUTH_TOKEN` in the frontend is an empty placeholder; wire the Bearer JWT + confirm header names against a real `/v2/auth` call.
|
|
40
|
+
- **Reconcile current-state vs canonical scoring** — dashboard uses Power BI current-state (`dtDone`+`workTypeNow`); canonical scoring uses `statusNow IN DONE`+`workTypeAtLock`. Decide which a leadership-facing view should use.
|
|
41
|
+
- **Burndown day-numbering** — currently 1-based (Target starts at 90% on day 1, hits 0 on day N). Confirm against Power BI whether it should be 0-based (start at 100%). One-char change (`k=i` vs `k=i+1`).
|
|
42
|
+
- **Multi-dev point splitting** — Points-by-Dev currently credits each assigned dev the task's full points (matches the KB rule). Add a split option only if Power BI splits.
|
|
43
|
+
- **Time-progression live refresh** — currently a snapshot computed on page load; add a timer if a wall display needs it to tick.
|
|
44
|
+
|
|
45
|
+
## Current file state
|
|
46
|
+
| File | Status | Notes |
|
|
47
|
+
|------|--------|-------|
|
|
48
|
+
| `test/@krishna/React/backend/server.js` | Created/rewritten | Live-verified; current-sprint middleware + 6 `/v2/sprints/*` endpoints; injection-safe; `no-store`; `FALLBACK_SPRINT=82` only if table empty. |
|
|
49
|
+
| `test/@krishna/React/frontend/dashboard.html` | Created | 2×2 dashboard; Status shows task **counts**; box-sizing fix applied; live. |
|
|
50
|
+
| `test/@krishna/React/frontend/dashboard1.html` | Created (copy, then edited) | Donut variant; `USE_MOCK=false`; Status donut shows **points** (`unit="points"`); live. |
|
|
51
|
+
| `test/@krishna/React/frontend/committed-tile.html` | Untouched | Original single-tile page; left as-is. |
|
|
52
|
+
| `test/@krishna/React/sql/tile_query.sql` | Created | Parameterized query reference (documents column/value per tile). |
|
|
53
|
+
| `test/@krishna/React/sql/committed_tile.sql`, `register_committed_tile_endpoint.sql` | Pre-existing | The latter is the api2 Record Script registration template for productionizing. |
|
|
54
|
+
| `test/@krishna/React/backend/.env` | Present, NOT committed | `MOCK_MODE=false`, `DB_NAME=Team`, core-cluster reader host + `admin` user. Credentials live here only — never commit. |
|
|
55
|
+
| `knowledge/2.0/apps/worker2/features/team-sprint-management.md` | UPDATED + pushed | DAX→SQL metric definitions + Team schema vocabularies (`dtDone` vs `dtCompleted`, many-to-many points). |
|
|
56
|
+
|
|
57
|
+
## Decisions made
|
|
58
|
+
- **One parameterized tile endpoint** over four near-identical routes (DRY). Rejected: separate `committed-tile`/`stretch-tile`/… files (the original single-tile approach) — too much duplication for a 4-tile dashboard.
|
|
59
|
+
- **Backend resolves the current sprint per request** (middleware) and the frontend sends **no `?sprint=`**. Rationale: "always show the current sprint, never hardcode." Accepted the minor cost of an extra resolve query per endpoint; `/current` skips the middleware to avoid a double query.
|
|
60
|
+
- **Express + mysql2 as a local api2 stand-in** that imitates the `/v2` envelope, so the React frontend is drop-in for the real api2 later. Rejected: querying the DB from the browser (impossible/insecure) or building the real Record Script now (out of scope for the prototype).
|
|
61
|
+
- **Knowledge placed in `worker2/features/team-sprint-management.md`**, not a new `test/` doc. Rationale: that doc already owns the Team-schema + sprint-metric subject and is cross-linked from api2; the `test` sandbox's per-developer folders are excluded from the KB.
|
|
62
|
+
- **`dashboard1.html` is a separate file** for the donut/points variant; `dashboard.html` stays on task counts. Rationale: user wanted a distinct second dashboard without changing the first.
|
|
63
|
+
- **Global `box-sizing: border-box`** — the correct fix for the row-overlap (not min-heights, not absolute positioning).
|
|
64
|
+
|
|
65
|
+
## Blockers
|
|
66
|
+
None functional. Operational note: **the dev server does not persist across Claude sessions** — it must be restarted each time (`cd test/@krishna/React/backend && npm start`). It also serves `dashboard1.html` automatically (static folder).
|
|
67
|
+
|
|
68
|
+
## Exact next step
|
|
69
|
+
> Restart the server (`cd c:/www/test/@krishna/React/backend && npm start`) and open `http://localhost:3001/dashboard1.html` to confirm it still auto-resolves the current sprint. Then, to move off the prototype stand-in, implement the **api2 Record Script** version of the tiles — `_Model_Team_Sprint::sprintTile()` on `_underscore`, registered via **dbchanges2** using `sql/register_committed_tile_endpoint.sql` as the template — so the dashboard fetches through the real api2/`_underscore` path (worker2 keeps populating the `Team` tables; api2 serves them).
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
_Saved by /session-save on 2026-07-24_
|
package/package.json
CHANGED