Commit Graph

109 Commits

Author SHA1 Message Date
fd6beb4591 fix: superadmin access for sessions/rooms; redesign room editor
Backend:
- sessions.rs: add is_superadmin bypass to list_sessions,
  create_session, create_slot, update_slot_status, delete_slot
- rooms.rs: allow empty layout on create_room (layout is built
  in editor after creation)

Frontend room editor:
- Fix drag coordinate sync: replace window mousemove delta calc
  with SVG CTM inverse transform (getScreenCTM), eliminating
  the 3x movement ratio bug
- Switch to pointer capture (setPointerCapture) per element;
  remove svelte:window handlers
- Positions always snap to 0.5 grid on drop, preventing
  backend validation errors
- Left floating sidebar toolbar (collapsible) with Sitz/Tisch/
  Tür/Lücke buttons and inline SVG icons
- Room dimensions bar (Breite × Tiefe, 5–50 grid units)
- Zoom controls (25%–400%) via scroll wheel or +/- buttons;
  SVG scales via width/height attrs so scrollbars work correctly
- Property panel inputs snap to 0.5 on blur (prevents save errors)
- Canvas bounded to room dimensions during drag
2026-05-06 16:09:08 +02:00
c8a4bc1820 fix: superadmin course access + navigate to correct course from courses page
Backend: list_students, add_student, import_students now bypass
tutor_courses check for superadmins, matching the existing pattern
in list_assigned_tutors. A superadmin creating a new course was
getting 401 when accessing it because no tutor_courses row exists
for them.

Frontend: courses page passes ?courseId= to students/sessions links;
both pages now pre-select the matching course on mount instead of
always defaulting to courses[0].
2026-05-06 15:46:54 +02:00
553eb00f87 ci: add context: . to Docker build step; fix docker-compose → docker compose 2026-05-06 15:36:53 +02:00
16e8c6c865 ci: upgrade Helm to v4.1.4, switch images to Alpine 3.23, disable backup cron
All checks were successful
Release / release (push) Successful in 5m28s
- release.yml: bump Helm v3.16.2 → v4.1.4; replace --wait with
  --rollback-on-failure (Helm 4 rename, implies --wait)
- Dockerfile: backend builder rust:1.95-slim-bookworm → rust:1.95-alpine3.23
  (adds cmake/g++/perl/nasm/sqlite-dev for aws-lc-rs + sqlx); runtime
  debian:trixie-slim → alpine:3.23 (adds sqlite-libs, uses adduser -D)
- cronjob-backup: gate on backup.enabled, pin image to alpine:3.23
- values.yaml: backup.enabled default true
- values_override.yaml: backup.enabled: false (disabled until tested)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v0.2.0
2026-05-06 15:29:51 +02:00
f97f91781a fix: use debian:trixie-slim runtime to match builder glibc 2.38
Some checks failed
Release / release (push) Failing after 8m35s
rust:1.95-slim is trixie-based (glibc 2.38); bookworm-slim only has
2.36, causing a crash on startup.
2026-05-05 03:36:22 +02:00
99b501d69c fix: ignore RUSTSEC-2023-0071 in release workflow cargo audit
Some checks failed
Release / release (push) Failing after 8m30s
2026-05-05 03:16:50 +02:00
b7d20d9573 chore: ignore screenshot-*.png files
Some checks failed
Release / release (push) Failing after 2m23s
2026-05-05 03:12:23 +02:00
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
d79c7ed08c added git worktrees to the plan 2026-05-04 17:26:24 +02:00
650f3456cb some planning and issue finding 2026-05-04 17:15:53 +02:00
08cb668bab fix: restore login page accessibility and wire silent token refresh
All checks were successful
Release / release (push) Successful in 7m12s
The admin layout guard rendered only a "Redirecting to login..." placeholder
for the /admin/login child route, trapping every unauthenticated visitor.
Exempt the login route from the auth gate so the form renders correctly.

Also wire the new POST /api/auth/refresh endpoint (from the dual-token
migration) into both auth.init() and the api request() 401 handler, so
sessions survive the 15-minute access-token lifetime without a hard logout.

