pnpm dev- Start all apps in development (default: server at port 3000)pnpm dev:server- Start only the serverpnpm check-types- Type check all apps
pnpm db:push- Push schema changes to PostgreSQL without migrationspnpm db:generate- Generate migrations from schemapnpm db:migrate- Apply migrations to databasepnpm db:studio- Open Drizzle Studio UIpnpm db:start- Start PostgreSQL via Docker Compose (detached)pnpm db:watch- Start PostgreSQL via Docker Compose (attached)pnpm db:stop- Stop PostgreSQL containerpnpm db:down- Stop and remove PostgreSQL container
pnpm build- Build all appspnpm test- Run tests with Vitest UIpnpm check- Run oxlint and oxfmt (auto-fix)
tsx watch src/index.ts- Run dev server with hot reloadpnpm compile- Compile server to standalone binary with Bun
apps/server/- Hono-based HTTP + WebSocket serverpackages/db/- Drizzle ORM schema, connection, queriespackages/env/- Zod-validated environment variablespackages/config/- Shared TypeScript configs
Entry point: apps/server/src/index.ts
HTTP Routes:
routes/auth.ts- User registration, login (JWT auth)routes/class.ts- Class CRUD, enrollment managementroutes/students.ts- Student listingroutes/attendance.ts- Start/clear attendance sessions
WebSocket:
websocket.ts- Real-time attendance updates- Auth via
?token=query param - Events:
ATTENDANCE_MARKED,TODAY_SUMMARY,MY_ATTENDANCE,DONE - In-memory attendance session state (cleared on
DONEor/attendance/clear-session)
Auth:
middleware/auth.ts- JWT verification middleware +requireRole()helper- JWT payload:
{ userId: uuid, role: "teacher" | "student" }
Schema: packages/db/src/schema.ts
Tables:
users- id, name, email, password (bcrypt), role (enum: teacher/student)classes- id, className, teacherId (FK users)class_enrollments- id, classId (FK classes), studentId (FK users)attendance- id, classId (FK classes), studentId (FK users), status (enum: present/absent)
Relations: packages/db/src/relations.ts
Database Config:
- Connection:
packages/db/src/index.ts(Drizzle client exported asdb) - Drizzle config:
packages/db/drizzle.config.ts(readsapps/server/.env) - Requires
DATABASE_URLinapps/server/.env
Required env vars in apps/server/.env:
DATABASE_URL- PostgreSQL connection stringJWT_SECRET- Secret for JWT signingCORS_ORIGIN- Allowed CORS origin
Validation: packages/env/src/server.ts (Zod schemas)
- Teacher starts attendance via POST
/attendance/start(creates in-memory session) - Teacher/students connect to
/ws?token=<jwt> - Teacher sends
ATTENDANCE_MARKEDevents (broadcast to all) - Students query
MY_ATTENDANCE(unicast response) - Teacher sends
TODAY_SUMMARY(broadcast summary) - Teacher sends
DONE(persists to DB, clears session, broadcasts final summary)
- In-memory attendance state in
routes/attendance.ts(activeSession) - WebSocket clients tracked in Map with authenticated user data
- Enrollment used to mark unmarked students as absent on
DONE - No frontend included (API-only backend)