D12 - the productivity factor, on the dashboard (was BL-023)
Nick's decision: 'find a spot on the dashboard.' The spot: an eighth metric
card beside Est./Actual hrs - actual/estimated to two decimals, green at or
under 1.0, red over. Both hour fields are optional (CR-017), so with nothing
to divide the card shows an em dash rather than vanishing: a metric that
disappears reads as 'no such measure', not 'nothing logged yet'. Server sums
(B4), the same m.est_hours/actual_hours its neighbours already render - zero
new fetches, and the card stays inside the block the metrics-failure path
skips, so an outage still shows the error panel and no cards.
aggregates_check gains the pin (16 -> 17): the card must equal the quotient
of the SERVER's sums, or the em dash when either sum is zero - derived, not
hardcoded. Backlog entry corrected in passing where it credited
/api/projects/{id}/summary with hour sums it never carried.
Items: D12 (decisions-2026-08-20.md), CR-017 read, B4 discipline.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -155,6 +155,18 @@ def main():
|
||||
str(shown) == str(as_root["total"]),
|
||||
"shown=%r server=%r (poisoned cache said 2)" % (shown, as_root["total"]))
|
||||
chk("...and is therefore not the poisoned cache's 2", str(shown) != "2", shown)
|
||||
# D12: the productivity factor card, computed from the SAME server
|
||||
# sums as its neighbours. Both hour fields are optional (CR-017),
|
||||
# so the expected value is derived, not hardcoded: a real quotient
|
||||
# when both sums exist, an em dash when either is zero.
|
||||
pf_shown = page.eval(
|
||||
"(()=>{const e=[...document.querySelectorAll('.dash-metric')]"
|
||||
".find(x=>/Productivity/i.test(x.textContent));"
|
||||
"return e?e.querySelector('.dm-val').textContent.trim():null})()")
|
||||
est, act = as_root.get("est_hours") or 0, as_root.get("actual_hours") or 0
|
||||
pf_want = ("%.2f" % (act / est)) if est > 0 and act > 0 else "—"
|
||||
chk("the D12 productivity card shows actual/estimated from the server sums",
|
||||
pf_shown == pf_want, "shown=%r want=%r (est=%r act=%r)" % (pf_shown, pf_want, est, act))
|
||||
|
||||
print("\n3. a failed aggregate request is an error, not a zero")
|
||||
page.eval("""(() => {
|
||||
|
||||
Reference in New Issue
Block a user