Adds a Playwright regression test asserting the login form is visible
in a clean (no-cookie) browser context.
v0.1.17
2026-05-04 04:19:42 +02:00
8c7678d06a feat: implement dual-token JWT auth, Argon2id migration, and zero-warnings quality mandate
All checks were successful
Release / release (push) Successful in 5m24s
v0.1.16
2026-05-03 00:41:50 +02:00
840fbb1cdd chore: add verify-all target and mandate local verification in GEMINI.md 2026-05-02 23:29:40 +02:00
a281d227c9 chore: move cargo audit ignore to explicit command-line flag
All checks were successful
Release / release (push) Successful in 4m37s
v0.1.15
2026-05-02 21:55:18 +02:00
20b3364786 chore: ignore RUSTSEC-2023-0071 in cargo audit (no fixed upgrade available)
Some checks failed
Release / release (push) Failing after 2m38s
v0.1.14
2026-05-02 21:15:43 +02:00
968f7d0691 fix: resolve cargo audit command failure in CI/CD pipelines
Some checks failed
Release / release (push) Failing after 2m13s
v0.1.13
2026-05-02 21:10:34 +02:00
6ca42d10e6 fix: resolve unit test failures caused by rate limiting and fix mod.rs router passing
Some checks failed
Release / release (push) Failing after 2m10s
v0.1.12
2026-05-02 21:04:31 +02:00
32e7dc5ac1 deploy: bump image tag to v0.1.11
Some checks failed
Release / release (push) Failing after 1m26s
v0.1.11
2026-05-02 20:56:22 +02:00
6ca852117d chore: update frontend dependencies to latest stable versions and sync lockfile 2026-05-02 20:56:03 +02:00
dec92509ff deploy: bump image tag to v0.1.10
Some checks failed
Release / release (push) Failing after 53s
v0.1.10
2026-05-02 20:48:56 +02:00
31f8ef74fe chore: remediate code audit findings and fix CI pipeline failures
- Security: Add Secure flag to checkin identity cookie, implement rate limiting on login, and harden Helm security context.
- Security: Add cargo-audit to CI and Release pipelines for dependency vulnerability scanning.
- Backend: Enable SQLite WAL mode and fix AppState initialization in tests.
- Frontend: Fully type the API client, fix importStudents FormData handling, and pin dependency versions.
- Frontend: Add auto-logout on 401 and resolve authentication initialization race conditions.
- CI/CD: Pin pnpm version in release workflow and include lint/audit quality gates.
2026-05-02 20:40:05 +02:00
536638b594 deploy: bump image tag to v0.1.9
Some checks failed
Release / release (push) Failing after 1m16s
v0.1.9
2026-05-02 05:28:30 +02:00
6cb5968b7b fix: resolve Docker build failure and E2E authentication race conditions
- Dockerfile: Update binary name from attendance to tutortool to fix the release build pipeline failure.
- Backend: Expose test_mode in AppState to conditionally disable the secure flag on auth cookies during local E2E testing over HTTP.
- Backend: Enable tower-http trace feature and attach TraceLayer for improved request logging.
- Frontend: Refactor auth.svelte.ts to a plain reactive object to resolve initialization race conditions during tests.
- Frontend: Append cache-busting timestamp to /api/auth/me to prevent stale session states.
- Frontend: Update Playwright locator in superadmin.spec.ts for greater resilience.
- Makefile: Inject required environment variables (STATIC_DIR, JWT_SECRET) into the test-up target.
2026-05-02 05:25:04 +02:00
66eed29c71 deploy: bump image tag to v0.1.8
Some checks failed
Release / release (push) Failing after 2m31s
v0.1.8
2026-05-02 03:22:29 +02:00
ff5ad26cfc feat: harden security with httpOnly cookies and modernize frontend with Svelte 5 runes
- Switched to secure httpOnly, SameSite=Strict cookies for JWT authentication.
- Refactored backend to use AppState for shared secrets and database pool caching.
- Modernized frontend with Svelte 5 runes ($state) and removed localStorage reliance.
- Gated destructive test endpoints behind debug_assertions and fixed unsafe test patterns.
- Enhanced CI pipeline with cargo clippy, cargo fmt, and pinned pnpm version.
- Updated documentation and implementation plans to match the hardened architecture.
2026-05-02 03:16:33 +02:00
7cafc7e119 deploy: pin image tag to v0.1.7 2026-05-01 18:41:21 +02:00
0e7df590ca tutortool: set successfulJobsHistoryLimit=1 on backup CronJob
Completed pods were showing 0/1 Ready and triggering false-positive
monitoring alerts.
2026-05-01 18:39:25 +02:00
e05cebc10c chore: ignore AI artefacts and log files 2026-04-30 01:04:43 +02:00
a2b41b5131 feat: enable DEMO seed via values_override
All checks were successful
Release / release (push) Successful in 3m23s
v0.1.7
2026-04-30 00:50:17 +02:00
cffb97ff76 fix: use Recreate strategy so SQLite + RWO PVC redeploy fits tenant CPU quota
All checks were successful
Release / release (push) Successful in 3m31s
v0.1.6
2026-04-30 00:42:55 +02:00
58248897db fix: lower CPU limit to 200m to fit rolling update within tenant quota
Some checks failed
Release / release (push) Failing after 7m23s
v0.1.5
2026-04-30 00:19:18 +02:00
b42ded93f6 feat: add DEMO env var to seed demo data on startup
Some checks failed
Release / release (push) Failing after 7m24s
v0.1.4
2026-04-29 23:05:05 +02:00
dcb4a92afd fix(deploy): use generic 'http' sectionName for HTTP→HTTPS redirect route 2026-04-29 22:19:51 +02:00
6b296460dd fix(ci): add context: . to Docker build-push step in release workflow
All checks were successful
Release / release (push) Successful in 4m7s
v0.1.3
2026-04-29 21:48:06 +02:00
ee98d6844a fix(frontend): add @types/node, fix Playwright base.extend type in fixtures
Some checks failed
Release / release (push) Failing after 1m27s
v0.1.2
2026-04-29 21:42:32 +02:00
bae4ff24ea fix(ci): run svelte-kit sync before pnpm check to generate .svelte-kit/tsconfig.json
Some checks failed
Release / release (push) Failing after 56s
v0.1.1
2026-04-29 21:28:21 +02:00
03a1e70df3 fix(deploy): correct HTTPRoute parentRefs, cert-manager annotation, imagePullSecrets
Some checks failed
Release / release (push) Failing after 56s
- httproute.yaml: name=default namespace=nginx-gateway (was: itsh-gateway, no namespace)
- httproute.yaml: add cert-manager.io/cluster-issuer annotation for TLS cert issuance
- httproute.yaml: parameterise sectionNames and parentRefs through values
- deployment.yaml: render imagePullSecrets from values (itsh-registry pull secret)
- values.yaml: add parentRefs, annotations, httpRedirectSectionName, imagePullSecrets
v0.1.0
2026-04-29 21:24:13 +02:00
Claude
e01f7808a0 Overhaul build pipeline: pnpm, non-root image, Helm chart, CI+release workflows
Some checks failed
CI / test (push) Failing after 1m35s
CI / test (pull_request) Failing after 1m34s
- db.rs: fix fresh-PVC startup crash by using SqliteConnectOptions with
  create_if_missing(true) and foreign_keys(true); drops after_connect
