mirror of
https://github.com/Matysh/houseplan-card
synced 2026-07-31 16:38:31 +00:00
perf/fix v1.43.1: external audit P1 — render cost, drag threshold, geometry, backend
L1: memoized space model + open pairs (structural fingerprint key, epoch bumped synchronously at mutation time, not inside the debounce); hoisted per-room geometry out of the render loop; smoke asserts zero recomputation across state pushes. L4: openings get the 3 px drag threshold used by every other pipeline and only write when the geometry actually changed — taps open the dialog again. G2: interiorPoint() replaces the vertex mean, so island rooms inside concave (U/L) parents are accepted and their evenodd holes render; traced duplicates still are not containment. G3: segKey rounds before ordering — one shared wall, one key. B2: _check_write fails closed when the entry is unavailable. B3: layout/set honours expected_rev and returns the new rev. B4: config/set without expected_rev over a non-empty store logs a warning. B5: coordinates reject NaN/Infinity; spaces/rooms/markers/decor/layout capped. +2 unit tests (118), +2 backend tests (14), smoke_render_perf; docs same-commit
This commit is contained in:
@@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## v1.43.1 — 2026-07-27 (external audit: P1 fixes)
|
||||
|
||||
- **Render cost (L1).** Home Assistant replaces `hass` on every state change in
|
||||
the home, and each of those renders recomputed the whole plan geometry —
|
||||
`_openPairs()` ran once per room (O(rooms³) collinear-overlap math) and the
|
||||
space model was rebuilt twice. Both are now memoized on the config's
|
||||
structural fingerprint and hoisted out of the per-room loop; cache
|
||||
invalidation happens synchronously at mutation time, not inside the debounce.
|
||||
- **Opening tap vs drag (L4).** Dragging a door/window had no movement
|
||||
threshold, so any pointer jitter counted as a drag: the properties dialog
|
||||
never opened and an unchanged config was written (which then fed the L2 race).
|
||||
Now the same 3 px threshold as every other drag pipeline, and the write only
|
||||
happens when the geometry actually changed.
|
||||
- **Concave rooms (G2).** Containment used the arithmetic mean of the vertices
|
||||
as an "interior point" — which lies OUTSIDE U- and L-shaped rooms, so island
|
||||
rooms in them were rejected as overlaps and their holes never rendered. A
|
||||
real interior point is computed instead (`interiorPoint`).
|
||||
- **Wall dedup (G3).** `segKey` ordered endpoints by raw floats but printed
|
||||
rounded ones, so one shared wall could produce two keys and be drawn twice.
|
||||
Rounds first, then orders.
|
||||
- **Backend hardening (B2–B5).** The write-authorization check now fails
|
||||
**closed** when the config entry is unavailable (it used to allow writes
|
||||
during a reload); `layout/set` supports `expected_rev` and conflicts like the
|
||||
config store; a `config/set` without `expected_rev` over a non-empty store
|
||||
logs a warning; coordinates reject NaN/Infinity, and spaces/rooms/markers/
|
||||
decor/layout have generous size caps.
|
||||
|
||||
## v1.43.0 — 2026-07-27 (external audit: P0 fixes)
|
||||
|
||||
An external code audit of v1.41.1 found four critical issues. All four are fixed
|
||||
|
||||
@@ -140,6 +140,20 @@ Run the *core flows* (marked ★ below) in each environment at least once per mi
|
||||
(explicit ripple color still wins); off/white lights unchanged [auto]
|
||||
- [ ] Alarm pulse (v1.27.0): leak/smoke/gas/CO/siren in 'on' pulse a red ring over any
|
||||
display mode; clears on 'off'; unavailable never alarms [auto]; reduced-motion static
|
||||
- [ ] Render cost (v1.43.1, audit L1): geometry (space model, open pairs) is
|
||||
computed once per config change, not per HA state push — smoke asserts
|
||||
zero recomputations across 10 state pushes and recomputation after an
|
||||
edit; the plan still renders dashes/islands correctly [auto]
|
||||
- [ ] Opening tap vs drag (v1.43.1, audit L4): a tap on a door in the Plan
|
||||
editor opens its properties (3 px threshold like the other pipelines) and
|
||||
writes nothing; a real drag that ends where it started also writes nothing [auto]
|
||||
- [ ] Concave containment (v1.43.1, audit G2): an island room inside a U- or
|
||||
L-shaped parent is accepted and punches the evenodd hole; a traced
|
||||
duplicate outline is still NOT containment [auto]
|
||||
- [ ] Backend hardening (v1.43.1, audit B2-B5): the admin check fails closed
|
||||
when the entry is unavailable; layout/set honours expected_rev; a
|
||||
config/set without expected_rev over a non-empty store logs a warning;
|
||||
NaN/Infinity coordinates and oversized collections are rejected [auto]
|
||||
- [ ] Save race (v1.43.0, audit L2): make a markup edit, then press Save in any
|
||||
dialog within 500 ms (or let another client save) — the markup edit must
|
||||
survive and reach the server; a failed reload now shows a toast [auto]
|
||||
|
||||
Reference in New Issue
Block a user