P2-12 Teacher Management:
- Add profile JSON field (subjects, joinedAt, qualifications) to User entity
- Add GET/PUT /rbac/users/:id/profile endpoints with UpdateProfileDto
- Add GET /rbac/teacher-workspace endpoint returning assignedClasses,
todaySchedules, and myStudents
- Create /teacher-workspace page with tabs (My Classes, Today's Schedule,
My Students)
- Add route with PermissionRoute and menu item in MainLayout
P2-13 Student Archive Multi-class:
- Add GET /students/:id/compare-classes endpoint returning side-by-side
enrollment data with per-class attendance statistics
- Students module now includes ClassStudent and AttendanceRecord entities
- No 2-enrollment cap existed in the codebase; student enrollments
already return all records via class-student table
- GET /classes/:id/roster/export — Excel export with 姓名/学号/加入日期/状态
- GET /attendance-records/export — Excel export with 姓名/班级/日期/时段/状态/来源/备注/打卡时间
- Add findAllForExport to AttendanceService (no pagination)
- Both use ExcelJS following classrooms controller downloadTemplate pattern
- Create AttendancePage with filter bar, table, calendar view toggle, batch add modal
- Register /attendance route with PermissionRoute (attendance:view)
- Add menu item in MainLayout with CheckCircleOutlined icon
- Add GET /attendance-records with pagination and filters
- Add GET /attendance-records/classes for class dropdown
- Add source column to AttendanceRecord entity (default: manual)
- Frontend tsc --noEmit: clean; backend: only pre-existing test errors
- Install oxfmt with .oxfmtrc.json (maps Prettier config)
- Install oxlint with oxlint.config.ts (TypeScript + React rules)
- Replace admin ESLint with oxlint
- Remove Prettier integration from server ESLint (keep ESLint for type checking)
- Delete server .prettierrc and admin eslint.config.js
- Move backend/ to apps/server/ via git mv
- Move frontend/ to apps/admin/ via git mv
- Create packages/typescript-config/ with base, nestjs, and react-vite presets