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

145 lines
8.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
<!-- SLM-START -->
## 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`.
<!-- SLM-END -->
# Commands
```bash
# 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: `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 (~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.rs``POST /__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).