Individual stroke widths shipped with a `:stroke-per-side` boolean on every
stroke, telling the renderer and the CSS generator whether the four
per-side widths were meaningful. Comparing the sides answers that on its
own, so the attribute was later dropped from the closed stroke schema
and the toggle became ephemeral editor state.
Files written between those two changes still carry the attribute, and
the closed schema rejects the unknown key, so loading such a file fails
`check-file-data` with a `:malli.core/extra-key` error and surfaces as
an internal error in the editor.
Add migration `0030-remove-stroke-per-side-attr`, which drops the
attribute from every stroke of every page and component shape. The
per-side widths are the saved design data and are kept untouched, so a
file whose boolean was `true` renders exactly as before.
The migration is naturally idempotent and a no-op for files that never
carried the attribute, since `dissoc` on a map without the key returns
an equal map.
Cover it with tests for the schema rejection, the per-side and global
widths surviving, component shapes, idempotency, and the run through
`migrate-file`.
Closes#11943
AI-assisted-by: space-bunny-free
Before background blur got its own shape attribute, the `:blur` attribute
accepted both `:layer-blur` and `:background-blur` types, so the editor and
the plugin API could save a background blur under `:blur`. The shape schema
was later tightened to only allow `:layer-blur` on `:blur`, but no migration
moved the existing values, so those files fail server schema validation.
Add migration 0029: when a shape has a `:blur` map with `:type
:background-blur`, move it to the `:background-blur` attribute. When the
shape already has a `:background-blur`, keep it and drop the mis-typed
`:blur`. The migration walks both pages and components.
Closes#11904
AI-assisted-by: deepseek-v4.1-flash
Repair text shapes with empty/broken content at all three levels
(root, paragraph-set, paragraph) in migration 0025 to prevent
workspace update failures. Handle all corner cases: nil/empty/non-
vector children, non-map items, wrong types. Remove geometry-only
validation skip in changes.cljc so all shapes are validated.
AI-assisted-by: qwen3.7-plus
Relevant changes:
- Add the ability to create migration in both directions, defaulting
to identity if not provided
- Move the version attribute to file table column for to make it more
accessible (previously it was on data blob)
- Reduce db update operations on file-update rpc method
Also optimizes some functions for faster shape and rect props
access (there is still a lot of work ahead optimizing the rest of
the functions)
Also normalizes shape creation and validation for ensuring
correct setup of all the mandatory properties.