Skip to main content

Story 5: Bulk Student Promotion & Transfer

Overview

FieldValue
Story IDNGE-13-5
Story Points13
SprintSprint 9

Technical Implementation

Background Job Processing

@Injectable()
export class PromotionService {
async initiateBulkPromotion(dto: BulkPromotionDto) {
// Queue background job
await this.queue.add('bulk-promotion', {
studentIds: dto.studentIds,
fromClassId: dto.fromClassId,
toAcademicYear: dto.toAcademicYear,
});

return { status: 'QUEUED', count: dto.studentIds.length };
}

@Processor('bulk-promotion')
async processBulkPromotion(job: Job) {
const { studentIds } = job.data;

// Process in batches of 50
for (const batch of chunk(studentIds, 50)) {
await this.prisma.$transaction(async (tx) => {
for (const studentId of batch) {
// Create promotion record
// Update student class/section
// Update section strengths
}
});

await job.updateProgress((processed / total) * 100);
}
}
}

Promotion Types

TypeDescription
PROMOTEDMove to next class
DETAINEDRepeat current class
TRANSFERRED_OUTLeft school
PASSED_OUTCompleted Class 12