Every node type persisted its size in `nodes.width` / `nodes.height` except
`groupRect`, which stashed it inside the `custom_colors` JSON next to its
colours. The columns already existed and were simply unused for zones, so
this was an inconsistency rather than a missing-column workaround, and it
put geometry in a blob that otherwise holds style.
The serializer now writes the columns for a zone too, and strips the legacy
`width`/`height` keys out of the blob so the two cannot drift apart and
leave an older canvas reading a stale size.
No data is lost on upgrade:
- `_backfill_zone_size` copies the blob geometry into the columns at
startup. It only fills a column that is still NULL, so it cannot overwrite
a size set since; it parses the JSON in Python rather than with
`json_extract`, so it does not depend on the SQLite build carrying JSON1;
and an unreadable row is skipped without costing the others their size.
Re-running it is a no-op.
- the reader still falls back to the blob, covering a payload the backfill
has not reached — an older server, or an import.
Standalone mode is unaffected: it stores React Flow nodes verbatim, so the
size was always on `node.width` / `node.height` there.
The four serializer tests that pinned the size to the blob now assert the
columns, since that is the behaviour being changed.
ha-relevant: yes