feat: unified bug fixes, tutor lifecycle, and room editor refactor #2

Merged
mpuchstein merged 7 commits from feature/unified-fixes-room-editor into main 2026-05-05 03:04:26 +02:00

7 Commits

Author SHA1 Message Date
39341ce69d fix: run svelte-kit sync before svelte-check in Docker build
Some checks failed
CI / test (pull_request) Has been cancelled
CI / test (push) Successful in 8m19s
.svelte-kit/tsconfig.json is gitignored and must be generated at
build time — svelte-check cannot run without it.
2026-05-05 02:48:40 +02:00
ab9d1fc547 fix: track Cargo.lock so Docker CI build can copy it
Some checks failed
CI / test (pull_request) Has been cancelled
CI / test (push) Failing after 6m57s
Cargo.lock was in .gitignore, making it absent from the git checkout
that CI builds the Docker image from — COPY backend/Cargo.lock failed.
2026-05-05 02:39:03 +02:00
681b43174b fix: implement random-port discovery for CI E2E backend
Some checks failed
CI / test (pull_request) Has been cancelled
CI / test (push) Failing after 4m51s
When PORT=0, the backend now writes its actual bound port to
data/test/.port. test-env.sh reads that file when TT_TEST_PORT=0
so all targets (test-up, test-reset, test-down) resolve the real URL.
test-up waits for .port to appear before the health-check loop.
2026-05-05 02:24:29 +02:00
24f2556c9d fix: replace per-element CASE WHEN in migration 003 with WHERE EXISTS
Some checks failed
CI / test (push) Failing after 3m32s
CI / test (pull_request) Failing after 3m26s
Instead of applying a per-element heuristic (skip if value ≤ 50), identify
pixel-scale rooms at the row level with WHERE EXISTS, then convert all
elements unconditionally. Eliminates the risk of mixed-scale elements within
the same room.
2026-05-05 02:02:30 +02:00
4939838a7f fix: address PR #2 review findings across backend and frontend
Some checks failed
CI / test (push) Failing after 4m9s
CI / test (pull_request) Failing after 3m26s
- Makefile: add SHELL := /bin/bash so test-env.sh pipefail works in CI
- RoomCanvas: fix onElementClick firing on drag start (now fires on mouseup
  for click-in-place only); fix Props type to accept null; guard grid pattern
  against snapStep=0 (invalid SVG); remove unsafe null cast
- live/[slotId]: fix studentNamesBySeat $derived wrapping a function instead
  of a value — reactivity was broken, map never updated
- s/[code]: block clicks on occupied seats before hitting the backend;
  pass occupiedSeatIds to confirmed-view RoomCanvas; clear errorMsg on retry
- rooms/+page: replace alert() in deleteRoom with inline errorMsg state
- rooms/[roomId]: replace deprecated .substr with .slice
- courses.rs: assign_tutor uses fetch_optional → 404 on unknown tutor_id
  instead of propagating RowNotFound as 500
- rooms.rs: delete_room returns 404 when room does not exist; replace
  fract() != 0.0 float check with epsilon-based validation
- auth_routes.rs: refresh endpoint re-checks is_active so deactivated tutors
  cannot obtain new access tokens; fix test INSERT to include is_active
- tutors.rs: wrap delete_tutor reference checks and DELETE in a transaction
- attendance.rs: replace #[allow(clippy::type_complexity)] with type alias
- migrations/003: document > 50 heuristic precondition

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 01:55:35 +02:00
827eb63bab fix: address review findings — error handling, migration safety, CI audit
Some checks failed
CI / test (push) Failing after 3m6s
CI / test (pull_request) Failing after 3m22s
Backend:
- migration 003: apply pixel→grid transform per-element (CASE WHEN > 50)
  instead of per-row, preventing double-conversion of mixed-scale rooms;
  skip empty arrays via json_array_length guard to avoid NULL assignment
- attendance.rs: log layout JSON parse errors instead of silently
  swallowing them with .ok()
- tutors.rs: check rows_affected() in set_tutor_active and return 404
  for non-existent IDs; remap FK constraint errors on delete to 409
  so concurrent inserts between conflict-check and DELETE don't surface
  as 500

Frontend:
- live/[slotId]: expose polling failures to the tutor via error banner
  instead of only console.error
- s/[code]: split checkin into two try/catch blocks so a successful
  POST followed by a failed reload doesn't report failure to the student;
  fix dead '409' string detection to match actual server error 'seat taken'
- rooms/[roomId]: remove duplicate onMount fetch; add .catch() to $effect
- tutors: expose loadTutors failures via error banner, not just console
- rooms: fix bare catch in createRoom (captures error, shows message);
  add try/catch to onMount rooms load

CI:
- sync cargo audit --ignore RUSTSEC-2023-0071 with Makefile; the advisory
  is in rsa which sqlx-mysql retains in the lock file even when the mysql
  feature is disabled — aws_lc_rs correctly removes it from the active tree
2026-05-05 01:28:40 +02:00
3b9c755e39 feat: unified bug fixes, tutor lifecycle, and room editor refactor
Some checks failed
CI / test (push) Failing after 10m30s
CI / test (pull_request) Failing after 7m25s
- Security: Fixed RUSTSEC-2023-0071 via aws_lc_rs
- API: Fixed empty 200 body parsing and check-in typing
- Tutors: Added is_active flag, safe deletion with 409 conflict checks, and admin toggle UI
- Rooms: Migrated room layouts from pixel to grid scale, added additive layout validators
- UI: Improved RoomCanvas with dynamic sizing, interactive editing, snap-to-grid
- App: Replaced static SeatMap component with dynamic RoomCanvas across live and checkin views
2026-05-05 00:47:05 +02:00