Sfoglia il codice sorgente

Docs: mark R02-N01 fixed, refresh SPEC §5 / §9 / §13

Server is now the single source of truth for capacity (per Path B in
the finding). §5 rewritten — drops the "any edit must touch both" line,
spells out that the JS does only a plain Ressourcen sum and that
Reserves / Available come from the PATCH `per_worker` envelope. New
§9 entry recording the simplification at 14b1cfd; SHA appended to §13.
REVIEW_02.md flips R02-N01's status to fixed-in-14b1cfd with the
closing note.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 1 giorno fa
parent
commit
22d5e2af96
2 ha cambiato i file con 45 aggiunte e 3 eliminazioni
  1. 33 2
      SPEC.md
  2. 12 1
      doc/REVIEW_02.md

+ 33 - 2
SPEC.md

@@ -187,8 +187,14 @@ runs — Phase 8):
 
 ## 5. Capacity math (spec §6.5)
 
-Runs identically in `App\Services\CapacityCalculator` (PHP) and in
-`sprint-planner.js` (JS). Any edit must touch both.
+Authoritatively in `App\Services\CapacityCalculator` (PHP) — single
+source of truth (R02-N01). The client (`sprint-planner.js`) does a
+plain DOM sum for the Ressourcen value so the row Σ updates while the
+user types; Reserves and Available come from the server's PATCH
+response (`per_worker` envelope), which is applied via
+`applyServerCapacity()` after every mutation (cell save, prio change,
+delete, move). With the 400 ms debounce on the days pipeline, the
+server-authoritative numbers settle within a beat of the user pausing.
 
 ```
 round_half(x)  = round(x * 2) / 2
@@ -1600,6 +1606,30 @@ OIDC kill-switch (`OIDC_ENABLED=false`):
       same way the sprints table on `/` does — also mirrored on
       JS-built rows in `sprint-planner.js::buildTaskRow`.
 
+- [x] **R02-N01 — Capacity formula no longer duplicated in JS**
+      (`14b1cfd`). The JS reproduced `roundHalf` / `after_reserves` /
+      `committed_p1` / `available` in `sprint-planner.js` so on-screen
+      totals updated during typing. Every PATCH response already returned
+      the freshly computed `per_worker` values, and
+      `applyServerCapacity()` applied them right after each save — so the
+      JS copy was just a typing-feel optimisation that doubled the
+      maintenance cost of any future change to the capacity rule (the
+      first finding from `doc/REVIEW_02.md`). Path B from the finding:
+      `recomputeRow()` is now a plain DOM sum of `[data-day]` inputs that
+      writes only `[data-sum-days]` and `[data-cap-ressourcen]`;
+      `capacity()`, `committedPrio1FromDom()`, and `recomputeAllCapacity()`
+      are gone, along with the now-unused `data-reserve-fraction`
+      attribute on `views/sprints/{show,present}.twig`. Reserves and
+      Available are server-authoritative from here on — the 400 ms
+      debounce on the days pipeline gives the cells "type and pause"
+      feel, and `applyServerCapacity()` snaps them to the official
+      number on every mutation. `POST /tasks/{id}/move` now also returns
+      `per_worker` for the source sprint (it didn't before, because the
+      old code refreshed via `recomputeAllCapacity()`); the move handler
+      applies it like every other mutation. JS file shrinks ~40 lines;
+      `CapacityCalculator.php` and its tests are untouched. First fix
+      from `doc/REVIEW_02.md`.
+
 ### Upcoming
 
 Nothing scheduled.
@@ -1701,6 +1731,7 @@ before acting — nothing here is load-bearing once it grows stale.
 ## 13. Git history (as of this writing)
 
 ```
+14b1cfd Fix R02-N01: drop JS-side capacity arithmetic, server is authoritative
 ef9b9b8 Fix R01-N16, doc R01-N17: composer-audit helper + admin-manual cadence note
 a0b717e Fix R01-N18: trust OIDC email only when issuer hasn't marked it unverified
 50f9bd2 Docs: mark R01-N09 / R01-N13 / R01-N14 fixed, refresh SPEC §3 / §9 / §11 / §13

+ 12 - 1
doc/REVIEW_02.md

@@ -57,7 +57,18 @@ REVIEW_01.
 
 ### R02-N01 — Capacity formula duplicated in PHP and JS
 - **Severity**: HIGH (already a documented two-place-edit hazard).
-- **Status**: open.
+- **Status**: fixed-in-14b1cfd. Path B applied — `recomputeRow()` is
+  now a plain DOM sum that writes only `[data-sum-days]` and
+  `[data-cap-ressourcen]`; `capacity()`, `committedPrio1FromDom()`,
+  and `recomputeAllCapacity()` are gone, along with the unused
+  `data-reserve-fraction` attribute on `views/sprints/{show,present}.twig`.
+  Reserves and Available now come from the server's `per_worker`
+  envelope on every PATCH (the days pipeline's 400 ms debounce settles
+  the cells within a beat). `POST /tasks/{id}/move` was extended to
+  return `per_worker` for the source sprint — that was the one
+  mutation site whose old `recomputeAllCapacity()` call had no
+  server-authoritative replacement. JS shrinks ~40 lines;
+  `CapacityCalculator.php` is untouched.
 - **Where**:
   - `src/Services/CapacityCalculator.php` — authoritative implementation.
   - `public/assets/js/sprint-planner.js` lines 172–222 — `recomputeRow()`