Every canvas position write (Auto-arrange, Save positions, drags, freeze pins)
used to send one PATCH per technology, all at once. On a large tree that was
dozens of concurrent full document updates, which exhausted the database pool
and could crash the server.
- Add POST /api/tech-tree/positions: validates `{ positions: [{ id, x, y }] }`
(null x/y clears a pin, capped at 2000) and applies every position in a
single UPDATE on the tree position columns. Access mirrors the technologies
update rule (technologies:update or Intelligence membership).
- Route all canvas position writes through it; failures now surface in the
toolbar instead of being swallowed.
- Auto-arrange is optimistic: the canvas re-lays out on click and the pins
are restored if the save fails. A spinner status chip shows while a layout
save runs, and layout controls and dragging are locked until it finishes.
- Integration tests for validation and the bulk write; the e2e checks the busy
indicator and that no per-node PATCHes are sent.
Round out the canvas editing experience.
- Dragging one card of a multi-selection now moves and persists the whole
selection (React Flow hands the full dragged set to onNodeDragStop).
- A category band is draggable by its header, which moves every technology in
that band; the band body stays click-through.
- A "Snap: On/Off" toolbar toggle (default on, remembered per browser) snaps
dragged cards to a 46px grid that divides the column and row steps, so
snapped cards line up with the automatic layout.
- Connection lines are adjustable: select an edge to reveal "+" handles at each
segment's midpoint (click to add a bend), drag bends to reroute, and
double-click a bend to remove it. Routes persist per browser.
- Edges route around technologies they are not connected to, and corners are
rounded, so lines no longer cut through unrelated cards.
- Ctrl/Cmd-clicking to multi-select no longer pops the side panel over the
canvas.
Add a custom admin view over the technologies collection so staff can model
prerequisites as a left-to-right tree instead of a flat list.
- React Flow v12 canvas with category bands, OR-prerequisite edges, a
lite side-panel editor, and a quick-create dialog.
- Propagating layout: a technology with prerequisites lands one column right
of its parents at their average row; uncategorized roots fill a catalog
grid keyed by each tech's rank among all uncategorized technologies, so
promoting one into the tree leaves an empty slot instead of re-shuffling
the grid.
- Stability contract: connecting or removing edges never moves a card (the
connected node is pinned to its current spot), and a "Save positions"
control commits every on-screen node so the arrangement survives reload;
"Auto-arrange" clears manual positions and restores the ordered layout.
- Progression-path edge colors and per-source lanes keep overlapping edges
readable. Wire the view and its nav entry into payload.config.ts and add
dark React Flow / scrollbar styling.