mirror of
https://github.com/Matysh/houseplan-card
synced 2026-07-31 08:28:31 +00:00
fix v1.43.0: external audit P0 — data loss, split geometry, auth, dialog zombies
L2 (silent data loss): debounce gains flush()/pending(); _reloadConfigOnly flushes a pending write and defers while one is in flight; conflict path forces; failed reload now toasts instead of an empty catch; teardown flushes. G1 (split corruption): same-edge cuts carve the niche properly instead of walking the outline twice; partition invariant (parts sum to the original) rejects anything else; +1 unit test covering 5 niche shapes and both legacy cut shapes. B1 (unauthenticated content): plans and marker files move to HouseplanContentView (/api/houseplan/content/..., requires_auth); only the card bundle stays static; contentUrl() rewrites legacy URLs on read (no storage migration); repairs.py accepts both prefixes; +1 unit test. L3 (dialog zombies): all four save catch-blocks guard against a closed dialog; the card no longer blanks when a save fails after Esc. smokes: smoke_save_race, smoke_dialog_zombie; docs (TESTING/CHANGELOG/ ARCHITECTURE incl. the optimistic-UI note) same-commit
This commit is contained in:
@@ -255,3 +255,20 @@ more specific tier overrides the more general one; "unset" always means
|
||||
The UI will later be unified around this model; until then each tier keeps its
|
||||
own dialog (general settings gear / space gear / room-card gear / marker
|
||||
dialog).
|
||||
|
||||
|
||||
## Audit follow-ups (2026-07-27)
|
||||
|
||||
- **Content is authenticated.** `/houseplan_files/…` now serves ONLY the card
|
||||
bundle (a Lovelace resource must be public). Plans and marker files go
|
||||
through `HouseplanContentView` (`/api/houseplan/content/<plans|files>/…`,
|
||||
`requires_auth`). `contentUrl()` rewrites legacy stored URLs on read, so no
|
||||
storage migration is needed. Static paths cannot be unregistered — the old
|
||||
routes survive until the next HA restart.
|
||||
- **Optimistic UI, stated explicitly (audit L7).** `_serverCfg` is mutated in
|
||||
place before a fallible save in ~22 places and there is no rollback: after a
|
||||
rejected save the UI shows the edit until the next reload. This is a
|
||||
deliberate optimistic-UI choice, not drift. Paths where it is unacceptable
|
||||
need their own rollback.
|
||||
- **Split invariant.** `splitRoomPath` guarantees a partition: the two parts'
|
||||
areas sum to the original (within epsilon) or the cut is rejected.
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## 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
|
||||
and covered by regression tests.
|
||||
|
||||
- **Silent data loss on save (L2).** A debounced config write read the config at
|
||||
fire time, so a `houseplan_config_updated` event arriving in between replaced
|
||||
it and the user's edit vanished with no error — reproducible in a single tab.
|
||||
The debounce now supports `flush()`/`pending()`, a reload flushes the pending
|
||||
write first and defers while a write is in flight, and a failed reload finally
|
||||
reports instead of staying silent.
|
||||
- **Split corrupted room geometry (G1).** A cut starting and ending on the SAME
|
||||
wall (carving a niche — a natural action) produced two overlapping,
|
||||
self-intersecting rooms whose areas summed to twice the original, and the
|
||||
overlap guard did not catch it. Same-edge cuts now carve the niche correctly,
|
||||
and a partition invariant (parts must sum to the original) rejects anything
|
||||
else.
|
||||
- **Plans and uploaded files were served without authentication (B1).** Anyone
|
||||
who could reach the HA endpoint could fetch floor plans and attached manuals
|
||||
without logging in. They are now served by an authenticated view; stored
|
||||
legacy URLs are rewritten on read, so nothing breaks. **The old public paths
|
||||
disappear after a Home Assistant restart.**
|
||||
- **Dialogs could resurrect and blank the card (L3).** Closing a dialog while
|
||||
its save was in flight, on a failed save, spread `null` into a truthy husk;
|
||||
the renderer then threw and the card went blank until reload. Guarded in all
|
||||
four save routines; the error toast still fires.
|
||||
|
||||
## v1.42.2 — 2026-07-26
|
||||
- Touch devices no longer pop hover tooltips on every tap (field feedback:
|
||||
"extra labels appear and get in the way on a tablet"). Hover tooltips are
|
||||
|
||||
@@ -140,6 +140,19 @@ 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
|
||||
- [ ] 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]
|
||||
- [ ] Niche split (v1.43.0, audit G1): a cut that starts AND ends on the same
|
||||
wall carves a niche; the two parts' areas must sum to the original (the
|
||||
invariant is enforced in code and asserted for every split test) [auto]
|
||||
- [ ] Authenticated content (v1.43.0, audit B1): plan images and marker files
|
||||
are only reachable through /api/houseplan/content/… with a session; the
|
||||
old /houseplan_files/plans|files paths return 404 after a restart; old
|
||||
stored URLs keep working (rewritten on read) [auto+manual]
|
||||
- [ ] Dialog zombies (v1.43.0, audit L3): close a dialog (Esc) while its save is
|
||||
in flight and let the save fail — the dialog stays closed, the card keeps
|
||||
rendering, the error toast still fires [auto]
|
||||
- [ ] No hover tooltips on touch (v1.42.2): on hover-less devices (tablets,
|
||||
phones) taps never pop the room/device tooltip — the data lives in room
|
||||
cards and long-press; desktop hover tooltips unchanged [auto]
|
||||
|
||||
Reference in New Issue
Block a user