All checks were successful
Release / release (push) Successful in 5m24s
145 lines
8.2 KiB
Markdown
145 lines
8.2 KiB
Markdown
# 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 (~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, 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 (~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:
|
||
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).
|