- 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