Story 5: Bulk Student Promotion & Transfer
Overview
| Field | Value |
|---|---|
| Story ID | NGE-13-5 |
| Story Points | 13 |
| Sprint | Sprint 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
| Type | Description |
|---|---|
| PROMOTED | Move to next class |
| DETAINED | Repeat current class |
| TRANSFERRED_OUT | Left school |
| PASSED_OUT | Completed Class 12 |