Files
tutortool/GEMINI.md
2026-05-03 00:41:50 +02:00

8.2 KiB
Raw Permalink Blame History

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 recall tool with relevant keywords (e.g., tutortool, architecture).
    • Remember: After implementing features, fixing bugs, or establishing new patterns, use the remember tool with appropriate tags.
  • 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 (~1050 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, so DATABASE_URL is not required for cargo build or cargo check. Migrations are automatically run at startup.
    • Auth: Hardened dual-token JWT system.
      • Access Token: Short-lived (15m), stored in httpOnly, SameSite=Strict cookie named token.
      • Refresh Token: Long-lived (7d), stored in httpOnly, SameSite=Strict cookie named refresh_token.
      • Content: JWT contains only sub (ID) and roles. Sensitive data like email is fetched from DB in the /api/auth/me handler.
      • Password Hashing: Argon2id for all new accounts. Legacy bcrypt hashes are lazily migrated on login.
    • Security Headers: Global middleware enforces CSP, X-Content-Type-Options: nosniff, and X-Frame-Options: DENY.
    • Shared State: Axum handlers use State<AppState> (or State<SqlitePool> via FromRef) which caches the JWT_SECRET and DB pool.
    • Static Serving: Serves the compiled SvelteKit frontend as a Single-Page App (SPA) via tower_http::ServeDir.
    • PRAGMA foreign_keys = ON is enforced on every connection in db.rs.
    • Route modules: auth_routes, checkin, courses, rooms, sessions, attendance, notes, export, tutors, and test_reset (mounted only when TT_TEST_MODE=1 AND in debug builds).
    • The /health route 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 the auth object in $lib/auth.svelte.ts.
    • Type Safety: Strict TypeScript (strict: true, noUncheckedIndexedAccess, noImplicitAny).
    • Linting: ESLint flat config with eslint-plugin-svelte and typescript-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.ts mirrors backend/src/models.rs — keep in sync when changing the API.

Routes

Backend

Route handlers live in backend/src/routes/ and are merged in routes/mod.rs.

Frontend

  • src/routes/admin/login/ — public login page
  • src/routes/admin/ — protected tutor-facing pages (guarded by +layout.svelte auth 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: closedopenlocked. 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 (~1050 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:

  1. cargo check + pnpm check + pnpm lint (Zero Warnings enforcement)
  2. cargo test (unit tests)
  3. pnpm audit (security dependency scan)
  4. pnpm build (frontend build)
  5. make test-up + pnpm test:e2e (E2E)

Key Files

  • backend/src/main.rs — entry point, TT_TEST_MODE flag, /health route
  • backend/src/db.rs — database initialization and migration logic
  • backend/src/auth.rs — JWT encoding/decoding and Axum extractor
  • backend/src/models.rs — shared data models (DB rows and Request/Response DTOs)
  • backend/src/routes/mod.rs — router assembly; test_reset mounted conditionally
  • backend/src/routes/test_reset.rsPOST /__test__/reset handler (test-mode only)
  • backend/demo/demo_seed.sql — demo/test seed data
  • frontend/src/lib/api.ts — API client for frontend-backend communication
  • frontend/src/lib/RoomCanvas.svelte — interactive SVG-based room layout component
  • docs/testing.md — E2E test pipeline guide
  • conductor/attendance-tool.md — main implementation plan and project scope
  • conductor/superadmin-crud.md — specification and plan for superadmin features
  • conductor/demo-plan.md — plan for demo data and presentation
  • conductor/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 rustfmt defaults.
  • All SQLx queries are runtime; DATABASE_URL is not required for cargo 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), and Makefile targets.
    • 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.
  • btrfs pnpm fix: See Global User Preferences (pnpm requires --package-import-method copy on this machine's btrfs filesystem).