@eeplatform/basic-edu 1.4.2 → 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() {
@@ -2115,24 +2124,41 @@ function useEnrollmentRepo() {
2115
2124
  status = "active",
2116
2125
  school = "",
2117
2126
  schoolYear = "",
2118
- gradeLevelToEnroll = ""
2127
+ gradeLevelToEnroll = "",
2128
+ createdBy = ""
2119
2129
  } = {}) {
2120
2130
  page = page > 0 ? page - 1 : 0;
2121
2131
  const query = {
2122
2132
  status
2123
2133
  };
2134
+ const cacheParams = {
2135
+ page,
2136
+ limit,
2137
+ sort: JSON.stringify(sort)
2138
+ };
2139
+ if (createdBy) {
2140
+ try {
2141
+ query.createdBy = new import_mongodb4.ObjectId(createdBy);
2142
+ cacheParams.createdBy = createdBy;
2143
+ } catch (error) {
2144
+ throw new import_nodejs_utils5.BadRequestError("Invalid createdBy ID.");
2145
+ }
2146
+ }
2124
2147
  if (school) {
2125
2148
  try {
2126
2149
  query.school = new import_mongodb4.ObjectId(school);
2150
+ cacheParams.school = school;
2127
2151
  } catch (error) {
2128
2152
  throw new import_nodejs_utils5.BadRequestError("Invalid school ID.");
2129
2153
  }
2130
2154
  }
2131
2155
  if (schoolYear) {
2132
2156
  query.schoolYear = schoolYear;
2157
+ cacheParams.schoolYear = schoolYear;
2133
2158
  }
2134
2159
  if (gradeLevelToEnroll) {
2135
2160
  query.gradeLevelToEnroll = gradeLevelToEnroll;
2161
+ cacheParams.gradeLevelToEnroll = gradeLevelToEnroll;
2136
2162
  }
2137
2163
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
2138
2164
  if (search) {
@@ -2144,11 +2170,6 @@ function useEnrollmentRepo() {
2144
2170
  { gradeLevelToEnroll: { $regex: search, $options: "i" } }
2145
2171
  ];
2146
2172
  }
2147
- const cacheParams = {
2148
- page,
2149
- limit,
2150
- sort: JSON.stringify(sort)
2151
- };
2152
2173
  if (search)
2153
2174
  cacheParams.search = search;
2154
2175
  if (status !== "active")
@@ -2376,6 +2397,7 @@ var import_nodejs_utils10 = require("@eeplatform/nodejs-utils");
2376
2397
  // src/resources/learner/learner.repository.ts
2377
2398
  var import_nodejs_utils6 = require("@eeplatform/nodejs-utils");
2378
2399
  var import_mongodb5 = require("mongodb");
2400
+ var import_joi5 = __toESM(require("joi"));
2379
2401
  function useLearnerRepo() {
2380
2402
  const db = import_nodejs_utils6.useAtlas.getDb();
2381
2403
  if (!db) {
@@ -2401,7 +2423,7 @@ function useLearnerRepo() {
2401
2423
  }
2402
2424
  ]);
2403
2425
  } catch (error) {
2404
- throw new Error("Failed to create index on enrollments.");
2426
+ throw new Error("Failed to create index on learners.");
2405
2427
  }
2406
2428
  }
2407
2429
  function delCachedData() {
@@ -2434,10 +2456,10 @@ function useLearnerRepo() {
2434
2456
  const isDuplicated = error.message.includes("duplicate");
2435
2457
  if (isDuplicated) {
2436
2458
  throw new import_nodejs_utils6.BadRequestError(
2437
- "Enrollment already exists for this learner and school year."
2459
+ "learner already exists for this learner and school year."
2438
2460
  );
2439
2461
  }
2440
- throw new Error("Failed to create enrollment.");
2462
+ throw new Error("Failed to create learner.");
2441
2463
  }
2442
2464
  }
2443
2465
  }
