- drag from a node's side port onto another node to create an edge
(dashed live preview, dedupe, self-link rejected); click an edge to
select (highlighted), Delete removes it, Ctrl+Z restores — all in
undo history and autosave
- generate panel shows an explicit hint when the site has no image
models instead of an empty dropdown
- render hardening: viewport-culling size now has a hard floor
(max(stageSize, window, 1600x900)) so a delayed/degenerate
ResizeObserver reading can never cull nodes out of the DOM; stage
listeners attach with retry + rAF self-healing measure; pointer
capture wrapped in try/catch for synthetic pointers
- paint from cv:cache:<id> before the network fetch (works offline too),
then reconcile with the server copy in the background; identical content
skips the re-apply so undo history and in-flight interaction survive
- cache is written on every successful autosave and cleared on delete;
quota errors are swallowed (best-effort by design)
- Teleport canvas to body: layout <main> z-10 stacking context let the
fixed site header (z-40) cover the canvas toolbar
- defer setPointerCapture until the 3px drag threshold: immediate capture
retargets click/dblclick to the stage, which silently broke note editing
- commitNote no longer early-returns on the editing flag (event-ordering
could drop typed text); sync node.text back to the non-controlled
contenteditable on undo/redo restores
- contenteditable only while editing: single click used to focus and allow
raw typing outside edit mode, swallowing Delete-key handling
- clientIP: stop trusting client-supplied X-Forwarded-For; use gin ClientIP
with trusted proxies limited to private docker networks
- payment: verify notify money matches order amount; remove hardcoded
gateway default, fail loudly when api_base is unset
- stats: public endpoint now serves aggregates only; recent files (owner
names) moved to admin-only /stats/recent
- auth: reject signups whose username/email-local collides with another
user's media directory namespace
- v1: recover panics in background video jobs, refund + mark failed