velxio/frontend/src
David Montero Crespo 6a88375bc0 feat: persist multi-board projects + add auto-save
The project save/load pipeline only persisted a single `board_type`, so
multi-board workspaces silently lost every board except the active one
on save, and wires referencing the dropped boards' IDs orphaned to the
canvas corner on reload. An audit of the production backup found 74/306
projects (24%) with at least one orphaned wire and 174/301 non-trivial
projects whose code was still the default Blink template — strong signal
that users save once and never re-save.

Backend
- Add `boards_json` column on `projects` with idempotent ALTER TABLE in
  the lifespan migration list.
- New `FileGroup` schema + `file_groups` array on
  ProjectCreate/Update/Response. Legacy `files`/`code` kept for back-compat.
- `project_files.py` now uses `{pid}/{groupId}/{filename}` subdirs via
  `read_groups`/`write_groups`. Legacy flat layouts are auto-promoted on
  read; legacy single-list `files` only updates the active group, leaving
  other boards' files intact.
- `_persist_files_from_body` honors file_groups → files → code priority.

Frontend
- `useSimulatorStore.addBoard` accepts an optional `explicitId` so
  saved board IDs can be restored verbatim (wires reference IDs literally).
- New `loadProjectState({boards, fileGroups, components, wires,
  activeBoardId})` action: tears down current boards, recreates from the
  payload, restores file groups atomically, recalculates wire positions
  on the next frame, and refreshes the Interconnect.
- `useEditorStore.replaceFileGroups` for atomic multi-group restore.
- `SaveProjectModal` and `ProjectByIdPage`/`ProjectPage` now go through
  `buildSavePayload` / `buildLoadPayload` (handles pre-backfill projects
  by synthesising a default board from `board_type`).

Auto-save (#useAutoSaveProject hook)
- 2.5s debounced silent PUT triggered ONLY when an authenticated user
  has a `currentProject` with a UUID. State hash detects real changes
  vs. UI-only churn; baseline is reset on project load so the just-loaded
  state isn't immediately re-saved.
- `beforeunload` flush via `fetch keepalive: true` (supports PUT +
  credentials, survives unload).
- Compact status indicator in `AppHeader` (idle/dirty/saving/saved/error).

Backfill script (one-off, idempotent)
- `backend/scripts/backfill_boards_2026_05.py` populates `boards_json`
  for legacy projects. Heuristic per project, based on which board IDs
  the wires reference:
    Case A — wires only ref 'arduino-uno' but board_type ≠ uno:
             rename id→board_type and rewrite wire endpoints.
    Case B — single-board normal: keep verbatim.
    Case C — multi-board: recreate one board per distinct ref, infer
             kind by stripping trailing -N suffix.
  Also moves any flat files into the active board's group subdir.
  Stdlib-only, runs from host or `docker exec`.

Docker
- `Dockerfile.standalone` now copies `backend/scripts/` into the image
  so the backfill is callable via `docker exec velxio-app python
  /app/scripts/backfill_boards_2026_05.py --apply`.

Verified locally on the restored production backup (363 projects):
33 Case A, 316 Case B, 14 Case C, 135 wire endpoints renamed, 0 orphans.
Re-running the script after apply skips all 363 (idempotent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 13:43:33 -03:00
..
__tests__ feat: add support for UC8159c (ACeP 7-colour) display 2026-04-30 00:27:40 -03:00
assets
components feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
data feat: add support for UC8159c (ACeP 7-colour) display 2026-04-30 00:27:40 -03:00
hooks feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
pages feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
services feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
simulation feat: add support for UC8159c (ACeP 7-colour) display 2026-04-30 00:27:40 -03:00
store feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
types feat(multi-board): add wire-aware cross-board interconnect router 2026-04-25 19:47:40 -03:00
utils feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
velxio-elements Add ESP32 chip demos and comprehensive tests for I2C, SPI, and UART interactions 2026-04-28 19:24:39 -03:00
App.css feat: persist multi-board projects + add auto-save 2026-05-01 13:43:33 -03:00
App.tsx SEO improvements 2026-04-30 00:27:39 -03:00
entry-server.tsx feat: add /v2-5 release landing page for Velxio 2.5 (SPICE) 2026-04-24 16:42:47 +02:00
index.css refactor: rename components and update prefixes to 'velxio-' for consistency 2026-04-21 16:45:45 -03:00
main.tsx refactor: rename components and update prefixes to 'velxio-' for consistency 2026-04-21 16:45:45 -03:00
seoRoutes.ts SEO improvements 2026-04-30 00:27:39 -03:00
vite-env.d.ts refactor: rename components and update prefixes to 'velxio-' for consistency 2026-04-21 16:45:45 -03:00