@@ -2449,61 +2471,50 @@ function useLearnerRepo() {
2449
2471
  status = "active",
2450
2472
  school = "",
2451
2473
  schoolYear = "",
2452
- gradeLevelToEnroll = ""
2474
+ level = ""
2453
2475
  } = {}) {
2454
2476
  page = page > 0 ? page - 1 : 0;
2455
2477
  const query = {
2456
2478
  status
2457
2479
  };
2480
+ const cacheParams = {
2481
+ status,
2482
+ page,
2483
+ limit,
2484
+ sort: JSON.stringify(sort)
2485
+ };
2458
2486
  if (school) {
2459
2487
  try {
2460
2488
  query.school = new import_mongodb5.ObjectId(school);
2489
+ cacheParams.school = school;
2461
2490
  } catch (error) {
2462
2491
  throw new import_nodejs_utils6.BadRequestError("Invalid school ID.");
2463
2492
  }
2464
2493
  }
2465
2494
  if (schoolYear) {
2466
2495
  query.schoolYear = schoolYear;
2496
+ cacheParams.schoolYear = schoolYear;
2467
2497
  }
2468
- if (gradeLevelToEnroll) {
2469
- query.gradeLevelToEnroll = gradeLevelToEnroll;
2498
+ if (level) {
2499
+ query.gradeLevel = level;
2500
+ cacheParams.level = level;
2470
2501
  }
2471
2502
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
2472
2503
  if (search) {
2473
- query.$or = [
2474
- { "learnerInfo.firstName": { $regex: search, $options: "i" } },
2475
- { "learnerInfo.lastName": { $regex: search, $options: "i" } },
2476
- { "learnerInfo.lrn": { $regex: search, $options: "i" } },
2477
- { schoolYear: { $regex: search, $options: "i" } },
2478
- { gradeLevelToEnroll: { $regex: search, $options: "i" } }
2479
- ];
2480
- }
2481
- const cacheParams = {
2482
- page,
2483
- limit,
2484
- sort: JSON.stringify(sort)
2485
- };
2486
- if (search)
2504
+ query.$text = { $search: search };
2487
2505
  cacheParams.search = search;
2488
- if (status !== "active")
2489
- cacheParams.status = status;
2490
- if (school)
2491
- cacheParams.school = school;
2492
- if (schoolYear)
2493
- cacheParams.schoolYear = schoolYear;
2494
- if (gradeLevelToEnroll)
2495
- cacheParams.gradeLevelToEnroll = gradeLevelToEnroll;
2506
+ }
2496
2507
  const cacheKey = (0, import_nodejs_utils6.makeCacheKey)(namespace_collection, cacheParams);
2497
2508
  import_nodejs_utils6.logger.log({
2498
2509
  level: "info",
2499
- message: `Cache key for getAll enrollments: ${cacheKey}`
2510
+ message: `Cache key for getAll learners: ${cacheKey}`
2500
2511
  });
2501
2512
  try {
2502
2513
  const cached = await getCache(cacheKey);
2503
2514
  if (cached) {
2504
2515
  import_nodejs_utils6.logger.log({
2505
2516
  level: "info",
2506
- message: `Cache hit for getAll enrollments: ${cacheKey}`
2517
+ message: `Cache hit for getAll learners: ${cacheKey}`
2507
2518
  });
2508
2519
  return cached;
2509
2520
  }
@@ -2519,12 +2530,12 @@ function useLearnerRepo() {
2519
2530
  setCache(cacheKey, data, 600).then(() => {
2520
2531
  import_nodejs_utils6.logger.log({
2521
2532
  level: "info",
2522
- message: `Cache set for getAll enrollments: ${cacheKey}`
2533
+ message: `Cache set for getAll learners: ${cacheKey}`
2523
2534
  });
2524
2535
  }).catch((err) => {
2525
2536
  import_nodejs_utils6.logger.log({
2526
2537
  level: "error",
2527
- message: `Failed to set cache for getAll enrollments: ${err.message}`
2538
+ message: `Failed to set cache for getAll learners: ${err.message}`
2528
2539
  });
2529
2540
  });
2530
2541
  return data;
@@ -2533,6 +2544,62 @@ function useLearnerRepo() {
2533
2544
  throw error;
2534
2545
  }
2535
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
+ }
2536
2603
  async function getById(_id, status = "") {
2537
2604
  try {
2538
2605
  _id = new import_mongodb5.ObjectId(_id);
@@ -2550,7 +2617,7 @@ function useLearnerRepo() {
2550
2617
  if (cachedData) {
2551
2618
  import_nodejs_utils6.logger.log({
2552
2619
  level: "info",
2553
- message: `Cache hit for enrollment by ID: ${cacheKey}`
2620
+ message: `Cache hit for learner by ID: ${cacheKey}`
2554
2621
  });
2555
2622
  return cachedData;
2556
2623
  }
@@ -2559,17 +2626,80 @@ function useLearnerRepo() {
2559
2626
  setCache(cacheKey, data, 600).then(() => {
2560
2627
  import_nodejs_utils6.logger.log({
2561
2628
  level: "info",
2562
- message: `Cache set for enrollment by ID: ${cacheKey}`
2629
+ message: `Cache set for learner by ID: ${cacheKey}`
2563
2630
  });
2564
2631
  }).catch((err) => {
2565
2632
  import_nodejs_utils6.logger.log({
2566
2633
  level: "error",
2567
- message: `Failed to set cache for enrollment by ID: ${err.message}`
2634
+ message: `Failed to set cache for learner by ID: ${err.message}`
2568
2635
  });
2569
2636
  });
2570
2637
  return data;
2571
2638
  } catch (error) {
2572
- 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.");
2573
2703
  }
2574
2704
  }
2575
2705
  async function updateStatusById(_id, status, session) {
@@ -2587,33 +2717,35 @@ function useLearnerRepo() {
2587
2717
  delCachedData();
2588
2718
  return result;
2589
2719
  } catch (error) {
2590
- throw new Error("Failed to update enrollment status.");
2720
+ throw new Error("Failed to update learner status.");
2591
2721
  }
2592
2722
  }
2593
2723
  return {
2594
2724
  createIndexes,
2595
2725
  add,
2596
2726
  getAll,
2727
+ getCountByGradeLevel,
2597
2728
  updateStatusById,
2598
- getById
2729
+ getById,
2730
+ getByGradeLevel
2599
2731
  };
2600
2732
  }
2601
2733
 
2602
2734
  // src/resources/learner/learner.controller.ts
2603
2735
  var import_nodejs_utils7 = require("@eeplatform/nodejs-utils");
2604
- var import_joi5 = __toESM(require("joi"));
2736
+ var import_joi6 = __toESM(require("joi"));
2605
2737
  function useLearnerController() {
2606
2738
  const { getAll: _getAll, updateStatusById: _updateStatusById } = useLearnerRepo();
2607
2739
  async function getAll(req, res, next) {
2608
2740
  const query = req.query;
2609
- const validation = import_joi5.default.object({
2610
- page: import_joi5.default.number().min(1).optional().allow("", null),
2611
- limit: import_joi5.default.number().min(1).max(100).optional().allow("", null),
2612
- search: import_joi5.default.string().optional().allow("", null),
2613
- status: import_joi5.default.string().optional().allow("", null),
2614
- school: import_joi5.default.string().hex().optional().allow("", null),
2615
- schoolYear: import_joi5.default.string().optional().allow("", null),
2616
- 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)
2617
2749
  });
2618
2750
  const { error } = validation.validate(query);
2619
2751
  if (error) {
@@ -2623,6 +2755,11 @@ function useLearnerController() {
2623
2755
  const page = parseInt(req.query.page) ?? 1;
2624
2756
  let limit = parseInt(req.query.limit) ?? 20;
2625
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 ?? "";
2626
2763
  const sort = req.query.sort ? String(req.query.sort).split(",") : "";
2627
2764
  const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
2628
2765
  const sortObj = {};
@@ -2637,11 +2774,11 @@ function useLearnerController() {
2637
2774
  page,
2638
2775
  limit,
2639
2776
  sort: sortObj,
2640
- search: req.query.search,
2641
- status: req.query.status,
2642
- school: req.query.school,
2643
- schoolYear: req.query.schoolYear,
2644
- gradeLevelToEnroll: req.query.gradeLevelToEnroll
2777
+ search,
2778
+ status,
2779
+ school,
2780
+ schoolYear,
2781
+ level
2645
2782
  });
2646
2783
  res.json(result);
2647
2784
  return;
@@ -2675,11 +2812,11 @@ var import_nodejs_utils9 = require("@eeplatform/nodejs-utils");
2675
2812
 
2676
2813
  // src/resources/count/count.model.ts
2677
2814
  var import_nodejs_utils8 = require("@eeplatform/nodejs-utils");
2678
- var import_joi6 = __toESM(require("joi"));
2679
- var schemaBasicEduCount = import_joi6.default.object({
2680
- _id: import_joi6.default.string().hex().length(24).optional(),
2681
- name: import_joi6.default.string().required(),
2682
- 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()
2683
2820
  });
2684
2821
  function modelBasicEduCount(value) {
2685
2822
  const { error } = schemaBasicEduCount.validate(value);
@@ -3017,7 +3154,7 @@ function useEnrollmentService() {
3017
3154
 
3018
3155
  // src/resources/enrollment/enrollment.controller.ts
3019
3156
  var import_nodejs_utils11 = require("@eeplatform/nodejs-utils");
3020
- var import_joi7 = __toESM(require("joi"));
3157
+ var import_joi8 = __toESM(require("joi"));
3021
3158
  function useEnrollmentController() {
3022
3159
  const { add: _add, updateStatusById: _updateStatusById } = useEnrollmentService();
3023
3160
  const { getAll: _getAll } = useEnrollmentRepo();
@@ -3039,14 +3176,15 @@ function useEnrollmentController() {
3039
3176
  }
3040
3177
  async function getAll(req, res, next) {
3041
3178
  const query = req.query;
3042
- const validation = import_joi7.default.object({
3043
- page: import_joi7.default.number().min(1).optional().allow("", null),
3044
- limit: import_joi7.default.number().min(1).max(100).optional().allow("", null),
3045
- search: import_joi7.default.string().optional().allow("", null),
3046
- status: import_joi7.default.string().optional().allow("", null),
3047
- school: import_joi7.default.string().hex().optional().allow("", null),
3048
- schoolYear: import_joi7.default.string().optional().allow("", null),
3049
- gradeLevelToEnroll: import_joi7.default.string().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)
3050
3188
  });
3051
3189
  const { error } = validation.validate(query);
3052
3190
  if (error) {
@@ -3058,6 +3196,7 @@ function useEnrollmentController() {
3058
3196
  limit = isNaN(limit) ? 20 : limit;
3059
3197
  const sort = req.query.sort ? String(req.query.sort).split(",") : "";
3060
3198
  const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
3199
+ const createdBy = req.query.createdBy ?? "";
3061
3200
  const sortObj = {};
3062
3201
  if (sort && sort.length > 0 && sortOrder && sortOrder.length > 0 && sort.length === sortOrder.length) {
3063
3202
  for (let i = 0; i < sort.length; i++) {
@@ -3074,7 +3213,8 @@ function useEnrollmentController() {
3074
3213
  status: req.query.status,
3075
3214
  school: req.query.school,
3076
3215
  schoolYear: req.query.schoolYear,
3077
- gradeLevelToEnroll: req.query.gradeLevelToEnroll
3216
+ gradeLevelToEnroll: req.query.gradeLevelToEnroll,
3217
+ createdBy
3078
3218
  });
3079
3219
  res.json(result);
3080
3220
  return;
@@ -3106,26 +3246,27 @@ function useEnrollmentController() {
3106
3246
 
3107
3247
  // src/resources/grade-level/grade-level.model.ts
3108
3248
  var import_nodejs_utils12 = require("@eeplatform/nodejs-utils");
3109
- var import_joi8 = __toESM(require("joi"));
3249
+ var import_joi9 = __toESM(require("joi"));
3110
3250
  var import_mongodb7 = require("mongodb");
3111
- var schemaGradeLevel = import_joi8.default.object({
3112
- _id: import_joi8.default.string().hex().optional(),
3113
- school: import_joi8.default.string().hex().optional(),
3114
- educationLevel: import_joi8.default.string().required(),
3115
- gradeLevel: import_joi8.default.string().required(),
3116
- tracks: import_joi8.default.array().items(import_joi8.default.string()).optional(),
3117
- trackStrands: import_joi8.default.array().items(import_joi8.default.string()).optional(),
3118
- teachingStyle: import_joi8.default.string().required(),
3119
- maxNumberOfLearners: import_joi8.default.number().required(),
3120
- defaultStartTime: import_joi8.default.string().optional().allow("", null),
3121
- defaultEndTime: import_joi8.default.string().optional().allow("", null),
3122
- status: import_joi8.default.string().optional().allow("", null),
3123
- createdAt: import_joi8.default.date().optional().allow("", null),
3124
- updatedAt: import_joi8.default.date().optional().allow("", null),
3125
- deletedAt: import_joi8.default.date().optional().allow("", null),
3126
- createdBy: import_joi8.default.string().optional().allow("", null),
3127
- updatedBy: import_joi8.default.string().optional().allow("", null),
3128
- 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)
3129
3270
  });
3130
3271
  function MGradeLevel(value) {
3131
3272
  const { error } = schemaGradeLevel.validate(value);
@@ -3147,6 +3288,11 @@ function MGradeLevel(value) {
3147
3288
  throw new import_nodejs_utils12.BadRequestError("Invalid school format");
3148
3289
  }
3149
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
+ }
3150
3296
  return {
3151
3297
  _id: value._id ?? void 0,
3152
3298
  school: value.school ?? void 0,
@@ -3156,6 +3302,7 @@ function MGradeLevel(value) {
3156
3302
  trackStrands: value.trackStrands ?? [],
3157
3303
  teachingStyle: value.teachingStyle ?? "",
3158
3304
  maxNumberOfLearners: value.maxNumberOfLearners ?? 0,
3305
+ minNumberOfLearners: value.minNumberOfLearners ?? 0,
3159
3306
  defaultStartTime: value.defaultStartTime ?? "",
3160
3307
  defaultEndTime: value.defaultEndTime ?? "",
3161
3308
  status: value.status ?? "active",
@@ -3176,7 +3323,7 @@ function useGradeLevelRepo() {
3176
3323
  if (!db) {
3177
3324
  throw new Error("Unable to connect to server.");
3178
3325
  }
3179
- const namespace_collection = "school.grade-levels";
3326
+ const namespace_collection = "deped.school.grade-levels";
3180
3327
  const collection = db.collection(namespace_collection);
3181
3328
  const { getCache, setCache, delNamespace } = (0, import_nodejs_utils13.useCache)(namespace_collection);
3182
3329
  async function createIndexes() {
@@ -3335,25 +3482,7 @@ function useGradeLevelRepo() {
3335
3482
  { $match: query },
3336
3483
  { $sort: sort },
3337
3484
  { $skip: page * limit },
3338
- { $limit: limit },
3339
- {
3340
- $lookup: {
3341
- from: "school.schools",
3342
- localField: "school",
3343
- foreignField: "_id",
3344
- as: "schoolDetails"
3345
- }
3346
- },
3347
- {
3348
- $addFields: {
3349
- schoolName: { $arrayElemAt: ["$schoolDetails.name", 0] }
3350
- }
3351
- },
3352
- {
3353
- $project: {
3354
- schoolDetails: 0
3355
- }
3356
- }
3485
+ { $limit: limit }
3357
3486
  ]).toArray();
3358
3487
  const length = await collection.countDocuments(query);
3359
3488
  const data = (0, import_nodejs_utils13.paginate)(items, page, limit, length);
@@ -3502,6 +3631,52 @@ function useGradeLevelRepo() {
3502
3631
  throw error;
3503
3632
  }
3504
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
+ }
3505
3680
  function delCachedData() {
3506
3681
  delNamespace().then(() => {
3507
3682
  import_nodejs_utils13.logger.log({
@@ -3522,13 +3697,14 @@ function useGradeLevelRepo() {
3522
3697
  getById,
3523
3698
  updateById,
3524
3699
  deleteById,
3525
- getByEducationLevel
3700
+ getByEducationLevel,
3701
+ getByGradeLevel
3526
3702
  };
3527
3703
  }
3528
3704
 
3529
3705
  // src/resources/grade-level/grade-level.controller.ts
3530
3706
  var import_nodejs_utils14 = require("@eeplatform/nodejs-utils");
3531
- var import_joi9 = __toESM(require("joi"));
3707
+ var import_joi10 = __toESM(require("joi"));
3532
3708
  function useGradeLevelController() {
3533
3709
  const {
3534
3710
  getAll: _getAll,
@@ -3560,17 +3736,17 @@ function useGradeLevelController() {
3560
3736
  async function updateById(req, res, next) {
3561
3737
  const value = req.body;
3562
3738
  const id = req.params.id ?? "";
3563
- const validation = import_joi9.default.object({
3564
- id: import_joi9.default.string().hex().required(),
3565
- value: import_joi9.default.object({
3566
- school: import_joi9.default.string().hex().optional(),
3567
- educationLevel: import_joi9.default.string().optional(),
3568
- gradeLevel: import_joi9.default.string().optional(),
3569
- teachingStyle: import_joi9.default.string().optional(),
3570
- maxTeachingHoursPerDay: import_joi9.default.number().integer().min(0).optional(),
3571
- maxTeachingHoursPerWeek: import_joi9.default.number().integer().min(0).optional(),
3572
- defaultStartTime: import_joi9.default.string().optional().allow("", null),
3573
- 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)
3574
3750
  }).min(1)
3575
3751
  });
3576
3752
  const { error } = validation.validate({ id, value });
@@ -3592,15 +3768,15 @@ function useGradeLevelController() {
3592
3768
  }
3593
3769
  async function getAll(req, res, next) {
3594
3770
  const query = req.query;
3595
- const validation = import_joi9.default.object({
3596
- page: import_joi9.default.number().min(1).optional().allow("", null),
3597
- limit: import_joi9.default.number().min(1).optional().allow("", null),
3598
- search: import_joi9.default.string().optional().allow("", null),
3599
- educationLevel: import_joi9.default.string().optional().allow("", null),
3600
- gradeLevel: import_joi9.default.string().optional().allow("", null),
3601
- teachingStyle: import_joi9.default.string().optional().allow("", null),
3602
- school: import_joi9.default.string().hex().optional().allow("", null),
3603
- 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)
3604
3780
  });
3605
3781
  const { error } = validation.validate(query);
3606
3782
  if (error) {
@@ -3644,8 +3820,8 @@ function useGradeLevelController() {
3644
3820
  }
3645
3821
  async function getById(req, res, next) {
3646
3822
  const id = req.params.id;
3647
- const validation = import_joi9.default.object({
3648
- id: import_joi9.default.string().hex().required()
3823
+ const validation = import_joi10.default.object({
3824
+ id: import_joi10.default.string().hex().required()
3649
3825
  });
3650
3826
  const { error } = validation.validate({ id });
3651
3827
  if (error) {
@@ -3665,8 +3841,8 @@ function useGradeLevelController() {
3665
3841
  }
3666
3842
  async function deleteById(req, res, next) {
3667
3843
  const id = req.params.id;
3668
- const validation = import_joi9.default.object({
3669
- id: import_joi9.default.string().hex().required()
3844
+ const validation = import_joi10.default.object({
3845
+ id: import_joi10.default.string().hex().required()
3670
3846
  });
3671
3847
  const { error } = validation.validate({ id });
3672
3848
  if (error) {
@@ -3687,9 +3863,9 @@ function useGradeLevelController() {
3687
3863
  async function getByEducationLevel(req, res, next) {
3688
3864
  const educationLevel = req.params.educationLevel;
3689
3865
  const school = req.query.school;
3690
- const validation = import_joi9.default.object({
3691
- educationLevel: import_joi9.default.string().required(),
3692
- 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)
3693
3869
  });
3694
3870
  const { error } = validation.validate({ educationLevel, school });
3695
3871
  if (error) {
@@ -3719,14 +3895,14 @@ function useGradeLevelController() {
3719
3895
 
3720
3896
  // src/resources/region/region.model.ts
3721
3897
  var import_nodejs_utils15 = require("@eeplatform/nodejs-utils");
3722
- var import_joi10 = __toESM(require("joi"));
3898
+ var import_joi11 = __toESM(require("joi"));
3723
3899
  var import_mongodb9 = require("mongodb");
3724
- var schemaRegion = import_joi10.default.object({
3725
- _id: import_joi10.default.string().hex().optional().allow(null, ""),
3726
- name: import_joi10.default.string().min(1).max(100).required(),
3727
- createdAt: import_joi10.default.string().isoDate().optional(),
3728
- updatedAt: import_joi10.default.string().isoDate().optional(),
3729
- 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, "")
3730
3906
  });
3731
3907
  function modelRegion(value) {
3732
3908
  const { error } = schemaRegion.validate(value);
@@ -4005,7 +4181,7 @@ function useRegionRepo() {
4005
4181
 
4006
4182
  // src/resources/region/region.controller.ts
4007
4183
  var import_nodejs_utils17 = require("@eeplatform/nodejs-utils");
4008
- var import_joi11 = __toESM(require("joi"));
4184
+ var import_joi12 = __toESM(require("joi"));
4009
4185
  function useRegionController() {
4010
4186
  const {
4011
4187
  add: _add,
@@ -4035,11 +4211,11 @@ function useRegionController() {
4035
4211
  }
4036
4212
  async function getAll(req, res, next) {
4037
4213
  const query = req.query;
4038
- const validation = import_joi11.default.object({
4039
- page: import_joi11.default.number().min(1).optional().allow("", null),
4040
- limit: import_joi11.default.number().min(1).optional().allow("", null),
4041
- search: import_joi11.default.string().optional().allow("", null),
4042
- 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)
4043
4219
  });
4044
4220
  const { error } = validation.validate(query);
4045
4221
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -4070,8 +4246,8 @@ function useRegionController() {
4070
4246
  }
4071
4247
  async function getById(req, res, next) {
4072
4248
  const id = req.params.id;
4073
- const validation = import_joi11.default.object({
4074
- id: import_joi11.default.string().hex().required()
4249
+ const validation = import_joi12.default.object({
4250
+ id: import_joi12.default.string().hex().required()
4075
4251
  });
4076
4252
  const { error } = validation.validate({ id });
4077
4253
  if (error) {
@@ -4091,8 +4267,8 @@ function useRegionController() {
4091
4267
  }
4092
4268
  async function getByName(req, res, next) {
4093
4269
  const name = req.params.name;
4094
- const validation = import_joi11.default.object({
4095
- name: import_joi11.default.string().required()
4270
+ const validation = import_joi12.default.object({
4271
+ name: import_joi12.default.string().required()
4096
4272
  });
4097
4273
  const { error } = validation.validate({ name });
4098
4274
  if (error) {
@@ -4113,10 +4289,10 @@ function useRegionController() {
4113
4289
  async function updateField(req, res, next) {
4114
4290
  const _id = req.params.id;
4115
4291
  const { field, value } = req.body;
4116
- const validation = import_joi11.default.object({
4117
- _id: import_joi11.default.string().hex().required(),
4118
- field: import_joi11.default.string().valid("name", "director", "directorName").required(),
4119
- 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()
4120
4296
  });
4121
4297
  const { error } = validation.validate({ _id, field, value });
4122
4298
  if (error) {
@@ -4133,8 +4309,8 @@ function useRegionController() {
4133
4309
  }
4134
4310
  async function deleteById(req, res, next) {
4135
4311
  const _id = req.params.id;
4136
- const validation = import_joi11.default.object({
4137
- _id: import_joi11.default.string().hex().required()
4312
+ const validation = import_joi12.default.object({
4313
+ _id: import_joi12.default.string().hex().required()
4138
4314
  });
4139
4315
  const { error } = validation.validate({ _id });
4140
4316
  if (error) {
@@ -4161,26 +4337,26 @@ function useRegionController() {
4161
4337
 
4162
4338
  // src/resources/division/division.model.ts
4163
4339
  var import_nodejs_utils18 = require("@eeplatform/nodejs-utils");
4164
- var import_joi12 = __toESM(require("joi"));
4340
+ var import_joi13 = __toESM(require("joi"));
4165
4341
  var import_mongodb11 = require("mongodb");
4166
- var schemaDivision = import_joi12.default.object({
4167
- _id: import_joi12.default.string().hex().optional().allow(null, ""),
4168
- name: import_joi12.default.string().min(1).max(100).required(),
4169
- region: import_joi12.default.string().hex().required(),
4170
- regionName: import_joi12.default.string().min(1).max(100).required(),
4171
- superintendent: import_joi12.default.string().hex().optional().allow(null, ""),
4172
- superintendentName: import_joi12.default.string().min(1).max(100).optional().allow(null, ""),
4173
- createdAt: import_joi12.default.string().isoDate().optional(),
4174
- updatedAt: import_joi12.default.string().isoDate().optional(),
4175
- 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, "")
4176
4352
  });
4177
- var schemaDivisionUpdate = import_joi12.default.object({
4178
- _id: import_joi12.default.string().hex().optional().allow(null, ""),
4179
- name: import_joi12.default.string().min(1).max(100).required(),
4180
- region: import_joi12.default.string().hex().required(),
4181
- regionName: import_joi12.default.string().min(1).max(100).required(),
4182
- superintendent: import_joi12.default.string().hex().optional().allow(null, ""),
4183
- 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, "")
4184
4360
  });
4185
4361
  function modelDivision(value) {
4186
4362
  const { error } = schemaDivision.validate(value);
@@ -4526,49 +4702,49 @@ var import_core2 = require("@eeplatform/core");
4526
4702
 
4527
4703
  // src/resources/school/school.model.ts
4528
4704
  var import_nodejs_utils20 = require("@eeplatform/nodejs-utils");
4529
- var import_joi13 = __toESM(require("joi"));
4705
+ var import_joi14 = __toESM(require("joi"));
4530
4706
  var import_mongodb13 = require("mongodb");
4531
- var schemaSchool = import_joi13.default.object({
4532
- _id: import_joi13.default.string().hex().optional().allow(null, ""),
4533
- id: import_joi13.default.string().min(1).max(50).required(),
4534
- name: import_joi13.default.string().min(1).max(100).required(),
4535
- region: import_joi13.default.string().hex().required(),
4536
- regionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4537
- division: import_joi13.default.string().hex().required(),
4538
- divisionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4539
- principal: import_joi13.default.string().hex().optional().allow(null, ""),
4540
- principalName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4541
- street: import_joi13.default.string().max(200).optional().allow(null, ""),
4542
- barangay: import_joi13.default.string().max(200).optional().allow(null, ""),
4543
- cityMunicipality: import_joi13.default.string().max(100).optional().allow(null, ""),
4544
- province: import_joi13.default.string().max(100).optional().allow(null, ""),
4545
- cityMunicipalityPSGC: import_joi13.default.string().length(10).optional().allow(null, ""),
4546
- postalCode: import_joi13.default.string().max(20).optional().allow(null, ""),
4547
- contactNumber: import_joi13.default.string().max(20).optional().allow(null, ""),
4548
- email: import_joi13.default.string().email().max(100).optional().allow(null, ""),
4549
- status: import_joi13.default.string().optional().allow(null, ""),
4550
- createdBy: import_joi13.default.string().optional().allow(null, ""),
4551
- createdAt: import_joi13.default.string().isoDate().optional().allow(null, ""),
4552
- updatedAt: import_joi13.default.string().isoDate().optional().allow(null, ""),
4553
- 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, "")
4554
4730
  });
4555
- var schemaSchoolUpdate = import_joi13.default.object({
4556
- id: import_joi13.default.string().min(1).max(50).required(),
4557
- name: import_joi13.default.string().min(1).max(100).required(),
4558
- region: import_joi13.default.string().hex().required(),
4559
- regionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4560
- division: import_joi13.default.string().hex().required(),
4561
- divisionName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4562
- principal: import_joi13.default.string().hex().optional().allow(null, ""),
4563
- principalName: import_joi13.default.string().min(1).max(100).optional().allow(null, ""),
4564
- street: import_joi13.default.string().max(200).optional().allow(null, ""),
4565
- barangay: import_joi13.default.string().max(200).optional().allow(null, ""),
4566
- cityMunicipality: import_joi13.default.string().max(100).optional().allow(null, ""),
4567
- province: import_joi13.default.string().max(100).optional().allow(null, ""),
4568
- cityMunicipalityPSGC: import_joi13.default.string().length(10).optional().allow(null, ""),
4569
- postalCode: import_joi13.default.string().max(20).optional().allow(null, ""),
4570
- contactNumber: import_joi13.default.string().max(20).optional().allow(null, ""),
4571
- 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, "")
4572
4748
  });
4573
4749
  function modelSchool(value) {
4574
4750
  const { error } = schemaSchool.validate(value);
@@ -33496,7 +33672,7 @@ ${errors.slice(0, 5).join("\n")}${errors.length > 5 ? `
33496
33672
 
33497
33673
  // src/resources/school/school.controller.ts
33498
33674
  var import_nodejs_utils23 = require("@eeplatform/nodejs-utils");
33499
- var import_joi14 = __toESM(require("joi"));
33675
+ var import_joi15 = __toESM(require("joi"));
33500
33676
  function useSchoolController() {
33501
33677
  const {
33502
33678
  getAll: _getAll,
@@ -33529,16 +33705,16 @@ function useSchoolController() {
33529
33705
  }
33530
33706
  }
33531
33707
  async function getAll(req, res, next) {
33532
- const validation = import_joi14.default.object({
33533
- page: import_joi14.default.number().optional().allow(null, ""),
33534
- limit: import_joi14.default.number().optional().allow(null, ""),
33535
- sort: import_joi14.default.string().optional().allow(null, ""),
33536
- sortOrder: import_joi14.default.string().optional().allow(null, ""),
33537
- status: import_joi14.default.string().optional().allow(null, ""),
33538
- org: import_joi14.default.string().hex().optional().allow(null, ""),
33539
- app: import_joi14.default.string().optional().allow(null, ""),
33540
- search: import_joi14.default.string().optional().allow(null, ""),
33541
- 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, "")
33542
33718
  });
33543
33719
  const { error } = validation.validate(req.query);
33544
33720
  if (error) {
@@ -33576,7 +33752,7 @@ function useSchoolController() {
33576
33752
  }
33577
33753
  async function getByCreatedBy(req, res, next) {
33578
33754
  const createdBy = req.params.createdBy;
33579
- const validation = import_joi14.default.string().hex().required();
33755
+ const validation = import_joi15.default.string().hex().required();
33580
33756
  const { error } = validation.validate(createdBy);
33581
33757
  if (error) {
33582
33758
  next(new import_nodejs_utils23.BadRequestError(`Validation error: ${error.message}`));
@@ -33593,9 +33769,9 @@ function useSchoolController() {
33593
33769
  async function updateStatusById(req, res, next) {
33594
33770
  const schoolId = req.params.id;
33595
33771
  const status = req.params.status;
33596
- const validation = import_joi14.default.object({
33597
- id: import_joi14.default.string().hex().required(),
33598
- 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()
33599
33775
  });
33600
33776
  const { error } = validation.validate({ id: schoolId, status });
33601
33777
  if (error) {
@@ -33628,8 +33804,8 @@ function useSchoolController() {
33628
33804
  }
33629
33805
  async function approveSchool(req, res, next) {
33630
33806
  const schoolId = req.params.id;
33631
- const validation = import_joi14.default.object({
33632
- id: import_joi14.default.string().hex().required()
33807
+ const validation = import_joi15.default.object({
33808
+ id: import_joi15.default.string().hex().required()
33633
33809
  });
33634
33810
  const { error } = validation.validate({ id: schoolId });
33635
33811
  if (error) {
@@ -33652,11 +33828,11 @@ function useSchoolController() {
33652
33828
  return;
33653
33829
  }
33654
33830
  const { region, regionName, division, divisionName } = req.body;
33655
- const validation = import_joi14.default.object({
33656
- region: import_joi14.default.string().hex().required(),
33657
- regionName: import_joi14.default.string().min(1).required(),
33658
- division: import_joi14.default.string().hex().required(),
33659
- 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()
33660
33836
  });
33661
33837
  const { error } = validation.validate({
33662
33838
  region,
@@ -33685,10 +33861,10 @@ function useSchoolController() {
33685
33861
  async function updateFieldById(req, res, next) {
33686
33862
  const _id = req.params.id;
33687
33863
  const { field, value } = req.body;
33688
- const validation = import_joi14.default.object({
33689
- _id: import_joi14.default.string().hex().required(),
33690
- field: import_joi14.default.string().valid("name", "director", "directorName").required(),
33691
- 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()
33692
33868
  });
33693
33869
  const { error } = validation.validate({ _id, field, value });
33694
33870
  if (error) {
@@ -33706,8 +33882,8 @@ function useSchoolController() {
33706
33882
  async function updateById(req, res, next) {
33707
33883
  const id = req.params.id;
33708
33884
  const payload = req.body;
33709
- const validation = import_joi14.default.object({
33710
- id: import_joi14.default.string().hex().required()
33885
+ const validation = import_joi15.default.object({
33886
+ id: import_joi15.default.string().hex().required()
33711
33887
  });
33712
33888
  const { error: idError } = validation.validate({ id });
33713
33889
  if (idError) {
@@ -33729,8 +33905,8 @@ function useSchoolController() {
33729
33905
  }
33730
33906
  async function deleteById(req, res, next) {
33731
33907
  const _id = req.params.id;
33732
- const validation = import_joi14.default.object({
33733
- _id: import_joi14.default.string().hex().required()
33908
+ const validation = import_joi15.default.object({
33909
+ _id: import_joi15.default.string().hex().required()
33734
33910
  });
33735
33911
  const { error } = validation.validate({ _id });
33736
33912
  if (error) {
@@ -33825,7 +34001,7 @@ function useDivisionService() {
33825
34001
 
33826
34002
  // src/resources/division/division.controller.ts
33827
34003
  var import_nodejs_utils25 = require("@eeplatform/nodejs-utils");
33828
- var import_joi15 = __toESM(require("joi"));
34004
+ var import_joi16 = __toESM(require("joi"));
33829
34005
  function useDivisionController() {
33830
34006
  const { add: _add, updateById: _updateById } = useDivisionService();
33831
34007
  const {
@@ -33855,12 +34031,12 @@ function useDivisionController() {
33855
34031
  }
33856
34032
  async function getAll(req, res, next) {
33857
34033
  const query = req.query;
33858
- const validation = import_joi15.default.object({
33859
- page: import_joi15.default.number().min(1).optional().allow("", null),
33860
- limit: import_joi15.default.number().min(1).optional().allow("", null),
33861
- search: import_joi15.default.string().optional().allow("", null),
33862
- status: import_joi15.default.string().optional().allow("", null),
33863
- 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)
33864
34040
  });
33865
34041
  const { error } = validation.validate(query);
33866
34042
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -33892,8 +34068,8 @@ function useDivisionController() {
33892
34068
  }
33893
34069
  async function getById(req, res, next) {
33894
34070
  const id = req.params.id;
33895
- const validation = import_joi15.default.object({
33896
- id: import_joi15.default.string().hex().required()
34071
+ const validation = import_joi16.default.object({
34072
+ id: import_joi16.default.string().hex().required()
33897
34073
  });
33898
34074
  const { error } = validation.validate({ id });
33899
34075
  if (error) {
@@ -33913,8 +34089,8 @@ function useDivisionController() {
33913
34089
  }
33914
34090
  async function getByName(req, res, next) {
33915
34091
  const name = req.params.name;
33916
- const validation = import_joi15.default.object({
33917
- name: import_joi15.default.string().required()
34092
+ const validation = import_joi16.default.object({
34093
+ name: import_joi16.default.string().required()
33918
34094
  });
33919
34095
  const { error } = validation.validate({ name });
33920
34096
  if (error) {
@@ -33935,10 +34111,10 @@ function useDivisionController() {
33935
34111
  async function updateField(req, res, next) {
33936
34112
  const _id = req.params.id;
33937
34113
  const { field, value } = req.body;
33938
- const validation = import_joi15.default.object({
33939
- _id: import_joi15.default.string().hex().required(),
33940
- field: import_joi15.default.string().valid("name", "director", "directorName").required(),
33941
- 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()
33942
34118
  });
33943
34119
  const { error } = validation.validate({ _id, field, value });
33944
34120
  if (error) {
@@ -33971,8 +34147,8 @@ function useDivisionController() {
33971
34147
  }
33972
34148
  async function deleteById(req, res, next) {
33973
34149
  const _id = req.params.id;
33974
- const validation = import_joi15.default.object({
33975
- _id: import_joi15.default.string().hex().required()
34150
+ const validation = import_joi16.default.object({
34151
+ _id: import_joi16.default.string().hex().required()
33976
34152
  });
33977
34153
  const { error } = validation.validate({ _id });
33978
34154
  if (error) {
@@ -34000,48 +34176,48 @@ function useDivisionController() {
34000
34176
 
34001
34177
  // src/resources/asset/asset.model.ts
34002
34178
  var import_nodejs_utils26 = require("@eeplatform/nodejs-utils");
34003
- var import_joi16 = __toESM(require("joi"));
34179
+ var import_joi17 = __toESM(require("joi"));
34004
34180
  var import_mongodb15 = require("mongodb");
34005
- var schemaAsset = import_joi16.default.object({
34006
- _id: import_joi16.default.string().hex().optional(),
34007
- school: import_joi16.default.string().hex().required(),
34008
- asset_type: import_joi16.default.string().required().allow("supply", "furniture-equipment", "fixed-asset"),
34009
- name: import_joi16.default.string().required(),
34010
- category: import_joi16.default.string().optional().allow("", null),
34011
- type: import_joi16.default.string().optional().allow("", null),
34012
- brand: import_joi16.default.string().optional().allow("", null),
34013
- unit: import_joi16.default.string().required(),
34014
- status: import_joi16.default.string().optional().allow("", null),
34015
- createdAt: import_joi16.default.date().optional().allow("", null),
34016
- updatedAt: import_joi16.default.date().optional().allow("", null),
34017
- deletedAt: import_joi16.default.date().optional().allow("", null),
34018
- metadata: import_joi16.default.object({
34019
- title: import_joi16.default.string().optional().allow("", null),
34020
- isbn: import_joi16.default.string().optional().allow("", null),
34021
- author: import_joi16.default.string().optional().allow("", null),
34022
- edition: import_joi16.default.string().optional().allow("", null),
34023
- subject: import_joi16.default.string().optional().allow("", null),
34024
- grade_level: import_joi16.default.number().integer().min(0).optional().allow("", null),
34025
- publisher: import_joi16.default.string().optional().allow("", null),
34026
- 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)
34027
34203
  }).optional().allow(null)
34028
34204
  });
34029
- var schemaAssetUpdateOption = import_joi16.default.object({
34030
- name: import_joi16.default.string().optional().allow("", null),
34031
- category: import_joi16.default.string().optional().allow("", null),
34032
- type: import_joi16.default.string().optional().allow("", null),
34033
- brand: import_joi16.default.string().optional().allow("", null),
34034
- qty: import_joi16.default.number().integer().min(0).optional().allow("", null),
34035
- unit: import_joi16.default.string().optional().allow("", null),
34036
- metadata: import_joi16.default.object({
34037
- title: import_joi16.default.string().optional().allow("", null),
34038
- isbn: import_joi16.default.string().optional().allow("", null),
34039
- author: import_joi16.default.string().optional().allow("", null),
34040
- edition: import_joi16.default.string().optional().allow("", null),
34041
- subject: import_joi16.default.string().optional().allow("", null),
34042
- grade_level: import_joi16.default.number().integer().min(0).optional().allow("", null),
34043
- publisher: import_joi16.default.string().optional().allow("", null),
34044
- 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)
34045
34221
  }).optional().allow(null)
34046
34222
  });
34047
34223
  function MAsset(value) {
@@ -34473,7 +34649,7 @@ function useAssetRepo() {
34473
34649
 
34474
34650
  // src/resources/asset/asset.controller.ts
34475
34651
  var import_nodejs_utils28 = require("@eeplatform/nodejs-utils");
34476
- var import_joi17 = __toESM(require("joi"));
34652
+ var import_joi18 = __toESM(require("joi"));
34477
34653
  function useAssetController() {
34478
34654
  const {
34479
34655
  add: _add,
@@ -34501,13 +34677,13 @@ function useAssetController() {
34501
34677
  }
34502
34678
  async function getAll(req, res, next) {
34503
34679
  const query = req.query;
34504
- const validation = import_joi17.default.object({
34505
- page: import_joi17.default.number().min(1).optional().allow("", null),
34506
- limit: import_joi17.default.number().min(1).optional().allow("", null),
34507
- search: import_joi17.default.string().optional().allow("", null),
34508
- status: import_joi17.default.string().optional().allow("", null),
34509
- school: import_joi17.default.string().hex().optional().allow("", null),
34510
- 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")
34511
34687
  });
34512
34688
  const { error } = validation.validate(query);
34513
34689
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -34547,7 +34723,7 @@ function useAssetController() {
34547
34723
  }
34548
34724
  async function deleteById(req, res, next) {
34549
34725
  const id = req.params.id;
34550
- const validation = import_joi17.default.string().hex().required();
34726
+ const validation = import_joi18.default.string().hex().required();
34551
34727
  const { error } = validation.validate(id);
34552
34728
  if (error) {
34553
34729
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34562,7 +34738,7 @@ function useAssetController() {
34562
34738
  }
34563
34739
  async function getById(req, res, next) {
34564
34740
  const id = req.params.id;
34565
- const validation = import_joi17.default.string().hex().required();
34741
+ const validation = import_joi18.default.string().hex().required();
34566
34742
  const { error } = validation.validate(id);
34567
34743
  if (error) {
34568
34744
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34593,7 +34769,7 @@ function useAssetController() {
34593
34769
  async function getCategories(req, res, next) {
34594
34770
  const school = req.params.school;
34595
34771
  const asset_type = req.params.asset_type;
34596
- const validation = import_joi17.default.string().hex().required();
34772
+ const validation = import_joi18.default.string().hex().required();
34597
34773
  const { error } = validation.validate(school);
34598
34774
  if (error) {
34599
34775
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34609,7 +34785,7 @@ function useAssetController() {
34609
34785
  async function getTypes(req, res, next) {
34610
34786
  const school = req.params.school;
34611
34787
  const asset_type = req.params.asset_type;
34612
- const validation = import_joi17.default.string().hex().required();
34788
+ const validation = import_joi18.default.string().hex().required();
34613
34789
  const { error } = validation.validate(school);
34614
34790
  if (error) {
34615
34791
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34624,7 +34800,7 @@ function useAssetController() {
34624
34800
  }
34625
34801
  async function getUnitsBySchool(req, res, next) {
34626
34802
  const school = req.params.school;
34627
- const validation = import_joi17.default.string().hex().required();
34803
+ const validation = import_joi18.default.string().hex().required();
34628
34804
  const { error } = validation.validate(school);
34629
34805
  if (error) {
34630
34806
  next(new import_nodejs_utils28.BadRequestError(error.message));
@@ -34651,26 +34827,26 @@ function useAssetController() {
34651
34827
 
34652
34828
  // src/resources/stock-card/stock-card.model.ts
34653
34829
  var import_nodejs_utils29 = require("@eeplatform/nodejs-utils");
34654
- var import_joi18 = __toESM(require("joi"));
34830
+ var import_joi19 = __toESM(require("joi"));
34655
34831
  var import_mongodb17 = require("mongodb");
34656
- var schemaStockCard = import_joi18.default.object({
34657
- _id: import_joi18.default.string().hex().optional().allow("", null),
34658
- school: import_joi18.default.string().hex().required(),
34659
- item: import_joi18.default.string().hex().required(),
34660
- balance: import_joi18.default.number().optional().allow(null, 0),
34661
- qty: import_joi18.default.number().required(),
34662
- unitCost: import_joi18.default.number().optional().allow(null, 0),
34663
- totalCost: import_joi18.default.number().optional().allow(null, 0),
34664
- status: import_joi18.default.string().optional().allow(null, ""),
34665
- condition: import_joi18.default.string().required(),
34666
- supplier: import_joi18.default.string().optional().allow("", null),
34667
- location: import_joi18.default.string().optional().allow("", null),
34668
- locationName: import_joi18.default.string().optional().allow("", null),
34669
- reason: import_joi18.default.string().optional().allow("", null),
34670
- remarks: import_joi18.default.string().optional().allow("", null),
34671
- createdAt: import_joi18.default.date().optional().allow("", null),
34672
- updatedAt: import_joi18.default.date().optional().allow("", null),
34673
- 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)
34674
34850
  });
34675
34851
  function MStockCard(value) {
34676
34852
  const { error } = schemaStockCard.validate(value);
@@ -34958,7 +35134,7 @@ function useStockCardService() {
34958
35134
 
34959
35135
  // src/resources/stock-card/stock-card.controller.ts
34960
35136
  var import_nodejs_utils32 = require("@eeplatform/nodejs-utils");
34961
- var import_joi19 = __toESM(require("joi"));
35137
+ var import_joi20 = __toESM(require("joi"));
34962
35138
  function useStockCardController() {
34963
35139
  const {
34964
35140
  getAll: _getAll,
@@ -34982,11 +35158,11 @@ function useStockCardController() {
34982
35158
  }
34983
35159
  async function getAll(req, res, next) {
34984
35160
  const query = req.query;
34985
- const validation = import_joi19.default.object({
34986
- page: import_joi19.default.number().min(1).optional().allow("", null),
34987
- limit: import_joi19.default.number().min(1).optional().allow("", null),
34988
- school: import_joi19.default.string().hex().optional().allow("", null),
34989
- 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()
34990
35166
  });
34991
35167
  const { error } = validation.validate(query);
34992
35168
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -35022,7 +35198,7 @@ function useStockCardController() {
35022
35198
  }
35023
35199
  async function getById(req, res, next) {
35024
35200
  const id = req.params.id;
35025
- const validation = import_joi19.default.string().hex().required();
35201
+ const validation = import_joi20.default.string().hex().required();
35026
35202
  const { error } = validation.validate(id);
35027
35203
  if (error) {
35028
35204
  next(new import_nodejs_utils32.BadRequestError(error.message));
@@ -35037,7 +35213,7 @@ function useStockCardController() {
35037
35213
  }
35038
35214
  async function getSuppliers(req, res, next) {
35039
35215
  const school = req.params.school;
35040
- const validation = import_joi19.default.string().hex().required();
35216
+ const validation = import_joi20.default.string().hex().required();
35041
35217
  const { error } = validation.validate(school);
35042
35218
  if (error) {
35043
35219
  next(new import_nodejs_utils32.BadRequestError(error.message));
@@ -35060,30 +35236,30 @@ function useStockCardController() {
35060
35236
 
35061
35237
  // src/resources/plantilla/plantilla.model.ts
35062
35238
  var import_nodejs_utils33 = require("@eeplatform/nodejs-utils");
35063
- var import_joi20 = __toESM(require("joi"));
35239
+ var import_joi21 = __toESM(require("joi"));
35064
35240
  var import_mongodb19 = require("mongodb");
35065
- var schemaPlantilla = import_joi20.default.object({
35066
- _id: import_joi20.default.string().hex().optional().allow(null, ""),
35067
- org: import_joi20.default.string().hex().required(),
35068
- orgUnitCode: import_joi20.default.string().optional().allow(null, ""),
35069
- employmentType: import_joi20.default.string().optional().allow(null, ""),
35070
- personnelType: import_joi20.default.string().required(),
35071
- itemNumber: import_joi20.default.string().required(),
35072
- positionTitle: import_joi20.default.string().required(),
35073
- positionCategory: import_joi20.default.string().required(),
35074
- region: import_joi20.default.string().hex().optional().allow(null, ""),
35075
- regionName: import_joi20.default.string().optional().allow(null, ""),
35076
- division: import_joi20.default.string().hex().optional().allow(null, ""),
35077
- divisionName: import_joi20.default.string().optional().allow(null, ""),
35078
- salaryGrade: import_joi20.default.number().required(),
35079
- employeeName: import_joi20.default.string().optional().allow(null, ""),
35080
- annualSalary: import_joi20.default.number().optional().allow(null, 0),
35081
- monthlySalary: import_joi20.default.number().optional().allow(null, 0),
35082
- status: import_joi20.default.string().required(),
35083
- employee: import_joi20.default.string().hex().optional().allow(null, ""),
35084
- createdAt: import_joi20.default.date().iso().optional().allow(null, ""),
35085
- updatedAt: import_joi20.default.date().iso().optional().allow(null, ""),
35086
- 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, "")
35087
35263
  });
35088
35264
  function MPlantilla(data) {
35089
35265
  const { error } = schemaPlantilla.validate(data);
@@ -35565,7 +35741,7 @@ ${errors.slice(0, 10).join("\n")}${errors.length > 10 ? `
35565
35741
 
35566
35742
  // src/resources/plantilla/plantilla.controller.ts
35567
35743
  var import_nodejs_utils36 = require("@eeplatform/nodejs-utils");
35568
- var import_joi21 = __toESM(require("joi"));
35744
+ var import_joi22 = __toESM(require("joi"));
35569
35745
  function usePlantillaController() {
35570
35746
  const {
35571
35747
  add: _addPlantilla,
@@ -35577,11 +35753,11 @@ function usePlantillaController() {
35577
35753
  const { addBulk: _addBulk } = usePlantillaService();
35578
35754
  async function createPlantilla(req, res, next) {
35579
35755
  const value = req.body;
35580
- const validation = import_joi21.default.object({
35581
- itemNumber: import_joi21.default.string().required(),
35582
- positionTitle: import_joi21.default.string().required(),
35583
- positionCategory: import_joi21.default.string().required(),
35584
- 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()
35585
35761
  });
35586
35762
  const { error } = validation.validate(value);
35587
35763
  if (error) {
@@ -35611,11 +35787,11 @@ function usePlantillaController() {
35611
35787
  next(new import_nodejs_utils36.BadRequestError("Invalid limit number."));
35612
35788
  return;
35613
35789
  }
35614
- const validation = import_joi21.default.object({
35615
- page: import_joi21.default.number().min(1).optional().allow("", null),
35616
- limit: import_joi21.default.number().min(1).optional().allow("", null),
35617
- search: import_joi21.default.string().optional().allow("", null),
35618
- 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)
35619
35795
  });
35620
35796
  const { error } = validation.validate({ page, limit, search, org });
35621
35797
  if (error) {
@@ -35637,8 +35813,8 @@ function usePlantillaController() {
35637
35813
  }
35638
35814
  async function getPlantillaById(req, res, next) {
35639
35815
  const id = req.params.id;
35640
- const validation = import_joi21.default.object({
35641
- id: import_joi21.default.string().hex().required()
35816
+ const validation = import_joi22.default.object({
35817
+ id: import_joi22.default.string().hex().required()
35642
35818
  });
35643
35819
  const { error } = validation.validate({ id });
35644
35820
  if (error) {
@@ -35660,12 +35836,12 @@ function usePlantillaController() {
35660
35836
  async function updatePlantilla(req, res, next) {
35661
35837
  const id = req.params.id;
35662
35838
  const value = req.body;
35663
- const validation = import_joi21.default.object({
35664
- id: import_joi21.default.string().hex().required(),
35665
- employee: import_joi21.default.string().hex().optional().allow(null, ""),
35666
- status: import_joi21.default.string().optional(),
35667
- positionTitle: import_joi21.default.string().optional(),
35668
- 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()
35669
35845
  });
35670
35846
  const { error } = validation.validate({ id, ...value });
35671
35847
  if (error) {
@@ -35686,8 +35862,8 @@ function usePlantillaController() {
35686
35862
  }
35687
35863
  async function deletePlantilla(req, res, next) {
35688
35864
  const id = req.params.id;
35689
- const validation = import_joi21.default.object({
35690
- id: import_joi21.default.string().hex().required()
35865
+ const validation = import_joi22.default.object({
35866
+ id: import_joi22.default.string().hex().required()
35691
35867
  });
35692
35868
  const { error } = validation.validate({ id });
35693
35869
  if (error) {
@@ -35712,9 +35888,9 @@ function usePlantillaController() {
35712
35888
  return;
35713
35889
  }
35714
35890
  const { region, division } = req.body;
35715
- const validation = import_joi21.default.object({
35716
- region: import_joi21.default.string().hex().optional(),
35717
- 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()
35718
35894
  });
35719
35895
  const { error } = validation.validate({ region, division });
35720
35896
  if (error) {
@@ -35748,6 +35924,1486 @@ function usePlantillaController() {
35748
35924
  };
35749
35925
  }
35750
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
+
35751
37407
  // src/config.ts
35752
37408
  var dotenv = __toESM(require("dotenv"));
35753
37409
  dotenv.config();
@@ -35763,6 +37419,8 @@ dotenv.config();
35763
37419
  modelDivision,
35764
37420
  modelRegion,
35765
37421
  modelSchool,
37422
+ modelSection,
37423
+ modelSectionPreset,
35766
37424
  schemaAsset,
35767
37425
  schemaAssetUpdateOption,
35768
37426
  schemaBasicEduCount,
@@ -35770,11 +37428,14 @@ dotenv.config();
35770
37428
  schemaDivision,
35771
37429
  schemaDivisionUpdate,
35772
37430
  schemaEnrollment,
37431
+ schemaGenerateSections,
35773
37432
  schemaGradeLevel,
35774
37433
  schemaPlantilla,
35775
37434
  schemaRegion,
35776
37435
  schemaSchool,
35777
37436
  schemaSchoolUpdate,
37437
+ schemaSection,
37438
+ schemaSectionPreset,
35778
37439
  schemaStockCard,
35779
37440
  schemaUpdateStatus,
35780
37441
  useAssetController,
@@ -35800,6 +37461,10 @@ dotenv.config();
35800
37461
  useSchoolController,
35801
37462
  useSchoolRepo,
35802
37463
  useSchoolService,
37464
+ useSectionController,
37465
+ useSectionPresetController,
37466
+ useSectionPresetRepo,
37467
+ useSectionRepo,
35803
37468
  useStockCardController,
35804
37469
  useStockCardRepository,
35805
37470
  useStockCardService