@eeplatform/basic-edu 1.4.3 → 1.5.1

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/dist/index.js CHANGED
@@ -1349,10 +1349,14 @@ __export(src_exports, {
1349
1349
  MLearner: () => MLearner,
1350
1350
  MPlantilla: () => MPlantilla,
1351
1351
  MStockCard: () => MStockCard,
1352
+ allowedSectionStudentStatuses: () => allowedSectionStudentStatuses,
1352
1353
  modelBasicEduCount: () => modelBasicEduCount,
1353
1354
  modelDivision: () => modelDivision,
1354
1355
  modelRegion: () => modelRegion,
1355
1356
  modelSchool: () => modelSchool,
1357
+ modelSection: () => modelSection,
1358
+ modelSectionPreset: () => modelSectionPreset,
1359
+ modelSectionStudent: () => modelSectionStudent,
1356
1360
  schemaAsset: () => schemaAsset,
1357
1361
  schemaAssetUpdateOption: () => schemaAssetUpdateOption,
1358
1362
  schemaBasicEduCount: () => schemaBasicEduCount,
@@ -1360,11 +1364,15 @@ __export(src_exports, {
1360
1364
  schemaDivision: () => schemaDivision,
1361
1365
  schemaDivisionUpdate: () => schemaDivisionUpdate,
1362
1366
  schemaEnrollment: () => schemaEnrollment,
1367
+ schemaGenerateSections: () => schemaGenerateSections,
1363
1368
  schemaGradeLevel: () => schemaGradeLevel,
1364
1369
  schemaPlantilla: () => schemaPlantilla,
1365
1370
  schemaRegion: () => schemaRegion,
1366
1371
  schemaSchool: () => schemaSchool,
1367
1372
  schemaSchoolUpdate: () => schemaSchoolUpdate,
1373
+ schemaSection: () => schemaSection,
1374
+ schemaSectionPreset: () => schemaSectionPreset,
1375
+ schemaSectionStudent: () => schemaSectionStudent,
1368
1376
  schemaStockCard: () => schemaStockCard,
1369
1377
  schemaUpdateStatus: () => schemaUpdateStatus,
1370
1378
  useAssetController: () => useAssetController,
@@ -1390,6 +1398,11 @@ __export(src_exports, {
1390
1398
  useSchoolController: () => useSchoolController,
1391
1399
  useSchoolRepo: () => useSchoolRepo,
1392
1400
  useSchoolService: () => useSchoolService,
1401
+ useSectionController: () => useSectionController,
1402
+ useSectionPresetController: () => useSectionPresetController,
1403
+ useSectionPresetRepo: () => useSectionPresetRepo,
1404
+ useSectionRepo: () => useSectionRepo,
1405
+ useSectionStudentRepo: () => useSectionStudentRepo,
1393
1406
  useStockCardController: () => useStockCardController,
1394
1407
  useStockCardRepository: () => useStockCardRepository,
1395
1408
  useStockCardService: () => useStockCardService
@@ -1466,7 +1479,7 @@ function useCurriculumRepo() {
1466
1479
  if (!db) {
1467
1480
  throw new Error("Unable to connect to server.");
1468
1481
  }
1469
- const namespace_collection = "school.curriculums";
1482
+ const namespace_collection = "deped.school.curriculums";
1470
1483
  const collection = db.collection(namespace_collection);
1471
1484
  const { getCache, setCache, delNamespace } = (0, import_nodejs_utils2.useCache)(namespace_collection);
1472
1485
  async function createIndexes() {
@@ -2388,6 +2401,7 @@ var import_nodejs_utils10 = require("@eeplatform/nodejs-utils");
2388
2401
  // src/resources/learner/learner.repository.ts
2389
2402
  var import_nodejs_utils6 = require("@eeplatform/nodejs-utils");
2390
2403
  var import_mongodb5 = require("mongodb");
2404
+ var import_joi5 = __toESM(require("joi"));
2391
2405
  function useLearnerRepo() {
2392
2406
  const db = import_nodejs_utils6.useAtlas.getDb();
2393
2407
  if (!db) {
@@ -2413,7 +2427,7 @@ function useLearnerRepo() {
2413
2427
  }
2414
2428
  ]);
2415
2429
  } catch (error) {
2416
- throw new Error("Failed to create index on enrollments.");
2430
+ throw new Error("Failed to create index on learners.");
2417
2431
  }
2418
2432
  }
2419
2433
  function delCachedData() {
@@ -2446,10 +2460,10 @@ function useLearnerRepo() {
2446
2460
  const isDuplicated = error.message.includes("duplicate");
2447
2461
  if (isDuplicated) {
2448
2462
  throw new import_nodejs_utils6.BadRequestError(
2449
- "Enrollment already exists for this learner and school year."
2463
+ "learner already exists for this learner and school year."
2450
2464
  );
2451
2465
  }
2452
- throw new Error("Failed to create enrollment.");
2466
+ throw new Error("Failed to create learner.");
2453
2467
  }
2454
2468
  }
2455
2469
  }
@@ -2461,61 +2475,50 @@ function useLearnerRepo() {
2461
2475
  status = "active",
2462
2476
  school = "",
2463
2477
  schoolYear = "",
2464
- gradeLevelToEnroll = ""
2478
+ level = ""
2465
2479
  } = {}) {
2466
2480
  page = page > 0 ? page - 1 : 0;
2467
2481
  const query = {
2468
2482
  status
2469
2483
  };
2484
+ const cacheParams = {
2485
+ status,
2486
+ page,
2487
+ limit,
2488
+ sort: JSON.stringify(sort)
2489
+ };
2470
2490
  if (school) {
2471
2491
  try {
2472
2492
  query.school = new import_mongodb5.ObjectId(school);
2493
+ cacheParams.school = school;
2473
2494
  } catch (error) {
2474
2495
  throw new import_nodejs_utils6.BadRequestError("Invalid school ID.");
2475
2496
  }
2476
2497
  }
2477
2498
  if (schoolYear) {
2478
2499
  query.schoolYear = schoolYear;
2500
+ cacheParams.schoolYear = schoolYear;
2479
2501
  }
2480
- if (gradeLevelToEnroll) {
2481
- query.gradeLevelToEnroll = gradeLevelToEnroll;
2502
+ if (level) {
2503
+ query.gradeLevel = level;
2504
+ cacheParams.level = level;
2482
2505
  }
2483
2506
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
2484
2507
  if (search) {
2485
- query.$or = [
2486
- { "learnerInfo.firstName": { $regex: search, $options: "i" } },
2487
- { "learnerInfo.lastName": { $regex: search, $options: "i" } },
2488
- { "learnerInfo.lrn": { $regex: search, $options: "i" } },
2489
- { schoolYear: { $regex: search, $options: "i" } },
2490
- { gradeLevelToEnroll: { $regex: search, $options: "i" } }
2491
- ];
2492
- }
2493
- const cacheParams = {
2494
- page,
2495
- limit,
2496
- sort: JSON.stringify(sort)
2497
- };
2498
- if (search)
2508
+ query.$text = { $search: search };
2499
2509
  cacheParams.search = search;
2500
- if (status !== "active")
2501
- cacheParams.status = status;
2502
- if (school)
2503
- cacheParams.school = school;
2504
- if (schoolYear)
2505
- cacheParams.schoolYear = schoolYear;
2506
- if (gradeLevelToEnroll)
2507
- cacheParams.gradeLevelToEnroll = gradeLevelToEnroll;
2510
+ }
2508
2511
  const cacheKey = (0, import_nodejs_utils6.makeCacheKey)(namespace_collection, cacheParams);
2509
2512
  import_nodejs_utils6.logger.log({
2510
2513
  level: "info",
2511
- message: `Cache key for getAll enrollments: ${cacheKey}`
2514
+ message: `Cache key for getAll learners: ${cacheKey}`
2512
2515
  });
2513
2516
  try {
2514
2517
  const cached = await getCache(cacheKey);
2515
2518
  if (cached) {
2516
2519
  import_nodejs_utils6.logger.log({
2517
2520
  level: "info",
2518
- message: `Cache hit for getAll enrollments: ${cacheKey}`
2521
+ message: `Cache hit for getAll learners: ${cacheKey}`
2519
2522
  });
2520
2523
  return cached;
2521
2524
  }
@@ -2531,12 +2534,12 @@ function useLearnerRepo() {
2531
2534
  setCache(cacheKey, data, 600).then(() => {
2532
2535
  import_nodejs_utils6.logger.log({
2533
2536
  level: "info",
2534
- message: `Cache set for getAll enrollments: ${cacheKey}`
2537
+ message: `Cache set for getAll learners: ${cacheKey}`
2535
2538
  });
2536
2539
  }).catch((err) => {
2537
2540
  import_nodejs_utils6.logger.log({
2538
2541
  level: "error",
2539
- message: `Failed to set cache for getAll enrollments: ${err.message}`
2542
+ message: `Failed to set cache for getAll learners: ${err.message}`
2540
2543
  });
2541
2544
  });
2542
2545
  return data;
@@ -2545,6 +2548,62 @@ function useLearnerRepo() {
2545
2548
  throw error;
2546
2549
  }
2547
2550
  }
2551
+ async function getCountByGradeLevel(value, session) {
2552
+ const validation = import_joi5.default.object({
2553
+ school: import_joi5.default.string().hex().required(),
2554
+ schoolYear: import_joi5.default.string().required(),
2555
+ gradeLevel: import_joi5.default.string().required(),
2556
+ status: import_joi5.default.string().optional()
2557
+ });
2558
+ const { error } = validation.validate(value);
2559
+ if (error) {
2560
+ throw new import_nodejs_utils6.BadRequestError(`Invalid data: ${error.message}`);
2561
+ }
2562
+ const status = value.status ?? "active";
2563
+ const query = {
2564
+ schoolYear: value.schoolYear,
2565
+ gradeLevel: value.gradeLevel,
2566
+ status
2567
+ };
2568
+ const cacheKeyOptions = {
2569
+ ...query,
2570
+ tag: "countByGradeLevel"
2571
+ };
2572
+ if (value.school && typeof value.school === "string") {
2573
+ try {
2574
+ query.school = new import_mongodb5.ObjectId(value.school);
2575
+ } catch (error2) {
2576
+ throw new import_nodejs_utils6.BadRequestError("Invalid school ID.");
2577
+ }
2578
+ cacheKeyOptions.school = value.school.toString();
2579
+ }
2580
+ const cacheKey = (0, import_nodejs_utils6.makeCacheKey)(namespace_collection, cacheKeyOptions);
2581
+ const cachedData = await getCache(cacheKey);
2582
+ if (cachedData !== void 0 && cachedData !== null) {
2583
+ import_nodejs_utils6.logger.log({
2584
+ level: "info",
2585
+ message: `Cache hit for learner count by grade level: ${cacheKey}`
2586
+ });
2587
+ return cachedData;
2588
+ }
2589
+ try {
2590
+ const count = await collection.countDocuments(query, { session });
2591
+ setCache(cacheKey, count, 600).then(() => {
2592
+ import_nodejs_utils6.logger.log({
2593
+ level: "info",
2594
+ message: `Cache set for learner count by grade level: ${cacheKey}`
2595
+ });
2596
+ }).catch((err) => {
2597
+ import_nodejs_utils6.logger.log({
2598
+ level: "error",
2599
+ message: `Failed to set cache for learner count by grade level: ${err.message}`
2600
+ });
2601
+ });
2602
+ return count;
2603
+ } catch (error2) {
2604
+ throw new import_nodejs_utils6.BadRequestError("Failed to get learner count by grade level.");
2605
+ }
2606
+ }
2548
2607
  async function getById(_id, status = "") {
2549
2608
  try {
2550
2609
  _id = new import_mongodb5.ObjectId(_id);
@@ -2562,7 +2621,7 @@ function useLearnerRepo() {
2562
2621
  if (cachedData) {
2563
2622
  import_nodejs_utils6.logger.log({
2564
2623
  level: "info",
2565
- message: `Cache hit for enrollment by ID: ${cacheKey}`
2624
+ message: `Cache hit for learner by ID: ${cacheKey}`
2566
2625
  });
2567
2626
  return cachedData;
2568
2627
  }
@@ -2571,17 +2630,80 @@ function useLearnerRepo() {
2571
2630
  setCache(cacheKey, data, 600).then(() => {
2572
2631
  import_nodejs_utils6.logger.log({
2573
2632
  level: "info",
2574
- message: `Cache set for enrollment by ID: ${cacheKey}`
2633
+ message: `Cache set for learner by ID: ${cacheKey}`
2575
2634
  });
2576
2635
  }).catch((err) => {
2577
2636
  import_nodejs_utils6.logger.log({
2578
2637
  level: "error",
2579
- message: `Failed to set cache for enrollment by ID: ${err.message}`
2638
+ message: `Failed to set cache for learner by ID: ${err.message}`
2580
2639
  });
2581
2640
  });
2582
2641
  return data;
2583
2642
  } catch (error) {
2584
- throw new import_nodejs_utils6.BadRequestError("Failed to get enrollment by ID.");
2643
+ throw new import_nodejs_utils6.BadRequestError("Failed to get learner by ID.");
2644
+ }
2645
+ }
2646
+ async function getByGradeLevel(value, session) {
2647
+ const validation = import_joi5.default.object({
2648
+ school: import_joi5.default.string().hex().required(),
2649
+ gradeLevel: import_joi5.default.string().required(),
2650
+ status: import_joi5.default.string().optional().allow("", null),
2651
+ limit: import_joi5.default.number().integer().required(),
2652
+ skip: import_joi5.default.number().integer().required()
2653
+ });
2654
+ const { error } = validation.validate(value);
2655
+ if (error) {
2656
+ throw new import_nodejs_utils6.BadRequestError(`Invalid data: ${error.message}`);
2657
+ }
2658
+ const status = value.status ?? "active";
2659
+ const query = {
2660
+ gradeLevel: value.gradeLevel,
2661
+ status
2662
+ };
2663
+ const cacheKeyOptions = {
2664
+ ...query,
2665
+ tag: "byGradeLevel"
2666
+ };
2667
+ if (value.school && typeof value.school === "string") {
2668
+ try {
2669
+ query.school = new import_mongodb5.ObjectId(value.school);
2670
+ } catch (error2) {
2671
+ throw new import_nodejs_utils6.BadRequestError("Invalid school ID.");
2672
+ }
2673
+ cacheKeyOptions.school = value.school.toString();
2674
+ }
2675
+ const cacheKey = (0, import_nodejs_utils6.makeCacheKey)(namespace_collection, cacheKeyOptions);
2676
+ const cachedData = await getCache(cacheKey);
2677
+ if (cachedData) {
2678
+ import_nodejs_utils6.logger.log({
2679
+ level: "info",
2680
+ message: `Cache hit for learner by ID: ${cacheKey}`
2681
+ });
2682
+ return cachedData;
2683
+ }
2684
+ try {
2685
+ const data = await collection.aggregate(
2686
+ [
2687
+ { $match: query },
2688
+ { $skip: value.skip ?? 0 },
2689
+ { $limit: value.limit ?? 100 }
2690
+ ],
2691
+ { session }
2692
+ ).toArray();
2693
+ setCache(cacheKey, data, 600).then(() => {
2694
+ import_nodejs_utils6.logger.log({
2695
+ level: "info",
2696
+ message: `Cache set for learner by ID: ${cacheKey}`
2697
+ });
2698
+ }).catch((err) => {
2699
+ import_nodejs_utils6.logger.log({
2700
+ level: "error",
2701
+ message: `Failed to set cache for learner by ID: ${err.message}`
2702
+ });
2703
+ });
2704
+ return data;
2705
+ } catch (error2) {
2706
+ throw new import_nodejs_utils6.BadRequestError("Failed to get learner by ID.");
2585
2707
  }
2586
2708
  }
2587
2709
  async function updateStatusById(_id, status, session) {
@@ -2599,33 +2721,35 @@ function useLearnerRepo() {
2599
2721
  delCachedData();
2600
2722
  return result;
2601
2723
  } catch (error) {
2602
- throw new Error("Failed to update enrollment status.");
2724
+ throw new Error("Failed to update learner status.");
2603
2725
  }
2604
2726
  }
2605
2727
  return {
2606
2728
  createIndexes,
2607
2729
  add,
2608
2730
  getAll,
2731
+ getCountByGradeLevel,
2609
2732
  updateStatusById,
2610
- getById
2733
+ getById,
2734
+ getByGradeLevel
2611
2735
  };
2612
2736
  }
2613
2737
 
2614
2738
  // src/resources/learner/learner.controller.ts
2615
2739
  var import_nodejs_utils7 = require("@eeplatform/nodejs-utils");
2616
- var import_joi5 = __toESM(require("joi"));
2740
+ var import_joi6 = __toESM(require("joi"));
2617
2741
  function useLearnerController() {
2618
2742
  const { getAll: _getAll, updateStatusById: _updateStatusById } = useLearnerRepo();
2619
2743
  async function getAll(req, res, next) {
2620
2744
  const query = req.query;
2621
- const validation = import_joi5.default.object({
2622
- page: import_joi5.default.number().min(1).optional().allow("", null),
2623
- limit: import_joi5.default.number().min(1).max(100).optional().allow("", null),
2624
- search: import_joi5.default.string().optional().allow("", null),
2625
- status: import_joi5.default.string().optional().allow("", null),
2626
- school: import_joi5.default.string().hex().optional().allow("", null),
2627
- schoolYear: import_joi5.default.string().optional().allow("", null),
2628
- gradeLevelToEnroll: import_joi5.default.string().optional().allow("", null)
2745
+ const validation = import_joi6.default.object({
2746
+ page: import_joi6.default.number().min(1).optional().allow("", null),
2747
+ limit: import_joi6.default.number().min(1).max(100).optional().allow("", null),
2748
+ search: import_joi6.default.string().optional().allow("", null),
2749
+ status: import_joi6.default.string().optional().allow("", null),
2750
+ school: import_joi6.default.string().hex().optional().allow("", null),
2751
+ schoolYear: import_joi6.default.string().optional().allow("", null),
2752
+ level: import_joi6.default.string().optional().allow("", null)
2629
2753
  });
2630
2754
  const { error } = validation.validate(query);
2631
2755
  if (error) {
@@ -2635,6 +2759,11 @@ function useLearnerController() {
2635
2759
  const page = parseInt(req.query.page) ?? 1;
2636
2760
  let limit = parseInt(req.query.limit) ?? 20;
2637
2761
  limit = isNaN(limit) ? 20 : limit;
2762
+ const level = req.query.level ?? "";
2763
+ const search = req.query.search ?? "";
2764
+ const status = req.query.status ?? "";
2765
+ const school = req.query.school ?? "";
2766
+ const schoolYear = req.query.schoolYear ?? "";
2638
2767
  const sort = req.query.sort ? String(req.query.sort).split(",") : "";
2639
2768
  const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
2640
2769
  const sortObj = {};
@@ -2649,11 +2778,11 @@ function useLearnerController() {
2649
2778
  page,
2650
2779
  limit,
2651
2780
  sort: sortObj,
2652
- search: req.query.search,
2653
- status: req.query.status,
2654
- school: req.query.school,
2655
- schoolYear: req.query.schoolYear,
2656
- gradeLevelToEnroll: req.query.gradeLevelToEnroll
2781
+ search,
2782
+ status,
2783
+ school,
2784
+ schoolYear,
2785
+ level
2657
2786
  });
2658
2787
  res.json(result);
2659
2788
  return;
@@ -2687,11 +2816,11 @@ var import_nodejs_utils9 = require("@eeplatform/nodejs-utils");
2687
2816
 
2688
2817
  // src/resources/count/count.model.ts
2689
2818
  var import_nodejs_utils8 = require("@eeplatform/nodejs-utils");
2690
- var import_joi6 = __toESM(require("joi"));
2691
- var schemaBasicEduCount = import_joi6.default.object({
2692
- _id: import_joi6.default.string().hex().length(24).optional(),
2693
- name: import_joi6.default.string().required(),
2694
- count: import_joi6.default.number().min(0).required()
2819
+ var import_joi7 = __toESM(require("joi"));
2820
+ var schemaBasicEduCount = import_joi7.default.object({
2821
+ _id: import_joi7.default.string().hex().length(24).optional(),
2822
+ name: import_joi7.default.string().required(),
2823
+ count: import_joi7.default.number().min(0).required()
2695
2824
  });
2696
2825
  function modelBasicEduCount(value) {
2697
2826
  const { error } = schemaBasicEduCount.validate(value);
@@ -3029,7 +3158,7 @@ function useEnrollmentService() {
3029
3158
 
3030
3159
  // src/resources/enrollment/enrollment.controller.ts
3031
3160
  var import_nodejs_utils11 = require("@eeplatform/nodejs-utils");
3032
- var import_joi7 = __toESM(require("joi"));
3161
+ var import_joi8 = __toESM(require("joi"));
3033
3162
  function useEnrollmentController() {
3034
3163
  const { add: _add, updateStatusById: _updateStatusById } = useEnrollmentService();
3035
3164
  const { getAll: _getAll } = useEnrollmentRepo();
@@ -3051,15 +3180,15 @@ function useEnrollmentController() {
3051
3180
  }
3052
3181
  async function getAll(req, res, next) {
3053
3182
  const query = req.query;
3054
- const validation = import_joi7.default.object({
3055
- page: import_joi7.default.number().min(1).optional().allow("", null),
3056
- limit: import_joi7.default.number().min(1).max(100).optional().allow("", null),
3057
- search: import_joi7.default.string().optional().allow("", null),
3058
- status: import_joi7.default.string().optional().allow("", null),
3059
- school: import_joi7.default.string().hex().optional().allow("", null),
3060
- schoolYear: import_joi7.default.string().optional().allow("", null),
3061
- gradeLevelToEnroll: import_joi7.default.string().optional().allow("", null),
3062
- createdBy: import_joi7.default.string().hex().optional().allow("", null)
3183
+ const validation = import_joi8.default.object({
3184
+ page: import_joi8.default.number().min(1).optional().allow("", null),
3185
+ limit: import_joi8.default.number().min(1).max(100).optional().allow("", null),
3186
+ search: import_joi8.default.string().optional().allow("", null),
3187
+ status: import_joi8.default.string().optional().allow("", null),
3188
+ school: import_joi8.default.string().hex().optional().allow("", null),
3189
+ schoolYear: import_joi8.default.string().optional().allow("", null),
3190
+ gradeLevelToEnroll: import_joi8.default.string().optional().allow("", null),
3191
+ createdBy: import_joi8.default.string().hex().optional().allow("", null)
3063
3192
  });
3064
3193
  const { error } = validation.validate(query);
3065
3194
  if (error) {
@@ -3121,26 +3250,27 @@ function useEnrollmentController() {
3121
3250
 
3122
3251
  // src/resources/grade-level/grade-level.model.ts
3123
3252
  var import_nodejs_utils12 = require("@eeplatform/nodejs-utils");
3124
- var import_joi8 = __toESM(require("joi"));
3253
+ var import_joi9 = __toESM(require("joi"));
3125
3254
  var import_mongodb7 = require("mongodb");
3126
- var schemaGradeLevel = import_joi8.default.object({
3127
- _id: import_joi8.default.string().hex().optional(),
3128
- school: import_joi8.default.string().hex().optional(),
3129
- educationLevel: import_joi8.default.string().required(),
3130
- gradeLevel: import_joi8.default.string().required(),
3131
- tracks: import_joi8.default.array().items(import_joi8.default.string()).optional(),
3132
- trackStrands: import_joi8.default.array().items(import_joi8.default.string()).optional(),
3133
- teachingStyle: import_joi8.default.string().required(),
3134
- maxNumberOfLearners: import_joi8.default.number().required(),
3135
- defaultStartTime: import_joi8.default.string().optional().allow("", null),
3136
- defaultEndTime: import_joi8.default.string().optional().allow("", null),
3137
- status: import_joi8.default.string().optional().allow("", null),
3138
- createdAt: import_joi8.default.date().optional().allow("", null),
3139
- updatedAt: import_joi8.default.date().optional().allow("", null),
3140
- deletedAt: import_joi8.default.date().optional().allow("", null),
3141
- createdBy: import_joi8.default.string().optional().allow("", null),
3142
- updatedBy: import_joi8.default.string().optional().allow("", null),
3143
- deletedBy: import_joi8.default.string().optional().allow("", null)
3255
+ var schemaGradeLevel = import_joi9.default.object({
3256
+ _id: import_joi9.default.string().hex().optional(),
3257
+ school: import_joi9.default.string().hex().optional(),
3258
+ educationLevel: import_joi9.default.string().required(),
3259
+ gradeLevel: import_joi9.default.string().required(),
3260
+ tracks: import_joi9.default.array().items(import_joi9.default.string()).optional(),
3261
+ trackStrands: import_joi9.default.array().items(import_joi9.default.string()).optional(),
3262
+ teachingStyle: import_joi9.default.string().required(),
3263
+ maxNumberOfLearners: import_joi9.default.number().required(),
3264
+ minNumberOfLearners: import_joi9.default.number().required(),
3265
+ defaultStartTime: import_joi9.default.string().optional().allow("", null),
3266
+ defaultEndTime: import_joi9.default.string().optional().allow("", null),
3267
+ status: import_joi9.default.string().optional().allow("", null),
3268
+ createdAt: import_joi9.default.date().optional().allow("", null),
3269
+ updatedAt: import_joi9.default.date().optional().allow("", null),
3270
+ deletedAt: import_joi9.default.date().optional().allow("", null),
3271
+ createdBy: import_joi9.default.string().optional().allow("", null),
3272
+ updatedBy: import_joi9.default.string().optional().allow("", null),
3273
+ deletedBy: import_joi9.default.string().optional().allow("", null)
3144
3274
  });
3145
3275
  function MGradeLevel(value) {
3146
3276
  const { error } = schemaGradeLevel.validate(value);
@@ -3162,6 +3292,11 @@ function MGradeLevel(value) {
3162
3292
  throw new import_nodejs_utils12.BadRequestError("Invalid school format");
3163
3293
  }
3164
3294
  }
3295
+ if (value.minNumberOfLearners > value.maxNumberOfLearners) {
3296
+ throw new import_nodejs_utils12.BadRequestError(
3297
+ "Minimum number of learners cannot be greater than maximum number of learners."
3298
+ );
3299
+ }
3165
3300
  return {
3166
3301
  _id: value._id ?? void 0,
3167
3302
  school: value.school ?? void 0,
@@ -3171,6 +3306,7 @@ function MGradeLevel(value) {
3171
3306
  trackStrands: value.trackStrands ?? [],
3172
3307
  teachingStyle: value.teachingStyle ?? "",
3173
3308
  maxNumberOfLearners: value.maxNumberOfLearners ?? 0,
3309
+ minNumberOfLearners: value.minNumberOfLearners ?? 0,
3174
3310
  defaultStartTime: value.defaultStartTime ?? "",
3175
3311
  defaultEndTime: value.defaultEndTime ?? "",
3176
3312
  status: value.status ?? "active",
@@ -3191,7 +3327,7 @@ function useGradeLevelRepo() {
3191
3327
  if (!db) {
3192
3328
  throw new Error("Unable to connect to server.");
3193
3329
  }
3194
- const namespace_collection = "school.grade-levels";
3330
+ const namespace_collection = "deped.school.grade-levels";
3195
3331
  const collection = db.collection(namespace_collection);
3196
3332
  const { getCache, setCache, delNamespace } = (0, import_nodejs_utils13.useCache)(namespace_collection);
3197
3333
  async function createIndexes() {
@@ -3350,25 +3486,7 @@ function useGradeLevelRepo() {
3350
3486
  { $match: query },
3351
3487
  { $sort: sort },
3352
3488
  { $skip: page * limit },
3353
- { $limit: limit },
3354
- {
3355
- $lookup: {
3356
- from: "school.schools",
3357
- localField: "school",
3358
- foreignField: "_id",
3359
- as: "schoolDetails"
3360
- }
3361
- },
3362
- {
3363
- $addFields: {
3364
- schoolName: { $arrayElemAt: ["$schoolDetails.name", 0] }
3365
- }
3366
- },
3367
- {
3368
- $project: {
3369
- schoolDetails: 0
3370
- }
3371
- }
3489
+ { $limit: limit }
3372
3490
  ]).toArray();
3373
3491
  const length = await collection.countDocuments(query);
3374
3492
  const data = (0, import_nodejs_utils13.paginate)(items, page, limit, length);
@@ -3517,6 +3635,52 @@ function useGradeLevelRepo() {
3517
3635
  throw error;
3518
3636
  }
3519
3637
  }
3638
+ async function getByGradeLevel(value, session) {
3639
+ const status = value.status ?? "active";
3640
+ const query = {
3641
+ gradeLevel: value.gradeLevel,
3642
+ status
3643
+ };
3644
+ const cacheKeyOptions = {
3645
+ gradeLevel: value.gradeLevel,
3646
+ status
3647
+ };
3648
+ if (value.school) {
3649
+ try {
3650
+ query.school = new import_mongodb8.ObjectId(value.school);
3651
+ } catch (error) {
3652
+ throw new import_nodejs_utils13.BadRequestError("Invalid school ID format.");
3653
+ }
3654
+ cacheKeyOptions.school = value.school;
3655
+ }
3656
+ const cacheKey = (0, import_nodejs_utils13.makeCacheKey)(namespace_collection, cacheKeyOptions);
3657
+ try {
3658
+ const cached = await getCache(cacheKey);
3659
+ if (cached) {
3660
+ import_nodejs_utils13.logger.log({
3661
+ level: "info",
3662
+ message: `Cache hit for getByGradeLevel: ${cacheKey}`
3663
+ });
3664
+ return cached;
3665
+ }
3666
+ const result = await collection.findOne(query, { session });
3667
+ setCache(cacheKey, result, 300).then(() => {
3668
+ import_nodejs_utils13.logger.log({
3669
+ level: "info",
3670
+ message: `Cache set for getByGradeLevel: ${cacheKey}`
3671
+ });
3672
+ }).catch((err) => {
3673
+ import_nodejs_utils13.logger.log({
3674
+ level: "error",
3675
+ message: `Failed to set cache for getByGradeLevel: ${err.message}`
3676
+ });
3677
+ });
3678
+ return result;
3679
+ } catch (error) {
3680
+ import_nodejs_utils13.logger.log({ level: "error", message: `${error}` });
3681
+ throw error;
3682
+ }
3683
+ }
3520
3684
  function delCachedData() {
3521
3685
  delNamespace().then(() => {
3522
3686
  import_nodejs_utils13.logger.log({
@@ -3537,13 +3701,14 @@ function useGradeLevelRepo() {
3537
3701
  getById,
3538
3702
  updateById,
3539
3703
  deleteById,
3540
- getByEducationLevel
3704
+ getByEducationLevel,
3705
+ getByGradeLevel
3541
3706
  };
3542
3707
  }
3543
3708
 
3544
3709
  // src/resources/grade-level/grade-level.controller.ts
3545
3710
  var import_nodejs_utils14 = require("@eeplatform/nodejs-utils");
3546
- var import_joi9 = __toESM(require("joi"));
3711
+ var import_joi10 = __toESM(require("joi"));
3547
3712
  function useGradeLevelController() {
3548
3713
  const {
3549
3714
  getAll: _getAll,
@@ -3575,17 +3740,17 @@ function useGradeLevelController() {
3575
3740
  async function updateById(req, res, next) {
3576
3741
  const value = req.body;
3577
3742
  const id = req.params.id ?? "";
3578
- const validation = import_joi9.default.object({
3579
- id: import_joi9.default.string().hex().required(),
3580
- value: import_joi9.default.object({
3581
- school: import_joi9.default.string().hex().optional(),
3582
- educationLevel: import_joi9.default.string().optional(),
3583
- gradeLevel: import_joi9.default.string().optional(),
3584
- teachingStyle: import_joi9.default.string().optional(),
3585
- maxTeachingHoursPerDay: import_joi9.default.number().integer().min(0).optional(),
3586
- maxTeachingHoursPerWeek: import_joi9.default.number().integer().min(0).optional(),
3587
- defaultStartTime: import_joi9.default.string().optional().allow("", null),
3588
- defaultEndTime: import_joi9.default.string().optional().allow("", null)
3743
+ const validation = import_joi10.default.object({
3744
+ id: import_joi10.default.string().hex().required(),
3745
+ value: import_joi10.default.object({
3746
+ school: import_joi10.default.string().hex().optional(),
3747
+ educationLevel: import_joi10.default.string().optional(),
3748
+ gradeLevel: import_joi10.default.string().optional(),
3749
+ teachingStyle: import_joi10.default.string().optional(),
3750
+ maxTeachingHoursPerDay: import_joi10.default.number().integer().min(0).optional(),
3751
+ maxTeachingHoursPerWeek: import_joi10.default.number().integer().min(0).optional(),
3752
+ defaultStartTime: import_joi10.default.string().optional().allow("", null),
3753
+ defaultEndTime: import_joi10.default.string().optional().allow("", null)
3589
3754
  }).min(1)
3590
3755
  });
3591
3756
  const { error } = validation.validate({ id, value });
@@ -3607,15 +3772,15 @@ function useGradeLevelController() {
3607
3772
  }
3608
3773
  async function getAll(req, res, next) {
3609
3774
  const query = req.query;
3610
- const validation = import_joi9.default.object({
3611
- page: import_joi9.default.number().min(1).optional().allow("", null),
3612
- limit: import_joi9.default.number().min(1).optional().allow("", null),
3613
- search: import_joi9.default.string().optional().allow("", null),
3614
- educationLevel: import_joi9.default.string().optional().allow("", null),
3615
- gradeLevel: import_joi9.default.string().optional().allow("", null),
3616
- teachingStyle: import_joi9.default.string().optional().allow("", null),
3617
- school: import_joi9.default.string().hex().optional().allow("", null),
3618
- status: import_joi9.default.string().optional().allow("", null)
3775
+ const validation = import_joi10.default.object({
3776
+ page: import_joi10.default.number().min(1).optional().allow("", null),
3777
+ limit: import_joi10.default.number().min(1).optional().allow("", null),
3778
+ search: import_joi10.default.string().optional().allow("", null),
3779
+ educationLevel: import_joi10.default.string().optional().allow("", null),
3780
+ gradeLevel: import_joi10.default.string().optional().allow("", null),
3781
+ teachingStyle: import_joi10.default.string().optional().allow("", null),
3782
+ school: import_joi10.default.string().hex().optional().allow("", null),
3783
+ status: import_joi10.default.string().optional().allow("", null)
3619
3784
  });
3620
3785
  const { error } = validation.validate(query);
3621
3786
  if (error) {
@@ -3659,8 +3824,8 @@ function useGradeLevelController() {
3659
3824
  }
3660
3825
  async function getById(req, res, next) {
3661
3826
  const id = req.params.id;
3662
- const validation = import_joi9.default.object({
3663
- id: import_joi9.default.string().hex().required()
3827
+ const validation = import_joi10.default.object({
3828
+ id: import_joi10.default.string().hex().required()
3664
3829
  });
3665
3830
  const { error } = validation.validate({ id });
3666
3831
  if (error) {
@@ -3680,8 +3845,8 @@ function useGradeLevelController() {
3680
3845
  }
3681
3846
  async function deleteById(req, res, next) {
3682
3847
  const id = req.params.id;
3683
- const validation = import_joi9.default.object({
3684
- id: import_joi9.default.string().hex().required()
3848
+ const validation = import_joi10.default.object({
3849
+ id: import_joi10.default.string().hex().required()
3685
3850
  });
3686
3851
  const { error } = validation.validate({ id });
3687
3852
  if (error) {
@@ -3702,9 +3867,9 @@ function useGradeLevelController() {
3702
3867
  async function getByEducationLevel(req, res, next) {
3703
3868
  const educationLevel = req.params.educationLevel;
3704
3869
  const school = req.query.school;
3705
- const validation = import_joi9.default.object({
3706
- educationLevel: import_joi9.default.string().required(),
3707
- school: import_joi9.default.string().hex().optional().allow("", null)
3870
+ const validation = import_joi10.default.object({
3871
+ educationLevel: import_joi10.default.string().required(),
3872
+ school: import_joi10.default.string().hex().optional().allow("", null)
3708
3873
  });
3709
3874
  const { error } = validation.validate({ educationLevel, school });
3710
3875
  if (error) {
@@ -3734,14 +3899,14 @@ function useGradeLevelController() {
3734
3899
 
3735
3900
  // src/resources/region/region.model.ts
3736
3901
  var import_nodejs_utils15 = require("@eeplatform/nodejs-utils");
3737
- var import_joi10 = __toESM(require("joi"));
3902
+ var import_joi11 = __toESM(require("joi"));
3738
3903
  var import_mongodb9 = require("mongodb");
3739
- var schemaRegion = import_joi10.default.object({
3740
- _id: import_joi10.default.string().hex().optional().allow(null, ""),
3741
- name: import_joi10.default.string().min(1).max(100).required(),
3742
- createdAt: import_joi10.default.string().isoDate().optional(),
3743
- updatedAt: import_joi10.default.string().isoDate().optional(),
3744
- deletedAt: import_joi10.default.string().isoDate().optional().allow(null, "")
3904
+ var schemaRegion = import_joi11.default.object({
3905
+ _id: import_joi11.default.string().hex().optional().allow(null, ""),
3906
+ name: import_joi11.default.string().min(1).max(100).required(),
3907
+ createdAt: import_joi11.default.string().isoDate().optional(),
3908
+ updatedAt: import_joi11.default.string().isoDate().optional(),
3909
+ deletedAt: import_joi11.default.string().isoDate().optional().allow(null, "")
3745
3910
  });
3746
3911
  function modelRegion(value) {
3747
3912
  const { error } = schemaRegion.validate(value);
@@ -4020,7 +4185,7 @@ function useRegionRepo() {
4020
4185
 
4021
4186
  // src/resources/region/region.controller.ts
4022
4187
  var import_nodejs_utils17 = require("@eeplatform/nodejs-utils");
4023
- var import_joi11 = __toESM(require("joi"));
4188
+ var import_joi12 = __toESM(require("joi"));
4024
4189
  function useRegionController() {
4025
4190
  const {
4026
4191
  add: _add,
@@ -4050,11 +4215,11 @@ function useRegionController() {
4050
4215
  }
4051
4216
  async function getAll(req, res, next) {
4052
4217
  const query = req.query;
4053
- const validation = import_joi11.default.object({
4054
- page: import_joi11.default.number().min(1).optional().allow("", null),
4055
- limit: import_joi11.default.number().min(1).optional().allow("", null),
4056
- search: import_joi11.default.string().optional().allow("", null),
4057
- status: import_joi11.default.string().optional().allow("", null)
4218
+ const validation = import_joi12.default.object({
4219
+ page: import_joi12.default.number().min(1).optional().allow("", null),
4220
+ limit: import_joi12.default.number().min(1).optional().allow("", null),
4221
+ search: import_joi12.default.string().optional().allow("", null),
4222
+ status: import_joi12.default.string().optional().allow("", null)
4058
4223
  });
4059
4224
  const { error } = validation.validate(query);
4060
4225
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -4085,8 +4250,8 @@ function useRegionController() {
4085
4250
  }
4086
4251
  async function getById(req, res, next) {
4087
4252
  const id = req.params.id;
4088
- const validation = import_joi11.default.object({
4089
- id: import_joi11.default.string().hex().required()
4253
+ const validation = import_joi12.default.object({
4254
+ id: import_joi12.default.string().hex().required()
4090
4255
  });
4091
4256
  const { error } = validation.validate({ id });
4092
4257
  if (error) {
@@ -4106,8 +4271,8 @@ function useRegionController() {
4106
4271
  }
4107
4272
  async function getByName(req, res, next) {
4108
4273
  const name = req.params.name;
4109
- const validation = import_joi11.default.object({
4110
- name: import_joi11.default.string().required()
4274
+ const validation = import_joi12.default.object({
4275
+ name: import_joi12.default.string().required()
4111
4276
  });
4112
4277
  const { error } = validation.validate({ name });
4113
4278
  if (error) {
@@ -4128,10 +4293,10 @@ function useRegionController() {
4128
4293
  async function updateField(req, res, next) {
4129
4294
  const _id = req.params.id;
4130
4295
  const { field, value } = req.body;
4131
- const validation = import_joi11.default.object({
4132
- _id: import_joi11.default.string().hex().required(),
4133
- field: import_joi11.default.string().valid("name", "director", "directorName").required(),
4134
- value: import_joi11.default.string().required()
4296
+ const validation = import_joi12.default.object({
4297
+ _id: import_joi12.default.string().hex().required(),
4298
+ field: import_joi12.default.string().valid("name", "director", "directorName").required(),
4299
+ value: import_joi12.default.string().required()
4135
4300
  });
4136
4301
  const { error } = validation.validate({ _id, field, value });
4137
4302
  if (error) {
@@ -4148,8 +4313,8 @@ function useRegionController() {
4148
4313
  }
4149
4314
  async function deleteById(req, res, next) {
4150
4315
  const _id = req.params.id;
4151
- const validation = import_joi11.default.object({
4152
- _id: import_joi11.default.string().hex().required()
4316
+ const validation = import_joi12.default.object({
4317
+ _id: import_joi12.default.string().hex().required()
4153
4318
  });
4154
4319
  const { error } = validation.validate({ _id });
4155
4320
  if (error) {
@@ -4176,26 +4341,26 @@ function useRegionController() {
4176
4341
 
4177
4342
  // src/resources/division/division.model.ts
4178
4343
  var import_nodejs_utils18 = require("@eeplatform/nodejs-utils");
4179
- var import_joi12 = __toESM(require("joi"));
4344
+ var import_joi13 = __toESM(require("joi"));
4180
4345
  var import_mongodb11 = require("mongodb");
4181
- var schemaDivision = import_joi12.default.object({
4182
- _id: import_joi12.default.string().hex().optional().allow(null, ""),
4183
- name: import_joi12.default.string().min(1).max(100).required(),
4184
- region: import_joi12.default.string().hex().required(),
4185
- regionName: import_joi12.default.string().min(1).max(100).required(),
4186
- superintendent: import_joi12.default.string().hex().optional().allow(null, ""),
4187
- superintendentName: import_joi12.default.string().min(1).max(100).optional().allow(null, ""),
4188
- createdAt: import_joi12.default.string().isoDate().optional(),
4189
- updatedAt: import_joi12.default.string().isoDate().optional(),
4190
- deletedAt: import_joi12.default.string().isoDate().optional().allow(null, "")
4346
+ var schemaDivision = import_joi13.default.object({
4347
+ _id: import_joi13.default.string().hex().optional().allow(null, ""),
4348
+ name: import_joi13.default.string().min(1).max(100).required(),
4349
+ region: import_joi13.default.string().hex().required(),
4350
+ regionName: import_joi13.default.string().min(1).max(100).required(),
4351
+ superintendent: import_joi13.default.string().hex().optional().allow(null, ""),
4352
+ superintendentName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4353
+ createdAt: import_joi13.default.string().isoDate().optional(),
4354
+ updatedAt: import_joi13.default.string().isoDate().optional(),
4355
+ deletedAt: import_joi13.default.string().isoDate().optional().allow(null, "")
4191
4356
  });
4192
- var schemaDivisionUpdate = import_joi12.default.object({
4193
- _id: import_joi12.default.string().hex().optional().allow(null, ""),
4194
- name: import_joi12.default.string().min(1).max(100).required(),
4195
- region: import_joi12.default.string().hex().required(),
4196
- regionName: import_joi12.default.string().min(1).max(100).required(),
4197
- superintendent: import_joi12.default.string().hex().optional().allow(null, ""),
4198
- superintendentName: import_joi12.default.string().min(1).max(100).optional().allow(null, "")
4357
+ var schemaDivisionUpdate = import_joi13.default.object({
4358
+ _id: import_joi13.default.string().hex().optional().allow(null, ""),
4359
+ name: import_joi13.default.string().min(1).max(100).required(),
4360
+ region: import_joi13.default.string().hex().required(),
4361
+ regionName: import_joi13.default.string().min(1).max(100).required(),
4362
+ superintendent: import_joi13.default.string().hex().optional().allow(null, ""),
4363
+ superintendentName: import_joi13.default.string().min(1).max(100).optional().allow(null, "")
4199
4364
  });
4200
4365
  function modelDivision(value) {
4201
4366
  const { error } = schemaDivision.validate(value);
@@ -4541,49 +4706,49 @@ var import_core2 = require("@eeplatform/core");
4541
4706
 
4542
4707
  // src/resources/school/school.model.ts
4543
4708
  var import_nodejs_utils20 = require("@eeplatform/nodejs-utils");
4544
- var import_joi13 = __toESM(require("joi"));
4709
+ var import_joi14 = __toESM(require("joi"));
4545
4710
  var import_mongodb13 = require("mongodb");
4546
- var schemaSchool = import_joi13.default.object({
4547
- _id: import_joi13.default.string().hex().optional().allow(null, ""),
4548
- id: import_joi13.default.string().min(1).max(50).required(),
4549
- name: import_joi13.default.string().min(1).max(100).required(),
4550
- region: import_joi13.default.string().hex().required(),
4551
- regionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4552
- division: import_joi13.default.string().hex().required(),
4553
- divisionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4554
- principal: import_joi13.default.string().hex().optional().allow(null, ""),
4555
- principalName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4556
- street: import_joi13.default.string().max(200).optional().allow(null, ""),
4557
- barangay: import_joi13.default.string().max(200).optional().allow(null, ""),
4558
- cityMunicipality: import_joi13.default.string().max(100).optional().allow(null, ""),
4559
- province: import_joi13.default.string().max(100).optional().allow(null, ""),
4560
- cityMunicipalityPSGC: import_joi13.default.string().length(10).optional().allow(null, ""),
4561
- postalCode: import_joi13.default.string().max(20).optional().allow(null, ""),
4562
- contactNumber: import_joi13.default.string().max(20).optional().allow(null, ""),
4563
- email: import_joi13.default.string().email().max(100).optional().allow(null, ""),
4564
- status: import_joi13.default.string().optional().allow(null, ""),
4565
- createdBy: import_joi13.default.string().optional().allow(null, ""),
4566
- createdAt: import_joi13.default.string().isoDate().optional().allow(null, ""),
4567
- updatedAt: import_joi13.default.string().isoDate().optional().allow(null, ""),
4568
- deletedAt: import_joi13.default.string().isoDate().optional().allow(null, "")
4711
+ var schemaSchool = import_joi14.default.object({
4712
+ _id: import_joi14.default.string().hex().optional().allow(null, ""),
4713
+ id: import_joi14.default.string().min(1).max(50).required(),
4714
+ name: import_joi14.default.string().min(1).max(100).required(),
4715
+ region: import_joi14.default.string().hex().required(),
4716
+ regionName: import_joi14.default.string().min(1).max(100).optional().allow(null, ""),
4717
+ division: import_joi14.default.string().hex().required(),
4718
+ divisionName: import_joi14.default.string().min(1).max(100).optional().allow(null, ""),
4719
+ principal: import_joi14.default.string().hex().optional().allow(null, ""),
4720
+ principalName: import_joi14.default.string().min(1).max(100).optional().allow(null, ""),
4721
+ street: import_joi14.default.string().max(200).optional().allow(null, ""),
4722
+ barangay: import_joi14.default.string().max(200).optional().allow(null, ""),
4723
+ cityMunicipality: import_joi14.default.string().max(100).optional().allow(null, ""),
4724
+ province: import_joi14.default.string().max(100).optional().allow(null, ""),
4725
+ cityMunicipalityPSGC: import_joi14.default.string().length(10).optional().allow(null, ""),
4726
+ postalCode: import_joi14.default.string().max(20).optional().allow(null, ""),
4727
+ contactNumber: import_joi14.default.string().max(20).optional().allow(null, ""),
4728
+ email: import_joi14.default.string().email().max(100).optional().allow(null, ""),
4729
+ status: import_joi14.default.string().optional().allow(null, ""),
4730
+ createdBy: import_joi14.default.string().optional().allow(null, ""),
4731
+ createdAt: import_joi14.default.string().isoDate().optional().allow(null, ""),
4732
+ updatedAt: import_joi14.default.string().isoDate().optional().allow(null, ""),
4733
+ deletedAt: import_joi14.default.string().isoDate().optional().allow(null, "")
4569
4734
  });
4570
- var schemaSchoolUpdate = import_joi13.default.object({
4571
- id: import_joi13.default.string().min(1).max(50).required(),
4572
- name: import_joi13.default.string().min(1).max(100).required(),
4573
- region: import_joi13.default.string().hex().required(),
4574
- regionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4575
- division: import_joi13.default.string().hex().required(),
4576
- divisionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4577
- principal: import_joi13.default.string().hex().optional().allow(null, ""),
4578
- principalName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4579
- street: import_joi13.default.string().max(200).optional().allow(null, ""),
4580
- barangay: import_joi13.default.string().max(200).optional().allow(null, ""),
4581
- cityMunicipality: import_joi13.default.string().max(100).optional().allow(null, ""),
4582
- province: import_joi13.default.string().max(100).optional().allow(null, ""),
4583
- cityMunicipalityPSGC: import_joi13.default.string().length(10).optional().allow(null, ""),
4584
- postalCode: import_joi13.default.string().max(20).optional().allow(null, ""),
4585
- contactNumber: import_joi13.default.string().max(20).optional().allow(null, ""),
4586
- email: import_joi13.default.string().email().max(100).optional().allow(null, "")
4735
+ var schemaSchoolUpdate = import_joi14.default.object({
4736
+ id: import_joi14.default.string().min(1).max(50).required(),
4737
+ name: import_joi14.default.string().min(1).max(100).required(),
4738
+ region: import_joi14.default.string().hex().required(),
4739
+ regionName: import_joi14.default.string().min(1).max(100).optional().allow(null, ""),
4740
+ division: import_joi14.default.string().hex().required(),
4741
+ divisionName: import_joi14.default.string().min(1).max(100).optional().allow(null, ""),
4742
+ principal: import_joi14.default.string().hex().optional().allow(null, ""),
4743
+ principalName: import_joi14.default.string().min(1).max(100).optional().allow(null, ""),
4744
+ street: import_joi14.default.string().max(200).optional().allow(null, ""),
4745
+ barangay: import_joi14.default.string().max(200).optional().allow(null, ""),
4746
+ cityMunicipality: import_joi14.default.string().max(100).optional().allow(null, ""),
4747
+ province: import_joi14.default.string().max(100).optional().allow(null, ""),
4748
+ cityMunicipalityPSGC: import_joi14.default.string().length(10).optional().allow(null, ""),
4749
+ postalCode: import_joi14.default.string().max(20).optional().allow(null, ""),
4750
+ contactNumber: import_joi14.default.string().max(20).optional().allow(null, ""),
4751
+ email: import_joi14.default.string().email().max(100).optional().allow(null, "")
4587
4752
  });
4588
4753
  function modelSchool(value) {
4589
4754
  const { error } = schemaSchool.validate(value);
@@ -33511,7 +33676,7 @@ ${errors.slice(0, 5).join("\n")}${errors.length > 5 ? `
33511
33676
 
33512
33677
  // src/resources/school/school.controller.ts
33513
33678
  var import_nodejs_utils23 = require("@eeplatform/nodejs-utils");
33514
- var import_joi14 = __toESM(require("joi"));
33679
+ var import_joi15 = __toESM(require("joi"));
33515
33680
  function useSchoolController() {
33516
33681
  const {
33517
33682
  getAll: _getAll,
@@ -33544,16 +33709,16 @@ function useSchoolController() {
33544
33709
  }
33545
33710
  }
33546
33711
  async function getAll(req, res, next) {
33547
- const validation = import_joi14.default.object({
33548
- page: import_joi14.default.number().optional().allow(null, ""),
33549
- limit: import_joi14.default.number().optional().allow(null, ""),
33550
- sort: import_joi14.default.string().optional().allow(null, ""),
33551
- sortOrder: import_joi14.default.string().optional().allow(null, ""),
33552
- status: import_joi14.default.string().optional().allow(null, ""),
33553
- org: import_joi14.default.string().hex().optional().allow(null, ""),
33554
- app: import_joi14.default.string().optional().allow(null, ""),
33555
- search: import_joi14.default.string().optional().allow(null, ""),
33556
- psgc: import_joi14.default.string().optional().allow(null, "")
33712
+ const validation = import_joi15.default.object({
33713
+ page: import_joi15.default.number().optional().allow(null, ""),
33714
+ limit: import_joi15.default.number().optional().allow(null, ""),
33715
+ sort: import_joi15.default.string().optional().allow(null, ""),
33716
+ sortOrder: import_joi15.default.string().optional().allow(null, ""),
33717
+ status: import_joi15.default.string().optional().allow(null, ""),
33718
+ org: import_joi15.default.string().hex().optional().allow(null, ""),
33719
+ app: import_joi15.default.string().optional().allow(null, ""),
33720
+ search: import_joi15.default.string().optional().allow(null, ""),
33721
+ psgc: import_joi15.default.string().optional().allow(null, "")
33557
33722
  });
33558
33723
  const { error } = validation.validate(req.query);
33559
33724
  if (error) {
@@ -33591,7 +33756,7 @@ function useSchoolController() {
33591
33756
  }
33592
33757
  async function getByCreatedBy(req, res, next) {
33593
33758
  const createdBy = req.params.createdBy;
33594
- const validation = import_joi14.default.string().hex().required();
33759
+ const validation = import_joi15.default.string().hex().required();
33595
33760
  const { error } = validation.validate(createdBy);
33596
33761
  if (error) {
33597
33762
  next(new import_nodejs_utils23.BadRequestError(`Validation error: ${error.message}`));
@@ -33608,9 +33773,9 @@ function useSchoolController() {
33608
33773
  async function updateStatusById(req, res, next) {
33609
33774
  const schoolId = req.params.id;
33610
33775
  const status = req.params.status;
33611
- const validation = import_joi14.default.object({
33612
- id: import_joi14.default.string().hex().required(),
33613
- status: import_joi14.default.string().valid("active", "deleted", "suspended").required()
33776
+ const validation = import_joi15.default.object({
33777
+ id: import_joi15.default.string().hex().required(),
33778
+ status: import_joi15.default.string().valid("active", "deleted", "suspended").required()
33614
33779
  });
33615
33780
  const { error } = validation.validate({ id: schoolId, status });
33616
33781
  if (error) {
@@ -33643,8 +33808,8 @@ function useSchoolController() {
33643
33808
  }
33644
33809
  async function approveSchool(req, res, next) {
33645
33810
  const schoolId = req.params.id;
33646
- const validation = import_joi14.default.object({
33647
- id: import_joi14.default.string().hex().required()
33811
+ const validation = import_joi15.default.object({
33812
+ id: import_joi15.default.string().hex().required()
33648
33813
  });
33649
33814
  const { error } = validation.validate({ id: schoolId });
33650
33815
  if (error) {
@@ -33667,11 +33832,11 @@ function useSchoolController() {
33667
33832
  return;
33668
33833
  }
33669
33834
  const { region, regionName, division, divisionName } = req.body;
33670
- const validation = import_joi14.default.object({
33671
- region: import_joi14.default.string().hex().required(),
33672
- regionName: import_joi14.default.string().min(1).required(),
33673
- division: import_joi14.default.string().hex().required(),
33674
- divisionName: import_joi14.default.string().min(1).required()
33835
+ const validation = import_joi15.default.object({
33836
+ region: import_joi15.default.string().hex().required(),
33837
+ regionName: import_joi15.default.string().min(1).required(),
33838
+ division: import_joi15.default.string().hex().required(),
33839
+ divisionName: import_joi15.default.string().min(1).required()
33675
33840
  });
33676
33841
  const { error } = validation.validate({
33677
33842
  region,
@@ -33700,10 +33865,10 @@ function useSchoolController() {
33700
33865
  async function updateFieldById(req, res, next) {
33701
33866
  const _id = req.params.id;
33702
33867
  const { field, value } = req.body;
33703
- const validation = import_joi14.default.object({
33704
- _id: import_joi14.default.string().hex().required(),
33705
- field: import_joi14.default.string().valid("name", "director", "directorName").required(),
33706
- value: import_joi14.default.string().required()
33868
+ const validation = import_joi15.default.object({
33869
+ _id: import_joi15.default.string().hex().required(),
33870
+ field: import_joi15.default.string().valid("name", "director", "directorName").required(),
33871
+ value: import_joi15.default.string().required()
33707
33872
  });
33708
33873
  const { error } = validation.validate({ _id, field, value });
33709
33874
  if (error) {
@@ -33721,8 +33886,8 @@ function useSchoolController() {
33721
33886
  async function updateById(req, res, next) {
33722
33887
  const id = req.params.id;
33723
33888
  const payload = req.body;
33724
- const validation = import_joi14.default.object({
33725
- id: import_joi14.default.string().hex().required()
33889
+ const validation = import_joi15.default.object({
33890
+ id: import_joi15.default.string().hex().required()
33726
33891
  });
33727
33892
  const { error: idError } = validation.validate({ id });
33728
33893
  if (idError) {
@@ -33744,8 +33909,8 @@ function useSchoolController() {
33744
33909
  }
33745
33910
  async function deleteById(req, res, next) {
33746
33911
  const _id = req.params.id;
33747
- const validation = import_joi14.default.object({
33748
- _id: import_joi14.default.string().hex().required()
33912
+ const validation = import_joi15.default.object({
33913
+ _id: import_joi15.default.string().hex().required()
33749
33914
  });
33750
33915
  const { error } = validation.validate({ _id });
33751
33916
  if (error) {
@@ -33840,7 +34005,7 @@ function useDivisionService() {
33840
34005
 
33841
34006
  // src/resources/division/division.controller.ts
33842
34007
  var import_nodejs_utils25 = require("@eeplatform/nodejs-utils");
33843
- var import_joi15 = __toESM(require("joi"));
34008
+ var import_joi16 = __toESM(require("joi"));
33844
34009
  function useDivisionController() {
33845
34010
  const { add: _add, updateById: _updateById } = useDivisionService();
33846
34011
  const {
@@ -33870,12 +34035,12 @@ function useDivisionController() {
33870
34035
  }
33871
34036
  async function getAll(req, res, next) {
33872
34037
  const query = req.query;
33873
- const validation = import_joi15.default.object({
33874
- page: import_joi15.default.number().min(1).optional().allow("", null),
33875
- limit: import_joi15.default.number().min(1).optional().allow("", null),
33876
- search: import_joi15.default.string().optional().allow("", null),
33877
- status: import_joi15.default.string().optional().allow("", null),
33878
- region: import_joi15.default.string().hex().optional().allow("", null)
34038
+ const validation = import_joi16.default.object({
34039
+ page: import_joi16.default.number().min(1).optional().allow("", null),
34040
+ limit: import_joi16.default.number().min(1).optional().allow("", null),
34041
+ search: import_joi16.default.string().optional().allow("", null),
34042
+ status: import_joi16.default.string().optional().allow("", null),
34043
+ region: import_joi16.default.string().hex().optional().allow("", null)
33879
34044
  });
33880
34045
  const { error } = validation.validate(query);
33881
34046
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -33907,8 +34072,8 @@ function useDivisionController() {
33907
34072
  }
33908
34073
  async function getById(req, res, next) {
33909
34074
  const id = req.params.id;
33910
- const validation = import_joi15.default.object({
33911
- id: import_joi15.default.string().hex().required()
34075
+ const validation = import_joi16.default.object({
34076
+ id: import_joi16.default.string().hex().required()
33912
34077
  });
33913
34078
  const { error } = validation.validate({ id });
33914
34079
  if (error) {
@@ -33928,8 +34093,8 @@ function useDivisionController() {
33928
34093
  }
33929
34094
  async function getByName(req, res, next) {
33930
34095
  const name = req.params.name;
33931
- const validation = import_joi15.default.object({
33932
- name: import_joi15.default.string().required()
34096
+ const validation = import_joi16.default.object({
34097
+ name: import_joi16.default.string().required()
33933
34098
  });
33934
34099
  const { error } = validation.validate({ name });
33935
34100
  if (error) {
@@ -33950,10 +34115,10 @@ function useDivisionController() {
33950
34115
  async function updateField(req, res, next) {
33951
34116
  const _id = req.params.id;
33952
34117
  const { field, value } = req.body;
33953
- const validation = import_joi15.default.object({
33954
- _id: import_joi15.default.string().hex().required(),
33955
- field: import_joi15.default.string().valid("name", "director", "directorName").required(),
33956
- value: import_joi15.default.string().required()
34118
+ const validation = import_joi16.default.object({
34119
+ _id: import_joi16.default.string().hex().required(),
34120
+ field: import_joi16.default.string().valid("name", "director", "directorName").required(),
34121
+ value: import_joi16.default.string().required()
33957
34122
  });
33958
34123
  const { error } = validation.validate({ _id, field, value });
33959
34124
  if (error) {
@@ -33986,8 +34151,8 @@ function useDivisionController() {
33986
34151
  }
33987
34152
  async function deleteById(req, res, next) {
33988
34153
  const _id = req.params.id;
33989
- const validation = import_joi15.default.object({
33990
- _id: import_joi15.default.string().hex().required()
34154
+ const validation = import_joi16.default.object({
34155
+ _id: import_joi16.default.string().hex().required()
33991
34156
  });
33992
34157
  const { error } = validation.validate({ _id });
33993
34158
  if (error) {
@@ -34015,48 +34180,48 @@ function useDivisionController() {
34015
34180
 
34016
34181
  // src/resources/asset/asset.model.ts
34017
34182
  var import_nodejs_utils26 = require("@eeplatform/nodejs-utils");
34018
- var import_joi16 = __toESM(require("joi"));
34183
+ var import_joi17 = __toESM(require("joi"));
34019
34184
  var import_mongodb15 = require("mongodb");
34020
- var schemaAsset = import_joi16.default.object({
34021
- _id: import_joi16.default.string().hex().optional(),
34022
- school: import_joi16.default.string().hex().required(),
34023
- asset_type: import_joi16.default.string().required().allow("supply", "furniture-equipment", "fixed-asset"),
34024
- name: import_joi16.default.string().required(),
34025
- category: import_joi16.default.string().optional().allow("", null),
34026
- type: import_joi16.default.string().optional().allow("", null),
34027
- brand: import_joi16.default.string().optional().allow("", null),
34028
- unit: import_joi16.default.string().required(),
34029
- status: import_joi16.default.string().optional().allow("", null),
34030
- createdAt: import_joi16.default.date().optional().allow("", null),
34031
- updatedAt: import_joi16.default.date().optional().allow("", null),
34032
- deletedAt: import_joi16.default.date().optional().allow("", null),
34033
- metadata: import_joi16.default.object({
34034
- title: import_joi16.default.string().optional().allow("", null),
34035
- isbn: import_joi16.default.string().optional().allow("", null),
34036
- author: import_joi16.default.string().optional().allow("", null),
34037
- edition: import_joi16.default.string().optional().allow("", null),
34038
- subject: import_joi16.default.string().optional().allow("", null),
34039
- grade_level: import_joi16.default.number().integer().min(0).optional().allow("", null),
34040
- publisher: import_joi16.default.string().optional().allow("", null),
34041
- language: import_joi16.default.string().optional().allow("", null)
34185
+ var schemaAsset = import_joi17.default.object({
34186
+ _id: import_joi17.default.string().hex().optional(),
34187
+ school: import_joi17.default.string().hex().required(),
34188
+ asset_type: import_joi17.default.string().required().allow("supply", "furniture-equipment", "fixed-asset"),
34189
+ name: import_joi17.default.string().required(),
34190
+ category: import_joi17.default.string().optional().allow("", null),
34191
+ type: import_joi17.default.string().optional().allow("", null),
34192
+ brand: import_joi17.default.string().optional().allow("", null),
34193
+ unit: import_joi17.default.string().required(),
34194
+ status: import_joi17.default.string().optional().allow("", null),
34195
+ createdAt: import_joi17.default.date().optional().allow("", null),
34196
+ updatedAt: import_joi17.default.date().optional().allow("", null),
34197
+ deletedAt: import_joi17.default.date().optional().allow("", null),
34198
+ metadata: import_joi17.default.object({
34199
+ title: import_joi17.default.string().optional().allow("", null),
34200
+ isbn: import_joi17.default.string().optional().allow("", null),
34201
+ author: import_joi17.default.string().optional().allow("", null),
34202
+ edition: import_joi17.default.string().optional().allow("", null),
34203
+ subject: import_joi17.default.string().optional().allow("", null),
34204
+ grade_level: import_joi17.default.number().integer().min(0).optional().allow("", null),
34205
+ publisher: import_joi17.default.string().optional().allow("", null),
34206
+ language: import_joi17.default.string().optional().allow("", null)
34042
34207
  }).optional().allow(null)
34043
34208
  });
34044
- var schemaAssetUpdateOption = import_joi16.default.object({
34045
- name: import_joi16.default.string().optional().allow("", null),
34046
- category: import_joi16.default.string().optional().allow("", null),
34047
- type: import_joi16.default.string().optional().allow("", null),
34048
- brand: import_joi16.default.string().optional().allow("", null),
34049
- qty: import_joi16.default.number().integer().min(0).optional().allow("", null),
34050
- unit: import_joi16.default.string().optional().allow("", null),
34051
- metadata: import_joi16.default.object({
34052
- title: import_joi16.default.string().optional().allow("", null),
34053
- isbn: import_joi16.default.string().optional().allow("", null),
34054
- author: import_joi16.default.string().optional().allow("", null),
34055
- edition: import_joi16.default.string().optional().allow("", null),
34056
- subject: import_joi16.default.string().optional().allow("", null),
34057
- grade_level: import_joi16.default.number().integer().min(0).optional().allow("", null),
34058
- publisher: import_joi16.default.string().optional().allow("", null),
34059
- language: import_joi16.default.string().optional().allow("", null)
34209
+ var schemaAssetUpdateOption = import_joi17.default.object({
34210
+ name: import_joi17.default.string().optional().allow("", null),
34211
+ category: import_joi17.default.string().optional().allow("", null),
34212
+ type: import_joi17.default.string().optional().allow("", null),
34213
+ brand: import_joi17.default.string().optional().allow("", null),
34214
+ qty: import_joi17.default.number().integer().min(0).optional().allow("", null),
34215
+ unit: import_joi17.default.string().optional().allow("", null),
34216
+ metadata: import_joi17.default.object({
34217
+ title: import_joi17.default.string().optional().allow("", null),
34218
+ isbn: import_joi17.default.string().optional().allow("", null),
34219
+ author: import_joi17.default.string().optional().allow("", null),
34220
+ edition: import_joi17.default.string().optional().allow("", null),
34221
+ subject: import_joi17.default.string().optional().allow("", null),
34222
+ grade_level: import_joi17.default.number().integer().min(0).optional().allow("", null),
34223
+ publisher: import_joi17.default.string().optional().allow("", null),
34224
+ language: import_joi17.default.string().optional().allow("", null)
34060
34225
  }).optional().allow(null)
34061
34226
  });
34062
34227
  function MAsset(value) {
@@ -34488,7 +34653,7 @@ function useAssetRepo() {
34488
34653
 
34489
34654
  // src/resources/asset/asset.controller.ts
34490
34655
  var import_nodejs_utils28 = require("@eeplatform/nodejs-utils");
34491
- var import_joi17 = __toESM(require("joi"));
34656
+ var import_joi18 = __toESM(require("joi"));
34492
34657
  function useAssetController() {
34493
34658
  const {
34494
34659
  add: _add,
@@ -34516,13 +34681,13 @@ function useAssetController() {
34516
34681
  }
34517
34682
  async function getAll(req, res, next) {
34518
34683
  const query = req.query;
34519
- const validation = import_joi17.default.object({
34520
- page: import_joi17.default.number().min(1).optional().allow("", null),
34521
- limit: import_joi17.default.number().min(1).optional().allow("", null),
34522
- search: import_joi17.default.string().optional().allow("", null),
34523
- status: import_joi17.default.string().optional().allow("", null),
34524
- school: import_joi17.default.string().hex().optional().allow("", null),
34525
- asset_type: import_joi17.default.string().required().allow("supply", "furniture-equipment", "fixed-asset")
34684
+ const validation = import_joi18.default.object({
34685
+ page: import_joi18.default.number().min(1).optional().allow("", null),
34686
+ limit: import_joi18.default.number().min(1).optional().allow("", null),
34687
+ search: import_joi18.default.string().optional().allow("", null),
34688
+ status: import_joi18.default.string().optional().allow("", null),
34689
+ school: import_joi18.default.string().hex().optional().allow("", null),
34690
+ asset_type: import_joi18.default.string().required().allow("supply", "furniture-equipment", "fixed-asset")
34526
34691
  });
34527
34692
  const { error } = validation.validate(query);
34528
34693
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -34562,7 +34727,7 @@ function useAssetController() {
34562
34727
  }
34563
34728
  async function deleteById(req, res, next) {
34564
34729
  const id = req.params.id;
34565
- const validation = import_joi17.default.string().hex().required();
34730
+ const validation = import_joi18.default.string().hex().required();
34566
34731
  const { error } = validation.validate(id);
34567
34732
  if (error) {
34568
34733
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34577,7 +34742,7 @@ function useAssetController() {
34577
34742
  }
34578
34743
  async function getById(req, res, next) {
34579
34744
  const id = req.params.id;
34580
- const validation = import_joi17.default.string().hex().required();
34745
+ const validation = import_joi18.default.string().hex().required();
34581
34746
  const { error } = validation.validate(id);
34582
34747
  if (error) {
34583
34748
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34608,7 +34773,7 @@ function useAssetController() {
34608
34773
  async function getCategories(req, res, next) {
34609
34774
  const school = req.params.school;
34610
34775
  const asset_type = req.params.asset_type;
34611
- const validation = import_joi17.default.string().hex().required();
34776
+ const validation = import_joi18.default.string().hex().required();
34612
34777
  const { error } = validation.validate(school);
34613
34778
  if (error) {
34614
34779
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34624,7 +34789,7 @@ function useAssetController() {
34624
34789
  async function getTypes(req, res, next) {
34625
34790
  const school = req.params.school;
34626
34791
  const asset_type = req.params.asset_type;
34627
- const validation = import_joi17.default.string().hex().required();
34792
+ const validation = import_joi18.default.string().hex().required();
34628
34793
  const { error } = validation.validate(school);
34629
34794
  if (error) {
34630
34795
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34639,7 +34804,7 @@ function useAssetController() {
34639
34804
  }
34640
34805
  async function getUnitsBySchool(req, res, next) {
34641
34806
  const school = req.params.school;
34642
- const validation = import_joi17.default.string().hex().required();
34807
+ const validation = import_joi18.default.string().hex().required();
34643
34808
  const { error } = validation.validate(school);
34644
34809
  if (error) {
34645
34810
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34666,26 +34831,26 @@ function useAssetController() {
34666
34831
 
34667
34832
  // src/resources/stock-card/stock-card.model.ts
34668
34833
  var import_nodejs_utils29 = require("@eeplatform/nodejs-utils");
34669
- var import_joi18 = __toESM(require("joi"));
34834
+ var import_joi19 = __toESM(require("joi"));
34670
34835
  var import_mongodb17 = require("mongodb");
34671
- var schemaStockCard = import_joi18.default.object({
34672
- _id: import_joi18.default.string().hex().optional().allow("", null),
34673
- school: import_joi18.default.string().hex().required(),
34674
- item: import_joi18.default.string().hex().required(),
34675
- balance: import_joi18.default.number().optional().allow(null, 0),
34676
- qty: import_joi18.default.number().required(),
34677
- unitCost: import_joi18.default.number().optional().allow(null, 0),
34678
- totalCost: import_joi18.default.number().optional().allow(null, 0),
34679
- status: import_joi18.default.string().optional().allow(null, ""),
34680
- condition: import_joi18.default.string().required(),
34681
- supplier: import_joi18.default.string().optional().allow("", null),
34682
- location: import_joi18.default.string().optional().allow("", null),
34683
- locationName: import_joi18.default.string().optional().allow("", null),
34684
- reason: import_joi18.default.string().optional().allow("", null),
34685
- remarks: import_joi18.default.string().optional().allow("", null),
34686
- createdAt: import_joi18.default.date().optional().allow("", null),
34687
- updatedAt: import_joi18.default.date().optional().allow("", null),
34688
- deletedAt: import_joi18.default.date().optional().allow("", null)
34836
+ var schemaStockCard = import_joi19.default.object({
34837
+ _id: import_joi19.default.string().hex().optional().allow("", null),
34838
+ school: import_joi19.default.string().hex().required(),
34839
+ item: import_joi19.default.string().hex().required(),
34840
+ balance: import_joi19.default.number().optional().allow(null, 0),
34841
+ qty: import_joi19.default.number().required(),
34842
+ unitCost: import_joi19.default.number().optional().allow(null, 0),
34843
+ totalCost: import_joi19.default.number().optional().allow(null, 0),
34844
+ status: import_joi19.default.string().optional().allow(null, ""),
34845
+ condition: import_joi19.default.string().required(),
34846
+ supplier: import_joi19.default.string().optional().allow("", null),
34847
+ location: import_joi19.default.string().optional().allow("", null),
34848
+ locationName: import_joi19.default.string().optional().allow("", null),
34849
+ reason: import_joi19.default.string().optional().allow("", null),
34850
+ remarks: import_joi19.default.string().optional().allow("", null),
34851
+ createdAt: import_joi19.default.date().optional().allow("", null),
34852
+ updatedAt: import_joi19.default.date().optional().allow("", null),
34853
+ deletedAt: import_joi19.default.date().optional().allow("", null)
34689
34854
  });
34690
34855
  function MStockCard(value) {
34691
34856
  const { error } = schemaStockCard.validate(value);
@@ -34973,7 +35138,7 @@ function useStockCardService() {
34973
35138
 
34974
35139
  // src/resources/stock-card/stock-card.controller.ts
34975
35140
  var import_nodejs_utils32 = require("@eeplatform/nodejs-utils");
34976
- var import_joi19 = __toESM(require("joi"));
35141
+ var import_joi20 = __toESM(require("joi"));
34977
35142
  function useStockCardController() {
34978
35143
  const {
34979
35144
  getAll: _getAll,
@@ -34997,11 +35162,11 @@ function useStockCardController() {
34997
35162
  }
34998
35163
  async function getAll(req, res, next) {
34999
35164
  const query = req.query;
35000
- const validation = import_joi19.default.object({
35001
- page: import_joi19.default.number().min(1).optional().allow("", null),
35002
- limit: import_joi19.default.number().min(1).optional().allow("", null),
35003
- school: import_joi19.default.string().hex().optional().allow("", null),
35004
- id: import_joi19.default.string().hex().required()
35165
+ const validation = import_joi20.default.object({
35166
+ page: import_joi20.default.number().min(1).optional().allow("", null),
35167
+ limit: import_joi20.default.number().min(1).optional().allow("", null),
35168
+ school: import_joi20.default.string().hex().optional().allow("", null),
35169
+ id: import_joi20.default.string().hex().required()
35005
35170
  });
35006
35171
  const { error } = validation.validate(query);
35007
35172
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -35037,7 +35202,7 @@ function useStockCardController() {
35037
35202
  }
35038
35203
  async function getById(req, res, next) {
35039
35204
  const id = req.params.id;
35040
- const validation = import_joi19.default.string().hex().required();
35205
+ const validation = import_joi20.default.string().hex().required();
35041
35206
  const { error } = validation.validate(id);
35042
35207
  if (error) {
35043
35208
  next(new import_nodejs_utils32.BadRequestError(error.message));
@@ -35052,7 +35217,7 @@ function useStockCardController() {
35052
35217
  }
35053
35218
  async function getSuppliers(req, res, next) {
35054
35219
  const school = req.params.school;
35055
- const validation = import_joi19.default.string().hex().required();
35220
+ const validation = import_joi20.default.string().hex().required();
35056
35221
  const { error } = validation.validate(school);
35057
35222
  if (error) {
35058
35223
  next(new import_nodejs_utils32.BadRequestError(error.message));
@@ -35075,30 +35240,30 @@ function useStockCardController() {
35075
35240
 
35076
35241
  // src/resources/plantilla/plantilla.model.ts
35077
35242
  var import_nodejs_utils33 = require("@eeplatform/nodejs-utils");
35078
- var import_joi20 = __toESM(require("joi"));
35243
+ var import_joi21 = __toESM(require("joi"));
35079
35244
  var import_mongodb19 = require("mongodb");
35080
- var schemaPlantilla = import_joi20.default.object({
35081
- _id: import_joi20.default.string().hex().optional().allow(null, ""),
35082
- org: import_joi20.default.string().hex().required(),
35083
- orgUnitCode: import_joi20.default.string().optional().allow(null, ""),
35084
- employmentType: import_joi20.default.string().optional().allow(null, ""),
35085
- personnelType: import_joi20.default.string().required(),
35086
- itemNumber: import_joi20.default.string().required(),
35087
- positionTitle: import_joi20.default.string().required(),
35088
- positionCategory: import_joi20.default.string().required(),
35089
- region: import_joi20.default.string().hex().optional().allow(null, ""),
35090
- regionName: import_joi20.default.string().optional().allow(null, ""),
35091
- division: import_joi20.default.string().hex().optional().allow(null, ""),
35092
- divisionName: import_joi20.default.string().optional().allow(null, ""),
35093
- salaryGrade: import_joi20.default.number().required(),
35094
- employeeName: import_joi20.default.string().optional().allow(null, ""),
35095
- annualSalary: import_joi20.default.number().optional().allow(null, 0),
35096
- monthlySalary: import_joi20.default.number().optional().allow(null, 0),
35097
- status: import_joi20.default.string().required(),
35098
- employee: import_joi20.default.string().hex().optional().allow(null, ""),
35099
- createdAt: import_joi20.default.date().iso().optional().allow(null, ""),
35100
- updatedAt: import_joi20.default.date().iso().optional().allow(null, ""),
35101
- deletedAt: import_joi20.default.date().iso().optional().allow(null, "")
35245
+ var schemaPlantilla = import_joi21.default.object({
35246
+ _id: import_joi21.default.string().hex().optional().allow(null, ""),
35247
+ org: import_joi21.default.string().hex().required(),
35248
+ orgUnitCode: import_joi21.default.string().optional().allow(null, ""),
35249
+ employmentType: import_joi21.default.string().optional().allow(null, ""),
35250
+ personnelType: import_joi21.default.string().required(),
35251
+ itemNumber: import_joi21.default.string().required(),
35252
+ positionTitle: import_joi21.default.string().required(),
35253
+ positionCategory: import_joi21.default.string().required(),
35254
+ region: import_joi21.default.string().hex().optional().allow(null, ""),
35255
+ regionName: import_joi21.default.string().optional().allow(null, ""),
35256
+ division: import_joi21.default.string().hex().optional().allow(null, ""),
35257
+ divisionName: import_joi21.default.string().optional().allow(null, ""),
35258
+ salaryGrade: import_joi21.default.number().required(),
35259
+ employeeName: import_joi21.default.string().optional().allow(null, ""),
35260
+ annualSalary: import_joi21.default.number().optional().allow(null, 0),
35261
+ monthlySalary: import_joi21.default.number().optional().allow(null, 0),
35262
+ status: import_joi21.default.string().required(),
35263
+ employee: import_joi21.default.string().hex().optional().allow(null, ""),
35264
+ createdAt: import_joi21.default.date().iso().optional().allow(null, ""),
35265
+ updatedAt: import_joi21.default.date().iso().optional().allow(null, ""),
35266
+ deletedAt: import_joi21.default.date().iso().optional().allow(null, "")
35102
35267
  });
35103
35268
  function MPlantilla(data) {
35104
35269
  const { error } = schemaPlantilla.validate(data);
@@ -35580,7 +35745,7 @@ ${errors.slice(0, 10).join("\n")}${errors.length > 10 ? `
35580
35745
 
35581
35746
  // src/resources/plantilla/plantilla.controller.ts
35582
35747
  var import_nodejs_utils36 = require("@eeplatform/nodejs-utils");
35583
- var import_joi21 = __toESM(require("joi"));
35748
+ var import_joi22 = __toESM(require("joi"));
35584
35749
  function usePlantillaController() {
35585
35750
  const {
35586
35751
  add: _addPlantilla,
@@ -35592,11 +35757,11 @@ function usePlantillaController() {
35592
35757
  const { addBulk: _addBulk } = usePlantillaService();
35593
35758
  async function createPlantilla(req, res, next) {
35594
35759
  const value = req.body;
35595
- const validation = import_joi21.default.object({
35596
- itemNumber: import_joi21.default.string().required(),
35597
- positionTitle: import_joi21.default.string().required(),
35598
- positionCategory: import_joi21.default.string().required(),
35599
- status: import_joi21.default.string().required()
35760
+ const validation = import_joi22.default.object({
35761
+ itemNumber: import_joi22.default.string().required(),
35762
+ positionTitle: import_joi22.default.string().required(),
35763
+ positionCategory: import_joi22.default.string().required(),
35764
+ status: import_joi22.default.string().required()
35600
35765
  });
35601
35766
  const { error } = validation.validate(value);
35602
35767
  if (error) {
@@ -35626,11 +35791,11 @@ function usePlantillaController() {
35626
35791
  next(new import_nodejs_utils36.BadRequestError("Invalid limit number."));
35627
35792
  return;
35628
35793
  }
35629
- const validation = import_joi21.default.object({
35630
- page: import_joi21.default.number().min(1).optional().allow("", null),
35631
- limit: import_joi21.default.number().min(1).optional().allow("", null),
35632
- search: import_joi21.default.string().optional().allow("", null),
35633
- org: import_joi21.default.string().optional().allow("", null)
35794
+ const validation = import_joi22.default.object({
35795
+ page: import_joi22.default.number().min(1).optional().allow("", null),
35796
+ limit: import_joi22.default.number().min(1).optional().allow("", null),
35797
+ search: import_joi22.default.string().optional().allow("", null),
35798
+ org: import_joi22.default.string().optional().allow("", null)
35634
35799
  });
35635
35800
  const { error } = validation.validate({ page, limit, search, org });
35636
35801
  if (error) {
@@ -35652,8 +35817,8 @@ function usePlantillaController() {
35652
35817
  }
35653
35818
  async function getPlantillaById(req, res, next) {
35654
35819
  const id = req.params.id;
35655
- const validation = import_joi21.default.object({
35656
- id: import_joi21.default.string().hex().required()
35820
+ const validation = import_joi22.default.object({
35821
+ id: import_joi22.default.string().hex().required()
35657
35822
  });
35658
35823
  const { error } = validation.validate({ id });
35659
35824
  if (error) {
@@ -35675,12 +35840,12 @@ function usePlantillaController() {
35675
35840
  async function updatePlantilla(req, res, next) {
35676
35841
  const id = req.params.id;
35677
35842
  const value = req.body;
35678
- const validation = import_joi21.default.object({
35679
- id: import_joi21.default.string().hex().required(),
35680
- employee: import_joi21.default.string().hex().optional().allow(null, ""),
35681
- status: import_joi21.default.string().optional(),
35682
- positionTitle: import_joi21.default.string().optional(),
35683
- positionCategory: import_joi21.default.string().optional()
35843
+ const validation = import_joi22.default.object({
35844
+ id: import_joi22.default.string().hex().required(),
35845
+ employee: import_joi22.default.string().hex().optional().allow(null, ""),
35846
+ status: import_joi22.default.string().optional(),
35847
+ positionTitle: import_joi22.default.string().optional(),
35848
+ positionCategory: import_joi22.default.string().optional()
35684
35849
  });
35685
35850
  const { error } = validation.validate({ id, ...value });
35686
35851
  if (error) {
@@ -35701,8 +35866,8 @@ function usePlantillaController() {
35701
35866
  }
35702
35867
  async function deletePlantilla(req, res, next) {
35703
35868
  const id = req.params.id;
35704
- const validation = import_joi21.default.object({
35705
- id: import_joi21.default.string().hex().required()
35869
+ const validation = import_joi22.default.object({
35870
+ id: import_joi22.default.string().hex().required()
35706
35871
  });
35707
35872
  const { error } = validation.validate({ id });
35708
35873
  if (error) {
@@ -35727,9 +35892,9 @@ function usePlantillaController() {
35727
35892
  return;
35728
35893
  }
35729
35894
  const { region, division } = req.body;
35730
- const validation = import_joi21.default.object({
35731
- region: import_joi21.default.string().hex().optional(),
35732
- division: import_joi21.default.string().hex().optional()
35895
+ const validation = import_joi22.default.object({
35896
+ region: import_joi22.default.string().hex().optional(),
35897
+ division: import_joi22.default.string().hex().optional()
35733
35898
  });
35734
35899
  const { error } = validation.validate({ region, division });
35735
35900
  if (error) {
@@ -35763,6 +35928,1486 @@ function usePlantillaController() {
35763
35928
  };
35764
35929
  }
35765
35930
 
35931
+ // src/resources/section-preset/section.preset.model.ts
35932
+ var import_nodejs_utils37 = require("@eeplatform/nodejs-utils");
35933
+ var import_joi23 = __toESM(require("joi"));
35934
+ var import_mongodb21 = require("mongodb");
35935
+ var schemaSectionPreset = import_joi23.default.object({
35936
+ _id: import_joi23.default.string().hex().optional().allow(null, ""),
35937
+ name: import_joi23.default.string().min(1).max(100).required(),
35938
+ description: import_joi23.default.string().max(500).optional().allow(null, ""),
35939
+ set: import_joi23.default.array().items(import_joi23.default.string()).required(),
35940
+ school: import_joi23.default.string().hex().required(),
35941
+ createdBy: import_joi23.default.string().hex().required(),
35942
+ createdAt: import_joi23.default.string().isoDate().optional(),
35943
+ updatedAt: import_joi23.default.string().isoDate().optional(),
35944
+ deletedAt: import_joi23.default.string().isoDate().optional().allow(null, "")
35945
+ });
35946
+ function modelSectionPreset(value) {
35947
+ const { error } = schemaSectionPreset.validate(value);
35948
+ if (error) {
35949
+ throw new import_nodejs_utils37.BadRequestError(`Invalid section preset data: ${error.message}`);
35950
+ }
35951
+ if (value._id && typeof value._id === "string") {
35952
+ try {
35953
+ value._id = new import_mongodb21.ObjectId(value._id);
35954
+ } catch (error2) {
35955
+ throw new Error("Invalid _id.");
35956
+ }
35957
+ }
35958
+ if (value.createdBy && typeof value.createdBy === "string") {
35959
+ try {
35960
+ value.createdBy = new import_mongodb21.ObjectId(value.createdBy);
35961
+ } catch (error2) {
35962
+ throw new Error("Invalid createdBy.");
35963
+ }
35964
+ }
35965
+ if (value.school && typeof value.school === "string") {
35966
+ try {
35967
+ value.school = new import_mongodb21.ObjectId(value.school);
35968
+ } catch (error2) {
35969
+ throw new Error("Invalid school.");
35970
+ }
35971
+ }
35972
+ return {
35973
+ _id: value._id,
35974
+ name: value.name,
35975
+ description: value.description ?? "",
35976
+ set: value.set,
35977
+ status: value.status ?? "active",
35978
+ school: value.school,
35979
+ createdBy: value.createdBy,
35980
+ createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
35981
+ updatedAt: value.updatedAt ?? "",
35982
+ deletedAt: value.deletedAt ?? ""
35983
+ };
35984
+ }
35985
+
35986
+ // src/resources/section-preset/section.preset.repository.ts
35987
+ var import_nodejs_utils38 = require("@eeplatform/nodejs-utils");
35988
+ var import_mongodb22 = require("mongodb");
35989
+ function useSectionPresetRepo() {
35990
+ const db = import_nodejs_utils38.useAtlas.getDb();
35991
+ if (!db) {
35992
+ throw new Error("Unable to connect to server.");
35993
+ }
35994
+ const namespace_collection = "deped.section.presets";
35995
+ const collection = db.collection(namespace_collection);
35996
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils38.useCache)(namespace_collection);
35997
+ async function createIndexes() {
35998
+ try {
35999
+ await collection.createIndexes([
36000
+ { key: { name: 1 } },
36001
+ { key: { createdAt: 1 } },
36002
+ { key: { createdBy: 1 } },
36003
+ { key: { name: "text", description: "text" } },
36004
+ {
36005
+ key: { name: 1, status: 1 },
36006
+ unique: true,
36007
+ name: "unique_section_preset"
36008
+ }
36009
+ ]);
36010
+ } catch (error) {
36011
+ throw new Error("Failed to create index on section presets.");
36012
+ }
36013
+ }
36014
+ function delCachedData() {
36015
+ delNamespace().then(() => {
36016
+ import_nodejs_utils38.logger.log({
36017
+ level: "info",
36018
+ message: `Cache namespace cleared for ${namespace_collection}`
36019
+ });
36020
+ }).catch((err) => {
36021
+ import_nodejs_utils38.logger.log({
36022
+ level: "error",
36023
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
36024
+ });
36025
+ });
36026
+ }
36027
+ async function add(value, session) {
36028
+ try {
36029
+ value = modelSectionPreset(value);
36030
+ const res = await collection.insertOne(value, { session });
36031
+ delCachedData();
36032
+ return res.insertedId;
36033
+ } catch (error) {
36034
+ import_nodejs_utils38.logger.log({
36035
+ level: "error",
36036
+ message: error.message
36037
+ });
36038
+ if (error instanceof import_nodejs_utils38.AppError) {
36039
+ throw error;
36040
+ } else {
36041
+ const isDuplicated = error.message.includes("duplicate");
36042
+ if (isDuplicated) {
36043
+ throw new import_nodejs_utils38.BadRequestError("Section preset already exists.");
36044
+ }
36045
+ throw new Error("Failed to create section preset.");
36046
+ }
36047
+ }
36048
+ }
36049
+ async function getAll({
36050
+ search = "",
36051
+ page = 1,
36052
+ limit = 10,
36053
+ sort = {},
36054
+ status = "active",
36055
+ createdBy,
36056
+ school = ""
36057
+ } = {}) {
36058
+ page = page > 0 ? page - 1 : 0;
36059
+ const query = {
36060
+ deletedAt: { $in: ["", null] },
36061
+ status
36062
+ };
36063
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
36064
+ const cacheKeyOptions = {
36065
+ status,
36066
+ page,
36067
+ limit,
36068
+ sort: JSON.stringify(sort)
36069
+ };
36070
+ if (createdBy) {
36071
+ try {
36072
+ query.createdBy = new import_mongodb22.ObjectId(createdBy);
36073
+ } catch (error) {
36074
+ throw new import_nodejs_utils38.BadRequestError("Invalid createdBy ID.");
36075
+ }
36076
+ cacheKeyOptions.createdBy = createdBy;
36077
+ }
36078
+ if (search) {
36079
+ query.$text = { $search: search };
36080
+ cacheKeyOptions.search = search;
36081
+ }
36082
+ if (school) {
36083
+ try {
36084
+ query.school = new import_mongodb22.ObjectId(school);
36085
+ } catch (error) {
36086
+ throw new import_nodejs_utils38.BadRequestError("Invalid school ID.");
36087
+ }
36088
+ cacheKeyOptions.school = school;
36089
+ }
36090
+ const cacheKey = (0, import_nodejs_utils38.makeCacheKey)(namespace_collection, cacheKeyOptions);
36091
+ import_nodejs_utils38.logger.log({
36092
+ level: "info",
36093
+ message: `Cache key for getAll section presets: ${cacheKey}`
36094
+ });
36095
+ try {
36096
+ const cached = await getCache(cacheKey);
36097
+ if (cached) {
36098
+ import_nodejs_utils38.logger.log({
36099
+ level: "info",
36100
+ message: `Cache hit for getAll section presets: ${cacheKey}`
36101
+ });
36102
+ return cached;
36103
+ }
36104
+ const items = await collection.aggregate([
36105
+ { $match: query },
36106
+ { $sort: sort },
36107
+ { $skip: page * limit },
36108
+ { $limit: limit }
36109
+ ]).toArray();
36110
+ const length = await collection.countDocuments(query);
36111
+ const data = (0, import_nodejs_utils38.paginate)(items, page, limit, length);
36112
+ setCache(cacheKey, data, 600).then(() => {
36113
+ import_nodejs_utils38.logger.log({
36114
+ level: "info",
36115
+ message: `Cache set for getAll section presets: ${cacheKey}`
36116
+ });
36117
+ }).catch((err) => {
36118
+ import_nodejs_utils38.logger.log({
36119
+ level: "error",
36120
+ message: `Failed to set cache for getAll section presets: ${err.message}`
36121
+ });
36122
+ });
36123
+ return data;
36124
+ } catch (error) {
36125
+ import_nodejs_utils38.logger.log({ level: "error", message: `${error}` });
36126
+ throw error;
36127
+ }
36128
+ }
36129
+ async function getById(_id) {
36130
+ try {
36131
+ _id = new import_mongodb22.ObjectId(_id);
36132
+ } catch (error) {
36133
+ throw new import_nodejs_utils38.BadRequestError("Invalid ID.");
36134
+ }
36135
+ const cacheKey = (0, import_nodejs_utils38.makeCacheKey)(namespace_collection, { _id: String(_id) });
36136
+ try {
36137
+ const cached = await getCache(cacheKey);
36138
+ if (cached) {
36139
+ import_nodejs_utils38.logger.log({
36140
+ level: "info",
36141
+ message: `Cache hit for getById section preset: ${cacheKey}`
36142
+ });
36143
+ return cached;
36144
+ }
36145
+ const result = await collection.findOne({
36146
+ _id,
36147
+ deletedAt: { $in: ["", null] }
36148
+ });
36149
+ if (!result) {
36150
+ throw new import_nodejs_utils38.BadRequestError("Section preset not found.");
36151
+ }
36152
+ setCache(cacheKey, result, 300).then(() => {
36153
+ import_nodejs_utils38.logger.log({
36154
+ level: "info",
36155
+ message: `Cache set for section preset by id: ${cacheKey}`
36156
+ });
36157
+ }).catch((err) => {
36158
+ import_nodejs_utils38.logger.log({
36159
+ level: "error",
36160
+ message: `Failed to set cache for section preset by id: ${err.message}`
36161
+ });
36162
+ });
36163
+ return result;
36164
+ } catch (error) {
36165
+ if (error instanceof import_nodejs_utils38.AppError) {
36166
+ throw error;
36167
+ } else {
36168
+ throw new import_nodejs_utils38.InternalServerError("Failed to get section preset.");
36169
+ }
36170
+ }
36171
+ }
36172
+ async function getByName(name) {
36173
+ const cacheKey = (0, import_nodejs_utils38.makeCacheKey)(namespace_collection, { name });
36174
+ try {
36175
+ const cached = await getCache(cacheKey);
36176
+ if (cached) {
36177
+ import_nodejs_utils38.logger.log({
36178
+ level: "info",
36179
+ message: `Cache hit for getByName section preset: ${cacheKey}`
36180
+ });
36181
+ return cached;
36182
+ }
36183
+ const result = await collection.findOne({
36184
+ name,
36185
+ deletedAt: { $in: ["", null] }
36186
+ });
36187
+ if (!result) {
36188
+ throw new import_nodejs_utils38.BadRequestError("Section preset not found.");
36189
+ }
36190
+ setCache(cacheKey, result, 300).then(() => {
36191
+ import_nodejs_utils38.logger.log({
36192
+ level: "info",
36193
+ message: `Cache set for section preset by name: ${cacheKey}`
36194
+ });
36195
+ }).catch((err) => {
36196
+ import_nodejs_utils38.logger.log({
36197
+ level: "error",
36198
+ message: `Failed to set cache for section preset by name: ${err.message}`
36199
+ });
36200
+ });
36201
+ return result;
36202
+ } catch (error) {
36203
+ if (error instanceof import_nodejs_utils38.AppError) {
36204
+ throw error;
36205
+ } else {
36206
+ throw new import_nodejs_utils38.InternalServerError("Failed to get section preset.");
36207
+ }
36208
+ }
36209
+ }
36210
+ async function updateFieldById({ _id, field, value } = {}, session) {
36211
+ const allowedFields = ["name", "description", "sets"];
36212
+ if (!allowedFields.includes(field)) {
36213
+ throw new import_nodejs_utils38.BadRequestError(
36214
+ `Field "${field}" is not allowed to be updated.`
36215
+ );
36216
+ }
36217
+ try {
36218
+ _id = new import_mongodb22.ObjectId(_id);
36219
+ } catch (error) {
36220
+ throw new import_nodejs_utils38.BadRequestError("Invalid ID.");
36221
+ }
36222
+ try {
36223
+ await collection.updateOne(
36224
+ { _id, deletedAt: { $in: ["", null] } },
36225
+ { $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
36226
+ { session }
36227
+ );
36228
+ delCachedData();
36229
+ return `Successfully updated section preset ${field}.`;
36230
+ } catch (error) {
36231
+ throw new import_nodejs_utils38.InternalServerError(
36232
+ `Failed to update section preset ${field}.`
36233
+ );
36234
+ }
36235
+ }
36236
+ async function deleteById(_id) {
36237
+ try {
36238
+ _id = new import_mongodb22.ObjectId(_id);
36239
+ } catch (error) {
36240
+ throw new import_nodejs_utils38.BadRequestError("Invalid ID.");
36241
+ }
36242
+ try {
36243
+ await collection.updateOne(
36244
+ { _id },
36245
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
36246
+ );
36247
+ delCachedData();
36248
+ return "Successfully deleted section preset.";
36249
+ } catch (error) {
36250
+ throw new import_nodejs_utils38.InternalServerError("Failed to delete section preset.");
36251
+ }
36252
+ }
36253
+ return {
36254
+ createIndexes,
36255
+ add,
36256
+ getAll,
36257
+ getById,
36258
+ updateFieldById,
36259
+ deleteById,
36260
+ getByName
36261
+ };
36262
+ }
36263
+
36264
+ // src/resources/section-preset/section.preset.controller.ts
36265
+ var import_nodejs_utils39 = require("@eeplatform/nodejs-utils");
36266
+ var import_joi24 = __toESM(require("joi"));
36267
+ function useSectionPresetController() {
36268
+ const {
36269
+ add: _add,
36270
+ getAll: _getAll,
36271
+ getById: _getById,
36272
+ getByName: _getByName,
36273
+ updateFieldById: _updateFieldById,
36274
+ deleteById: _deleteById
36275
+ } = useSectionPresetRepo();
36276
+ async function add(req, res, next) {
36277
+ const value = req.body;
36278
+ const { error } = schemaSectionPreset.validate(value);
36279
+ if (error) {
36280
+ next(new import_nodejs_utils39.BadRequestError(error.message));
36281
+ return;
36282
+ }
36283
+ try {
36284
+ const data = await _add(value);
36285
+ res.json({
36286
+ message: "Successfully created section preset.",
36287
+ data
36288
+ });
36289
+ return;
36290
+ } catch (error2) {
36291
+ next(error2);
36292
+ }
36293
+ }
36294
+ async function getAll(req, res, next) {
36295
+ const query = req.query;
36296
+ const validation = import_joi24.default.object({
36297
+ page: import_joi24.default.number().min(1).optional().allow("", null),
36298
+ limit: import_joi24.default.number().min(1).optional().allow("", null),
36299
+ search: import_joi24.default.string().optional().allow("", null),
36300
+ status: import_joi24.default.string().optional().allow("", null),
36301
+ school: import_joi24.default.string().hex().optional().allow("", null),
36302
+ createdBy: import_joi24.default.string().hex().optional().allow("", null)
36303
+ });
36304
+ const { error } = validation.validate(query);
36305
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
36306
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
36307
+ const search = req.query.search ?? "";
36308
+ const status = req.query.status ?? "active";
36309
+ const school = req.query.school ?? "";
36310
+ const createdBy = req.query.createdBy ?? "";
36311
+ const isPageNumber = isFinite(page);
36312
+ if (!isPageNumber) {
36313
+ next(new import_nodejs_utils39.BadRequestError("Invalid page number."));
36314
+ return;
36315
+ }
36316
+ const isLimitNumber = isFinite(limit);
36317
+ if (!isLimitNumber) {
36318
+ next(new import_nodejs_utils39.BadRequestError("Invalid limit number."));
36319
+ return;
36320
+ }
36321
+ if (error) {
36322
+ next(new import_nodejs_utils39.BadRequestError(error.message));
36323
+ return;
36324
+ }
36325
+ try {
36326
+ const data = await _getAll({
36327
+ page,
36328
+ limit,
36329
+ search,
36330
+ status,
36331
+ school,
36332
+ createdBy: createdBy || void 0
36333
+ });
36334
+ res.json(data);
36335
+ return;
36336
+ } catch (error2) {
36337
+ next(error2);
36338
+ }
36339
+ }
36340
+ async function getById(req, res, next) {
36341
+ const id = req.params.id;
36342
+ const validation = import_joi24.default.object({
36343
+ id: import_joi24.default.string().hex().required()
36344
+ });
36345
+ const { error } = validation.validate({ id });
36346
+ if (error) {
36347
+ next(new import_nodejs_utils39.BadRequestError(error.message));
36348
+ return;
36349
+ }
36350
+ try {
36351
+ const data = await _getById(id);
36352
+ res.json({
36353
+ message: "Successfully retrieved section preset.",
36354
+ data
36355
+ });
36356
+ return;
36357
+ } catch (error2) {
36358
+ next(error2);
36359
+ }
36360
+ }
36361
+ async function getByName(req, res, next) {
36362
+ const name = req.params.name;
36363
+ const validation = import_joi24.default.object({
36364
+ name: import_joi24.default.string().required()
36365
+ });
36366
+ const { error } = validation.validate({ name });
36367
+ if (error) {
36368
+ next(new import_nodejs_utils39.BadRequestError(error.message));
36369
+ return;
36370
+ }
36371
+ try {
36372
+ const data = await _getByName(name);
36373
+ res.json({
36374
+ message: "Successfully retrieved section preset.",
36375
+ data
36376
+ });
36377
+ return;
36378
+ } catch (error2) {
36379
+ next(error2);
36380
+ }
36381
+ }
36382
+ async function updateField(req, res, next) {
36383
+ const _id = req.params.id;
36384
+ const { field, value } = req.body;
36385
+ const validation = import_joi24.default.object({
36386
+ _id: import_joi24.default.string().hex().required(),
36387
+ field: import_joi24.default.string().valid("name", "description", "sets").required(),
36388
+ value: import_joi24.default.alternatives().try(import_joi24.default.string(), import_joi24.default.array().items(import_joi24.default.string())).required()
36389
+ });
36390
+ const { error } = validation.validate({ _id, field, value });
36391
+ if (error) {
36392
+ next(new import_nodejs_utils39.BadRequestError(error.message));
36393
+ return;
36394
+ }
36395
+ try {
36396
+ const message = await _updateFieldById({ _id, field, value });
36397
+ res.json({ message });
36398
+ return;
36399
+ } catch (error2) {
36400
+ next(error2);
36401
+ }
36402
+ }
36403
+ async function deleteById(req, res, next) {
36404
+ const _id = req.params.id;
36405
+ const validation = import_joi24.default.object({
36406
+ _id: import_joi24.default.string().hex().required()
36407
+ });
36408
+ const { error } = validation.validate({ _id });
36409
+ if (error) {
36410
+ next(new import_nodejs_utils39.BadRequestError(error.message));
36411
+ return;
36412
+ }
36413
+ try {
36414
+ const message = await _deleteById(_id);
36415
+ res.json({ message });
36416
+ return;
36417
+ } catch (error2) {
36418
+ next(error2);
36419
+ }
36420
+ }
36421
+ return {
36422
+ add,
36423
+ getAll,
36424
+ getById,
36425
+ getByName,
36426
+ updateField,
36427
+ deleteById
36428
+ };
36429
+ }
36430
+
36431
+ // src/resources/section/section.model.ts
36432
+ var import_nodejs_utils40 = require("@eeplatform/nodejs-utils");
36433
+ var import_joi25 = __toESM(require("joi"));
36434
+ var import_mongodb23 = require("mongodb");
36435
+ var schemaSection = import_joi25.default.object({
36436
+ _id: import_joi25.default.string().hex().optional().allow(null, ""),
36437
+ school: import_joi25.default.string().hex().required(),
36438
+ name: import_joi25.default.string().min(1).max(100).required(),
36439
+ schoolYear: import_joi25.default.string().required(),
36440
+ gradeLevel: import_joi25.default.string().required(),
36441
+ students: import_joi25.default.number().integer().min(0).optional(),
36442
+ adviser: import_joi25.default.string().hex().optional().allow(null, ""),
36443
+ adviserName: import_joi25.default.string().optional().allow(null, ""),
36444
+ status: import_joi25.default.string().valid("active", "inactive").optional(),
36445
+ createdAt: import_joi25.default.string().isoDate().optional().allow(null, ""),
36446
+ updatedAt: import_joi25.default.string().isoDate().optional().allow(null, ""),
36447
+ deletedAt: import_joi25.default.string().isoDate().optional().allow(null, "")
36448
+ });
36449
+ var schemaGenerateSections = import_joi25.default.object({
36450
+ school: import_joi25.default.string().hex().required(),
36451
+ schoolYear: import_joi25.default.string().required(),
36452
+ gradeLevel: import_joi25.default.string().required(),
36453
+ set: import_joi25.default.array().items(import_joi25.default.string().min(1).max(100)).required()
36454
+ });
36455
+ function modelSection(value) {
36456
+ const { error } = schemaSection.validate(value);
36457
+ if (error) {
36458
+ throw new import_nodejs_utils40.BadRequestError(`Invalid section data: ${error.message}`);
36459
+ }
36460
+ if (value._id && typeof value._id === "string") {
36461
+ try {
36462
+ value._id = new import_mongodb23.ObjectId(value._id);
36463
+ } catch (error2) {
36464
+ throw new Error("Invalid _id.");
36465
+ }
36466
+ }
36467
+ if (value.school && typeof value.school === "string") {
36468
+ try {
36469
+ value.school = new import_mongodb23.ObjectId(value.school);
36470
+ } catch (error2) {
36471
+ throw new Error("Invalid school ID.");
36472
+ }
36473
+ }
36474
+ if (value.adviser && typeof value.adviser === "string") {
36475
+ try {
36476
+ value.adviser = new import_mongodb23.ObjectId(value.adviser);
36477
+ } catch (error2) {
36478
+ throw new Error("Invalid adviser ID.");
36479
+ }
36480
+ }
36481
+ return {
36482
+ _id: value._id,
36483
+ school: value.school,
36484
+ name: value.name,
36485
+ schoolYear: value.schoolYear,
36486
+ gradeLevel: value.gradeLevel,
36487
+ adviser: value.adviser,
36488
+ adviserName: value.adviserName,
36489
+ students: value.students ?? 0,
36490
+ status: value.status ?? "active",
36491
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
36492
+ updatedAt: value.updatedAt ?? "",
36493
+ deletedAt: value.deletedAt ?? ""
36494
+ };
36495
+ }
36496
+
36497
+ // src/resources/section/section.repository.ts
36498
+ var import_nodejs_utils41 = require("@eeplatform/nodejs-utils");
36499
+ var import_mongodb24 = require("mongodb");
36500
+ function useSectionRepo() {
36501
+ const db = import_nodejs_utils41.useAtlas.getDb();
36502
+ if (!db) {
36503
+ throw new Error("Unable to connect to server.");
36504
+ }
36505
+ const namespace_collection = "deped.sections";
36506
+ const collection = db.collection(namespace_collection);
36507
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils41.useCache)(namespace_collection);
36508
+ async function createIndexes() {
36509
+ try {
36510
+ await collection.createIndexes([
36511
+ { key: { name: 1 } },
36512
+ { key: { school: 1 } },
36513
+ { key: { schoolYear: 1 } },
36514
+ { key: { gradeLevel: 1 } },
36515
+ { key: { adviser: 1 } },
36516
+ { key: { createdAt: 1 } },
36517
+ { key: { name: "text", schoolYear: "text", gradeLevel: "text" } },
36518
+ {
36519
+ key: { school: 1, name: 1, schoolYear: 1, status: 1 },
36520
+ unique: true,
36521
+ name: "unique_section"
36522
+ }
36523
+ ]);
36524
+ } catch (error) {
36525
+ throw new Error("Failed to create index on sections.");
36526
+ }
36527
+ }
36528
+ function delCachedData() {
36529
+ delNamespace().then(() => {
36530
+ import_nodejs_utils41.logger.log({
36531
+ level: "info",
36532
+ message: `Cache namespace cleared for ${namespace_collection}`
36533
+ });
36534
+ }).catch((err) => {
36535
+ import_nodejs_utils41.logger.log({
36536
+ level: "error",
36537
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
36538
+ });
36539
+ });
36540
+ }
36541
+ async function add(value, session) {
36542
+ try {
36543
+ value = modelSection(value);
36544
+ const res = await collection.insertOne(value, { session });
36545
+ delCachedData();
36546
+ return res.insertedId;
36547
+ } catch (error) {
36548
+ import_nodejs_utils41.logger.log({
36549
+ level: "error",
36550
+ message: error.message
36551
+ });
36552
+ if (error instanceof import_nodejs_utils41.AppError) {
36553
+ throw error;
36554
+ } else {
36555
+ const isDuplicated = error.message.includes("duplicate");
36556
+ if (isDuplicated) {
36557
+ throw new import_nodejs_utils41.BadRequestError("Section already exists.");
36558
+ }
36559
+ throw new Error("Failed to create section.");
36560
+ }
36561
+ }
36562
+ }
36563
+ async function getAll({
36564
+ search = "",
36565
+ page = 1,
36566
+ limit = 10,
36567
+ sort = {},
36568
+ status = "active",
36569
+ school = "",
36570
+ schoolYear = "",
36571
+ gradeLevel = ""
36572
+ } = {}) {
36573
+ page = page > 0 ? page - 1 : 0;
36574
+ const query = {
36575
+ deletedAt: { $in: ["", null] },
36576
+ status
36577
+ };
36578
+ const cacheKeyOptions = {
36579
+ status,
36580
+ page,
36581
+ limit,
36582
+ sort: JSON.stringify(sort)
36583
+ };
36584
+ if (school) {
36585
+ try {
36586
+ query.school = new import_mongodb24.ObjectId(school);
36587
+ } catch (error) {
36588
+ throw new import_nodejs_utils41.BadRequestError("Invalid school ID.");
36589
+ }
36590
+ cacheKeyOptions.school = school;
36591
+ }
36592
+ if (schoolYear) {
36593
+ query.schoolYear = schoolYear;
36594
+ cacheKeyOptions.schoolYear = schoolYear;
36595
+ }
36596
+ if (gradeLevel) {
36597
+ query.gradeLevel = gradeLevel;
36598
+ cacheKeyOptions.gradeLevel = gradeLevel;
36599
+ }
36600
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
36601
+ if (search) {
36602
+ query.$text = { $search: search };
36603
+ cacheKeyOptions.search = search;
36604
+ }
36605
+ const cacheKey = (0, import_nodejs_utils41.makeCacheKey)(namespace_collection, cacheKeyOptions);
36606
+ import_nodejs_utils41.logger.log({
36607
+ level: "info",
36608
+ message: `Cache key for getAll sections: ${cacheKey}`
36609
+ });
36610
+ try {
36611
+ const cached = await getCache(cacheKey);
36612
+ if (cached) {
36613
+ import_nodejs_utils41.logger.log({
36614
+ level: "info",
36615
+ message: `Cache hit for getAll sections: ${cacheKey}`
36616
+ });
36617
+ return cached;
36618
+ }
36619
+ const items = await collection.aggregate([
36620
+ { $match: query },
36621
+ { $sort: sort },
36622
+ { $skip: page * limit },
36623
+ { $limit: limit }
36624
+ ]).toArray();
36625
+ const length = await collection.countDocuments(query);
36626
+ const data = (0, import_nodejs_utils41.paginate)(items, page, limit, length);
36627
+ setCache(cacheKey, data, 600).then(() => {
36628
+ import_nodejs_utils41.logger.log({
36629
+ level: "info",
36630
+ message: `Cache set for getAll sections: ${cacheKey}`
36631
+ });
36632
+ }).catch((err) => {
36633
+ import_nodejs_utils41.logger.log({
36634
+ level: "error",
36635
+ message: `Failed to set cache for getAll sections: ${err.message}`
36636
+ });
36637
+ });
36638
+ return data;
36639
+ } catch (error) {
36640
+ import_nodejs_utils41.logger.log({ level: "error", message: `${error}` });
36641
+ throw error;
36642
+ }
36643
+ }
36644
+ async function getById(_id) {
36645
+ try {
36646
+ _id = new import_mongodb24.ObjectId(_id);
36647
+ } catch (error) {
36648
+ throw new import_nodejs_utils41.BadRequestError("Invalid ID.");
36649
+ }
36650
+ const cacheKey = (0, import_nodejs_utils41.makeCacheKey)(namespace_collection, { _id: String(_id) });
36651
+ try {
36652
+ const cached = await getCache(cacheKey);
36653
+ if (cached) {
36654
+ import_nodejs_utils41.logger.log({
36655
+ level: "info",
36656
+ message: `Cache hit for getById section: ${cacheKey}`
36657
+ });
36658
+ return cached;
36659
+ }
36660
+ const result = await collection.findOne({
36661
+ _id,
36662
+ deletedAt: { $in: ["", null] }
36663
+ });
36664
+ if (!result) {
36665
+ throw new import_nodejs_utils41.BadRequestError("Section not found.");
36666
+ }
36667
+ setCache(cacheKey, result, 300).then(() => {
36668
+ import_nodejs_utils41.logger.log({
36669
+ level: "info",
36670
+ message: `Cache set for section by id: ${cacheKey}`
36671
+ });
36672
+ }).catch((err) => {
36673
+ import_nodejs_utils41.logger.log({
36674
+ level: "error",
36675
+ message: `Failed to set cache for section by id: ${err.message}`
36676
+ });
36677
+ });
36678
+ return result;
36679
+ } catch (error) {
36680
+ if (error instanceof import_nodejs_utils41.AppError) {
36681
+ throw error;
36682
+ } else {
36683
+ throw new import_nodejs_utils41.InternalServerError("Failed to get section.");
36684
+ }
36685
+ }
36686
+ }
36687
+ async function getByName(name) {
36688
+ const cacheKey = (0, import_nodejs_utils41.makeCacheKey)(namespace_collection, { name });
36689
+ try {
36690
+ const cached = await getCache(cacheKey);
36691
+ if (cached) {
36692
+ import_nodejs_utils41.logger.log({
36693
+ level: "info",
36694
+ message: `Cache hit for getByName section: ${cacheKey}`
36695
+ });
36696
+ return cached;
36697
+ }
36698
+ const result = await collection.findOne({
36699
+ name,
36700
+ deletedAt: { $in: ["", null] }
36701
+ });
36702
+ if (!result) {
36703
+ throw new import_nodejs_utils41.BadRequestError("Section not found.");
36704
+ }
36705
+ setCache(cacheKey, result, 300).then(() => {
36706
+ import_nodejs_utils41.logger.log({
36707
+ level: "info",
36708
+ message: `Cache set for section by name: ${cacheKey}`
36709
+ });
36710
+ }).catch((err) => {
36711
+ import_nodejs_utils41.logger.log({
36712
+ level: "error",
36713
+ message: `Failed to set cache for section by name: ${err.message}`
36714
+ });
36715
+ });
36716
+ return result;
36717
+ } catch (error) {
36718
+ if (error instanceof import_nodejs_utils41.AppError) {
36719
+ throw error;
36720
+ } else {
36721
+ throw new import_nodejs_utils41.InternalServerError("Failed to get section.");
36722
+ }
36723
+ }
36724
+ }
36725
+ async function getBySchool(school) {
36726
+ try {
36727
+ school = new import_mongodb24.ObjectId(school);
36728
+ } catch (error) {
36729
+ throw new import_nodejs_utils41.BadRequestError("Invalid school ID.");
36730
+ }
36731
+ const cacheKey = (0, import_nodejs_utils41.makeCacheKey)(namespace_collection, {
36732
+ school: String(school)
36733
+ });
36734
+ try {
36735
+ const cached = await getCache(cacheKey);
36736
+ if (cached) {
36737
+ import_nodejs_utils41.logger.log({
36738
+ level: "info",
36739
+ message: `Cache hit for getBySchool sections: ${cacheKey}`
36740
+ });
36741
+ return cached;
36742
+ }
36743
+ const result = await collection.find({
36744
+ school,
36745
+ deletedAt: { $in: ["", null] }
36746
+ }).toArray();
36747
+ setCache(cacheKey, result, 300).then(() => {
36748
+ import_nodejs_utils41.logger.log({
36749
+ level: "info",
36750
+ message: `Cache set for sections by school: ${cacheKey}`
36751
+ });
36752
+ }).catch((err) => {
36753
+ import_nodejs_utils41.logger.log({
36754
+ level: "error",
36755
+ message: `Failed to set cache for sections by school: ${err.message}`
36756
+ });
36757
+ });
36758
+ return result;
36759
+ } catch (error) {
36760
+ if (error instanceof import_nodejs_utils41.AppError) {
36761
+ throw error;
36762
+ } else {
36763
+ throw new import_nodejs_utils41.InternalServerError("Failed to get sections by school.");
36764
+ }
36765
+ }
36766
+ }
36767
+ async function updateFieldById({ _id, field, value } = {}, session) {
36768
+ const allowedFields = [
36769
+ "name",
36770
+ "schoolYear",
36771
+ "gradeLevel",
36772
+ "adviser",
36773
+ "adviserName"
36774
+ ];
36775
+ if (!allowedFields.includes(field)) {
36776
+ throw new import_nodejs_utils41.BadRequestError(
36777
+ `Field "${field}" is not allowed to be updated.`
36778
+ );
36779
+ }
36780
+ try {
36781
+ _id = new import_mongodb24.ObjectId(_id);
36782
+ } catch (error) {
36783
+ throw new import_nodejs_utils41.BadRequestError("Invalid ID.");
36784
+ }
36785
+ if (field === "adviser" && value) {
36786
+ try {
36787
+ value = new import_mongodb24.ObjectId(value).toString();
36788
+ } catch (error) {
36789
+ throw new import_nodejs_utils41.BadRequestError("Invalid adviser ID.");
36790
+ }
36791
+ }
36792
+ try {
36793
+ const updateValue = field === "adviser" ? new import_mongodb24.ObjectId(value) : value;
36794
+ await collection.updateOne(
36795
+ { _id, deletedAt: { $in: ["", null] } },
36796
+ { $set: { [field]: updateValue, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
36797
+ { session }
36798
+ );
36799
+ delCachedData();
36800
+ return `Successfully updated section ${field}.`;
36801
+ } catch (error) {
36802
+ throw new import_nodejs_utils41.InternalServerError(`Failed to update section ${field}.`);
36803
+ }
36804
+ }
36805
+ async function addStudentToSection(_id, studentId, session) {
36806
+ try {
36807
+ _id = new import_mongodb24.ObjectId(_id);
36808
+ } catch (error) {
36809
+ throw new import_nodejs_utils41.BadRequestError("Invalid section ID.");
36810
+ }
36811
+ try {
36812
+ await collection.updateOne(
36813
+ { _id, deletedAt: { $in: ["", null] } },
36814
+ {
36815
+ $addToSet: { students: studentId },
36816
+ $set: { updatedAt: (/* @__PURE__ */ new Date()).toISOString() }
36817
+ },
36818
+ { session }
36819
+ );
36820
+ delCachedData();
36821
+ return "Successfully added student to section.";
36822
+ } catch (error) {
36823
+ throw new import_nodejs_utils41.InternalServerError("Failed to add student to section.");
36824
+ }
36825
+ }
36826
+ async function removeStudentFromSection(_id, studentId, session) {
36827
+ try {
36828
+ _id = new import_mongodb24.ObjectId(_id);
36829
+ } catch (error) {
36830
+ throw new import_nodejs_utils41.BadRequestError("Invalid section ID.");
36831
+ }
36832
+ try {
36833
+ await collection.updateOne(
36834
+ { _id },
36835
+ {
36836
+ // @ts-ignore
36837
+ $pull: { students: studentId },
36838
+ $set: { updatedAt: (/* @__PURE__ */ new Date()).toISOString() }
36839
+ },
36840
+ { session }
36841
+ );
36842
+ delCachedData();
36843
+ return "Successfully removed student from section.";
36844
+ } catch (error) {
36845
+ throw new import_nodejs_utils41.InternalServerError("Failed to remove student from section.");
36846
+ }
36847
+ }
36848
+ async function deleteById(_id) {
36849
+ try {
36850
+ _id = new import_mongodb24.ObjectId(_id);
36851
+ } catch (error) {
36852
+ throw new import_nodejs_utils41.BadRequestError("Invalid ID.");
36853
+ }
36854
+ try {
36855
+ await collection.updateOne(
36856
+ { _id },
36857
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
36858
+ );
36859
+ delCachedData();
36860
+ return "Successfully deleted section.";
36861
+ } catch (error) {
36862
+ throw new import_nodejs_utils41.InternalServerError("Failed to delete section.");
36863
+ }
36864
+ }
36865
+ return {
36866
+ createIndexes,
36867
+ add,
36868
+ getAll,
36869
+ getById,
36870
+ getByName,
36871
+ getBySchool,
36872
+ updateFieldById,
36873
+ addStudentToSection,
36874
+ removeStudentFromSection,
36875
+ deleteById
36876
+ };
36877
+ }
36878
+
36879
+ // src/resources/section/section.controller.ts
36880
+ var import_nodejs_utils45 = require("@eeplatform/nodejs-utils");
36881
+ var import_joi27 = __toESM(require("joi"));
36882
+
36883
+ // src/resources/section/section.service.ts
36884
+ var import_nodejs_utils44 = require("@eeplatform/nodejs-utils");
36885
+
36886
+ // src/resources/section-student/section.student.repository.ts
36887
+ var import_nodejs_utils43 = require("@eeplatform/nodejs-utils");
36888
+
36889
+ // src/resources/section-student/section.student.model.ts
36890
+ var import_nodejs_utils42 = require("@eeplatform/nodejs-utils");
36891
+ var import_joi26 = __toESM(require("joi"));
36892
+ var import_mongodb25 = require("mongodb");
36893
+ var allowedSectionStudentStatuses = [
36894
+ "active",
36895
+ "dropped",
36896
+ "section-transferred",
36897
+ "school-transferred"
36898
+ ];
36899
+ var schemaSectionStudent = import_joi26.default.object({
36900
+ _id: import_joi26.default.string().hex().optional().allow(null, ""),
36901
+ section: import_joi26.default.string().hex().required(),
36902
+ student: import_joi26.default.string().required(),
36903
+ studentName: import_joi26.default.string().required(),
36904
+ status: import_joi26.default.string().valid(...allowedSectionStudentStatuses).optional().allow(null, ""),
36905
+ assignedAt: import_joi26.default.string().isoDate().optional().allow(null, ""),
36906
+ updatedAt: import_joi26.default.string().isoDate().optional().allow(null, "")
36907
+ });
36908
+ function modelSectionStudent(value) {
36909
+ const { error } = schemaSectionStudent.validate(value);
36910
+ if (error) {
36911
+ throw new import_nodejs_utils42.BadRequestError(`Invalid section-student data: ${error.message}`);
36912
+ }
36913
+ if (value._id && typeof value._id === "string") {
36914
+ try {
36915
+ value._id = new import_mongodb25.ObjectId(value._id);
36916
+ } catch (error2) {
36917
+ throw new Error("Invalid _id.");
36918
+ }
36919
+ }
36920
+ if (value.section && typeof value.section === "string") {
36921
+ try {
36922
+ value.section = new import_mongodb25.ObjectId(value.section);
36923
+ } catch (error2) {
36924
+ throw new Error("Invalid section ID.");
36925
+ }
36926
+ }
36927
+ return {
36928
+ _id: value._id,
36929
+ section: value.section,
36930
+ student: value.student,
36931
+ studentName: value.studentName,
36932
+ status: value.status ?? "active",
36933
+ assignedAt: value.assignedAt ?? "",
36934
+ updatedAt: value.updatedAt ?? ""
36935
+ };
36936
+ }
36937
+
36938
+ // src/resources/section-student/section.student.repository.ts
36939
+ function useSectionStudentRepo() {
36940
+ const db = import_nodejs_utils43.useAtlas.getDb();
36941
+ if (!db) {
36942
+ throw new Error("Unable to connect to server.");
36943
+ }
36944
+ const namespace_collection = "deped.section.students";
36945
+ const collection = db.collection(namespace_collection);
36946
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils43.useCache)(namespace_collection);
36947
+ async function createIndexes() {
36948
+ try {
36949
+ await collection.createIndexes([
36950
+ { key: { status: 1 } },
36951
+ { key: { school: 1, status: 1 } },
36952
+ { key: { "learnerInfo.lrn": 1 } },
36953
+ { key: { schoolYear: 1 } },
36954
+ { key: { gradeLevelToEnroll: 1 } },
36955
+ {
36956
+ key: {
36957
+ "learnerInfo.firstName": "text",
36958
+ "learnerInfo.lastName": "text"
36959
+ },
36960
+ name: "learner_name_text_index"
36961
+ }
36962
+ ]);
36963
+ } catch (error) {
36964
+ throw new Error("Failed to create index on learners.");
36965
+ }
36966
+ }
36967
+ function delCachedData() {
36968
+ delNamespace().then(() => {
36969
+ import_nodejs_utils43.logger.log({
36970
+ level: "info",
36971
+ message: `Cache cleared for namespace: ${namespace_collection}`
36972
+ });
36973
+ }).catch((error) => {
36974
+ import_nodejs_utils43.logger.log({
36975
+ level: "error",
36976
+ message: `Failed to clear cache for namespace ${namespace_collection}: ${error.message}`
36977
+ });
36978
+ });
36979
+ }
36980
+ async function add(value, session) {
36981
+ try {
36982
+ value = modelSectionStudent(value);
36983
+ const res = await collection.insertOne(value, { session });
36984
+ delCachedData();
36985
+ return res.insertedId;
36986
+ } catch (error) {
36987
+ import_nodejs_utils43.logger.log({
36988
+ level: "error",
36989
+ message: error.message
36990
+ });
36991
+ if (error instanceof import_nodejs_utils43.AppError) {
36992
+ throw error;
36993
+ } else {
36994
+ const isDuplicated = error.message.includes("duplicate");
36995
+ if (isDuplicated) {
36996
+ throw new import_nodejs_utils43.BadRequestError("Section student already exists.");
36997
+ }
36998
+ throw new import_nodejs_utils43.InternalServerError("Failed to create section student.");
36999
+ }
37000
+ }
37001
+ }
37002
+ return {
37003
+ createIndexes,
37004
+ delCachedData,
37005
+ add
37006
+ };
37007
+ }
37008
+
37009
+ // src/resources/section/section.service.ts
37010
+ function useSectionService() {
37011
+ const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
37012
+ const { getByGradeLevel } = useGradeLevelRepo();
37013
+ const { add: createSection } = useSectionRepo();
37014
+ const { add: assignStudent } = useSectionStudentRepo();
37015
+ function distributeStudents(total, minPer, maxPer) {
37016
+ if (total <= 0)
37017
+ return [];
37018
+ if (minPer <= 0 || maxPer <= 0)
37019
+ return [];
37020
+ if (minPer > maxPer) {
37021
+ throw new import_nodejs_utils44.BadRequestError(
37022
+ "Minimum students per section cannot be greater than maximum."
37023
+ );
37024
+ }
37025
+ const minSections = Math.ceil(total / maxPer);
37026
+ const maxSections = Math.floor(total / minPer);
37027
+ let sectionCount;
37028
+ if (minSections <= maxSections) {
37029
+ sectionCount = minSections;
37030
+ } else {
37031
+ sectionCount = minSections;
37032
+ }
37033
+ const base = Math.floor(total / sectionCount);
37034
+ const extra = total % sectionCount;
37035
+ const sizes = new Array(sectionCount).fill(base);
37036
+ for (let i = 0; i < extra; i++) {
37037
+ sizes[i] += 1;
37038
+ }
37039
+ for (const size of sizes) {
37040
+ if (size > maxPer) {
37041
+ throw new import_nodejs_utils44.BadRequestError(
37042
+ `Generated section exceeds max limit of ${maxPer}.`
37043
+ );
37044
+ }
37045
+ }
37046
+ return sizes;
37047
+ }
37048
+ async function generateSections(value) {
37049
+ const { error } = schemaGenerateSections.validate(value);
37050
+ if (error) {
37051
+ throw new import_nodejs_utils44.BadRequestError(
37052
+ `Invalid section generation data: ${error.message}`
37053
+ );
37054
+ }
37055
+ const session = import_nodejs_utils44.useAtlas.getClient()?.startSession();
37056
+ if (!session) {
37057
+ throw new Error("Unable to start database session.");
37058
+ }
37059
+ try {
37060
+ await session.startTransaction();
37061
+ const studentCount = await getCountByGradeLevel(
37062
+ {
37063
+ school: value.school,
37064
+ schoolYear: value.schoolYear,
37065
+ gradeLevel: value.gradeLevel
37066
+ },
37067
+ session
37068
+ );
37069
+ if (studentCount === 0) {
37070
+ throw new import_nodejs_utils44.BadRequestError("No learners found for this grade level.");
37071
+ }
37072
+ const gradeLevelData = await getByGradeLevel(
37073
+ {
37074
+ school: value.school,
37075
+ gradeLevel: value.gradeLevel
37076
+ },
37077
+ session
37078
+ );
37079
+ if (!gradeLevelData) {
37080
+ throw new import_nodejs_utils44.BadRequestError("Grade level not found.");
37081
+ }
37082
+ const minPerSection = gradeLevelData.minNumberOfLearners;
37083
+ const maxPerSection = gradeLevelData.maxNumberOfLearners;
37084
+ const sectionsNeeded = Math.ceil(studentCount / minPerSection);
37085
+ if (sectionsNeeded > value.set.length) {
37086
+ throw new import_nodejs_utils44.BadRequestError(
37087
+ "Insufficient number of section names in set[]."
37088
+ );
37089
+ }
37090
+ const sectionSizes = distributeStudents(
37091
+ studentCount,
37092
+ minPerSection,
37093
+ maxPerSection
37094
+ );
37095
+ if (sectionSizes.length === 0) {
37096
+ throw new import_nodejs_utils44.BadRequestError("Unable to compute section sizes.");
37097
+ }
37098
+ let pointer = 0;
37099
+ for (let i = 0; i < sectionSizes.length; i++) {
37100
+ const size = sectionSizes[i];
37101
+ const sectionName = value.set[i];
37102
+ const section = await createSection(
37103
+ {
37104
+ school: value.school,
37105
+ schoolYear: value.schoolYear,
37106
+ gradeLevel: value.gradeLevel,
37107
+ name: sectionName,
37108
+ students: size
37109
+ },
37110
+ session
37111
+ );
37112
+ const learners = await getLeanerByGradeLevel(
37113
+ {
37114
+ school: value.school,
37115
+ gradeLevel: value.gradeLevel,
37116
+ skip: pointer,
37117
+ limit: size
37118
+ },
37119
+ session
37120
+ );
37121
+ if (!learners.length) {
37122
+ throw new import_nodejs_utils44.BadRequestError(`No learners found for section #${i + 1}.`);
37123
+ }
37124
+ pointer += size;
37125
+ for (const student of learners) {
37126
+ if (!student._id) {
37127
+ throw new import_nodejs_utils44.BadRequestError("Learner ID is missing.");
37128
+ }
37129
+ await assignStudent(
37130
+ {
37131
+ section: section.toString(),
37132
+ student: student._id?.toString(),
37133
+ studentName: `${student.learnerInfo.firstName} ${student.learnerInfo.lastName}`,
37134
+ status: "active"
37135
+ },
37136
+ session
37137
+ );
37138
+ }
37139
+ }
37140
+ await session.commitTransaction();
37141
+ return "Sections generated successfully.";
37142
+ } catch (error2) {
37143
+ await session.abortTransaction();
37144
+ if (error2 instanceof import_nodejs_utils44.AppError) {
37145
+ throw error2;
37146
+ } else {
37147
+ throw new import_nodejs_utils44.InternalServerError("Failed to generate sections.");
37148
+ }
37149
+ } finally {
37150
+ await session?.endSession();
37151
+ }
37152
+ }
37153
+ return { generateSections };
37154
+ }
37155
+
37156
+ // src/resources/section/section.controller.ts
37157
+ function useSectionController() {
37158
+ const {
37159
+ add: _add,
37160
+ getAll: _getAll,
37161
+ getById: _getById,
37162
+ getByName: _getByName,
37163
+ getBySchool: _getBySchool,
37164
+ updateFieldById: _updateFieldById,
37165
+ addStudentToSection: _addStudentToSection,
37166
+ removeStudentFromSection: _removeStudentFromSection,
37167
+ deleteById: _deleteById
37168
+ } = useSectionRepo();
37169
+ const { generateSections: _generateSections } = useSectionService();
37170
+ async function add(req, res, next) {
37171
+ const value = req.body;
37172
+ const { error } = schemaSection.validate(value);
37173
+ if (error) {
37174
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37175
+ return;
37176
+ }
37177
+ try {
37178
+ const data = await _add(value);
37179
+ res.json({
37180
+ message: "Successfully created section.",
37181
+ data
37182
+ });
37183
+ return;
37184
+ } catch (error2) {
37185
+ next(error2);
37186
+ }
37187
+ }
37188
+ async function generateSections(req, res, next) {
37189
+ const value = req.body;
37190
+ const { error } = schemaGenerateSections.validate(value);
37191
+ if (error) {
37192
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37193
+ return;
37194
+ }
37195
+ try {
37196
+ const data = await _generateSections(value);
37197
+ res.json({
37198
+ message: "Successfully created section.",
37199
+ data
37200
+ });
37201
+ return;
37202
+ } catch (error2) {
37203
+ next(error2);
37204
+ }
37205
+ }
37206
+ async function getAll(req, res, next) {
37207
+ const query = req.query;
37208
+ const validation = import_joi27.default.object({
37209
+ page: import_joi27.default.number().min(1).optional().allow("", null),
37210
+ limit: import_joi27.default.number().min(1).optional().allow("", null),
37211
+ search: import_joi27.default.string().optional().allow("", null),
37212
+ status: import_joi27.default.string().optional().allow("", null),
37213
+ school: import_joi27.default.string().hex().optional().allow("", null),
37214
+ schoolYear: import_joi27.default.string().optional().allow("", null),
37215
+ gradeLevel: import_joi27.default.string().optional().allow("", null)
37216
+ });
37217
+ const { error } = validation.validate(query);
37218
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
37219
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
37220
+ const search = req.query.search ?? "";
37221
+ const status = req.query.status ?? "active";
37222
+ const school = req.query.school ?? "";
37223
+ const schoolYear = req.query.schoolYear ?? "";
37224
+ const gradeLevel = req.query.gradeLevel ?? "";
37225
+ const isPageNumber = isFinite(page);
37226
+ if (!isPageNumber) {
37227
+ next(new import_nodejs_utils45.BadRequestError("Invalid page number."));
37228
+ return;
37229
+ }
37230
+ const isLimitNumber = isFinite(limit);
37231
+ if (!isLimitNumber) {
37232
+ next(new import_nodejs_utils45.BadRequestError("Invalid limit number."));
37233
+ return;
37234
+ }
37235
+ if (error) {
37236
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37237
+ return;
37238
+ }
37239
+ try {
37240
+ const data = await _getAll({
37241
+ page,
37242
+ limit,
37243
+ search,
37244
+ status,
37245
+ school,
37246
+ schoolYear,
37247
+ gradeLevel
37248
+ });
37249
+ res.json(data);
37250
+ return;
37251
+ } catch (error2) {
37252
+ next(error2);
37253
+ }
37254
+ }
37255
+ async function getById(req, res, next) {
37256
+ const id = req.params.id;
37257
+ const validation = import_joi27.default.object({
37258
+ id: import_joi27.default.string().hex().required()
37259
+ });
37260
+ const { error } = validation.validate({ id });
37261
+ if (error) {
37262
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37263
+ return;
37264
+ }
37265
+ try {
37266
+ const data = await _getById(id);
37267
+ res.json({
37268
+ message: "Successfully retrieved section.",
37269
+ data
37270
+ });
37271
+ return;
37272
+ } catch (error2) {
37273
+ next(error2);
37274
+ }
37275
+ }
37276
+ async function getByName(req, res, next) {
37277
+ const name = req.params.name;
37278
+ const validation = import_joi27.default.object({
37279
+ name: import_joi27.default.string().required()
37280
+ });
37281
+ const { error } = validation.validate({ name });
37282
+ if (error) {
37283
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37284
+ return;
37285
+ }
37286
+ try {
37287
+ const data = await _getByName(name);
37288
+ res.json({
37289
+ message: "Successfully retrieved section.",
37290
+ data
37291
+ });
37292
+ return;
37293
+ } catch (error2) {
37294
+ next(error2);
37295
+ }
37296
+ }
37297
+ async function getBySchool(req, res, next) {
37298
+ const school = req.params.school;
37299
+ const validation = import_joi27.default.object({
37300
+ school: import_joi27.default.string().hex().required()
37301
+ });
37302
+ const { error } = validation.validate({ school });
37303
+ if (error) {
37304
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37305
+ return;
37306
+ }
37307
+ try {
37308
+ const data = await _getBySchool(school);
37309
+ res.json({
37310
+ message: "Successfully retrieved sections.",
37311
+ data
37312
+ });
37313
+ return;
37314
+ } catch (error2) {
37315
+ next(error2);
37316
+ }
37317
+ }
37318
+ async function updateField(req, res, next) {
37319
+ const _id = req.params.id;
37320
+ const { field, value } = req.body;
37321
+ const validation = import_joi27.default.object({
37322
+ _id: import_joi27.default.string().hex().required(),
37323
+ field: import_joi27.default.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
37324
+ value: import_joi27.default.string().required()
37325
+ });
37326
+ const { error } = validation.validate({ _id, field, value });
37327
+ if (error) {
37328
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37329
+ return;
37330
+ }
37331
+ try {
37332
+ const message = await _updateFieldById({ _id, field, value });
37333
+ res.json({ message });
37334
+ return;
37335
+ } catch (error2) {
37336
+ next(error2);
37337
+ }
37338
+ }
37339
+ async function addStudent(req, res, next) {
37340
+ const _id = req.params.id;
37341
+ const { studentId } = req.body;
37342
+ const validation = import_joi27.default.object({
37343
+ _id: import_joi27.default.string().hex().required(),
37344
+ studentId: import_joi27.default.string().required()
37345
+ });
37346
+ const { error } = validation.validate({ _id, studentId });
37347
+ if (error) {
37348
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37349
+ return;
37350
+ }
37351
+ try {
37352
+ const message = await _addStudentToSection(_id, studentId);
37353
+ res.json({ message });
37354
+ return;
37355
+ } catch (error2) {
37356
+ next(error2);
37357
+ }
37358
+ }
37359
+ async function removeStudent(req, res, next) {
37360
+ const _id = req.params.id;
37361
+ const { studentId } = req.body;
37362
+ const validation = import_joi27.default.object({
37363
+ _id: import_joi27.default.string().hex().required(),
37364
+ studentId: import_joi27.default.string().required()
37365
+ });
37366
+ const { error } = validation.validate({ _id, studentId });
37367
+ if (error) {
37368
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37369
+ return;
37370
+ }
37371
+ try {
37372
+ const message = await _removeStudentFromSection(_id, studentId);
37373
+ res.json({ message });
37374
+ return;
37375
+ } catch (error2) {
37376
+ next(error2);
37377
+ }
37378
+ }
37379
+ async function deleteById(req, res, next) {
37380
+ const _id = req.params.id;
37381
+ const validation = import_joi27.default.object({
37382
+ _id: import_joi27.default.string().hex().required()
37383
+ });
37384
+ const { error } = validation.validate({ _id });
37385
+ if (error) {
37386
+ next(new import_nodejs_utils45.BadRequestError(error.message));
37387
+ return;
37388
+ }
37389
+ try {
37390
+ const message = await _deleteById(_id);
37391
+ res.json({ message });
37392
+ return;
37393
+ } catch (error2) {
37394
+ next(error2);
37395
+ }
37396
+ }
37397
+ return {
37398
+ add,
37399
+ generateSections,
37400
+ getAll,
37401
+ getById,
37402
+ getByName,
37403
+ getBySchool,
37404
+ updateField,
37405
+ addStudent,
37406
+ removeStudent,
37407
+ deleteById
37408
+ };
37409
+ }
37410
+
35766
37411
  // src/config.ts
35767
37412
  var dotenv = __toESM(require("dotenv"));
35768
37413
  dotenv.config();
@@ -35774,10 +37419,14 @@ dotenv.config();
35774
37419
  MLearner,
35775
37420
  MPlantilla,
35776
37421
  MStockCard,
37422
+ allowedSectionStudentStatuses,
35777
37423
  modelBasicEduCount,
35778
37424
  modelDivision,
35779
37425
  modelRegion,
35780
37426
  modelSchool,
37427
+ modelSection,
37428
+ modelSectionPreset,
37429
+ modelSectionStudent,
35781
37430
  schemaAsset,
35782
37431
  schemaAssetUpdateOption,
35783
37432
  schemaBasicEduCount,
@@ -35785,11 +37434,15 @@ dotenv.config();
35785
37434
  schemaDivision,
35786
37435
  schemaDivisionUpdate,
35787
37436
  schemaEnrollment,
37437
+ schemaGenerateSections,
35788
37438
  schemaGradeLevel,
35789
37439
  schemaPlantilla,
35790
37440
  schemaRegion,
35791
37441
  schemaSchool,
35792
37442
  schemaSchoolUpdate,
37443
+ schemaSection,
37444
+ schemaSectionPreset,
37445
+ schemaSectionStudent,
35793
37446
  schemaStockCard,
35794
37447
  schemaUpdateStatus,
35795
37448
  useAssetController,
@@ -35815,6 +37468,11 @@ dotenv.config();
35815
37468
  useSchoolController,
35816
37469
  useSchoolRepo,
35817
37470
  useSchoolService,
37471
+ useSectionController,
37472
+ useSectionPresetController,
37473
+ useSectionPresetRepo,
37474
+ useSectionRepo,
37475
+ useSectionStudentRepo,
35818
37476
  useStockCardController,
35819
37477
  useStockCardRepository,
35820
37478
  useStockCardService