@eeplatform/basic-edu 1.8.6 → 1.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +208 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +208 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -473,6 +473,7 @@ declare function useGradeLevelController(): {
|
|
|
473
473
|
updateById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
474
474
|
deleteById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
475
475
|
getByEducationLevel: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
476
|
+
getByGradeLevel: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
476
477
|
};
|
|
477
478
|
|
|
478
479
|
type TRegion = {
|
|
@@ -870,6 +871,7 @@ declare function useLearnerRepo(): {
|
|
|
870
871
|
school: string | ObjectId;
|
|
871
872
|
schoolYear: string;
|
|
872
873
|
gradeLevel: string;
|
|
874
|
+
specialProgram?: string | ObjectId;
|
|
873
875
|
status?: string;
|
|
874
876
|
}, session?: ClientSession) => Promise<number>;
|
|
875
877
|
updateStatusById: (_id: string | ObjectId, status: string, session?: ClientSession) => Promise<mongodb.UpdateResult<bson.Document>>;
|
|
@@ -1013,6 +1015,7 @@ declare function useSectionRepo(): {
|
|
|
1013
1015
|
declare function useSectionController(): {
|
|
1014
1016
|
add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
1015
1017
|
generateSections: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
1018
|
+
generateSectionPreview: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
1016
1019
|
getAll: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
1017
1020
|
getById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
1018
1021
|
getByName: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
@@ -1636,6 +1639,8 @@ declare function useProgramScreeningRepo(): {
|
|
|
1636
1639
|
}, session?: ClientSession) => Promise<string>;
|
|
1637
1640
|
deleteById: (_id: string | ObjectId) => Promise<string>;
|
|
1638
1641
|
updateById: (_id: string | ObjectId, value: Pick<TProgramScreening, "specialProgram" | "specialProgramName" | "status">) => Promise<string>;
|
|
1642
|
+
updateStatusByApplicantId: (_id: string | ObjectId, status: string, session?: ClientSession) => Promise<string>;
|
|
1643
|
+
getByApplicantId: (_id: string | ObjectId) => Promise<TProgramScreening>;
|
|
1639
1644
|
};
|
|
1640
1645
|
|
|
1641
1646
|
declare function useProgramScreeningController(): {
|
package/dist/index.js
CHANGED
|
@@ -2968,7 +2968,7 @@ var learnerInfoSchema = import_joi5.default.object({
|
|
|
2968
2968
|
});
|
|
2969
2969
|
var schemaUpdateStatus = import_joi5.default.object({
|
|
2970
2970
|
_id: import_joi5.default.string().hex().length(24).required(),
|
|
2971
|
-
status: import_joi5.default.string().valid("pending", "accepted", "rejected").required()
|
|
2971
|
+
status: import_joi5.default.string().valid("pending", "accepted", "rejected", "cancelled").required()
|
|
2972
2972
|
});
|
|
2973
2973
|
var gradeLevels = [
|
|
2974
2974
|
"K1",
|
|
@@ -3649,17 +3649,16 @@ function useLearnerRepo() {
|
|
|
3649
3649
|
school: import_joi7.default.string().hex().required(),
|
|
3650
3650
|
schoolYear: import_joi7.default.string().required(),
|
|
3651
3651
|
gradeLevel: import_joi7.default.string().required(),
|
|
3652
|
+
specialProgram: import_joi7.default.string().hex().optional().allow(null, ""),
|
|
3652
3653
|
status: import_joi7.default.string().optional()
|
|
3653
3654
|
});
|
|
3654
3655
|
const { error } = validation.validate(value);
|
|
3655
3656
|
if (error) {
|
|
3656
3657
|
throw new import_nodejs_utils10.BadRequestError(`Invalid data: ${error.message}`);
|
|
3657
3658
|
}
|
|
3658
|
-
const status = value.status ?? "active";
|
|
3659
3659
|
const query = {
|
|
3660
3660
|
schoolYear: value.schoolYear,
|
|
3661
|
-
gradeLevel: value.gradeLevel
|
|
3662
|
-
status
|
|
3661
|
+
gradeLevel: value.gradeLevel
|
|
3663
3662
|
};
|
|
3664
3663
|
const cacheKeyOptions = {
|
|
3665
3664
|
...query,
|
|
@@ -3673,6 +3672,16 @@ function useLearnerRepo() {
|
|
|
3673
3672
|
}
|
|
3674
3673
|
cacheKeyOptions.school = value.school.toString();
|
|
3675
3674
|
}
|
|
3675
|
+
if (value.specialProgram) {
|
|
3676
|
+
try {
|
|
3677
|
+
query["learnerInfo.specialProgram"] = new import_mongodb7.ObjectId(
|
|
3678
|
+
value.specialProgram
|
|
3679
|
+
);
|
|
3680
|
+
} catch (error2) {
|
|
3681
|
+
throw new import_nodejs_utils10.BadRequestError("Invalid special program ID.");
|
|
3682
|
+
}
|
|
3683
|
+
cacheKeyOptions.specialProgram = value.specialProgram.toString();
|
|
3684
|
+
}
|
|
3676
3685
|
const cacheKey = (0, import_nodejs_utils10.makeCacheKey)(namespace_collection, cacheKeyOptions);
|
|
3677
3686
|
const cachedData = await getCache(cacheKey);
|
|
3678
3687
|
if (cachedData !== void 0 && cachedData !== null) {
|
|
@@ -4390,6 +4399,51 @@ function useProgramScreeningRepo() {
|
|
|
4390
4399
|
}
|
|
4391
4400
|
}
|
|
4392
4401
|
}
|
|
4402
|
+
async function getByApplicantId(_id) {
|
|
4403
|
+
try {
|
|
4404
|
+
_id = new import_mongodb10.ObjectId(_id);
|
|
4405
|
+
} catch (error) {
|
|
4406
|
+
throw new import_nodejs_utils15.BadRequestError("Invalid ID.");
|
|
4407
|
+
}
|
|
4408
|
+
const cacheKey = (0, import_nodejs_utils15.makeCacheKey)(namespace_collection, {
|
|
4409
|
+
applicant: String(_id)
|
|
4410
|
+
});
|
|
4411
|
+
try {
|
|
4412
|
+
const cached = await getCache(cacheKey);
|
|
4413
|
+
if (cached) {
|
|
4414
|
+
import_nodejs_utils15.logger.log({
|
|
4415
|
+
level: "info",
|
|
4416
|
+
message: `Cache hit for getById program screening: ${cacheKey}`
|
|
4417
|
+
});
|
|
4418
|
+
return cached;
|
|
4419
|
+
}
|
|
4420
|
+
const result = await collection.findOne({
|
|
4421
|
+
applicant: _id,
|
|
4422
|
+
status: { $ne: "deleted" }
|
|
4423
|
+
});
|
|
4424
|
+
if (!result) {
|
|
4425
|
+
throw new import_nodejs_utils15.BadRequestError("Program screening not found.");
|
|
4426
|
+
}
|
|
4427
|
+
setCache(cacheKey, result, 300).then(() => {
|
|
4428
|
+
import_nodejs_utils15.logger.log({
|
|
4429
|
+
level: "info",
|
|
4430
|
+
message: `Cache set for program screening by id: ${cacheKey}`
|
|
4431
|
+
});
|
|
4432
|
+
}).catch((err) => {
|
|
4433
|
+
import_nodejs_utils15.logger.log({
|
|
4434
|
+
level: "error",
|
|
4435
|
+
message: `Failed to set cache for program screening by id: ${err.message}`
|
|
4436
|
+
});
|
|
4437
|
+
});
|
|
4438
|
+
return result;
|
|
4439
|
+
} catch (error) {
|
|
4440
|
+
if (error instanceof import_nodejs_utils15.AppError) {
|
|
4441
|
+
throw error;
|
|
4442
|
+
} else {
|
|
4443
|
+
throw new import_nodejs_utils15.InternalServerError("Failed to get program screening.");
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4446
|
+
}
|
|
4393
4447
|
async function getByCode(code, school) {
|
|
4394
4448
|
try {
|
|
4395
4449
|
school = new import_mongodb10.ObjectId(school);
|
|
@@ -4513,6 +4567,26 @@ function useProgramScreeningRepo() {
|
|
|
4513
4567
|
);
|
|
4514
4568
|
}
|
|
4515
4569
|
}
|
|
4570
|
+
async function updateStatusByApplicantId(_id, status, session) {
|
|
4571
|
+
try {
|
|
4572
|
+
_id = new import_mongodb10.ObjectId(_id);
|
|
4573
|
+
} catch (error) {
|
|
4574
|
+
throw new import_nodejs_utils15.BadRequestError("Invalid ID.");
|
|
4575
|
+
}
|
|
4576
|
+
try {
|
|
4577
|
+
await collection.updateOne(
|
|
4578
|
+
{ applicant: _id },
|
|
4579
|
+
{ $set: { status, updatedAt: /* @__PURE__ */ new Date() } },
|
|
4580
|
+
{ session }
|
|
4581
|
+
);
|
|
4582
|
+
delCachedData();
|
|
4583
|
+
return "Successfully updated program screening status.";
|
|
4584
|
+
} catch (error) {
|
|
4585
|
+
throw new import_nodejs_utils15.InternalServerError(
|
|
4586
|
+
"Failed to update program screening status."
|
|
4587
|
+
);
|
|
4588
|
+
}
|
|
4589
|
+
}
|
|
4516
4590
|
return {
|
|
4517
4591
|
createIndexes,
|
|
4518
4592
|
add,
|
|
@@ -4521,7 +4595,9 @@ function useProgramScreeningRepo() {
|
|
|
4521
4595
|
getByCode,
|
|
4522
4596
|
updateFieldById,
|
|
4523
4597
|
deleteById,
|
|
4524
|
-
updateById
|
|
4598
|
+
updateById,
|
|
4599
|
+
updateStatusByApplicantId,
|
|
4600
|
+
getByApplicantId
|
|
4525
4601
|
};
|
|
4526
4602
|
}
|
|
4527
4603
|
|
|
@@ -5408,7 +5484,11 @@ function useEnrollmentService() {
|
|
|
5408
5484
|
getById: _getById,
|
|
5409
5485
|
updateStatusById: _updateStatusById
|
|
5410
5486
|
} = useEnrollmentRepo();
|
|
5411
|
-
const {
|
|
5487
|
+
const {
|
|
5488
|
+
add: addProgramScreening,
|
|
5489
|
+
updateStatusByApplicantId,
|
|
5490
|
+
getByApplicantId
|
|
5491
|
+
} = useProgramScreeningRepo();
|
|
5412
5492
|
const { getById: getProgramById } = useProgramRepo();
|
|
5413
5493
|
async function add(value) {
|
|
5414
5494
|
const session = import_nodejs_utils21.useAtlas.getClient()?.startSession();
|
|
@@ -5539,6 +5619,11 @@ function useEnrollmentService() {
|
|
|
5539
5619
|
if (status === "rejected" && enrollment.status == "accepted") {
|
|
5540
5620
|
throw new import_nodejs_utils21.BadRequestError("Accepted enrollments cannot be rejected.");
|
|
5541
5621
|
}
|
|
5622
|
+
if (status === "withdrawn" && enrollment.status !== "screening") {
|
|
5623
|
+
throw new import_nodejs_utils21.BadRequestError(
|
|
5624
|
+
"Only enrollments in screening status can be withdrawn."
|
|
5625
|
+
);
|
|
5626
|
+
}
|
|
5542
5627
|
const result = await _updateStatusById(_id, status, session);
|
|
5543
5628
|
if (result.modifiedCount === 0) {
|
|
5544
5629
|
throw new import_nodejs_utils21.InternalServerError("Failed to accept enrollment");
|
|
@@ -5578,6 +5663,14 @@ function useEnrollmentService() {
|
|
|
5578
5663
|
enrollment.createdBy = enrollment.createdBy?.toString();
|
|
5579
5664
|
await addLearner(enrollment, session);
|
|
5580
5665
|
}
|
|
5666
|
+
const programScreening = await getByApplicantId(_id);
|
|
5667
|
+
if (programScreening) {
|
|
5668
|
+
if (["cancelled", "withdrawn"].includes(status)) {
|
|
5669
|
+
await updateStatusByApplicantId(_id, "cancelled", session);
|
|
5670
|
+
} else {
|
|
5671
|
+
await updateStatusByApplicantId(_id, status, session);
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5581
5674
|
await session.commitTransaction();
|
|
5582
5675
|
return "Enrollment accepted successfully";
|
|
5583
5676
|
} catch (error2) {
|
|
@@ -6203,7 +6296,8 @@ function useGradeLevelController() {
|
|
|
6203
6296
|
add: _add,
|
|
6204
6297
|
updateById: _updateById,
|
|
6205
6298
|
deleteById: _deleteById,
|
|
6206
|
-
getByEducationLevel: _getByEducationLevel
|
|
6299
|
+
getByEducationLevel: _getByEducationLevel,
|
|
6300
|
+
getByGradeLevel: _getByGradeLevel
|
|
6207
6301
|
} = useGradeLevelRepo();
|
|
6208
6302
|
async function add(req, res, next) {
|
|
6209
6303
|
const value = req.body;
|
|
@@ -6374,13 +6468,34 @@ function useGradeLevelController() {
|
|
|
6374
6468
|
next(error2);
|
|
6375
6469
|
}
|
|
6376
6470
|
}
|
|
6471
|
+
async function getByGradeLevel(req, res, next) {
|
|
6472
|
+
const gradeLevel = req.params.gradeLevel;
|
|
6473
|
+
const school = req.params.school;
|
|
6474
|
+
const validation = import_joi16.default.object({
|
|
6475
|
+
gradeLevel: import_joi16.default.string().required(),
|
|
6476
|
+
school: import_joi16.default.string().hex().required()
|
|
6477
|
+
});
|
|
6478
|
+
const { error } = validation.validate({ gradeLevel, school });
|
|
6479
|
+
if (error) {
|
|
6480
|
+
next(new import_nodejs_utils25.BadRequestError(error.message));
|
|
6481
|
+
return;
|
|
6482
|
+
}
|
|
6483
|
+
try {
|
|
6484
|
+
const data = await _getByGradeLevel({ gradeLevel, school });
|
|
6485
|
+
res.json(data);
|
|
6486
|
+
return;
|
|
6487
|
+
} catch (error2) {
|
|
6488
|
+
next(error2);
|
|
6489
|
+
}
|
|
6490
|
+
}
|
|
6377
6491
|
return {
|
|
6378
6492
|
add,
|
|
6379
6493
|
getAll,
|
|
6380
6494
|
getById,
|
|
6381
6495
|
updateById,
|
|
6382
6496
|
deleteById,
|
|
6383
|
-
getByEducationLevel
|
|
6497
|
+
getByEducationLevel,
|
|
6498
|
+
getByGradeLevel
|
|
6384
6499
|
};
|
|
6385
6500
|
}
|
|
6386
6501
|
|
|
@@ -38933,6 +39048,9 @@ var schemaGenerateSections = import_joi31.default.object({
|
|
|
38933
39048
|
school: import_joi31.default.string().hex().required(),
|
|
38934
39049
|
schoolYear: import_joi31.default.string().required(),
|
|
38935
39050
|
gradeLevel: import_joi31.default.string().required(),
|
|
39051
|
+
minStudents: import_joi31.default.number().integer().min(1).required(),
|
|
39052
|
+
maxStudents: import_joi31.default.number().integer().min(import_joi31.default.ref("minStudents")).required(),
|
|
39053
|
+
specialProgram: import_joi31.default.string().hex().optional().allow(null, ""),
|
|
38936
39054
|
set: import_joi31.default.array().items(import_joi31.default.string().min(1).max(100)).required()
|
|
38937
39055
|
});
|
|
38938
39056
|
function modelSection(value) {
|
|
@@ -42343,7 +42461,8 @@ function useSectionService() {
|
|
|
42343
42461
|
{
|
|
42344
42462
|
school: value.school,
|
|
42345
42463
|
schoolYear: value.schoolYear,
|
|
42346
|
-
gradeLevel: value.gradeLevel
|
|
42464
|
+
gradeLevel: value.gradeLevel,
|
|
42465
|
+
specialProgram: value.specialProgram
|
|
42347
42466
|
},
|
|
42348
42467
|
session
|
|
42349
42468
|
);
|
|
@@ -42360,8 +42479,8 @@ function useSectionService() {
|
|
|
42360
42479
|
if (!gradeLevelData) {
|
|
42361
42480
|
throw new import_nodejs_utils69.BadRequestError("Grade level not found.");
|
|
42362
42481
|
}
|
|
42363
|
-
const minPerSection = gradeLevelData.minNumberOfLearners;
|
|
42364
|
-
const maxPerSection = gradeLevelData.maxNumberOfLearners;
|
|
42482
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
42483
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
42365
42484
|
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
42366
42485
|
if (sectionsNeeded > value.set.length) {
|
|
42367
42486
|
throw new import_nodejs_utils69.BadRequestError(
|
|
@@ -42507,7 +42626,64 @@ function useSectionService() {
|
|
|
42507
42626
|
await session?.endSession();
|
|
42508
42627
|
}
|
|
42509
42628
|
}
|
|
42510
|
-
|
|
42629
|
+
async function generateSectionPreview(value) {
|
|
42630
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
42631
|
+
if (error) {
|
|
42632
|
+
throw new import_nodejs_utils69.BadRequestError(
|
|
42633
|
+
`Invalid section generation data: ${error.message}`
|
|
42634
|
+
);
|
|
42635
|
+
}
|
|
42636
|
+
try {
|
|
42637
|
+
const studentCount = await getCountByGradeLevel({
|
|
42638
|
+
school: value.school,
|
|
42639
|
+
schoolYear: value.schoolYear,
|
|
42640
|
+
gradeLevel: value.gradeLevel,
|
|
42641
|
+
specialProgram: value.specialProgram
|
|
42642
|
+
});
|
|
42643
|
+
if (studentCount === 0) {
|
|
42644
|
+
throw new import_nodejs_utils69.BadRequestError("No learners found for this grade level.");
|
|
42645
|
+
}
|
|
42646
|
+
const gradeLevelData = await getByGradeLevel({
|
|
42647
|
+
school: value.school,
|
|
42648
|
+
gradeLevel: value.gradeLevel
|
|
42649
|
+
});
|
|
42650
|
+
if (!gradeLevelData) {
|
|
42651
|
+
throw new import_nodejs_utils69.BadRequestError("Grade level not found.");
|
|
42652
|
+
}
|
|
42653
|
+
const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
|
|
42654
|
+
const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
|
|
42655
|
+
const sectionsNeeded = Math.ceil(studentCount / minPerSection);
|
|
42656
|
+
if (sectionsNeeded > value.set.length) {
|
|
42657
|
+
throw new import_nodejs_utils69.BadRequestError(
|
|
42658
|
+
"Insufficient number of section names in set[]."
|
|
42659
|
+
);
|
|
42660
|
+
}
|
|
42661
|
+
const sectionSizes = distributeStudents(
|
|
42662
|
+
studentCount,
|
|
42663
|
+
minPerSection,
|
|
42664
|
+
maxPerSection
|
|
42665
|
+
);
|
|
42666
|
+
if (sectionSizes.length === 0) {
|
|
42667
|
+
throw new import_nodejs_utils69.BadRequestError("Unable to compute section sizes.");
|
|
42668
|
+
}
|
|
42669
|
+
const sections = sectionSizes.map((size, index) => ({
|
|
42670
|
+
name: value.set[index],
|
|
42671
|
+
value: size
|
|
42672
|
+
}));
|
|
42673
|
+
return {
|
|
42674
|
+
totalSectionsGenerated: sectionSizes.length,
|
|
42675
|
+
totalStudentsAssigned: studentCount,
|
|
42676
|
+
sections
|
|
42677
|
+
};
|
|
42678
|
+
} catch (error2) {
|
|
42679
|
+
if (error2 instanceof import_nodejs_utils69.AppError) {
|
|
42680
|
+
throw error2;
|
|
42681
|
+
} else {
|
|
42682
|
+
throw new import_nodejs_utils69.InternalServerError("Failed to generate section preview.");
|
|
42683
|
+
}
|
|
42684
|
+
}
|
|
42685
|
+
}
|
|
42686
|
+
return { generateSections, generateSectionPreview };
|
|
42511
42687
|
}
|
|
42512
42688
|
|
|
42513
42689
|
// src/resources/section/section.controller.ts
|
|
@@ -42523,7 +42699,10 @@ function useSectionController() {
|
|
|
42523
42699
|
removeStudentFromSection: _removeStudentFromSection,
|
|
42524
42700
|
deleteById: _deleteById
|
|
42525
42701
|
} = useSectionRepo();
|
|
42526
|
-
const {
|
|
42702
|
+
const {
|
|
42703
|
+
generateSections: _generateSections,
|
|
42704
|
+
generateSectionPreview: _generateSectionPreview
|
|
42705
|
+
} = useSectionService();
|
|
42527
42706
|
async function add(req, res, next) {
|
|
42528
42707
|
const value = req.body;
|
|
42529
42708
|
const { error } = schemaSection.validate(value);
|
|
@@ -42560,6 +42739,21 @@ function useSectionController() {
|
|
|
42560
42739
|
next(error2);
|
|
42561
42740
|
}
|
|
42562
42741
|
}
|
|
42742
|
+
async function generateSectionPreview(req, res, next) {
|
|
42743
|
+
const value = req.body;
|
|
42744
|
+
const { error } = schemaGenerateSections.validate(value);
|
|
42745
|
+
if (error) {
|
|
42746
|
+
next(new import_nodejs_utils70.BadRequestError(error.message));
|
|
42747
|
+
return;
|
|
42748
|
+
}
|
|
42749
|
+
try {
|
|
42750
|
+
const data = await _generateSectionPreview(value);
|
|
42751
|
+
res.json(data);
|
|
42752
|
+
return;
|
|
42753
|
+
} catch (error2) {
|
|
42754
|
+
next(error2);
|
|
42755
|
+
}
|
|
42756
|
+
}
|
|
42563
42757
|
async function getAll(req, res, next) {
|
|
42564
42758
|
const query = req.query;
|
|
42565
42759
|
const validation = import_joi43.default.object({
|
|
@@ -42751,6 +42945,7 @@ function useSectionController() {
|
|
|
42751
42945
|
return {
|
|
42752
42946
|
add,
|
|
42753
42947
|
generateSections,
|
|
42948
|
+
generateSectionPreview,
|
|
42754
42949
|
getAll,
|
|
42755
42950
|
getById,
|
|
42756
42951
|
getByName,
|