3.3 KiB
3.3 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
# Development
make dev # start backend + frontend in parallel
make dev-backend # cargo run (port 3000)
make dev-frontend # pnpm dev (port 5173, /api proxied to :3000)
# Build
make build # pnpm build, then cargo build --release
make compose-up # docker compose build + start
# Backend
cargo test # run all tests (uses sqlx::test macro — no DB setup needed)
cargo check # fast type check without linking
# Frontend
pnpm check # TypeScript + Svelte type check
pnpm check:watch # watch mode
pnpm build # Vite build to dist/
Architecture
TutorTool is a Rust + SvelteKit attendance tracker for tutoring sessions.
Backend (backend/)
- Framework: Axum (async) on Tokio, port 3000
- Database: SQLite via SQLx — all queries use the runtime
sqlx::query()/sqlx::query_as::<_, T>()(not compile-time macros); noDATABASE_URLneeded forcargo build/cargo check - Auth: JWT (7-day expiry,
jsonwebtokencrate) + bcrypt passwords;TutorClaimsextractor inauth.rs - Static serving:
tower_http::ServeDirserves compiled frontend fromfrontend/build/with SPA fallback toindex.html - Migrations: auto-run via
sqlx::migrate!at startup frombackend/migrations/ PRAGMA foreign_keys = ONis enforced on every connection indb.rs
Route handlers live in backend/src/routes/ and are merged into the main router in main.rs. Each handler receives State<SqlitePool> and extracts TutorClaims from the JWT on protected routes.
Frontend (frontend/)
- Framework: SvelteKit 5 (Svelte runes,
$state/$derived) with TypeScript - Adapter:
adapter-static→ single-page app,fallback: 'index.html' - API client:
src/lib/api.ts— all fetch calls go through here; JWT injected fromsrc/lib/auth.ts(localStorage-backed store) - Types:
src/lib/types.tsmirrors the Rust models exactly — keep them in sync when changing the API
Routes:
routes/admin/login/— public loginroutes/admin/— all tutor-facing pages (guarded by+layout.svelteauth check)routes/s/[code]/— public student check-in page
Data Model (SQLite, 9 tables)
tutors ──< tutor_courses >── courses ──< students
└──< sessions ──< slots ──< attendances
└──< notes
rooms (layout_json) ←── slots.room_id
Key slot status transitions: closed → open → locked. The code field on slots is the public check-in token students use at /s/[code].
Container / K8s
Dockerfile: 3-stage build (Node 20 frontend → Rust 1.95 backend → Debian slim runtime)k8s/: Deployment, Service, PVC for SQLite, CronJob for nightly vacuum + backup rotation- Live at
tutor.puchstein.dev(tenant-5, ITSH Cloud)
Conventions
- SQLx compile-time queries require
DATABASE_URLset to a valid SQLite file duringcargo build/cargo check. Useexport DATABASE_URL=sqlite:./dev.dbif running outsidemake dev. - Rust toolchain is pinned to 1.95.0 via
rust-toolchain.toml. - Frontend indentation: 2 spaces (Svelte/TS files). Backend: standard
rustfmtdefaults.