* refactor: use fractional indexing for project and issue sort order
Replace integer-based sequential sortOrder with string-based fractional
indexing (jittered-fractional-indexing). Each drag operation now computes
a key between neighbors and updates only the moved item — O(1) DB writes
instead of O(n).
- Schema: sortOrder integer → text (default 'a0') for both projects and issues
- Backend: single-item PATCH /sort for projects, fractional key on issue create
- Frontend: generateKeyBetween in HomePage and board-store drag handlers
- Validation: regex /^[a-z0-9]+$/i on all sortOrder inputs
- Existence check on project sort endpoint
* fix: address PR review comments for fractional indexing
- Preserve legacy issue ordering during migration by converting numeric
sort_order values to zero-padded string keys (e.g. 10 -> a0010)
- Invalidate project cache after sort order updates
- Use existing.id instead of raw id in sort WHERE clause to handle alias lookups
* fix: persist same-column reorders by comparing against pre-drag snapshot
applyDragOver mutates groupedItems during drag, so comparing against
current state in applyDragEnd always shows oldIdx === idx for same-column
reorders. Capture pre-drag snapshot on first dragOver and compare against
that to correctly detect position changes.
* fix: add projects table rebuild and persist same-column reorders
- Add projects table recreation in migration 0012 to convert sort_order
from INTEGER to TEXT for databases that already ran old migration 0011
- Fix same-column drag reorders by comparing against pre-drag snapshot
instead of mutated intermediate state