@eeplatform/basic-edu 1.4.3 → 1.5.0

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