Loads/saves OpenFresco.Scene documents from the template's canvas
JSONB column, with lazy migration from the legacy canvas format.
Storage strategy: the column keeps its name (canvas) and JSONB type;
its content is now an OpenFresco scene map (%{"version" => _, "canvas" => _, "elements" => _}). Pre-switch rows hold the legacy
editor canvas (%{"width" => _, "height" => _, "elements" => _, "background" => _}) — load/1 detects those by the missing
"version" key and converts through OpenFresco.OgImport, so old
templates keep working with no DB migration; the next editor save
persists the scene form.
Summary
Functions
A fresh 1200×630 scene with the house dark background.
Serializes a scene for the JSONB column.
Returns the template's %OpenFresco.Scene{}, converting legacy canvas
maps on the fly. A nil/empty/unparseable canvas yields blank/0 —
rendering must never crash on a malformed stored document.
Unique {{slot}}s used by the scene, [%{name: _, type: :text | :image}]
— same shape PhoenixKitOG.Slots.used/1 returned for legacy canvases,
so Variables.resolve/3 and the assignments UI consume it unchanged.
Functions
@spec blank() :: OpenFresco.Scene.t()
A fresh 1200×630 scene with the house dark background.
@spec dump(OpenFresco.Scene.t()) :: map()
Serializes a scene for the JSONB column.
@spec load(map() | nil) :: OpenFresco.Scene.t()
Returns the template's %OpenFresco.Scene{}, converting legacy canvas
maps on the fly. A nil/empty/unparseable canvas yields blank/0 —
rendering must never crash on a malformed stored document.
@spec slots(OpenFresco.Scene.t()) :: [%{name: String.t(), type: :text | :image}]
Unique {{slot}}s used by the scene, [%{name: _, type: :text | :image}]
— same shape PhoenixKitOG.Slots.used/1 returned for legacy canvases,
so Variables.resolve/3 and the assignments UI consume it unchanged.