8.2 KiB
TutorTool: Attendance Tracking System
TutorTool is a full-stack web application for tracking student attendance in tutoring sessions. It features a Rust backend and a SvelteKit frontend.
SuperLocalMemory (SLM)
- Mandate: Use SLM for all project-related memories, decisions, and context.
- Workflow:
- Recall: At the start of every session or when context is missing, use the
recalltool with relevant keywords (e.g.,tutortool,architecture). - Remember: After implementing features, fixing bugs, or establishing new patterns, use the
remembertool with appropriate tags.
- Recall: At the start of every session or when context is missing, use the
- Tools:
remember,recall,list,get_status.
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)
# Linting & Quality (Zero Warnings Policy)
make lint # runs cargo fmt, clippy (-D warnings), svelte-check, and eslint
make verify-all # full local pre-flight: lint + tests + E2E + audit
# Build
make build # runs lint, then pnpm build and cargo build --release
# 🚨 MANDATE: Run `make verify-all` locally before every release tag or push.
# This ensures that all quality, security, and lockfile gates pass, minimizing
# CI/CD debugging cycles.
Testing
make test # runs lint, then cargo test (backend unit tests) make test-e2e # test-up + pnpm test:e2e in one step
# Demo data
make seed-demo # wipe dev.db and reseed from backend/demo/demo_seed.sql
# E2E test pipeline (see docs/testing.md for full detail)
make test-up # build test DB if missing, start backend on test port, wait for /health
make test-down # stop the test backend
make test-reset # fast DB reset via POST /__test__/reset (~10–50 ms)
make test-rebuild # wipe and rebuild test DB from migrations + seed
make test-e2e # test-up + pnpm test:e2e in one step
Architecture
- Architecture: Standalone repo with a Rust backend (Axum) and a SvelteKit 5 frontend.
- Backend:
- Framework: Axum (async) on Tokio, port 3000.
- Database: SQLite via SQLx. All queries use runtime
sqlx::query()/sqlx::query_as::<_, T>()— no compile-time macros, soDATABASE_URLis not required forcargo buildorcargo check. Migrations are automatically run at startup. - Auth: Hardened dual-token JWT system.
- Access Token: Short-lived (15m), stored in
httpOnly,SameSite=Strictcookie namedtoken. - Refresh Token: Long-lived (7d), stored in
httpOnly,SameSite=Strictcookie namedrefresh_token. - Content: JWT contains only
sub(ID) and roles. Sensitive data like email is fetched from DB in the/api/auth/mehandler. - Password Hashing: Argon2id for all new accounts. Legacy bcrypt hashes are lazily migrated on login.
- Access Token: Short-lived (15m), stored in
- Security Headers: Global middleware enforces CSP,
X-Content-Type-Options: nosniff, andX-Frame-Options: DENY. - Shared State: Axum handlers use
State<AppState>(orState<SqlitePool>viaFromRef) which caches theJWT_SECRETand DB pool. - Static Serving: Serves the compiled SvelteKit frontend as a Single-Page App (SPA) via
tower_http::ServeDir. PRAGMA foreign_keys = ONis enforced on every connection indb.rs.- Route modules:
auth_routes,checkin,courses,rooms,sessions,attendance,notes,export,tutors, andtest_reset(mounted only whenTT_TEST_MODE=1AND in debug builds). - The
/healthroute always returns"ok"— used by the test pipeline to wait for startup.
- Frontend:
- Framework: SvelteKit 5 using Svelte Runes (
$state,$derived, etc.). Authentication state is managed by theauthobject in$lib/auth.svelte.ts. - Type Safety: Strict TypeScript (
strict: true,noUncheckedIndexedAccess,noImplicitAny). - Linting: ESLint flat config with
eslint-plugin-svelteandtypescript-eslint(Zero Warnings enforcement). - Build Tool: Vite with
adapter-static(SPA mode,fallback: 'index.html'). - Package Manager: pnpm (preferred over npm).
- Styling: Vanilla CSS (based on design handoff).
- API: Centralized fetch wrapper in
src/lib/api.ts; relies on browser automatic cookie handling. - Types:
src/lib/types.tsmirrorsbackend/src/models.rs— keep in sync when changing the API.
- Framework: SvelteKit 5 using Svelte Runes (
Routes
Backend
Route handlers live in backend/src/routes/ and are merged in routes/mod.rs.
Frontend
src/routes/admin/login/— public login pagesrc/routes/admin/— protected tutor-facing pages (guarded by+layout.svelteauth check)attendance/,courses/,export/,live/,rooms/,sessions/,students/,tutors/
src/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].
Testing
E2E tests run Playwright against a dedicated test backend daemon. The test backend uses a separate DB and is started with TT_TEST_MODE=1, which enables POST /__test__/reset for fast state resets (~10–50 ms) without restarting the process. Each git worktree gets its own deterministic port and DB path — no collisions when testing across branches.
See docs/testing.md for the full guide including seed data, MCP-driven verification, and worktree isolation details.
Demo / seed credentials:
- Admin:
admin@tutortool.com/admin
CI
Gitea Actions at .gitea/workflows/test.yml runs on every push to main and on PRs:
cargo check+pnpm check+pnpm lint(Zero Warnings enforcement)cargo test(unit tests)pnpm audit(security dependency scan)pnpm build(frontend build)make test-up+pnpm test:e2e(E2E)
Key Files
backend/src/main.rs— entry point,TT_TEST_MODEflag,/healthroutebackend/src/db.rs— database initialization and migration logicbackend/src/auth.rs— JWT encoding/decoding and Axum extractorbackend/src/models.rs— shared data models (DB rows and Request/Response DTOs)backend/src/routes/mod.rs— router assembly; test_reset mounted conditionallybackend/src/routes/test_reset.rs—POST /__test__/resethandler (test-mode only)backend/demo/demo_seed.sql— demo/test seed datafrontend/src/lib/api.ts— API client for frontend-backend communicationfrontend/src/lib/RoomCanvas.svelte— interactive SVG-based room layout componentdocs/testing.md— E2E test pipeline guideconductor/attendance-tool.md— main implementation plan and project scopeconductor/superadmin-crud.md— specification and plan for superadmin featuresconductor/demo-plan.md— plan for demo data and presentationconductor/fix-playwright-mcp-config.md— context on Playwright/MCP configuration issues
Conventions
- Rust toolchain is pinned to 1.95.0 via
rust-toolchain.toml. - Frontend indentation: 2 spaces (Svelte/TS files). Backend: standard
rustfmtdefaults. - All SQLx queries are runtime;
DATABASE_URLis not required forcargo build/cargo check. - Infrastructure & Workflow:
- Always check for and respect existing project infrastructure like git worktrees, specialized test environments (e.g.,
scripts/test-env.sh), andMakefiletargets. - Avoid creating custom workarounds for environment issues that established project tools already solve.
- Prioritize systematic adherence to local development conventions over erratic troubleshooting.
- If unsure about project infrastructure, a specific workflow, or the best way to resolve an environment issue, stop and ask for clarification instead of guessing or attempting erratic workarounds.
- Always check for and respect existing project infrastructure like git worktrees, specialized test environments (e.g.,
- btrfs pnpm fix: See Global User Preferences (pnpm requires
--package-import-method copyon this machine's btrfs filesystem).