diff --git a/apps/server/src/archive/archive-report.service.spec.ts b/apps/server/src/archive/archive-report.service.spec.ts
new file mode 100644
index 0000000..457b337
--- /dev/null
+++ b/apps/server/src/archive/archive-report.service.spec.ts
@@ -0,0 +1,31 @@
+import { ArchiveReportService } from './archive-report.service';
+
+describe('ArchiveReportService retired profile fields', () => {
+ it('does not render the retired campus field in a student report', async () => {
+ const service = new ArchiveReportService(
+ { findOne: jest.fn().mockResolvedValue({ campusLocation: '旧校区', grade: '高三' }) } as never,
+ { find: jest.fn().mockResolvedValue([]) } as never,
+ { find: jest.fn().mockResolvedValue([]) } as never,
+ { find: jest.fn().mockResolvedValue([]) } as never,
+ { findOne: jest.fn().mockResolvedValue(null) } as never,
+ { find: jest.fn().mockResolvedValue([]) } as never,
+ {
+ findOne: jest.fn().mockResolvedValue({
+ id: 1,
+ name: '测试学生',
+ gender: '男',
+ phone: '',
+ ethnicity: '',
+ emergencyContact: '',
+ emergencyPhone: '',
+ }),
+ } as never,
+ );
+
+ const html = await service.generateReportHtml(1);
+
+ expect(html).not.toContain('旧校区');
+ expect(html).not.toContain('校区');
+ expect(html).toContain('高三');
+ });
+});
diff --git a/apps/server/src/archive/archive-report.service.ts b/apps/server/src/archive/archive-report.service.ts
index 5e58672..036af73 100644
--- a/apps/server/src/archive/archive-report.service.ts
+++ b/apps/server/src/archive/archive-report.service.ts
@@ -308,7 +308,6 @@ ${this.buildLearningAndResult(learnings, result, now)}
民族${this.esc(student.ethnicity || '-')}
紧急联系人${this.esc(student.emergencyContact || '-')}
紧急电话${this.esc(student.emergencyPhone || '-')}
- 校区${this.esc(profile?.campusLocation || '-')}
年级${this.esc(profile?.grade || '-')}
`;
diff --git a/apps/server/src/archive/dto/archive.dto.spec.ts b/apps/server/src/archive/dto/archive.dto.spec.ts
new file mode 100644
index 0000000..4094440
--- /dev/null
+++ b/apps/server/src/archive/dto/archive.dto.spec.ts
@@ -0,0 +1,18 @@
+import 'reflect-metadata';
+import { plainToInstance } from 'class-transformer';
+import { validate } from 'class-validator';
+import { UpsertProfileDto } from './archive.dto';
+
+describe('UpsertProfileDto retired fields', () => {
+ it('removes the retired campusLocation field under whitelist validation', async () => {
+ const dto = plainToInstance(UpsertProfileDto, {
+ grade: '高三',
+ campusLocation: '旧校区',
+ });
+
+ await validate(dto, { whitelist: true });
+
+ expect(dto).toMatchObject({ grade: '高三' });
+ expect(dto).not.toHaveProperty('campusLocation');
+ });
+});
diff --git a/apps/server/src/archive/dto/archive.dto.ts b/apps/server/src/archive/dto/archive.dto.ts
index 404cb77..9d7c6a9 100644
--- a/apps/server/src/archive/dto/archive.dto.ts
+++ b/apps/server/src/archive/dto/archive.dto.ts
@@ -5,7 +5,6 @@ export class UpsertProfileDto {
@IsOptional() @IsString() targetMajor?: string;
@IsOptional() @IsString() subjectDirection?: string;
@IsOptional() @IsString() grade?: string;
- @IsOptional() @IsString() campusLocation?: string;
@IsOptional() @IsDateString() profileDate?: string;
@IsOptional() @IsString() notes?: string;
}
diff --git a/apps/server/src/entities/student-profile.entity.ts b/apps/server/src/entities/student-profile.entity.ts
index 9a83f78..bac56a9 100644
--- a/apps/server/src/entities/student-profile.entity.ts
+++ b/apps/server/src/entities/student-profile.entity.ts
@@ -33,9 +33,6 @@ export class StudentProfile {
@Column({ length: 20, nullable: true })
grade: string;
- @Column({ name: 'campus_location', length: 100, nullable: true })
- campusLocation: string;
-
@Column({ name: 'profile_date', type: 'date', nullable: true })
profileDate: string;
diff --git a/apps/server/src/schedules/dto/schedule.dto.spec.ts b/apps/server/src/schedules/dto/schedule.dto.spec.ts
index 5e85269..62fc926 100644
--- a/apps/server/src/schedules/dto/schedule.dto.spec.ts
+++ b/apps/server/src/schedules/dto/schedule.dto.spec.ts
@@ -27,3 +27,21 @@ describe('schedule notes validation', () => {
expect(errors.some((error) => error.property === 'notes')).toBe(true);
});
});
+
+it('removes the retired departmentId field from create requests', async () => {
+ const dto = Object.assign(new CreateScheduleDto(), {
+ classId: 1,
+ classroomId: 2,
+ weekDay: 1,
+ startTime: '09:00',
+ endTime: '10:00',
+ startDate: '2026-07-01',
+ endDate: '2026-07-31',
+ subject: '语文',
+ departmentId: 99,
+ });
+
+ await validate(dto, { whitelist: true });
+
+ expect(dto).not.toHaveProperty('departmentId');
+});
diff --git a/apps/server/src/schedules/dto/schedule.dto.ts b/apps/server/src/schedules/dto/schedule.dto.ts
index 016560a..b193c59 100644
--- a/apps/server/src/schedules/dto/schedule.dto.ts
+++ b/apps/server/src/schedules/dto/schedule.dto.ts
@@ -63,9 +63,6 @@ export class CreateScheduleDto {
@MaxLength(500)
notes?: string;
- @IsOptional()
- @IsInt()
- departmentId?: number;
}
export class UpdateScheduleDto {