- Dockerfile: switch to Node 22 + pnpm (corepack), run pnpm check before
  build, copy backend/demo/ for TT_TEST_MODE support, non-root app user,
  add HEALTHCHECK, remove baked-in JWT_SECRET
- .dockerignore: exclude node_modules, build artifacts, data/, logs
- deploy/: new Helm chart replacing k8s/ — Deployment, Service, HTTPRoute
  (Gateway API), PVC (hcloud-volumes), CronJob backup, ServiceAccount, VPA;
  JWT_SECRET sourced from pre-provisioned K8s Secret
- k8s/: removed (superseded by deploy/)
- ci.yml: replaces test.yml — Node 20->22, same test steps, adds no-push
  Docker build; triggers on non-main pushes and PRs
- release.yml: new tag-driven workflow (v*.*.*) — runs tests, pushes image
  to registry.itsh.dev/s0wlz/tutortool, deploys via helm upgrade

https://claude.ai/code/session_01N1kWaQJkz1fC7mUippdQR5
2026-04-29 19:11:29 +00:00
0b806b59be feat: add implementation plans for room editor refactor (core and visualization)
Some checks failed
Test / test (push) Failing after 1m40s
2026-04-29 05:36:44 +02:00
7212e982ef docs: update GEMINI.md with project-specific conventions and conductor references
Some checks failed
Test / test (push) Failing after 1m39s
2026-04-29 05:24:03 +02:00
75203bd796 fix: resolve test pipeline migration conflicts and sync demo layout with frontend 2026-04-29 05:23:42 +02:00
276b367530 docs: track design handoff, plans, specs, and conductor notes
Some checks failed
Test / test (push) Failing after 2m12s
2026-04-29 04:38:26 +02:00
bbcdbf957e feat: add IF NOT EXISTS to migrations, add courses nav item, lock playwright deps 2026-04-29 04:38:20 +02:00
7a0f6aa0a7 chore: gitignore server.log and start_backend.sh 2026-04-29 04:38:14 +02:00