wangziqi
257c2065b8
fix(server): 迁移超长科目备份移到截断前、keepPlus/rels 解析加固、钉钉导入失败补偿
...
CI / check (pull_request) Successful in 4m26s
Dependency Check / check (pull_request) Successful in 2m48s
- 迁移:超长科目原值备份移到 step 2 拆分 UPDATE 之前(原位置截断后按长度查不到原值,备份无效)
- keepPlus:'+' 后紧跟公式触发符(- + = @ 等)不保留前缀,写回 Excel 不会被当公式
- workbook rels:逐元素解析任意属性顺序/引号,声明大小超限拒绝,防文件名绕过与内存放大
- create():钉钉导入失败时补偿删除刚建班级(成员外键 CASCADE),避免孤儿班级
2026-08-11 12:46:12 +08:00
wangziqi
122f3843a2
fix(server): 班级创建事务化、花名册同名新生兜底修正、迁移超长科目备份
...
- create() 班级/学生/教师写入整体包事务,避免教师失败留下孤儿班级
- 花名册提交:行内带标识的同名新生不再复用本批姓名兜底(避免被误判冲突丢弃,与预览一致)
- 迁移:超长科目截断前备份原值,且备份表确保存在(全新部署不因缺表启动失败)
- workbook rels 解析真实工作表路径,防自定义文件名绕过 sheet/行数预扫描
- keepPlus 完整正则对齐注释意图(+ 86 前缀保留);formatDate 用 UTC getter
- main.ts 大 JSON 路由前缀与限制提取为常量并注明耦合点
2026-08-11 12:38:24 +08:00
wangziqi
545d087b3d
feat(server): 教师分配 DTO 校验与实体对齐,重复分配由唯一索引兜底
...
- 科目长度上限收敛到 dto MAX_SUBJECT_LENGTH(30),subjects/subject 加 @MaxLength
- ValidateSubjectTeacherHasSubject 对非字符串元素做类型守卫,避免 500
- normalizeTeacherSubjects 去重键小写对齐 MySQL 大小写不敏感 collation
- 任课老师逐行保存并包事务:并发 1062 跳过、非重复错误整体回滚
- 非科目角色去掉无事务悲观锁,改查重 + save 捕获 1062 转 400
- 实体 subject 列对齐迁移后 NOT NULL DEFAULT '',唯一索引显式命名
- 提交 DTO 跨字段校验:合计行数不超过文件解析上限,id 需为正整数
2026-08-11 11:52:09 +08:00
wangziqi
99ea931409
fix(security): 认证/越权/注入/上传/凭据全链路加固
...
由 OCR(open-codereview.ai,deepseek-v4-flash)审查驱动修复:
- JWT 生产必填、密码 8-72 字节、防枚举;全局 ValidationPipe
- classes/dashboard/schedules/students/attendance/archive/exams 越权与 IDOR 修复
- LIKE 通配符转义(14 处);上传 10MB 上限 + MIME 白名单 + 附件 XSS
- 集成配置 appSecret AES 加密 + 回填脚本;审计 best-effort;IP 来源防伪造
Reviewed-by: OCR (open-codereview.ai)
2026-08-09 21:29:22 +08:00
wangziqi
7905f1ee23
fix(server): 业务日期'今天'统一为中国日期,避免凌晨 UTC 偏一天
...
joinDate/leaveDate/checkInDate/sync 起始日等业务日期默认值原来用
dayjs().utc()(UTC 今天),在国内 00:00-07:59 会取到昨天。
统一改为 dayjs().utcOffset(8)(固定 UTC+8 中国日期),与考勤周边界
修复保持一致;pending-tasks/controller-base 的本地 dayjs() 也显式化。
2026-08-08 17:58:16 +08:00
wangziqi
8936453e84
refactor(server): 日期/月份格式化统一改用 dayjs
...
- 替换散落的 toISOString().slice(0,10) / split('T')[0] / replace('T',' ')(UTC 语义用 dayjs(...).utc() 保持完全一致)
- Asia/Shanghai 固定时区日期(Intl.DateTimeFormat en-CA)改用 dayjs().utcOffset(8)
- 月份边界 first/last、daysInMonth、nextMonth、shiftDate/addDays 等改 dayjs 简洁实现
- 涉及 attendance/classes/classrooms/room/dashboard/bills/expenses/occupancies/sync/ai-chat/rental 等 28 个文件
2026-08-08 17:52:32 +08:00
wangziqi
fd39e1686a
feat: 重构各业务模块管理页面与服务
2026-08-05 17:12:00 +08:00
xiongyuxing
c1bb05502e
修复班级教师姓名显示
CI / check (pull_request) Successful in 2m26s
2026-07-24 17:19:18 +08:00
xiongyuxing
f3b59935d6
feat: 集成 AI 对话与只读查询工具
2026-07-23 14:24:40 +08:00
wangziqi
c11f6bb614
fix: harden DingTalk student synchronization
2026-07-18 14:51:53 +08:00
wangziqi
f7328d670d
fix: 归档删除改为软删除
2026-07-17 14:13:17 +08:00
wangziqi
b1f35f9d1a
test: harden business boundary conditions
2026-07-15 00:03:55 +08:00
wangziqi
0533c30ece
refactor(classes): preserve student membership history
2026-07-13 16:12:57 +08:00
wangziqi
a266d450e1
chore: apply eslint --fix autofixes (remove unnecessary as never casts in tests)
2026-07-12 23:01:37 +08:00
wangziqi and Code Review <branch-review>
cc4f4dae4e
fix: audit remediation — SSE user scoping, FK transactional safety, UI error handling
...
- H4: scoped SSE import progress to exact userId match; non-HTTP events excluded from all subscribers
- H2: moved PRAGMA foreign_key_check inside SQLite transaction before COMMIT; violations rollback preserving old tables
- M1: removed dead axios-style error branch from extractErrorMessage (interceptor already unwraps)
- M2: split handleSave try/catch — save errors vs reload errors shown distinctly
- M3: added provider field validation before AI config test request
- Added SSE scoping regression tests (import service + controller)
- Added FK check failure rollback test (database-migrations.spec)
- Updated controller spec expectations for userId parameter
Co-authored-by: Code Review <branch-review>
2026-07-12 22:59:03 +08:00
wangziqi
8ed1682b90
fix permissions and teacher attendance workflows
2026-07-10 20:40:52 +08:00
wangziqi
31bcd15189
fix: use real name and phone from frontend when importing students
2026-07-10 09:50:18 +08:00
wangziqi
6029d8e2fd
refactor(server): remove Department/UserDepartment entities, CampusScope, and departmentId from all entities
...
- Delete department.entity.ts, user-department.entity.ts
- Remove Department/UserDepartment from entities/index.ts
- Remove departmentId column from 18 entities (AttendanceRecord, ArchiveAttachment, Bill, ClassSchedule, Classroom, ClassroomRental, Deposit, DepositInstallment, ExamScore, LearningRecord, Occupancy, PersonalExpense, ResultArchive, Room, RoomExpense, Student, StudentEnrollment, StudentProfile, StudentReport)
- Remove departments/ module entirely
- Delete campus-scope.ts, campus-scope.middleware.ts (request-utils.ts kept — it's just IP extraction)
- Simplify common.module.ts to empty module
- Remove CampusScopeMiddleware from app.module.ts
- Remove all CampusScope injections and filter calls across all services
- Remove departmentId from all DTOs and controllers
- Simplify dingtalk/wecom sync to only sync users (no dept table)
- Update seed module to remove department seeding
- Clean frontend compilation
2026-07-09 17:51:32 +08:00
wangziqi
22bc1876d8
refactor: remove departmentId from Class entity
2026-07-09 17:32:37 +08:00
wangziqi
40fef906cd
fix: resolve DingTalk dept ID to local department ID in class create
2026-07-09 17:28:12 +08:00
wangziqi
9b7a8e37b4
fix: resolve 5 review findings
...
Critical 1: Remove broken '钉钉绑定' tab (IntegConfig) — deleted /rbac/user-ding-mappings calls
Critical 2: Fix decorator placement in CreateClassDto — @IsOptional @IsArray restored to teachers
Important 1: Restore sync.service.spec.ts from 1fa3363 , strip importDingTalkUsers tests
Important 2: Fix N+1 in batchImportStudents — batched find/save with In() operator
Important 3: Add migrate-student-ding-mapping.sql
2026-07-09 17:25:44 +08:00
wangziqi
91035e9f2c
feat: add batch-import students to class endpoint
2026-07-09 17:12:23 +08:00
wangziqi
b81a06e77c
refactor(classes): remove CampusScope dependency
2026-07-09 16:32:01 +08:00
wangziqi
454a0d24c6
fix: release beds/lockers in batchCheckOut
...
The batchCheckOut method was not releasing assigned beds and lockers
after checkout, leaving them orphaned as 'occupied'. Added the same
release pattern used in checkOut() — using runner.manager.update()
since batchCheckOut operates inside a QueryRunner transaction.
2026-07-09 12:05:36 +08:00
wangziqi
5ea49d0a9e
feat(classes): add schedule and attendance-summary endpoints + frontend tabs
...
- Add GET /classes/:id/schedule returning ClassSchedule list with classroom name
- Add GET /classes/:id/attendance-summary returning attendance/absence/late rates
- Add 课表 and 出勤汇总 tabs to Classes detail page
- Register ClassSchedule and AttendanceRecord in ClassesModule
2026-07-06 17:48:19 +08:00
wangziqi
cd6364268d
feat: integrate CampusScope.filter() into all business services (12 services + 12 modules)
2026-07-05 23:58:51 +08:00
wangziqi
66aadfe3ff
fix: I2 add studentNo to class listing, I4 replace attendance edit placeholder with working edit modal
2026-07-05 20:31:53 +08:00
wangziqi
c378cc45f8
feat: add ClassesService with CRUD + student/teacher management
2026-07-05 18:59:09 +08:00