@eeplatform/basic-edu 1.4.3 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1420,7 +1420,7 @@ function useCurriculumRepo() {
1420
1420
  if (!db) {
1421
1421
  throw new Error("Unable to connect to server.");
1422
1422
  }
1423
- const namespace_collection = "school.curriculums";
1423
+ const namespace_collection = "deped.school.curriculums";
1424
1424
  const collection = db.collection(namespace_collection);
1425
1425
  const { getCache, setCache, delNamespace } = useCache(namespace_collection);
1426
1426
  async function createIndexes() {
@@ -2349,7 +2349,7 @@ function useEnrollmentRepo() {
2349
2349
  import {
2350
2350
  AppError as AppError5,
2351
2351
  BadRequestError as BadRequestError10,
2352
- InternalServerError as InternalServerError4,
2352
+ InternalServerError as InternalServerError3,
2353
2353
  logger as logger8,
2354
2354
  NotFoundError,
2355
2355
  useAtlas as useAtlas5
@@ -2366,6 +2366,7 @@ import {
2366
2366
  useCache as useCache3
2367
2367
  } from "@eeplatform/nodejs-utils";
2368
2368
  import { ObjectId as ObjectId5 } from "mongodb";
2369
+ import Joi5 from "joi";
2369
2370
  function useLearnerRepo() {
2370
2371
  const db = useAtlas3.getDb();
2371
2372
  if (!db) {
@@ -2391,7 +2392,7 @@ function useLearnerRepo() {
2391
2392
  }
2392
2393
  ]);
2393
2394
  } catch (error) {
2394
- throw new Error("Failed to create index on enrollments.");
2395
+ throw new Error("Failed to create index on learners.");
2395
2396
  }
2396
2397
  }
2397
2398
  function delCachedData() {
@@ -2424,10 +2425,10 @@ function useLearnerRepo() {
2424
2425
  const isDuplicated = error.message.includes("duplicate");
2425
2426
  if (isDuplicated) {
2426
2427
  throw new BadRequestError6(
2427
- "Enrollment already exists for this learner and school year."
2428
+ "learner already exists for this learner and school year."
2428
2429
  );
2429
2430
  }
2430
- throw new Error("Failed to create enrollment.");
2431
+ throw new Error("Failed to create learner.");
2431
2432
  }
2432
2433
  }
2433
2434
  }
@@ -2439,61 +2440,50 @@ function useLearnerRepo() {
2439
2440
  status = "active",
2440
2441
  school = "",
2441
2442
  schoolYear = "",
2442
- gradeLevelToEnroll = ""
2443
+ level = ""
2443
2444
  } = {}) {
2444
2445
  page = page > 0 ? page - 1 : 0;
2445
2446
  const query = {
2446
2447
  status
2447
2448
  };
2449
+ const cacheParams = {
2450
+ status,
2451
+ page,
2452
+ limit,
2453
+ sort: JSON.stringify(sort)
2454
+ };
2448
2455
  if (school) {
2449
2456
  try {
2450
2457
  query.school = new ObjectId5(school);
2458
+ cacheParams.school = school;
2451
2459
  } catch (error) {
2452
2460
  throw new BadRequestError6("Invalid school ID.");
2453
2461
  }
2454
2462
  }
2455
2463
  if (schoolYear) {
2456
2464
  query.schoolYear = schoolYear;
2465
+ cacheParams.schoolYear = schoolYear;
2457
2466
  }
2458
- if (gradeLevelToEnroll) {
2459
- query.gradeLevelToEnroll = gradeLevelToEnroll;
2467
+ if (level) {
2468
+ query.gradeLevel = level;
2469
+ cacheParams.level = level;
2460
2470
  }
2461
2471
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
2462
2472
  if (search) {
2463
- query.$or = [
2464
- { "learnerInfo.firstName": { $regex: search, $options: "i" } },
2465
- { "learnerInfo.lastName": { $regex: search, $options: "i" } },
2466
- { "learnerInfo.lrn": { $regex: search, $options: "i" } },
2467
- { schoolYear: { $regex: search, $options: "i" } },
2468
- { gradeLevelToEnroll: { $regex: search, $options: "i" } }
2469
- ];
2470
- }
2471
- const cacheParams = {
2472
- page,
2473
- limit,
2474
- sort: JSON.stringify(sort)
2475
- };
2476
- if (search)
2473
+ query.$text = { $search: search };
2477
2474
  cacheParams.search = search;
2478
- if (status !== "active")
2479
- cacheParams.status = status;
2480
- if (school)
2481
- cacheParams.school = school;
2482
- if (schoolYear)
2483
- cacheParams.schoolYear = schoolYear;
2484
- if (gradeLevelToEnroll)
2485
- cacheParams.gradeLevelToEnroll = gradeLevelToEnroll;
2475
+ }
2486
2476
  const cacheKey = makeCacheKey3(namespace_collection, cacheParams);
2487
2477
  logger6.log({
2488
2478
  level: "info",
2489
- message: `Cache key for getAll enrollments: ${cacheKey}`
2479
+ message: `Cache key for getAll learners: ${cacheKey}`
2490
2480
  });
2491
2481
  try {
2492
2482
  const cached = await getCache(cacheKey);
2493
2483
  if (cached) {
2494
2484
  logger6.log({
2495
2485
  level: "info",
2496
- message: `Cache hit for getAll enrollments: ${cacheKey}`
2486
+ message: `Cache hit for getAll learners: ${cacheKey}`
2497
2487
  });
2498
2488
  return cached;
2499
2489
  }
@@ -2509,12 +2499,12 @@ function useLearnerRepo() {
2509
2499
  setCache(cacheKey, data, 600).then(() => {
2510
2500
  logger6.log({
2511
2501
  level: "info",
2512
- message: `Cache set for getAll enrollments: ${cacheKey}`
2502
+ message: `Cache set for getAll learners: ${cacheKey}`
2513
2503
  });
2514
2504
  }).catch((err) => {
2515
2505
  logger6.log({
2516
2506
  level: "error",
2517
- message: `Failed to set cache for getAll enrollments: ${err.message}`
2507
+ message: `Failed to set cache for getAll learners: ${err.message}`
2518
2508
  });
2519
2509
  });
2520
2510
  return data;
@@ -2523,6 +2513,62 @@ function useLearnerRepo() {
2523
2513
  throw error;
2524
2514
  }
2525
2515
  }
2516
+ async function getCountByGradeLevel(value, session) {
2517
+ const validation = Joi5.object({
2518
+ school: Joi5.string().hex().required(),
2519
+ schoolYear: Joi5.string().required(),
2520
+ gradeLevel: Joi5.string().required(),
2521
+ status: Joi5.string().optional()
2522
+ });
2523
+ const { error } = validation.validate(value);
2524
+ if (error) {
2525
+ throw new BadRequestError6(`Invalid data: ${error.message}`);
2526
+ }
2527
+ const status = value.status ?? "active";
2528
+ const query = {
2529
+ schoolYear: value.schoolYear,
2530
+ gradeLevel: value.gradeLevel,
2531
+ status
2532
+ };
2533
+ const cacheKeyOptions = {
2534
+ ...query,
2535
+ tag: "countByGradeLevel"
2536
+ };
2537
+ if (value.school && typeof value.school === "string") {
2538
+ try {
2539
+ query.school = new ObjectId5(value.school);
2540
+ } catch (error2) {
2541
+ throw new BadRequestError6("Invalid school ID.");
2542
+ }
2543
+ cacheKeyOptions.school = value.school.toString();
2544
+ }
2545
+ const cacheKey = makeCacheKey3(namespace_collection, cacheKeyOptions);
2546
+ const cachedData = await getCache(cacheKey);
2547
+ if (cachedData !== void 0 && cachedData !== null) {
2548
+ logger6.log({
2549
+ level: "info",
2550
+ message: `Cache hit for learner count by grade level: ${cacheKey}`
2551
+ });
2552
+ return cachedData;
2553
+ }
2554
+ try {
2555
+ const count = await collection.countDocuments(query, { session });
2556
+ setCache(cacheKey, count, 600).then(() => {
2557
+ logger6.log({
2558
+ level: "info",
2559
+ message: `Cache set for learner count by grade level: ${cacheKey}`
2560
+ });
2561
+ }).catch((err) => {
2562
+ logger6.log({
2563
+ level: "error",
2564
+ message: `Failed to set cache for learner count by grade level: ${err.message}`
2565
+ });
2566
+ });
2567
+ return count;
2568
+ } catch (error2) {
2569
+ throw new BadRequestError6("Failed to get learner count by grade level.");
2570
+ }
2571
+ }
2526
2572
  async function getById(_id, status = "") {
2527
2573
  try {
2528
2574
  _id = new ObjectId5(_id);
@@ -2540,7 +2586,7 @@ function useLearnerRepo() {
2540
2586
  if (cachedData) {
2541
2587
  logger6.log({
2542
2588
  level: "info",
2543
- message: `Cache hit for enrollment by ID: ${cacheKey}`
2589
+ message: `Cache hit for learner by ID: ${cacheKey}`
2544
2590
  });
2545
2591
  return cachedData;
2546
2592
  }
@@ -2549,17 +2595,80 @@ function useLearnerRepo() {
2549
2595
  setCache(cacheKey, data, 600).then(() => {
2550
2596
  logger6.log({
2551
2597
  level: "info",
2552
- message: `Cache set for enrollment by ID: ${cacheKey}`
2598
+ message: `Cache set for learner by ID: ${cacheKey}`
2553
2599
  });
2554
2600
  }).catch((err) => {
2555
2601
  logger6.log({
2556
2602
  level: "error",
2557
- message: `Failed to set cache for enrollment by ID: ${err.message}`
2603
+ message: `Failed to set cache for learner by ID: ${err.message}`
2558
2604
  });
2559
2605
  });
2560
2606
  return data;
2561
2607
  } catch (error) {
2562
- throw new BadRequestError6("Failed to get enrollment by ID.");
2608
+ throw new BadRequestError6("Failed to get learner by ID.");
2609
+ }
2610
+ }
2611
+ async function getByGradeLevel(value, session) {
2612
+ const validation = Joi5.object({
2613
+ school: Joi5.string().hex().required(),
2614
+ gradeLevel: Joi5.string().required(),
2615
+ status: Joi5.string().optional().allow("", null),
2616
+ limit: Joi5.number().integer().required(),
2617
+ skip: Joi5.number().integer().required()
2618
+ });
2619
+ const { error } = validation.validate(value);
2620
+ if (error) {
2621
+ throw new BadRequestError6(`Invalid data: ${error.message}`);
2622
+ }
2623
+ const status = value.status ?? "active";
2624
+ const query = {
2625
+ gradeLevel: value.gradeLevel,
2626
+ status
2627
+ };
2628
+ const cacheKeyOptions = {
2629
+ ...query,
2630
+ tag: "byGradeLevel"
2631
+ };
2632
+ if (value.school && typeof value.school === "string") {
2633
+ try {
2634
+ query.school = new ObjectId5(value.school);
2635
+ } catch (error2) {
2636
+ throw new BadRequestError6("Invalid school ID.");
2637
+ }
2638
+ cacheKeyOptions.school = value.school.toString();
2639
+ }
2640
+ const cacheKey = makeCacheKey3(namespace_collection, cacheKeyOptions);
2641
+ const cachedData = await getCache(cacheKey);
2642
+ if (cachedData) {
2643
+ logger6.log({
2644
+ level: "info",
2645
+ message: `Cache hit for learner by ID: ${cacheKey}`
2646
+ });
2647
+ return cachedData;
2648
+ }
2649
+ try {
2650
+ const data = await collection.aggregate(
2651
+ [
2652
+ { $match: query },
2653
+ { $skip: value.skip ?? 0 },
2654
+ { $limit: value.limit ?? 100 }
2655
+ ],
2656
+ { session }
2657
+ ).toArray();
2658
+ setCache(cacheKey, data, 600).then(() => {
2659
+ logger6.log({
2660
+ level: "info",
2661
+ message: `Cache set for learner by ID: ${cacheKey}`
2662
+ });
2663
+ }).catch((err) => {
2664
+ logger6.log({
2665
+ level: "error",
2666
+ message: `Failed to set cache for learner by ID: ${err.message}`
2667
+ });
2668
+ });
2669
+ return data;
2670
+ } catch (error2) {
2671
+ throw new BadRequestError6("Failed to get learner by ID.");
2563
2672
  }
2564
2673
  }
2565
2674
  async function updateStatusById(_id, status, session) {
@@ -2577,33 +2686,35 @@ function useLearnerRepo() {
2577
2686
  delCachedData();
2578
2687
  return result;
2579
2688
  } catch (error) {
2580
- throw new Error("Failed to update enrollment status.");
2689
+ throw new Error("Failed to update learner status.");
2581
2690
  }
2582
2691
  }
2583
2692
  return {
2584
2693
  createIndexes,
2585
2694
  add,
2586
2695
  getAll,
2696
+ getCountByGradeLevel,
2587
2697
  updateStatusById,
2588
- getById
2698
+ getById,
2699
+ getByGradeLevel
2589
2700
  };
2590
2701
  }
2591
2702
 
2592
2703
  // src/resources/learner/learner.controller.ts
2593
2704
  import { BadRequestError as BadRequestError7 } from "@eeplatform/nodejs-utils";
2594
- import Joi5 from "joi";
2705
+ import Joi6 from "joi";
2595
2706
  function useLearnerController() {
2596
2707
  const { getAll: _getAll, updateStatusById: _updateStatusById } = useLearnerRepo();
2597
2708
  async function getAll(req, res, next) {
2598
2709
  const query = req.query;
2599
- const validation = Joi5.object({
2600
- page: Joi5.number().min(1).optional().allow("", null),
2601
- limit: Joi5.number().min(1).max(100).optional().allow("", null),
2602
- search: Joi5.string().optional().allow("", null),
2603
- status: Joi5.string().optional().allow("", null),
2604
- school: Joi5.string().hex().optional().allow("", null),
2605
- schoolYear: Joi5.string().optional().allow("", null),
2606
- gradeLevelToEnroll: Joi5.string().optional().allow("", null)
2710
+ const validation = Joi6.object({
2711
+ page: Joi6.number().min(1).optional().allow("", null),
2712
+ limit: Joi6.number().min(1).max(100).optional().allow("", null),
2713
+ search: Joi6.string().optional().allow("", null),
2714
+ status: Joi6.string().optional().allow("", null),
2715
+ school: Joi6.string().hex().optional().allow("", null),
2716
+ schoolYear: Joi6.string().optional().allow("", null),
2717
+ level: Joi6.string().optional().allow("", null)
2607
2718
  });
2608
2719
  const { error } = validation.validate(query);
2609
2720
  if (error) {
@@ -2613,6 +2724,11 @@ function useLearnerController() {
2613
2724
  const page = parseInt(req.query.page) ?? 1;
2614
2725
  let limit = parseInt(req.query.limit) ?? 20;
2615
2726
  limit = isNaN(limit) ? 20 : limit;
2727
+ const level = req.query.level ?? "";
2728
+ const search = req.query.search ?? "";
2729
+ const status = req.query.status ?? "";
2730
+ const school = req.query.school ?? "";
2731
+ const schoolYear = req.query.schoolYear ?? "";
2616
2732
  const sort = req.query.sort ? String(req.query.sort).split(",") : "";
2617
2733
  const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
2618
2734
  const sortObj = {};
@@ -2627,11 +2743,11 @@ function useLearnerController() {
2627
2743
  page,
2628
2744
  limit,
2629
2745
  sort: sortObj,
2630
- search: req.query.search,
2631
- status: req.query.status,
2632
- school: req.query.school,
2633
- schoolYear: req.query.schoolYear,
2634
- gradeLevelToEnroll: req.query.gradeLevelToEnroll
2746
+ search,
2747
+ status,
2748
+ school,
2749
+ schoolYear,
2750
+ level
2635
2751
  });
2636
2752
  res.json(result);
2637
2753
  return;
@@ -2672,11 +2788,11 @@ import {
2672
2788
 
2673
2789
  // src/resources/count/count.model.ts
2674
2790
  import { BadRequestError as BadRequestError8 } from "@eeplatform/nodejs-utils";
2675
- import Joi6 from "joi";
2676
- var schemaBasicEduCount = Joi6.object({
2677
- _id: Joi6.string().hex().length(24).optional(),
2678
- name: Joi6.string().required(),
2679
- count: Joi6.number().min(0).required()
2791
+ import Joi7 from "joi";
2792
+ var schemaBasicEduCount = Joi7.object({
2793
+ _id: Joi7.string().hex().length(24).optional(),
2794
+ name: Joi7.string().required(),
2795
+ count: Joi7.number().min(0).required()
2680
2796
  });
2681
2797
  function modelBasicEduCount(value) {
2682
2798
  const { error } = schemaBasicEduCount.validate(value);
@@ -2928,7 +3044,7 @@ function useEnrollmentService() {
2928
3044
  level: "error",
2929
3045
  message: `Error creating enrollment: ${error.message}`
2930
3046
  });
2931
- throw new InternalServerError4("Failed to create enrollment");
3047
+ throw new InternalServerError3("Failed to create enrollment");
2932
3048
  }
2933
3049
  }
2934
3050
  const { add: addLearner } = useLearnerRepo();
@@ -2948,7 +3064,7 @@ function useEnrollmentService() {
2948
3064
  }
2949
3065
  const client = useAtlas5.getClient();
2950
3066
  if (!client) {
2951
- throw new InternalServerError4("Database client not available");
3067
+ throw new InternalServerError3("Database client not available");
2952
3068
  }
2953
3069
  const session = client.startSession();
2954
3070
  try {
@@ -2959,7 +3075,7 @@ function useEnrollmentService() {
2959
3075
  }
2960
3076
  const result = await _updateStatusById(_id, status, session);
2961
3077
  if (result.modifiedCount === 0) {
2962
- throw new InternalServerError4("Failed to accept enrollment");
3078
+ throw new InternalServerError3("Failed to accept enrollment");
2963
3079
  }
2964
3080
  if (status === "accepted") {
2965
3081
  delete enrollment._id;
@@ -2972,7 +3088,7 @@ function useEnrollmentService() {
2972
3088
  if (!enrollment.learnerInfo.lrn) {
2973
3089
  const counter = await getByName(enrollment.schoolId);
2974
3090
  if (!counter) {
2975
- throw new InternalServerError4(
3091
+ throw new InternalServerError3(
2976
3092
  "Failed to retrieve enrollment counter"
2977
3093
  );
2978
3094
  }
@@ -3002,7 +3118,7 @@ function useEnrollmentService() {
3002
3118
  if (error2 instanceof AppError5) {
3003
3119
  throw error2;
3004
3120
  } else {
3005
- throw new InternalServerError4("Failed to retrieve enrollment");
3121
+ throw new InternalServerError3("Failed to retrieve enrollment");
3006
3122
  }
3007
3123
  }
3008
3124
  }
@@ -3014,7 +3130,7 @@ function useEnrollmentService() {
3014
3130
 
3015
3131
  // src/resources/enrollment/enrollment.controller.ts
3016
3132
  import { BadRequestError as BadRequestError11, logger as logger9 } from "@eeplatform/nodejs-utils";
3017
- import Joi7 from "joi";
3133
+ import Joi8 from "joi";
3018
3134
  function useEnrollmentController() {
3019
3135
  const { add: _add, updateStatusById: _updateStatusById } = useEnrollmentService();
3020
3136
  const { getAll: _getAll } = useEnrollmentRepo();
@@ -3036,15 +3152,15 @@ function useEnrollmentController() {
3036
3152
  }
3037
3153
  async function getAll(req, res, next) {
3038
3154
  const query = req.query;
3039
- const validation = Joi7.object({
3040
- page: Joi7.number().min(1).optional().allow("", null),
3041
- limit: Joi7.number().min(1).max(100).optional().allow("", null),
3042
- search: Joi7.string().optional().allow("", null),
3043
- status: Joi7.string().optional().allow("", null),
3044
- school: Joi7.string().hex().optional().allow("", null),
3045
- schoolYear: Joi7.string().optional().allow("", null),
3046
- gradeLevelToEnroll: Joi7.string().optional().allow("", null),
3047
- createdBy: Joi7.string().hex().optional().allow("", null)
3155
+ const validation = Joi8.object({
3156
+ page: Joi8.number().min(1).optional().allow("", null),
3157
+ limit: Joi8.number().min(1).max(100).optional().allow("", null),
3158
+ search: Joi8.string().optional().allow("", null),
3159
+ status: Joi8.string().optional().allow("", null),
3160
+ school: Joi8.string().hex().optional().allow("", null),
3161
+ schoolYear: Joi8.string().optional().allow("", null),
3162
+ gradeLevelToEnroll: Joi8.string().optional().allow("", null),
3163
+ createdBy: Joi8.string().hex().optional().allow("", null)
3048
3164
  });
3049
3165
  const { error } = validation.validate(query);
3050
3166
  if (error) {
@@ -3106,26 +3222,27 @@ function useEnrollmentController() {
3106
3222
 
3107
3223
  // src/resources/grade-level/grade-level.model.ts
3108
3224
  import { BadRequestError as BadRequestError12, logger as logger10 } from "@eeplatform/nodejs-utils";
3109
- import Joi8 from "joi";
3225
+ import Joi9 from "joi";
3110
3226
  import { ObjectId as ObjectId7 } from "mongodb";
3111
- var schemaGradeLevel = Joi8.object({
3112
- _id: Joi8.string().hex().optional(),
3113
- school: Joi8.string().hex().optional(),
3114
- educationLevel: Joi8.string().required(),
3115
- gradeLevel: Joi8.string().required(),
3116
- tracks: Joi8.array().items(Joi8.string()).optional(),
3117
- trackStrands: Joi8.array().items(Joi8.string()).optional(),
3118
- teachingStyle: Joi8.string().required(),
3119
- maxNumberOfLearners: Joi8.number().required(),
3120
- defaultStartTime: Joi8.string().optional().allow("", null),
3121
- defaultEndTime: Joi8.string().optional().allow("", null),
3122
- status: Joi8.string().optional().allow("", null),
3123
- createdAt: Joi8.date().optional().allow("", null),
3124
- updatedAt: Joi8.date().optional().allow("", null),
3125
- deletedAt: Joi8.date().optional().allow("", null),
3126
- createdBy: Joi8.string().optional().allow("", null),
3127
- updatedBy: Joi8.string().optional().allow("", null),
3128
- deletedBy: Joi8.string().optional().allow("", null)
3227
+ var schemaGradeLevel = Joi9.object({
3228
+ _id: Joi9.string().hex().optional(),
3229
+ school: Joi9.string().hex().optional(),
3230
+ educationLevel: Joi9.string().required(),
3231
+ gradeLevel: Joi9.string().required(),
3232
+ tracks: Joi9.array().items(Joi9.string()).optional(),
3233
+ trackStrands: Joi9.array().items(Joi9.string()).optional(),
3234
+ teachingStyle: Joi9.string().required(),
3235
+ maxNumberOfLearners: Joi9.number().required(),
3236
+ minNumberOfLearners: Joi9.number().required(),
3237
+ defaultStartTime: Joi9.string().optional().allow("", null),
3238
+ defaultEndTime: Joi9.string().optional().allow("", null),
3239
+ status: Joi9.string().optional().allow("", null),
3240
+ createdAt: Joi9.date().optional().allow("", null),
3241
+ updatedAt: Joi9.date().optional().allow("", null),
3242
+ deletedAt: Joi9.date().optional().allow("", null),
3243
+ createdBy: Joi9.string().optional().allow("", null),
3244
+ updatedBy: Joi9.string().optional().allow("", null),
3245
+ deletedBy: Joi9.string().optional().allow("", null)
3129
3246
  });
3130
3247
  function MGradeLevel(value) {
3131
3248
  const { error } = schemaGradeLevel.validate(value);
@@ -3147,6 +3264,11 @@ function MGradeLevel(value) {
3147
3264
  throw new BadRequestError12("Invalid school format");
3148
3265
  }
3149
3266
  }
3267
+ if (value.minNumberOfLearners > value.maxNumberOfLearners) {
3268
+ throw new BadRequestError12(
3269
+ "Minimum number of learners cannot be greater than maximum number of learners."
3270
+ );
3271
+ }
3150
3272
  return {
3151
3273
  _id: value._id ?? void 0,
3152
3274
  school: value.school ?? void 0,
@@ -3156,6 +3278,7 @@ function MGradeLevel(value) {
3156
3278
  trackStrands: value.trackStrands ?? [],
3157
3279
  teachingStyle: value.teachingStyle ?? "",
3158
3280
  maxNumberOfLearners: value.maxNumberOfLearners ?? 0,
3281
+ minNumberOfLearners: value.minNumberOfLearners ?? 0,
3159
3282
  defaultStartTime: value.defaultStartTime ?? "",
3160
3283
  defaultEndTime: value.defaultEndTime ?? "",
3161
3284
  status: value.status ?? "active",
@@ -3172,7 +3295,7 @@ function MGradeLevel(value) {
3172
3295
  import {
3173
3296
  AppError as AppError6,
3174
3297
  BadRequestError as BadRequestError13,
3175
- InternalServerError as InternalServerError5,
3298
+ InternalServerError as InternalServerError4,
3176
3299
  logger as logger11,
3177
3300
  makeCacheKey as makeCacheKey5,
3178
3301
  paginate as paginate4,
@@ -3185,7 +3308,7 @@ function useGradeLevelRepo() {
3185
3308
  if (!db) {
3186
3309
  throw new Error("Unable to connect to server.");
3187
3310
  }
3188
- const namespace_collection = "school.grade-levels";
3311
+ const namespace_collection = "deped.school.grade-levels";
3189
3312
  const collection = db.collection(namespace_collection);
3190
3313
  const { getCache, setCache, delNamespace } = useCache5(namespace_collection);
3191
3314
  async function createIndexes() {
@@ -3344,25 +3467,7 @@ function useGradeLevelRepo() {
3344
3467
  { $match: query },
3345
3468
  { $sort: sort },
3346
3469
  { $skip: page * limit },
3347
- { $limit: limit },
3348
- {
3349
- $lookup: {
3350
- from: "school.schools",
3351
- localField: "school",
3352
- foreignField: "_id",
3353
- as: "schoolDetails"
3354
- }
3355
- },
3356
- {
3357
- $addFields: {
3358
- schoolName: { $arrayElemAt: ["$schoolDetails.name", 0] }
3359
- }
3360
- },
3361
- {
3362
- $project: {
3363
- schoolDetails: 0
3364
- }
3365
- }
3470
+ { $limit: limit }
3366
3471
  ]).toArray();
3367
3472
  const length = await collection.countDocuments(query);
3368
3473
  const data = paginate4(items, page, limit, length);
@@ -3437,7 +3542,7 @@ function useGradeLevelRepo() {
3437
3542
  if (error instanceof AppError6) {
3438
3543
  throw error;
3439
3544
  } else {
3440
- throw new InternalServerError5("Failed to get grade level.");
3545
+ throw new InternalServerError4("Failed to get grade level.");
3441
3546
  }
3442
3547
  }
3443
3548
  }
@@ -3463,7 +3568,7 @@ function useGradeLevelRepo() {
3463
3568
  if (error instanceof AppError6) {
3464
3569
  throw error;
3465
3570
  } else {
3466
- throw new InternalServerError5("Failed to delete grade level.");
3571
+ throw new InternalServerError4("Failed to delete grade level.");
3467
3572
  }
3468
3573
  }
3469
3574
  }
@@ -3511,6 +3616,52 @@ function useGradeLevelRepo() {
3511
3616
  throw error;
3512
3617
  }
3513
3618
  }
3619
+ async function getByGradeLevel(value, session) {
3620
+ const status = value.status ?? "active";
3621
+ const query = {
3622
+ gradeLevel: value.gradeLevel,
3623
+ status
3624
+ };
3625
+ const cacheKeyOptions = {
3626
+ gradeLevel: value.gradeLevel,
3627
+ status
3628
+ };
3629
+ if (value.school) {
3630
+ try {
3631
+ query.school = new ObjectId8(value.school);
3632
+ } catch (error) {
3633
+ throw new BadRequestError13("Invalid school ID format.");
3634
+ }
3635
+ cacheKeyOptions.school = value.school;
3636
+ }
3637
+ const cacheKey = makeCacheKey5(namespace_collection, cacheKeyOptions);
3638
+ try {
3639
+ const cached = await getCache(cacheKey);
3640
+ if (cached) {
3641
+ logger11.log({
3642
+ level: "info",
3643
+ message: `Cache hit for getByGradeLevel: ${cacheKey}`
3644
+ });
3645
+ return cached;
3646
+ }
3647
+ const result = await collection.findOne(query, { session });
3648
+ setCache(cacheKey, result, 300).then(() => {
3649
+ logger11.log({
3650
+ level: "info",
3651
+ message: `Cache set for getByGradeLevel: ${cacheKey}`
3652
+ });
3653
+ }).catch((err) => {
3654
+ logger11.log({
3655
+ level: "error",
3656
+ message: `Failed to set cache for getByGradeLevel: ${err.message}`
3657
+ });
3658
+ });
3659
+ return result;
3660
+ } catch (error) {
3661
+ logger11.log({ level: "error", message: `${error}` });
3662
+ throw error;
3663
+ }
3664
+ }
3514
3665
  function delCachedData() {
3515
3666
  delNamespace().then(() => {
3516
3667
  logger11.log({
@@ -3531,13 +3682,14 @@ function useGradeLevelRepo() {
3531
3682
  getById,
3532
3683
  updateById,
3533
3684
  deleteById,
3534
- getByEducationLevel
3685
+ getByEducationLevel,
3686
+ getByGradeLevel
3535
3687
  };
3536
3688
  }
3537
3689
 
3538
3690
  // src/resources/grade-level/grade-level.controller.ts
3539
3691
  import { BadRequestError as BadRequestError14, logger as logger12 } from "@eeplatform/nodejs-utils";
3540
- import Joi9 from "joi";
3692
+ import Joi10 from "joi";
3541
3693
  function useGradeLevelController() {
3542
3694
  const {
3543
3695
  getAll: _getAll,
@@ -3569,17 +3721,17 @@ function useGradeLevelController() {
3569
3721
  async function updateById(req, res, next) {
3570
3722
  const value = req.body;
3571
3723
  const id = req.params.id ?? "";
3572
- const validation = Joi9.object({
3573
- id: Joi9.string().hex().required(),
3574
- value: Joi9.object({
3575
- school: Joi9.string().hex().optional(),
3576
- educationLevel: Joi9.string().optional(),
3577
- gradeLevel: Joi9.string().optional(),
3578
- teachingStyle: Joi9.string().optional(),
3579
- maxTeachingHoursPerDay: Joi9.number().integer().min(0).optional(),
3580
- maxTeachingHoursPerWeek: Joi9.number().integer().min(0).optional(),
3581
- defaultStartTime: Joi9.string().optional().allow("", null),
3582
- defaultEndTime: Joi9.string().optional().allow("", null)
3724
+ const validation = Joi10.object({
3725
+ id: Joi10.string().hex().required(),
3726
+ value: Joi10.object({
3727
+ school: Joi10.string().hex().optional(),
3728
+ educationLevel: Joi10.string().optional(),
3729
+ gradeLevel: Joi10.string().optional(),
3730
+ teachingStyle: Joi10.string().optional(),
3731
+ maxTeachingHoursPerDay: Joi10.number().integer().min(0).optional(),
3732
+ maxTeachingHoursPerWeek: Joi10.number().integer().min(0).optional(),
3733
+ defaultStartTime: Joi10.string().optional().allow("", null),
3734
+ defaultEndTime: Joi10.string().optional().allow("", null)
3583
3735
  }).min(1)
3584
3736
  });
3585
3737
  const { error } = validation.validate({ id, value });
@@ -3601,15 +3753,15 @@ function useGradeLevelController() {
3601
3753
  }
3602
3754
  async function getAll(req, res, next) {
3603
3755
  const query = req.query;
3604
- const validation = Joi9.object({
3605
- page: Joi9.number().min(1).optional().allow("", null),
3606
- limit: Joi9.number().min(1).optional().allow("", null),
3607
- search: Joi9.string().optional().allow("", null),
3608
- educationLevel: Joi9.string().optional().allow("", null),
3609
- gradeLevel: Joi9.string().optional().allow("", null),
3610
- teachingStyle: Joi9.string().optional().allow("", null),
3611
- school: Joi9.string().hex().optional().allow("", null),
3612
- status: Joi9.string().optional().allow("", null)
3756
+ const validation = Joi10.object({
3757
+ page: Joi10.number().min(1).optional().allow("", null),
3758
+ limit: Joi10.number().min(1).optional().allow("", null),
3759
+ search: Joi10.string().optional().allow("", null),
3760
+ educationLevel: Joi10.string().optional().allow("", null),
3761
+ gradeLevel: Joi10.string().optional().allow("", null),
3762
+ teachingStyle: Joi10.string().optional().allow("", null),
3763
+ school: Joi10.string().hex().optional().allow("", null),
3764
+ status: Joi10.string().optional().allow("", null)
3613
3765
  });
3614
3766
  const { error } = validation.validate(query);
3615
3767
  if (error) {
@@ -3653,8 +3805,8 @@ function useGradeLevelController() {
3653
3805
  }
3654
3806
  async function getById(req, res, next) {
3655
3807
  const id = req.params.id;
3656
- const validation = Joi9.object({
3657
- id: Joi9.string().hex().required()
3808
+ const validation = Joi10.object({
3809
+ id: Joi10.string().hex().required()
3658
3810
  });
3659
3811
  const { error } = validation.validate({ id });
3660
3812
  if (error) {
@@ -3674,8 +3826,8 @@ function useGradeLevelController() {
3674
3826
  }
3675
3827
  async function deleteById(req, res, next) {
3676
3828
  const id = req.params.id;
3677
- const validation = Joi9.object({
3678
- id: Joi9.string().hex().required()
3829
+ const validation = Joi10.object({
3830
+ id: Joi10.string().hex().required()
3679
3831
  });
3680
3832
  const { error } = validation.validate({ id });
3681
3833
  if (error) {
@@ -3696,9 +3848,9 @@ function useGradeLevelController() {
3696
3848
  async function getByEducationLevel(req, res, next) {
3697
3849
  const educationLevel = req.params.educationLevel;
3698
3850
  const school = req.query.school;
3699
- const validation = Joi9.object({
3700
- educationLevel: Joi9.string().required(),
3701
- school: Joi9.string().hex().optional().allow("", null)
3851
+ const validation = Joi10.object({
3852
+ educationLevel: Joi10.string().required(),
3853
+ school: Joi10.string().hex().optional().allow("", null)
3702
3854
  });
3703
3855
  const { error } = validation.validate({ educationLevel, school });
3704
3856
  if (error) {
@@ -3728,14 +3880,14 @@ function useGradeLevelController() {
3728
3880
 
3729
3881
  // src/resources/region/region.model.ts
3730
3882
  import { BadRequestError as BadRequestError15 } from "@eeplatform/nodejs-utils";
3731
- import Joi10 from "joi";
3883
+ import Joi11 from "joi";
3732
3884
  import { ObjectId as ObjectId9 } from "mongodb";
3733
- var schemaRegion = Joi10.object({
3734
- _id: Joi10.string().hex().optional().allow(null, ""),
3735
- name: Joi10.string().min(1).max(100).required(),
3736
- createdAt: Joi10.string().isoDate().optional(),
3737
- updatedAt: Joi10.string().isoDate().optional(),
3738
- deletedAt: Joi10.string().isoDate().optional().allow(null, "")
3885
+ var schemaRegion = Joi11.object({
3886
+ _id: Joi11.string().hex().optional().allow(null, ""),
3887
+ name: Joi11.string().min(1).max(100).required(),
3888
+ createdAt: Joi11.string().isoDate().optional(),
3889
+ updatedAt: Joi11.string().isoDate().optional(),
3890
+ deletedAt: Joi11.string().isoDate().optional().allow(null, "")
3739
3891
  });
3740
3892
  function modelRegion(value) {
3741
3893
  const { error } = schemaRegion.validate(value);
@@ -3763,7 +3915,7 @@ function modelRegion(value) {
3763
3915
  import {
3764
3916
  AppError as AppError7,
3765
3917
  BadRequestError as BadRequestError16,
3766
- InternalServerError as InternalServerError6,
3918
+ InternalServerError as InternalServerError5,
3767
3919
  logger as logger13,
3768
3920
  makeCacheKey as makeCacheKey6,
3769
3921
  paginate as paginate5,
@@ -3927,7 +4079,7 @@ function useRegionRepo() {
3927
4079
  if (error instanceof AppError7) {
3928
4080
  throw error;
3929
4081
  } else {
3930
- throw new InternalServerError6("Failed to get region.");
4082
+ throw new InternalServerError5("Failed to get region.");
3931
4083
  }
3932
4084
  }
3933
4085
  }
@@ -3965,7 +4117,7 @@ function useRegionRepo() {
3965
4117
  if (error instanceof AppError7) {
3966
4118
  throw error;
3967
4119
  } else {
3968
- throw new InternalServerError6("Failed to get region.");
4120
+ throw new InternalServerError5("Failed to get region.");
3969
4121
  }
3970
4122
  }
3971
4123
  }
@@ -3990,7 +4142,7 @@ function useRegionRepo() {
3990
4142
  delCachedData();
3991
4143
  return `Successfully updated region ${field}.`;
3992
4144
  } catch (error) {
3993
- throw new InternalServerError6(`Failed to update region ${field}.`);
4145
+ throw new InternalServerError5(`Failed to update region ${field}.`);
3994
4146
  }
3995
4147
  }
3996
4148
  async function deleteById(_id) {
@@ -4007,7 +4159,7 @@ function useRegionRepo() {
4007
4159
  delCachedData();
4008
4160
  return "Successfully deleted region.";
4009
4161
  } catch (error) {
4010
- throw new InternalServerError6("Failed to delete region.");
4162
+ throw new InternalServerError5("Failed to delete region.");
4011
4163
  }
4012
4164
  }
4013
4165
  return {
@@ -4023,7 +4175,7 @@ function useRegionRepo() {
4023
4175
 
4024
4176
  // src/resources/region/region.controller.ts
4025
4177
  import { BadRequestError as BadRequestError17 } from "@eeplatform/nodejs-utils";
4026
- import Joi11 from "joi";
4178
+ import Joi12 from "joi";
4027
4179
  function useRegionController() {
4028
4180
  const {
4029
4181
  add: _add,
@@ -4053,11 +4205,11 @@ function useRegionController() {
4053
4205
  }
4054
4206
  async function getAll(req, res, next) {
4055
4207
  const query = req.query;
4056
- const validation = Joi11.object({
4057
- page: Joi11.number().min(1).optional().allow("", null),
4058
- limit: Joi11.number().min(1).optional().allow("", null),
4059
- search: Joi11.string().optional().allow("", null),
4060
- status: Joi11.string().optional().allow("", null)
4208
+ const validation = Joi12.object({
4209
+ page: Joi12.number().min(1).optional().allow("", null),
4210
+ limit: Joi12.number().min(1).optional().allow("", null),
4211
+ search: Joi12.string().optional().allow("", null),
4212
+ status: Joi12.string().optional().allow("", null)
4061
4213
  });
4062
4214
  const { error } = validation.validate(query);
4063
4215
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -4088,8 +4240,8 @@ function useRegionController() {
4088
4240
  }
4089
4241
  async function getById(req, res, next) {
4090
4242
  const id = req.params.id;
4091
- const validation = Joi11.object({
4092
- id: Joi11.string().hex().required()
4243
+ const validation = Joi12.object({
4244
+ id: Joi12.string().hex().required()
4093
4245
  });
4094
4246
  const { error } = validation.validate({ id });
4095
4247
  if (error) {
@@ -4109,8 +4261,8 @@ function useRegionController() {
4109
4261
  }
4110
4262
  async function getByName(req, res, next) {
4111
4263
  const name = req.params.name;
4112
- const validation = Joi11.object({
4113
- name: Joi11.string().required()
4264
+ const validation = Joi12.object({
4265
+ name: Joi12.string().required()
4114
4266
  });
4115
4267
  const { error } = validation.validate({ name });
4116
4268
  if (error) {
@@ -4131,10 +4283,10 @@ function useRegionController() {
4131
4283
  async function updateField(req, res, next) {
4132
4284
  const _id = req.params.id;
4133
4285
  const { field, value } = req.body;
4134
- const validation = Joi11.object({
4135
- _id: Joi11.string().hex().required(),
4136
- field: Joi11.string().valid("name", "director", "directorName").required(),
4137
- value: Joi11.string().required()
4286
+ const validation = Joi12.object({
4287
+ _id: Joi12.string().hex().required(),
4288
+ field: Joi12.string().valid("name", "director", "directorName").required(),
4289
+ value: Joi12.string().required()
4138
4290
  });
4139
4291
  const { error } = validation.validate({ _id, field, value });
4140
4292
  if (error) {
@@ -4151,8 +4303,8 @@ function useRegionController() {
4151
4303
  }
4152
4304
  async function deleteById(req, res, next) {
4153
4305
  const _id = req.params.id;
4154
- const validation = Joi11.object({
4155
- _id: Joi11.string().hex().required()
4306
+ const validation = Joi12.object({
4307
+ _id: Joi12.string().hex().required()
4156
4308
  });
4157
4309
  const { error } = validation.validate({ _id });
4158
4310
  if (error) {
@@ -4179,26 +4331,26 @@ function useRegionController() {
4179
4331
 
4180
4332
  // src/resources/division/division.model.ts
4181
4333
  import { BadRequestError as BadRequestError18 } from "@eeplatform/nodejs-utils";
4182
- import Joi12 from "joi";
4334
+ import Joi13 from "joi";
4183
4335
  import { ObjectId as ObjectId11 } from "mongodb";
4184
- var schemaDivision = Joi12.object({
4185
- _id: Joi12.string().hex().optional().allow(null, ""),
4186
- name: Joi12.string().min(1).max(100).required(),
4187
- region: Joi12.string().hex().required(),
4188
- regionName: Joi12.string().min(1).max(100).required(),
4189
- superintendent: Joi12.string().hex().optional().allow(null, ""),
4190
- superintendentName: Joi12.string().min(1).max(100).optional().allow(null, ""),
4191
- createdAt: Joi12.string().isoDate().optional(),
4192
- updatedAt: Joi12.string().isoDate().optional(),
4193
- deletedAt: Joi12.string().isoDate().optional().allow(null, "")
4336
+ var schemaDivision = Joi13.object({
4337
+ _id: Joi13.string().hex().optional().allow(null, ""),
4338
+ name: Joi13.string().min(1).max(100).required(),
4339
+ region: Joi13.string().hex().required(),
4340
+ regionName: Joi13.string().min(1).max(100).required(),
4341
+ superintendent: Joi13.string().hex().optional().allow(null, ""),
4342
+ superintendentName: Joi13.string().min(1).max(100).optional().allow(null, ""),
4343
+ createdAt: Joi13.string().isoDate().optional(),
4344
+ updatedAt: Joi13.string().isoDate().optional(),
4345
+ deletedAt: Joi13.string().isoDate().optional().allow(null, "")
4194
4346
  });
4195
- var schemaDivisionUpdate = Joi12.object({
4196
- _id: Joi12.string().hex().optional().allow(null, ""),
4197
- name: Joi12.string().min(1).max(100).required(),
4198
- region: Joi12.string().hex().required(),
4199
- regionName: Joi12.string().min(1).max(100).required(),
4200
- superintendent: Joi12.string().hex().optional().allow(null, ""),
4201
- superintendentName: Joi12.string().min(1).max(100).optional().allow(null, "")
4347
+ var schemaDivisionUpdate = Joi13.object({
4348
+ _id: Joi13.string().hex().optional().allow(null, ""),
4349
+ name: Joi13.string().min(1).max(100).required(),
4350
+ region: Joi13.string().hex().required(),
4351
+ regionName: Joi13.string().min(1).max(100).required(),
4352
+ superintendent: Joi13.string().hex().optional().allow(null, ""),
4353
+ superintendentName: Joi13.string().min(1).max(100).optional().allow(null, "")
4202
4354
  });
4203
4355
  function modelDivision(value) {
4204
4356
  const { error } = schemaDivision.validate(value);
@@ -4244,7 +4396,7 @@ function modelDivision(value) {
4244
4396
  import {
4245
4397
  AppError as AppError8,
4246
4398
  BadRequestError as BadRequestError19,
4247
- InternalServerError as InternalServerError7,
4399
+ InternalServerError as InternalServerError6,
4248
4400
  logger as logger14,
4249
4401
  makeCacheKey as makeCacheKey7,
4250
4402
  paginate as paginate6,
@@ -4424,7 +4576,7 @@ function useDivisionRepo() {
4424
4576
  if (error instanceof AppError8) {
4425
4577
  throw error;
4426
4578
  } else {
4427
- throw new InternalServerError7("Failed to get division.");
4579
+ throw new InternalServerError6("Failed to get division.");
4428
4580
  }
4429
4581
  }
4430
4582
  }
@@ -4462,7 +4614,7 @@ function useDivisionRepo() {
4462
4614
  if (error instanceof AppError8) {
4463
4615
  throw error;
4464
4616
  } else {
4465
- throw new InternalServerError7("Failed to get division.");
4617
+ throw new InternalServerError6("Failed to get division.");
4466
4618
  }
4467
4619
  }
4468
4620
  }
@@ -4487,7 +4639,7 @@ function useDivisionRepo() {
4487
4639
  delCachedData();
4488
4640
  return `Successfully updated division ${field}.`;
4489
4641
  } catch (error) {
4490
- throw new InternalServerError7(`Failed to update division ${field}.`);
4642
+ throw new InternalServerError6(`Failed to update division ${field}.`);
4491
4643
  }
4492
4644
  }
4493
4645
  async function updateById(_id, options, session) {
@@ -4515,7 +4667,7 @@ function useDivisionRepo() {
4515
4667
  delCachedData();
4516
4668
  return `Successfully updated division.`;
4517
4669
  } catch (error2) {
4518
- throw new InternalServerError7(`Failed to update division.`);
4670
+ throw new InternalServerError6(`Failed to update division.`);
4519
4671
  }
4520
4672
  }
4521
4673
  async function deleteById(_id) {
@@ -4532,7 +4684,7 @@ function useDivisionRepo() {
4532
4684
  delCachedData();
4533
4685
  return "Successfully deleted division.";
4534
4686
  } catch (error) {
4535
- throw new InternalServerError7("Failed to delete division.");
4687
+ throw new InternalServerError6("Failed to delete division.");
4536
4688
  }
4537
4689
  }
4538
4690
  return {
@@ -4553,49 +4705,49 @@ import { useRoleRepo as useRoleRepo2 } from "@eeplatform/core";
4553
4705
 
4554
4706
  // src/resources/school/school.model.ts
4555
4707
  import { BadRequestError as BadRequestError20 } from "@eeplatform/nodejs-utils";
4556
- import Joi13 from "joi";
4708
+ import Joi14 from "joi";
4557
4709
  import { ObjectId as ObjectId13 } from "mongodb";
4558
- var schemaSchool = Joi13.object({
4559
- _id: Joi13.string().hex().optional().allow(null, ""),
4560
- id: Joi13.string().min(1).max(50).required(),
4561
- name: Joi13.string().min(1).max(100).required(),
4562
- region: Joi13.string().hex().required(),
4563
- regionName: Joi13.string().min(1).max(100).optional().allow(null, ""),
4564
- division: Joi13.string().hex().required(),
4565
- divisionName: Joi13.string().min(1).max(100).optional().allow(null, ""),
4566
- principal: Joi13.string().hex().optional().allow(null, ""),
4567
- principalName: Joi13.string().min(1).max(100).optional().allow(null, ""),
4568
- street: Joi13.string().max(200).optional().allow(null, ""),
4569
- barangay: Joi13.string().max(200).optional().allow(null, ""),
4570
- cityMunicipality: Joi13.string().max(100).optional().allow(null, ""),
4571
- province: Joi13.string().max(100).optional().allow(null, ""),
4572
- cityMunicipalityPSGC: Joi13.string().length(10).optional().allow(null, ""),
4573
- postalCode: Joi13.string().max(20).optional().allow(null, ""),
4574
- contactNumber: Joi13.string().max(20).optional().allow(null, ""),
4575
- email: Joi13.string().email().max(100).optional().allow(null, ""),
4576
- status: Joi13.string().optional().allow(null, ""),
4577
- createdBy: Joi13.string().optional().allow(null, ""),
4578
- createdAt: Joi13.string().isoDate().optional().allow(null, ""),
4579
- updatedAt: Joi13.string().isoDate().optional().allow(null, ""),
4580
- deletedAt: Joi13.string().isoDate().optional().allow(null, "")
4710
+ var schemaSchool = Joi14.object({
4711
+ _id: Joi14.string().hex().optional().allow(null, ""),
4712
+ id: Joi14.string().min(1).max(50).required(),
4713
+ name: Joi14.string().min(1).max(100).required(),
4714
+ region: Joi14.string().hex().required(),
4715
+ regionName: Joi14.string().min(1).max(100).optional().allow(null, ""),
4716
+ division: Joi14.string().hex().required(),
4717
+ divisionName: Joi14.string().min(1).max(100).optional().allow(null, ""),
4718
+ principal: Joi14.string().hex().optional().allow(null, ""),
4719
+ principalName: Joi14.string().min(1).max(100).optional().allow(null, ""),
4720
+ street: Joi14.string().max(200).optional().allow(null, ""),
4721
+ barangay: Joi14.string().max(200).optional().allow(null, ""),
4722
+ cityMunicipality: Joi14.string().max(100).optional().allow(null, ""),
4723
+ province: Joi14.string().max(100).optional().allow(null, ""),
4724
+ cityMunicipalityPSGC: Joi14.string().length(10).optional().allow(null, ""),
4725
+ postalCode: Joi14.string().max(20).optional().allow(null, ""),
4726
+ contactNumber: Joi14.string().max(20).optional().allow(null, ""),
4727
+ email: Joi14.string().email().max(100).optional().allow(null, ""),
4728
+ status: Joi14.string().optional().allow(null, ""),
4729
+ createdBy: Joi14.string().optional().allow(null, ""),
4730
+ createdAt: Joi14.string().isoDate().optional().allow(null, ""),
4731
+ updatedAt: Joi14.string().isoDate().optional().allow(null, ""),
4732
+ deletedAt: Joi14.string().isoDate().optional().allow(null, "")
4581
4733
  });
4582
- var schemaSchoolUpdate = Joi13.object({
4583
- id: Joi13.string().min(1).max(50).required(),
4584
- name: Joi13.string().min(1).max(100).required(),
4585
- region: Joi13.string().hex().required(),
4586
- regionName: Joi13.string().min(1).max(100).optional().allow(null, ""),
4587
- division: Joi13.string().hex().required(),
4588
- divisionName: Joi13.string().min(1).max(100).optional().allow(null, ""),
4589
- principal: Joi13.string().hex().optional().allow(null, ""),
4590
- principalName: Joi13.string().min(1).max(100).optional().allow(null, ""),
4591
- street: Joi13.string().max(200).optional().allow(null, ""),
4592
- barangay: Joi13.string().max(200).optional().allow(null, ""),
4593
- cityMunicipality: Joi13.string().max(100).optional().allow(null, ""),
4594
- province: Joi13.string().max(100).optional().allow(null, ""),
4595
- cityMunicipalityPSGC: Joi13.string().length(10).optional().allow(null, ""),
4596
- postalCode: Joi13.string().max(20).optional().allow(null, ""),
4597
- contactNumber: Joi13.string().max(20).optional().allow(null, ""),
4598
- email: Joi13.string().email().max(100).optional().allow(null, "")
4734
+ var schemaSchoolUpdate = Joi14.object({
4735
+ id: Joi14.string().min(1).max(50).required(),
4736
+ name: Joi14.string().min(1).max(100).required(),
4737
+ region: Joi14.string().hex().required(),
4738
+ regionName: Joi14.string().min(1).max(100).optional().allow(null, ""),
4739
+ division: Joi14.string().hex().required(),
4740
+ divisionName: Joi14.string().min(1).max(100).optional().allow(null, ""),
4741
+ principal: Joi14.string().hex().optional().allow(null, ""),
4742
+ principalName: Joi14.string().min(1).max(100).optional().allow(null, ""),
4743
+ street: Joi14.string().max(200).optional().allow(null, ""),
4744
+ barangay: Joi14.string().max(200).optional().allow(null, ""),
4745
+ cityMunicipality: Joi14.string().max(100).optional().allow(null, ""),
4746
+ province: Joi14.string().max(100).optional().allow(null, ""),
4747
+ cityMunicipalityPSGC: Joi14.string().length(10).optional().allow(null, ""),
4748
+ postalCode: Joi14.string().max(20).optional().allow(null, ""),
4749
+ contactNumber: Joi14.string().max(20).optional().allow(null, ""),
4750
+ email: Joi14.string().email().max(100).optional().allow(null, "")
4599
4751
  });
4600
4752
  function modelSchool(value) {
4601
4753
  const { error } = schemaSchool.validate(value);
@@ -4660,7 +4812,7 @@ function modelSchool(value) {
4660
4812
  import {
4661
4813
  AppError as AppError9,
4662
4814
  BadRequestError as BadRequestError21,
4663
- InternalServerError as InternalServerError8,
4815
+ InternalServerError as InternalServerError7,
4664
4816
  logger as logger15,
4665
4817
  makeCacheKey as makeCacheKey8,
4666
4818
  paginate as paginate7,
@@ -4729,7 +4881,7 @@ function useSchoolRepo() {
4729
4881
  if (isDuplicated) {
4730
4882
  throw new BadRequestError21("Duplicate, school already exists.");
4731
4883
  }
4732
- throw new InternalServerError8("Failed to add school.");
4884
+ throw new InternalServerError7("Failed to add school.");
4733
4885
  }
4734
4886
  }
4735
4887
  }
@@ -4845,7 +4997,7 @@ function useSchoolRepo() {
4845
4997
  if (error instanceof AppError9) {
4846
4998
  throw error;
4847
4999
  } else {
4848
- throw new InternalServerError8("Failed to get school.");
5000
+ throw new InternalServerError7("Failed to get school.");
4849
5001
  }
4850
5002
  }
4851
5003
  }
@@ -4888,7 +5040,7 @@ function useSchoolRepo() {
4888
5040
  if (error instanceof AppError9) {
4889
5041
  throw error;
4890
5042
  } else {
4891
- throw new InternalServerError8("Failed to get school.");
5043
+ throw new InternalServerError7("Failed to get school.");
4892
5044
  }
4893
5045
  }
4894
5046
  }
@@ -4926,7 +5078,7 @@ function useSchoolRepo() {
4926
5078
  if (error instanceof AppError9) {
4927
5079
  throw error;
4928
5080
  } else {
4929
- throw new InternalServerError8("Failed to get school.");
5081
+ throw new InternalServerError7("Failed to get school.");
4930
5082
  }
4931
5083
  }
4932
5084
  }
@@ -4948,7 +5100,7 @@ function useSchoolRepo() {
4948
5100
  if (error instanceof AppError9) {
4949
5101
  throw error;
4950
5102
  } else {
4951
- throw new InternalServerError8("Failed to update school status.");
5103
+ throw new InternalServerError7("Failed to update school status.");
4952
5104
  }
4953
5105
  }
4954
5106
  }
@@ -4979,7 +5131,7 @@ function useSchoolRepo() {
4979
5131
  delCachedData();
4980
5132
  return `Successfully updated school ${field}.`;
4981
5133
  } catch (error) {
4982
- throw new InternalServerError8(`Failed to update school ${field}.`);
5134
+ throw new InternalServerError7(`Failed to update school ${field}.`);
4983
5135
  }
4984
5136
  }
4985
5137
  async function updateDivisionNameByDivision(division, name, session) {
@@ -5003,7 +5155,7 @@ function useSchoolRepo() {
5003
5155
  delCachedData();
5004
5156
  return `Successfully updated school divisionName.`;
5005
5157
  } catch (error) {
5006
- throw new InternalServerError8(`Failed to update school divisionName.`);
5158
+ throw new InternalServerError7(`Failed to update school divisionName.`);
5007
5159
  }
5008
5160
  }
5009
5161
  async function updateById(_id, options, session) {
@@ -5021,7 +5173,7 @@ function useSchoolRepo() {
5021
5173
  delCachedData();
5022
5174
  return `Successfully updated school.`;
5023
5175
  } catch (error2) {
5024
- throw new InternalServerError8(`Failed to update school.`);
5176
+ throw new InternalServerError7(`Failed to update school.`);
5025
5177
  }
5026
5178
  }
5027
5179
  async function deleteById(_id) {
@@ -5038,7 +5190,7 @@ function useSchoolRepo() {
5038
5190
  delCachedData();
5039
5191
  return "Successfully deleted school.";
5040
5192
  } catch (error) {
5041
- throw new InternalServerError8("Failed to delete school.");
5193
+ throw new InternalServerError7("Failed to delete school.");
5042
5194
  }
5043
5195
  }
5044
5196
  return {
@@ -33537,7 +33689,7 @@ ${errors.slice(0, 5).join("\n")}${errors.length > 5 ? `
33537
33689
 
33538
33690
  // src/resources/school/school.controller.ts
33539
33691
  import { BadRequestError as BadRequestError23 } from "@eeplatform/nodejs-utils";
33540
- import Joi14 from "joi";
33692
+ import Joi15 from "joi";
33541
33693
  function useSchoolController() {
33542
33694
  const {
33543
33695
  getAll: _getAll,
@@ -33570,16 +33722,16 @@ function useSchoolController() {
33570
33722
  }
33571
33723
  }
33572
33724
  async function getAll(req, res, next) {
33573
- const validation = Joi14.object({
33574
- page: Joi14.number().optional().allow(null, ""),
33575
- limit: Joi14.number().optional().allow(null, ""),
33576
- sort: Joi14.string().optional().allow(null, ""),
33577
- sortOrder: Joi14.string().optional().allow(null, ""),
33578
- status: Joi14.string().optional().allow(null, ""),
33579
- org: Joi14.string().hex().optional().allow(null, ""),
33580
- app: Joi14.string().optional().allow(null, ""),
33581
- search: Joi14.string().optional().allow(null, ""),
33582
- psgc: Joi14.string().optional().allow(null, "")
33725
+ const validation = Joi15.object({
33726
+ page: Joi15.number().optional().allow(null, ""),
33727
+ limit: Joi15.number().optional().allow(null, ""),
33728
+ sort: Joi15.string().optional().allow(null, ""),
33729
+ sortOrder: Joi15.string().optional().allow(null, ""),
33730
+ status: Joi15.string().optional().allow(null, ""),
33731
+ org: Joi15.string().hex().optional().allow(null, ""),
33732
+ app: Joi15.string().optional().allow(null, ""),
33733
+ search: Joi15.string().optional().allow(null, ""),
33734
+ psgc: Joi15.string().optional().allow(null, "")
33583
33735
  });
33584
33736
  const { error } = validation.validate(req.query);
33585
33737
  if (error) {
@@ -33617,7 +33769,7 @@ function useSchoolController() {
33617
33769
  }
33618
33770
  async function getByCreatedBy(req, res, next) {
33619
33771
  const createdBy = req.params.createdBy;
33620
- const validation = Joi14.string().hex().required();
33772
+ const validation = Joi15.string().hex().required();
33621
33773
  const { error } = validation.validate(createdBy);
33622
33774
  if (error) {
33623
33775
  next(new BadRequestError23(`Validation error: ${error.message}`));
@@ -33634,9 +33786,9 @@ function useSchoolController() {
33634
33786
  async function updateStatusById(req, res, next) {
33635
33787
  const schoolId = req.params.id;
33636
33788
  const status = req.params.status;
33637
- const validation = Joi14.object({
33638
- id: Joi14.string().hex().required(),
33639
- status: Joi14.string().valid("active", "deleted", "suspended").required()
33789
+ const validation = Joi15.object({
33790
+ id: Joi15.string().hex().required(),
33791
+ status: Joi15.string().valid("active", "deleted", "suspended").required()
33640
33792
  });
33641
33793
  const { error } = validation.validate({ id: schoolId, status });
33642
33794
  if (error) {
@@ -33669,8 +33821,8 @@ function useSchoolController() {
33669
33821
  }
33670
33822
  async function approveSchool(req, res, next) {
33671
33823
  const schoolId = req.params.id;
33672
- const validation = Joi14.object({
33673
- id: Joi14.string().hex().required()
33824
+ const validation = Joi15.object({
33825
+ id: Joi15.string().hex().required()
33674
33826
  });
33675
33827
  const { error } = validation.validate({ id: schoolId });
33676
33828
  if (error) {
@@ -33693,11 +33845,11 @@ function useSchoolController() {
33693
33845
  return;
33694
33846
  }
33695
33847
  const { region, regionName, division, divisionName } = req.body;
33696
- const validation = Joi14.object({
33697
- region: Joi14.string().hex().required(),
33698
- regionName: Joi14.string().min(1).required(),
33699
- division: Joi14.string().hex().required(),
33700
- divisionName: Joi14.string().min(1).required()
33848
+ const validation = Joi15.object({
33849
+ region: Joi15.string().hex().required(),
33850
+ regionName: Joi15.string().min(1).required(),
33851
+ division: Joi15.string().hex().required(),
33852
+ divisionName: Joi15.string().min(1).required()
33701
33853
  });
33702
33854
  const { error } = validation.validate({
33703
33855
  region,
@@ -33726,10 +33878,10 @@ function useSchoolController() {
33726
33878
  async function updateFieldById(req, res, next) {
33727
33879
  const _id = req.params.id;
33728
33880
  const { field, value } = req.body;
33729
- const validation = Joi14.object({
33730
- _id: Joi14.string().hex().required(),
33731
- field: Joi14.string().valid("name", "director", "directorName").required(),
33732
- value: Joi14.string().required()
33881
+ const validation = Joi15.object({
33882
+ _id: Joi15.string().hex().required(),
33883
+ field: Joi15.string().valid("name", "director", "directorName").required(),
33884
+ value: Joi15.string().required()
33733
33885
  });
33734
33886
  const { error } = validation.validate({ _id, field, value });
33735
33887
  if (error) {
@@ -33747,8 +33899,8 @@ function useSchoolController() {
33747
33899
  async function updateById(req, res, next) {
33748
33900
  const id = req.params.id;
33749
33901
  const payload = req.body;
33750
- const validation = Joi14.object({
33751
- id: Joi14.string().hex().required()
33902
+ const validation = Joi15.object({
33903
+ id: Joi15.string().hex().required()
33752
33904
  });
33753
33905
  const { error: idError } = validation.validate({ id });
33754
33906
  if (idError) {
@@ -33770,8 +33922,8 @@ function useSchoolController() {
33770
33922
  }
33771
33923
  async function deleteById(req, res, next) {
33772
33924
  const _id = req.params.id;
33773
- const validation = Joi14.object({
33774
- _id: Joi14.string().hex().required()
33925
+ const validation = Joi15.object({
33926
+ _id: Joi15.string().hex().required()
33775
33927
  });
33776
33928
  const { error } = validation.validate({ _id });
33777
33929
  if (error) {
@@ -33866,7 +34018,7 @@ function useDivisionService() {
33866
34018
 
33867
34019
  // src/resources/division/division.controller.ts
33868
34020
  import { BadRequestError as BadRequestError24 } from "@eeplatform/nodejs-utils";
33869
- import Joi15 from "joi";
34021
+ import Joi16 from "joi";
33870
34022
  function useDivisionController() {
33871
34023
  const { add: _add, updateById: _updateById } = useDivisionService();
33872
34024
  const {
@@ -33896,12 +34048,12 @@ function useDivisionController() {
33896
34048
  }
33897
34049
  async function getAll(req, res, next) {
33898
34050
  const query = req.query;
33899
- const validation = Joi15.object({
33900
- page: Joi15.number().min(1).optional().allow("", null),
33901
- limit: Joi15.number().min(1).optional().allow("", null),
33902
- search: Joi15.string().optional().allow("", null),
33903
- status: Joi15.string().optional().allow("", null),
33904
- region: Joi15.string().hex().optional().allow("", null)
34051
+ const validation = Joi16.object({
34052
+ page: Joi16.number().min(1).optional().allow("", null),
34053
+ limit: Joi16.number().min(1).optional().allow("", null),
34054
+ search: Joi16.string().optional().allow("", null),
34055
+ status: Joi16.string().optional().allow("", null),
34056
+ region: Joi16.string().hex().optional().allow("", null)
33905
34057
  });
33906
34058
  const { error } = validation.validate(query);
33907
34059
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -33933,8 +34085,8 @@ function useDivisionController() {
33933
34085
  }
33934
34086
  async function getById(req, res, next) {
33935
34087
  const id = req.params.id;
33936
- const validation = Joi15.object({
33937
- id: Joi15.string().hex().required()
34088
+ const validation = Joi16.object({
34089
+ id: Joi16.string().hex().required()
33938
34090
  });
33939
34091
  const { error } = validation.validate({ id });
33940
34092
  if (error) {
@@ -33954,8 +34106,8 @@ function useDivisionController() {
33954
34106
  }
33955
34107
  async function getByName(req, res, next) {
33956
34108
  const name = req.params.name;
33957
- const validation = Joi15.object({
33958
- name: Joi15.string().required()
34109
+ const validation = Joi16.object({
34110
+ name: Joi16.string().required()
33959
34111
  });
33960
34112
  const { error } = validation.validate({ name });
33961
34113
  if (error) {
@@ -33976,10 +34128,10 @@ function useDivisionController() {
33976
34128
  async function updateField(req, res, next) {
33977
34129
  const _id = req.params.id;
33978
34130
  const { field, value } = req.body;
33979
- const validation = Joi15.object({
33980
- _id: Joi15.string().hex().required(),
33981
- field: Joi15.string().valid("name", "director", "directorName").required(),
33982
- value: Joi15.string().required()
34131
+ const validation = Joi16.object({
34132
+ _id: Joi16.string().hex().required(),
34133
+ field: Joi16.string().valid("name", "director", "directorName").required(),
34134
+ value: Joi16.string().required()
33983
34135
  });
33984
34136
  const { error } = validation.validate({ _id, field, value });
33985
34137
  if (error) {
@@ -34012,8 +34164,8 @@ function useDivisionController() {
34012
34164
  }
34013
34165
  async function deleteById(req, res, next) {
34014
34166
  const _id = req.params.id;
34015
- const validation = Joi15.object({
34016
- _id: Joi15.string().hex().required()
34167
+ const validation = Joi16.object({
34168
+ _id: Joi16.string().hex().required()
34017
34169
  });
34018
34170
  const { error } = validation.validate({ _id });
34019
34171
  if (error) {
@@ -34041,48 +34193,48 @@ function useDivisionController() {
34041
34193
 
34042
34194
  // src/resources/asset/asset.model.ts
34043
34195
  import { BadRequestError as BadRequestError25 } from "@eeplatform/nodejs-utils";
34044
- import Joi16 from "joi";
34196
+ import Joi17 from "joi";
34045
34197
  import { ObjectId as ObjectId15 } from "mongodb";
34046
- var schemaAsset = Joi16.object({
34047
- _id: Joi16.string().hex().optional(),
34048
- school: Joi16.string().hex().required(),
34049
- asset_type: Joi16.string().required().allow("supply", "furniture-equipment", "fixed-asset"),
34050
- name: Joi16.string().required(),
34051
- category: Joi16.string().optional().allow("", null),
34052
- type: Joi16.string().optional().allow("", null),
34053
- brand: Joi16.string().optional().allow("", null),
34054
- unit: Joi16.string().required(),
34055
- status: Joi16.string().optional().allow("", null),
34056
- createdAt: Joi16.date().optional().allow("", null),
34057
- updatedAt: Joi16.date().optional().allow("", null),
34058
- deletedAt: Joi16.date().optional().allow("", null),
34059
- metadata: Joi16.object({
34060
- title: Joi16.string().optional().allow("", null),
34061
- isbn: Joi16.string().optional().allow("", null),
34062
- author: Joi16.string().optional().allow("", null),
34063
- edition: Joi16.string().optional().allow("", null),
34064
- subject: Joi16.string().optional().allow("", null),
34065
- grade_level: Joi16.number().integer().min(0).optional().allow("", null),
34066
- publisher: Joi16.string().optional().allow("", null),
34067
- language: Joi16.string().optional().allow("", null)
34198
+ var schemaAsset = Joi17.object({
34199
+ _id: Joi17.string().hex().optional(),
34200
+ school: Joi17.string().hex().required(),
34201
+ asset_type: Joi17.string().required().allow("supply", "furniture-equipment", "fixed-asset"),
34202
+ name: Joi17.string().required(),
34203
+ category: Joi17.string().optional().allow("", null),
34204
+ type: Joi17.string().optional().allow("", null),
34205
+ brand: Joi17.string().optional().allow("", null),
34206
+ unit: Joi17.string().required(),
34207
+ status: Joi17.string().optional().allow("", null),
34208
+ createdAt: Joi17.date().optional().allow("", null),
34209
+ updatedAt: Joi17.date().optional().allow("", null),
34210
+ deletedAt: Joi17.date().optional().allow("", null),
34211
+ metadata: Joi17.object({
34212
+ title: Joi17.string().optional().allow("", null),
34213
+ isbn: Joi17.string().optional().allow("", null),
34214
+ author: Joi17.string().optional().allow("", null),
34215
+ edition: Joi17.string().optional().allow("", null),
34216
+ subject: Joi17.string().optional().allow("", null),
34217
+ grade_level: Joi17.number().integer().min(0).optional().allow("", null),
34218
+ publisher: Joi17.string().optional().allow("", null),
34219
+ language: Joi17.string().optional().allow("", null)
34068
34220
  }).optional().allow(null)
34069
34221
  });
34070
- var schemaAssetUpdateOption = Joi16.object({
34071
- name: Joi16.string().optional().allow("", null),
34072
- category: Joi16.string().optional().allow("", null),
34073
- type: Joi16.string().optional().allow("", null),
34074
- brand: Joi16.string().optional().allow("", null),
34075
- qty: Joi16.number().integer().min(0).optional().allow("", null),
34076
- unit: Joi16.string().optional().allow("", null),
34077
- metadata: Joi16.object({
34078
- title: Joi16.string().optional().allow("", null),
34079
- isbn: Joi16.string().optional().allow("", null),
34080
- author: Joi16.string().optional().allow("", null),
34081
- edition: Joi16.string().optional().allow("", null),
34082
- subject: Joi16.string().optional().allow("", null),
34083
- grade_level: Joi16.number().integer().min(0).optional().allow("", null),
34084
- publisher: Joi16.string().optional().allow("", null),
34085
- language: Joi16.string().optional().allow("", null)
34222
+ var schemaAssetUpdateOption = Joi17.object({
34223
+ name: Joi17.string().optional().allow("", null),
34224
+ category: Joi17.string().optional().allow("", null),
34225
+ type: Joi17.string().optional().allow("", null),
34226
+ brand: Joi17.string().optional().allow("", null),
34227
+ qty: Joi17.number().integer().min(0).optional().allow("", null),
34228
+ unit: Joi17.string().optional().allow("", null),
34229
+ metadata: Joi17.object({
34230
+ title: Joi17.string().optional().allow("", null),
34231
+ isbn: Joi17.string().optional().allow("", null),
34232
+ author: Joi17.string().optional().allow("", null),
34233
+ edition: Joi17.string().optional().allow("", null),
34234
+ subject: Joi17.string().optional().allow("", null),
34235
+ grade_level: Joi17.number().integer().min(0).optional().allow("", null),
34236
+ publisher: Joi17.string().optional().allow("", null),
34237
+ language: Joi17.string().optional().allow("", null)
34086
34238
  }).optional().allow(null)
34087
34239
  });
34088
34240
  function MAsset(value) {
@@ -34521,7 +34673,7 @@ function useAssetRepo() {
34521
34673
 
34522
34674
  // src/resources/asset/asset.controller.ts
34523
34675
  import { BadRequestError as BadRequestError27 } from "@eeplatform/nodejs-utils";
34524
- import Joi17 from "joi";
34676
+ import Joi18 from "joi";
34525
34677
  function useAssetController() {
34526
34678
  const {
34527
34679
  add: _add,
@@ -34549,13 +34701,13 @@ function useAssetController() {
34549
34701
  }
34550
34702
  async function getAll(req, res, next) {
34551
34703
  const query = req.query;
34552
- const validation = Joi17.object({
34553
- page: Joi17.number().min(1).optional().allow("", null),
34554
- limit: Joi17.number().min(1).optional().allow("", null),
34555
- search: Joi17.string().optional().allow("", null),
34556
- status: Joi17.string().optional().allow("", null),
34557
- school: Joi17.string().hex().optional().allow("", null),
34558
- asset_type: Joi17.string().required().allow("supply", "furniture-equipment", "fixed-asset")
34704
+ const validation = Joi18.object({
34705
+ page: Joi18.number().min(1).optional().allow("", null),
34706
+ limit: Joi18.number().min(1).optional().allow("", null),
34707
+ search: Joi18.string().optional().allow("", null),
34708
+ status: Joi18.string().optional().allow("", null),
34709
+ school: Joi18.string().hex().optional().allow("", null),
34710
+ asset_type: Joi18.string().required().allow("supply", "furniture-equipment", "fixed-asset")
34559
34711
  });
34560
34712
  const { error } = validation.validate(query);
34561
34713
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -34595,7 +34747,7 @@ function useAssetController() {
34595
34747
  }
34596
34748
  async function deleteById(req, res, next) {
34597
34749
  const id = req.params.id;
34598
- const validation = Joi17.string().hex().required();
34750
+ const validation = Joi18.string().hex().required();
34599
34751
  const { error } = validation.validate(id);
34600
34752
  if (error) {
34601
34753
  next(new BadRequestError27(error.message));
@@ -34610,7 +34762,7 @@ function useAssetController() {
34610
34762
  }
34611
34763
  async function getById(req, res, next) {
34612
34764
  const id = req.params.id;
34613
- const validation = Joi17.string().hex().required();
34765
+ const validation = Joi18.string().hex().required();
34614
34766
  const { error } = validation.validate(id);
34615
34767
  if (error) {
34616
34768
  next(new BadRequestError27(error.message));
@@ -34641,7 +34793,7 @@ function useAssetController() {
34641
34793
  async function getCategories(req, res, next) {
34642
34794
  const school = req.params.school;
34643
34795
  const asset_type = req.params.asset_type;
34644
- const validation = Joi17.string().hex().required();
34796
+ const validation = Joi18.string().hex().required();
34645
34797
  const { error } = validation.validate(school);
34646
34798
  if (error) {
34647
34799
  next(new BadRequestError27(error.message));
@@ -34657,7 +34809,7 @@ function useAssetController() {
34657
34809
  async function getTypes(req, res, next) {
34658
34810
  const school = req.params.school;
34659
34811
  const asset_type = req.params.asset_type;
34660
- const validation = Joi17.string().hex().required();
34812
+ const validation = Joi18.string().hex().required();
34661
34813
  const { error } = validation.validate(school);
34662
34814
  if (error) {
34663
34815
  next(new BadRequestError27(error.message));
@@ -34672,7 +34824,7 @@ function useAssetController() {
34672
34824
  }
34673
34825
  async function getUnitsBySchool(req, res, next) {
34674
34826
  const school = req.params.school;
34675
- const validation = Joi17.string().hex().required();
34827
+ const validation = Joi18.string().hex().required();
34676
34828
  const { error } = validation.validate(school);
34677
34829
  if (error) {
34678
34830
  next(new BadRequestError27(error.message));
@@ -34699,26 +34851,26 @@ function useAssetController() {
34699
34851
 
34700
34852
  // src/resources/stock-card/stock-card.model.ts
34701
34853
  import { BadRequestError as BadRequestError28 } from "@eeplatform/nodejs-utils";
34702
- import Joi18 from "joi";
34854
+ import Joi19 from "joi";
34703
34855
  import { ObjectId as ObjectId17 } from "mongodb";
34704
- var schemaStockCard = Joi18.object({
34705
- _id: Joi18.string().hex().optional().allow("", null),
34706
- school: Joi18.string().hex().required(),
34707
- item: Joi18.string().hex().required(),
34708
- balance: Joi18.number().optional().allow(null, 0),
34709
- qty: Joi18.number().required(),
34710
- unitCost: Joi18.number().optional().allow(null, 0),
34711
- totalCost: Joi18.number().optional().allow(null, 0),
34712
- status: Joi18.string().optional().allow(null, ""),
34713
- condition: Joi18.string().required(),
34714
- supplier: Joi18.string().optional().allow("", null),
34715
- location: Joi18.string().optional().allow("", null),
34716
- locationName: Joi18.string().optional().allow("", null),
34717
- reason: Joi18.string().optional().allow("", null),
34718
- remarks: Joi18.string().optional().allow("", null),
34719
- createdAt: Joi18.date().optional().allow("", null),
34720
- updatedAt: Joi18.date().optional().allow("", null),
34721
- deletedAt: Joi18.date().optional().allow("", null)
34856
+ var schemaStockCard = Joi19.object({
34857
+ _id: Joi19.string().hex().optional().allow("", null),
34858
+ school: Joi19.string().hex().required(),
34859
+ item: Joi19.string().hex().required(),
34860
+ balance: Joi19.number().optional().allow(null, 0),
34861
+ qty: Joi19.number().required(),
34862
+ unitCost: Joi19.number().optional().allow(null, 0),
34863
+ totalCost: Joi19.number().optional().allow(null, 0),
34864
+ status: Joi19.string().optional().allow(null, ""),
34865
+ condition: Joi19.string().required(),
34866
+ supplier: Joi19.string().optional().allow("", null),
34867
+ location: Joi19.string().optional().allow("", null),
34868
+ locationName: Joi19.string().optional().allow("", null),
34869
+ reason: Joi19.string().optional().allow("", null),
34870
+ remarks: Joi19.string().optional().allow("", null),
34871
+ createdAt: Joi19.date().optional().allow("", null),
34872
+ updatedAt: Joi19.date().optional().allow("", null),
34873
+ deletedAt: Joi19.date().optional().allow("", null)
34722
34874
  });
34723
34875
  function MStockCard(value) {
34724
34876
  const { error } = schemaStockCard.validate(value);
@@ -35017,7 +35169,7 @@ function useStockCardService() {
35017
35169
 
35018
35170
  // src/resources/stock-card/stock-card.controller.ts
35019
35171
  import { BadRequestError as BadRequestError31 } from "@eeplatform/nodejs-utils";
35020
- import Joi19 from "joi";
35172
+ import Joi20 from "joi";
35021
35173
  function useStockCardController() {
35022
35174
  const {
35023
35175
  getAll: _getAll,
@@ -35041,11 +35193,11 @@ function useStockCardController() {
35041
35193
  }
35042
35194
  async function getAll(req, res, next) {
35043
35195
  const query = req.query;
35044
- const validation = Joi19.object({
35045
- page: Joi19.number().min(1).optional().allow("", null),
35046
- limit: Joi19.number().min(1).optional().allow("", null),
35047
- school: Joi19.string().hex().optional().allow("", null),
35048
- id: Joi19.string().hex().required()
35196
+ const validation = Joi20.object({
35197
+ page: Joi20.number().min(1).optional().allow("", null),
35198
+ limit: Joi20.number().min(1).optional().allow("", null),
35199
+ school: Joi20.string().hex().optional().allow("", null),
35200
+ id: Joi20.string().hex().required()
35049
35201
  });
35050
35202
  const { error } = validation.validate(query);
35051
35203
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -35081,7 +35233,7 @@ function useStockCardController() {
35081
35233
  }
35082
35234
  async function getById(req, res, next) {
35083
35235
  const id = req.params.id;
35084
- const validation = Joi19.string().hex().required();
35236
+ const validation = Joi20.string().hex().required();
35085
35237
  const { error } = validation.validate(id);
35086
35238
  if (error) {
35087
35239
  next(new BadRequestError31(error.message));
@@ -35096,7 +35248,7 @@ function useStockCardController() {
35096
35248
  }
35097
35249
  async function getSuppliers(req, res, next) {
35098
35250
  const school = req.params.school;
35099
- const validation = Joi19.string().hex().required();
35251
+ const validation = Joi20.string().hex().required();
35100
35252
  const { error } = validation.validate(school);
35101
35253
  if (error) {
35102
35254
  next(new BadRequestError31(error.message));
@@ -35119,30 +35271,30 @@ function useStockCardController() {
35119
35271
 
35120
35272
  // src/resources/plantilla/plantilla.model.ts
35121
35273
  import { BadRequestError as BadRequestError32 } from "@eeplatform/nodejs-utils";
35122
- import Joi20 from "joi";
35274
+ import Joi21 from "joi";
35123
35275
  import { ObjectId as ObjectId19 } from "mongodb";
35124
- var schemaPlantilla = Joi20.object({
35125
- _id: Joi20.string().hex().optional().allow(null, ""),
35126
- org: Joi20.string().hex().required(),
35127
- orgUnitCode: Joi20.string().optional().allow(null, ""),
35128
- employmentType: Joi20.string().optional().allow(null, ""),
35129
- personnelType: Joi20.string().required(),
35130
- itemNumber: Joi20.string().required(),
35131
- positionTitle: Joi20.string().required(),
35132
- positionCategory: Joi20.string().required(),
35133
- region: Joi20.string().hex().optional().allow(null, ""),
35134
- regionName: Joi20.string().optional().allow(null, ""),
35135
- division: Joi20.string().hex().optional().allow(null, ""),
35136
- divisionName: Joi20.string().optional().allow(null, ""),
35137
- salaryGrade: Joi20.number().required(),
35138
- employeeName: Joi20.string().optional().allow(null, ""),
35139
- annualSalary: Joi20.number().optional().allow(null, 0),
35140
- monthlySalary: Joi20.number().optional().allow(null, 0),
35141
- status: Joi20.string().required(),
35142
- employee: Joi20.string().hex().optional().allow(null, ""),
35143
- createdAt: Joi20.date().iso().optional().allow(null, ""),
35144
- updatedAt: Joi20.date().iso().optional().allow(null, ""),
35145
- deletedAt: Joi20.date().iso().optional().allow(null, "")
35276
+ var schemaPlantilla = Joi21.object({
35277
+ _id: Joi21.string().hex().optional().allow(null, ""),
35278
+ org: Joi21.string().hex().required(),
35279
+ orgUnitCode: Joi21.string().optional().allow(null, ""),
35280
+ employmentType: Joi21.string().optional().allow(null, ""),
35281
+ personnelType: Joi21.string().required(),
35282
+ itemNumber: Joi21.string().required(),
35283
+ positionTitle: Joi21.string().required(),
35284
+ positionCategory: Joi21.string().required(),
35285
+ region: Joi21.string().hex().optional().allow(null, ""),
35286
+ regionName: Joi21.string().optional().allow(null, ""),
35287
+ division: Joi21.string().hex().optional().allow(null, ""),
35288
+ divisionName: Joi21.string().optional().allow(null, ""),
35289
+ salaryGrade: Joi21.number().required(),
35290
+ employeeName: Joi21.string().optional().allow(null, ""),
35291
+ annualSalary: Joi21.number().optional().allow(null, 0),
35292
+ monthlySalary: Joi21.number().optional().allow(null, 0),
35293
+ status: Joi21.string().required(),
35294
+ employee: Joi21.string().hex().optional().allow(null, ""),
35295
+ createdAt: Joi21.date().iso().optional().allow(null, ""),
35296
+ updatedAt: Joi21.date().iso().optional().allow(null, ""),
35297
+ deletedAt: Joi21.date().iso().optional().allow(null, "")
35146
35298
  });
35147
35299
  function MPlantilla(data) {
35148
35300
  const { error } = schemaPlantilla.validate(data);
@@ -35185,7 +35337,7 @@ function MPlantilla(data) {
35185
35337
  import {
35186
35338
  AppError as AppError10,
35187
35339
  BadRequestError as BadRequestError33,
35188
- InternalServerError as InternalServerError9,
35340
+ InternalServerError as InternalServerError8,
35189
35341
  logger as logger19,
35190
35342
  makeCacheKey as makeCacheKey11,
35191
35343
  paginate as paginate10,
@@ -35372,7 +35524,7 @@ function usePlantillaRepo() {
35372
35524
  if (error instanceof AppError10) {
35373
35525
  throw error;
35374
35526
  } else {
35375
- throw new InternalServerError9("Failed to get plantilla.");
35527
+ throw new InternalServerError8("Failed to get plantilla.");
35376
35528
  }
35377
35529
  }
35378
35530
  }
@@ -35397,7 +35549,7 @@ function usePlantillaRepo() {
35397
35549
  if (error instanceof AppError10) {
35398
35550
  throw error;
35399
35551
  } else {
35400
- throw new InternalServerError9("Failed to delete plantilla.");
35552
+ throw new InternalServerError8("Failed to delete plantilla.");
35401
35553
  }
35402
35554
  }
35403
35555
  }
@@ -35633,7 +35785,7 @@ ${errors.slice(0, 10).join("\n")}${errors.length > 10 ? `
35633
35785
 
35634
35786
  // src/resources/plantilla/plantilla.controller.ts
35635
35787
  import { BadRequestError as BadRequestError35 } from "@eeplatform/nodejs-utils";
35636
- import Joi21 from "joi";
35788
+ import Joi22 from "joi";
35637
35789
  function usePlantillaController() {
35638
35790
  const {
35639
35791
  add: _addPlantilla,
@@ -35645,11 +35797,11 @@ function usePlantillaController() {
35645
35797
  const { addBulk: _addBulk } = usePlantillaService();
35646
35798
  async function createPlantilla(req, res, next) {
35647
35799
  const value = req.body;
35648
- const validation = Joi21.object({
35649
- itemNumber: Joi21.string().required(),
35650
- positionTitle: Joi21.string().required(),
35651
- positionCategory: Joi21.string().required(),
35652
- status: Joi21.string().required()
35800
+ const validation = Joi22.object({
35801
+ itemNumber: Joi22.string().required(),
35802
+ positionTitle: Joi22.string().required(),
35803
+ positionCategory: Joi22.string().required(),
35804
+ status: Joi22.string().required()
35653
35805
  });
35654
35806
  const { error } = validation.validate(value);
35655
35807
  if (error) {
@@ -35679,11 +35831,11 @@ function usePlantillaController() {
35679
35831
  next(new BadRequestError35("Invalid limit number."));
35680
35832
  return;
35681
35833
  }
35682
- const validation = Joi21.object({
35683
- page: Joi21.number().min(1).optional().allow("", null),
35684
- limit: Joi21.number().min(1).optional().allow("", null),
35685
- search: Joi21.string().optional().allow("", null),
35686
- org: Joi21.string().optional().allow("", null)
35834
+ const validation = Joi22.object({
35835
+ page: Joi22.number().min(1).optional().allow("", null),
35836
+ limit: Joi22.number().min(1).optional().allow("", null),
35837
+ search: Joi22.string().optional().allow("", null),
35838
+ org: Joi22.string().optional().allow("", null)
35687
35839
  });
35688
35840
  const { error } = validation.validate({ page, limit, search, org });
35689
35841
  if (error) {
@@ -35705,8 +35857,8 @@ function usePlantillaController() {
35705
35857
  }
35706
35858
  async function getPlantillaById(req, res, next) {
35707
35859
  const id = req.params.id;
35708
- const validation = Joi21.object({
35709
- id: Joi21.string().hex().required()
35860
+ const validation = Joi22.object({
35861
+ id: Joi22.string().hex().required()
35710
35862
  });
35711
35863
  const { error } = validation.validate({ id });
35712
35864
  if (error) {
@@ -35728,12 +35880,12 @@ function usePlantillaController() {
35728
35880
  async function updatePlantilla(req, res, next) {
35729
35881
  const id = req.params.id;
35730
35882
  const value = req.body;
35731
- const validation = Joi21.object({
35732
- id: Joi21.string().hex().required(),
35733
- employee: Joi21.string().hex().optional().allow(null, ""),
35734
- status: Joi21.string().optional(),
35735
- positionTitle: Joi21.string().optional(),
35736
- positionCategory: Joi21.string().optional()
35883
+ const validation = Joi22.object({
35884
+ id: Joi22.string().hex().required(),
35885
+ employee: Joi22.string().hex().optional().allow(null, ""),
35886
+ status: Joi22.string().optional(),
35887
+ positionTitle: Joi22.string().optional(),
35888
+ positionCategory: Joi22.string().optional()
35737
35889
  });
35738
35890
  const { error } = validation.validate({ id, ...value });
35739
35891
  if (error) {
@@ -35754,8 +35906,8 @@ function usePlantillaController() {
35754
35906
  }
35755
35907
  async function deletePlantilla(req, res, next) {
35756
35908
  const id = req.params.id;
35757
- const validation = Joi21.object({
35758
- id: Joi21.string().hex().required()
35909
+ const validation = Joi22.object({
35910
+ id: Joi22.string().hex().required()
35759
35911
  });
35760
35912
  const { error } = validation.validate({ id });
35761
35913
  if (error) {
@@ -35780,9 +35932,9 @@ function usePlantillaController() {
35780
35932
  return;
35781
35933
  }
35782
35934
  const { region, division } = req.body;
35783
- const validation = Joi21.object({
35784
- region: Joi21.string().hex().optional(),
35785
- division: Joi21.string().hex().optional()
35935
+ const validation = Joi22.object({
35936
+ region: Joi22.string().hex().optional(),
35937
+ division: Joi22.string().hex().optional()
35786
35938
  });
35787
35939
  const { error } = validation.validate({ region, division });
35788
35940
  if (error) {
@@ -35816,6 +35968,1516 @@ function usePlantillaController() {
35816
35968
  };
35817
35969
  }
35818
35970
 
35971
+ // src/resources/section-preset/section.preset.model.ts
35972
+ import { BadRequestError as BadRequestError36 } from "@eeplatform/nodejs-utils";
35973
+ import Joi23 from "joi";
35974
+ import { ObjectId as ObjectId21 } from "mongodb";
35975
+ var schemaSectionPreset = Joi23.object({
35976
+ _id: Joi23.string().hex().optional().allow(null, ""),
35977
+ name: Joi23.string().min(1).max(100).required(),
35978
+ description: Joi23.string().max(500).optional().allow(null, ""),
35979
+ set: Joi23.array().items(Joi23.string()).required(),
35980
+ school: Joi23.string().hex().required(),
35981
+ createdBy: Joi23.string().hex().required(),
35982
+ createdAt: Joi23.string().isoDate().optional(),
35983
+ updatedAt: Joi23.string().isoDate().optional(),
35984
+ deletedAt: Joi23.string().isoDate().optional().allow(null, "")
35985
+ });
35986
+ function modelSectionPreset(value) {
35987
+ const { error } = schemaSectionPreset.validate(value);
35988
+ if (error) {
35989
+ throw new BadRequestError36(`Invalid section preset data: ${error.message}`);
35990
+ }
35991
+ if (value._id && typeof value._id === "string") {
35992
+ try {
35993
+ value._id = new ObjectId21(value._id);
35994
+ } catch (error2) {
35995
+ throw new Error("Invalid _id.");
35996
+ }
35997
+ }
35998
+ if (value.createdBy && typeof value.createdBy === "string") {
35999
+ try {
36000
+ value.createdBy = new ObjectId21(value.createdBy);
36001
+ } catch (error2) {
36002
+ throw new Error("Invalid createdBy.");
36003
+ }
36004
+ }
36005
+ if (value.school && typeof value.school === "string") {
36006
+ try {
36007
+ value.school = new ObjectId21(value.school);
36008
+ } catch (error2) {
36009
+ throw new Error("Invalid school.");
36010
+ }
36011
+ }
36012
+ return {
36013
+ _id: value._id,
36014
+ name: value.name,
36015
+ description: value.description ?? "",
36016
+ set: value.set,
36017
+ status: value.status ?? "active",
36018
+ school: value.school,
36019
+ createdBy: value.createdBy,
36020
+ createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
36021
+ updatedAt: value.updatedAt ?? "",
36022
+ deletedAt: value.deletedAt ?? ""
36023
+ };
36024
+ }
36025
+
36026
+ // src/resources/section-preset/section.preset.repository.ts
36027
+ import {
36028
+ AppError as AppError11,
36029
+ BadRequestError as BadRequestError37,
36030
+ InternalServerError as InternalServerError9,
36031
+ logger as logger21,
36032
+ makeCacheKey as makeCacheKey12,
36033
+ paginate as paginate11,
36034
+ useAtlas as useAtlas17,
36035
+ useCache as useCache12
36036
+ } from "@eeplatform/nodejs-utils";
36037
+ import { ObjectId as ObjectId22 } from "mongodb";
36038
+ function useSectionPresetRepo() {
36039
+ const db = useAtlas17.getDb();
36040
+ if (!db) {
36041
+ throw new Error("Unable to connect to server.");
36042
+ }
36043
+ const namespace_collection = "deped.section.presets";
36044
+ const collection = db.collection(namespace_collection);
36045
+ const { getCache, setCache, delNamespace } = useCache12(namespace_collection);
36046
+ async function createIndexes() {
36047
+ try {
36048
+ await collection.createIndexes([
36049
+ { key: { name: 1 } },
36050
+ { key: { createdAt: 1 } },
36051
+ { key: { createdBy: 1 } },
36052
+ { key: { name: "text", description: "text" } },
36053
+ {
36054
+ key: { name: 1, status: 1 },
36055
+ unique: true,
36056
+ name: "unique_section_preset"
36057
+ }
36058
+ ]);
36059
+ } catch (error) {
36060
+ throw new Error("Failed to create index on section presets.");
36061
+ }
36062
+ }
36063
+ function delCachedData() {
36064
+ delNamespace().then(() => {
36065
+ logger21.log({
36066
+ level: "info",
36067
+ message: `Cache namespace cleared for ${namespace_collection}`
36068
+ });
36069
+ }).catch((err) => {
36070
+ logger21.log({
36071
+ level: "error",
36072
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
36073
+ });
36074
+ });
36075
+ }
36076
+ async function add(value, session) {
36077
+ try {
36078
+ value = modelSectionPreset(value);
36079
+ const res = await collection.insertOne(value, { session });
36080
+ delCachedData();
36081
+ return res.insertedId;
36082
+ } catch (error) {
36083
+ logger21.log({
36084
+ level: "error",
36085
+ message: error.message
36086
+ });
36087
+ if (error instanceof AppError11) {
36088
+ throw error;
36089
+ } else {
36090
+ const isDuplicated = error.message.includes("duplicate");
36091
+ if (isDuplicated) {
36092
+ throw new BadRequestError37("Section preset already exists.");
36093
+ }
36094
+ throw new Error("Failed to create section preset.");
36095
+ }
36096
+ }
36097
+ }
36098
+ async function getAll({
36099
+ search = "",
36100
+ page = 1,
36101
+ limit = 10,
36102
+ sort = {},
36103
+ status = "active",
36104
+ createdBy,
36105
+ school = ""
36106
+ } = {}) {
36107
+ page = page > 0 ? page - 1 : 0;
36108
+ const query = {
36109
+ deletedAt: { $in: ["", null] },
36110
+ status
36111
+ };
36112
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
36113
+ const cacheKeyOptions = {
36114
+ status,
36115
+ page,
36116
+ limit,
36117
+ sort: JSON.stringify(sort)
36118
+ };
36119
+ if (createdBy) {
36120
+ try {
36121
+ query.createdBy = new ObjectId22(createdBy);
36122
+ } catch (error) {
36123
+ throw new BadRequestError37("Invalid createdBy ID.");
36124
+ }
36125
+ cacheKeyOptions.createdBy = createdBy;
36126
+ }
36127
+ if (search) {
36128
+ query.$text = { $search: search };
36129
+ cacheKeyOptions.search = search;
36130
+ }
36131
+ if (school) {
36132
+ try {
36133
+ query.school = new ObjectId22(school);
36134
+ } catch (error) {
36135
+ throw new BadRequestError37("Invalid school ID.");
36136
+ }
36137
+ cacheKeyOptions.school = school;
36138
+ }
36139
+ const cacheKey = makeCacheKey12(namespace_collection, cacheKeyOptions);
36140
+ logger21.log({
36141
+ level: "info",
36142
+ message: `Cache key for getAll section presets: ${cacheKey}`
36143
+ });
36144
+ try {
36145
+ const cached = await getCache(cacheKey);
36146
+ if (cached) {
36147
+ logger21.log({
36148
+ level: "info",
36149
+ message: `Cache hit for getAll section presets: ${cacheKey}`
36150
+ });
36151
+ return cached;
36152
+ }
36153
+ const items = await collection.aggregate([
36154
+ { $match: query },
36155
+ { $sort: sort },
36156
+ { $skip: page * limit },
36157
+ { $limit: limit }
36158
+ ]).toArray();
36159
+ const length = await collection.countDocuments(query);
36160
+ const data = paginate11(items, page, limit, length);
36161
+ setCache(cacheKey, data, 600).then(() => {
36162
+ logger21.log({
36163
+ level: "info",
36164
+ message: `Cache set for getAll section presets: ${cacheKey}`
36165
+ });
36166
+ }).catch((err) => {
36167
+ logger21.log({
36168
+ level: "error",
36169
+ message: `Failed to set cache for getAll section presets: ${err.message}`
36170
+ });
36171
+ });
36172
+ return data;
36173
+ } catch (error) {
36174
+ logger21.log({ level: "error", message: `${error}` });
36175
+ throw error;
36176
+ }
36177
+ }
36178
+ async function getById(_id) {
36179
+ try {
36180
+ _id = new ObjectId22(_id);
36181
+ } catch (error) {
36182
+ throw new BadRequestError37("Invalid ID.");
36183
+ }
36184
+ const cacheKey = makeCacheKey12(namespace_collection, { _id: String(_id) });
36185
+ try {
36186
+ const cached = await getCache(cacheKey);
36187
+ if (cached) {
36188
+ logger21.log({
36189
+ level: "info",
36190
+ message: `Cache hit for getById section preset: ${cacheKey}`
36191
+ });
36192
+ return cached;
36193
+ }
36194
+ const result = await collection.findOne({
36195
+ _id,
36196
+ deletedAt: { $in: ["", null] }
36197
+ });
36198
+ if (!result) {
36199
+ throw new BadRequestError37("Section preset not found.");
36200
+ }
36201
+ setCache(cacheKey, result, 300).then(() => {
36202
+ logger21.log({
36203
+ level: "info",
36204
+ message: `Cache set for section preset by id: ${cacheKey}`
36205
+ });
36206
+ }).catch((err) => {
36207
+ logger21.log({
36208
+ level: "error",
36209
+ message: `Failed to set cache for section preset by id: ${err.message}`
36210
+ });
36211
+ });
36212
+ return result;
36213
+ } catch (error) {
36214
+ if (error instanceof AppError11) {
36215
+ throw error;
36216
+ } else {
36217
+ throw new InternalServerError9("Failed to get section preset.");
36218
+ }
36219
+ }
36220
+ }
36221
+ async function getByName(name) {
36222
+ const cacheKey = makeCacheKey12(namespace_collection, { name });
36223
+ try {
36224
+ const cached = await getCache(cacheKey);
36225
+ if (cached) {
36226
+ logger21.log({
36227
+ level: "info",
36228
+ message: `Cache hit for getByName section preset: ${cacheKey}`
36229
+ });
36230
+ return cached;
36231
+ }
36232
+ const result = await collection.findOne({
36233
+ name,
36234
+ deletedAt: { $in: ["", null] }
36235
+ });
36236
+ if (!result) {
36237
+ throw new BadRequestError37("Section preset not found.");
36238
+ }
36239
+ setCache(cacheKey, result, 300).then(() => {
36240
+ logger21.log({
36241
+ level: "info",
36242
+ message: `Cache set for section preset by name: ${cacheKey}`
36243
+ });
36244
+ }).catch((err) => {
36245
+ logger21.log({
36246
+ level: "error",
36247
+ message: `Failed to set cache for section preset by name: ${err.message}`
36248
+ });
36249
+ });
36250
+ return result;
36251
+ } catch (error) {
36252
+ if (error instanceof AppError11) {
36253
+ throw error;
36254
+ } else {
36255
+ throw new InternalServerError9("Failed to get section preset.");
36256
+ }
36257
+ }
36258
+ }
36259
+ async function updateFieldById({ _id, field, value } = {}, session) {
36260
+ const allowedFields = ["name", "description", "sets"];
36261
+ if (!allowedFields.includes(field)) {
36262
+ throw new BadRequestError37(
36263
+ `Field "${field}" is not allowed to be updated.`
36264
+ );
36265
+ }
36266
+ try {
36267
+ _id = new ObjectId22(_id);
36268
+ } catch (error) {
36269
+ throw new BadRequestError37("Invalid ID.");
36270
+ }
36271
+ try {
36272
+ await collection.updateOne(
36273
+ { _id, deletedAt: { $in: ["", null] } },
36274
+ { $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
36275
+ { session }
36276
+ );
36277
+ delCachedData();
36278
+ return `Successfully updated section preset ${field}.`;
36279
+ } catch (error) {
36280
+ throw new InternalServerError9(
36281
+ `Failed to update section preset ${field}.`
36282
+ );
36283
+ }
36284
+ }
36285
+ async function deleteById(_id) {
36286
+ try {
36287
+ _id = new ObjectId22(_id);
36288
+ } catch (error) {
36289
+ throw new BadRequestError37("Invalid ID.");
36290
+ }
36291
+ try {
36292
+ await collection.updateOne(
36293
+ { _id },
36294
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
36295
+ );
36296
+ delCachedData();
36297
+ return "Successfully deleted section preset.";
36298
+ } catch (error) {
36299
+ throw new InternalServerError9("Failed to delete section preset.");
36300
+ }
36301
+ }
36302
+ return {
36303
+ createIndexes,
36304
+ add,
36305
+ getAll,
36306
+ getById,
36307
+ updateFieldById,
36308
+ deleteById,
36309
+ getByName
36310
+ };
36311
+ }
36312
+
36313
+ // src/resources/section-preset/section.preset.controller.ts
36314
+ import { BadRequestError as BadRequestError38 } from "@eeplatform/nodejs-utils";
36315
+ import Joi24 from "joi";
36316
+ function useSectionPresetController() {
36317
+ const {
36318
+ add: _add,
36319
+ getAll: _getAll,
36320
+ getById: _getById,
36321
+ getByName: _getByName,
36322
+ updateFieldById: _updateFieldById,
36323
+ deleteById: _deleteById
36324
+ } = useSectionPresetRepo();
36325
+ async function add(req, res, next) {
36326
+ const value = req.body;
36327
+ const { error } = schemaSectionPreset.validate(value);
36328
+ if (error) {
36329
+ next(new BadRequestError38(error.message));
36330
+ return;
36331
+ }
36332
+ try {
36333
+ const data = await _add(value);
36334
+ res.json({
36335
+ message: "Successfully created section preset.",
36336
+ data
36337
+ });
36338
+ return;
36339
+ } catch (error2) {
36340
+ next(error2);
36341
+ }
36342
+ }
36343
+ async function getAll(req, res, next) {
36344
+ const query = req.query;
36345
+ const validation = Joi24.object({
36346
+ page: Joi24.number().min(1).optional().allow("", null),
36347
+ limit: Joi24.number().min(1).optional().allow("", null),
36348
+ search: Joi24.string().optional().allow("", null),
36349
+ status: Joi24.string().optional().allow("", null),
36350
+ school: Joi24.string().hex().optional().allow("", null),
36351
+ createdBy: Joi24.string().hex().optional().allow("", null)
36352
+ });
36353
+ const { error } = validation.validate(query);
36354
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
36355
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
36356
+ const search = req.query.search ?? "";
36357
+ const status = req.query.status ?? "active";
36358
+ const school = req.query.school ?? "";
36359
+ const createdBy = req.query.createdBy ?? "";
36360
+ const isPageNumber = isFinite(page);
36361
+ if (!isPageNumber) {
36362
+ next(new BadRequestError38("Invalid page number."));
36363
+ return;
36364
+ }
36365
+ const isLimitNumber = isFinite(limit);
36366
+ if (!isLimitNumber) {
36367
+ next(new BadRequestError38("Invalid limit number."));
36368
+ return;
36369
+ }
36370
+ if (error) {
36371
+ next(new BadRequestError38(error.message));
36372
+ return;
36373
+ }
36374
+ try {
36375
+ const data = await _getAll({
36376
+ page,
36377
+ limit,
36378
+ search,
36379
+ status,
36380
+ school,
36381
+ createdBy: createdBy || void 0
36382
+ });
36383
+ res.json(data);
36384
+ return;
36385
+ } catch (error2) {
36386
+ next(error2);
36387
+ }
36388
+ }
36389
+ async function getById(req, res, next) {
36390
+ const id = req.params.id;
36391
+ const validation = Joi24.object({
36392
+ id: Joi24.string().hex().required()
36393
+ });
36394
+ const { error } = validation.validate({ id });
36395
+ if (error) {
36396
+ next(new BadRequestError38(error.message));
36397
+ return;
36398
+ }
36399
+ try {
36400
+ const data = await _getById(id);
36401
+ res.json({
36402
+ message: "Successfully retrieved section preset.",
36403
+ data
36404
+ });
36405
+ return;
36406
+ } catch (error2) {
36407
+ next(error2);
36408
+ }
36409
+ }
36410
+ async function getByName(req, res, next) {
36411
+ const name = req.params.name;
36412
+ const validation = Joi24.object({
36413
+ name: Joi24.string().required()
36414
+ });
36415
+ const { error } = validation.validate({ name });
36416
+ if (error) {
36417
+ next(new BadRequestError38(error.message));
36418
+ return;
36419
+ }
36420
+ try {
36421
+ const data = await _getByName(name);
36422
+ res.json({
36423
+ message: "Successfully retrieved section preset.",
36424
+ data
36425
+ });
36426
+ return;
36427
+ } catch (error2) {
36428
+ next(error2);
36429
+ }
36430
+ }
36431
+ async function updateField(req, res, next) {
36432
+ const _id = req.params.id;
36433
+ const { field, value } = req.body;
36434
+ const validation = Joi24.object({
36435
+ _id: Joi24.string().hex().required(),
36436
+ field: Joi24.string().valid("name", "description", "sets").required(),
36437
+ value: Joi24.alternatives().try(Joi24.string(), Joi24.array().items(Joi24.string())).required()
36438
+ });
36439
+ const { error } = validation.validate({ _id, field, value });
36440
+ if (error) {
36441
+ next(new BadRequestError38(error.message));
36442
+ return;
36443
+ }
36444
+ try {
36445
+ const message = await _updateFieldById({ _id, field, value });
36446
+ res.json({ message });
36447
+ return;
36448
+ } catch (error2) {
36449
+ next(error2);
36450
+ }
36451
+ }
36452
+ async function deleteById(req, res, next) {
36453
+ const _id = req.params.id;
36454
+ const validation = Joi24.object({
36455
+ _id: Joi24.string().hex().required()
36456
+ });
36457
+ const { error } = validation.validate({ _id });
36458
+ if (error) {
36459
+ next(new BadRequestError38(error.message));
36460
+ return;
36461
+ }
36462
+ try {
36463
+ const message = await _deleteById(_id);
36464
+ res.json({ message });
36465
+ return;
36466
+ } catch (error2) {
36467
+ next(error2);
36468
+ }
36469
+ }
36470
+ return {
36471
+ add,
36472
+ getAll,
36473
+ getById,
36474
+ getByName,
36475
+ updateField,
36476
+ deleteById
36477
+ };
36478
+ }
36479
+
36480
+ // src/resources/section/section.model.ts
36481
+ import { BadRequestError as BadRequestError39 } from "@eeplatform/nodejs-utils";
36482
+ import Joi25 from "joi";
36483
+ import { ObjectId as ObjectId23 } from "mongodb";
36484
+ var schemaSection = Joi25.object({
36485
+ _id: Joi25.string().hex().optional().allow(null, ""),
36486
+ school: Joi25.string().hex().required(),
36487
+ name: Joi25.string().min(1).max(100).required(),
36488
+ schoolYear: Joi25.string().required(),
36489
+ gradeLevel: Joi25.string().required(),
36490
+ students: Joi25.number().integer().min(0).optional(),
36491
+ adviser: Joi25.string().hex().optional().allow(null, ""),
36492
+ adviserName: Joi25.string().optional().allow(null, ""),
36493
+ status: Joi25.string().valid("active", "inactive").optional(),
36494
+ createdAt: Joi25.string().isoDate().optional().allow(null, ""),
36495
+ updatedAt: Joi25.string().isoDate().optional().allow(null, ""),
36496
+ deletedAt: Joi25.string().isoDate().optional().allow(null, "")
36497
+ });
36498
+ var schemaGenerateSections = Joi25.object({
36499
+ school: Joi25.string().hex().required(),
36500
+ schoolYear: Joi25.string().required(),
36501
+ gradeLevel: Joi25.string().required(),
36502
+ set: Joi25.array().items(Joi25.string().min(1).max(100)).required()
36503
+ });
36504
+ function modelSection(value) {
36505
+ const { error } = schemaSection.validate(value);
36506
+ if (error) {
36507
+ throw new BadRequestError39(`Invalid section data: ${error.message}`);
36508
+ }
36509
+ if (value._id && typeof value._id === "string") {
36510
+ try {
36511
+ value._id = new ObjectId23(value._id);
36512
+ } catch (error2) {
36513
+ throw new Error("Invalid _id.");
36514
+ }
36515
+ }
36516
+ if (value.school && typeof value.school === "string") {
36517
+ try {
36518
+ value.school = new ObjectId23(value.school);
36519
+ } catch (error2) {
36520
+ throw new Error("Invalid school ID.");
36521
+ }
36522
+ }
36523
+ if (value.adviser && typeof value.adviser === "string") {
36524
+ try {
36525
+ value.adviser = new ObjectId23(value.adviser);
36526
+ } catch (error2) {
36527
+ throw new Error("Invalid adviser ID.");
36528
+ }
36529
+ }
36530
+ return {
36531
+ _id: value._id,
36532
+ school: value.school,
36533
+ name: value.name,
36534
+ schoolYear: value.schoolYear,
36535
+ gradeLevel: value.gradeLevel,
36536
+ adviser: value.adviser,
36537
+ adviserName: value.adviserName,
36538
+ students: value.students ?? 0,
36539
+ status: value.status ?? "active",
36540
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
36541
+ updatedAt: value.updatedAt ?? "",
36542
+ deletedAt: value.deletedAt ?? ""
36543
+ };
36544
+ }
36545
+
36546
+ // src/resources/section/section.repository.ts
36547
+ import {
36548
+ AppError as AppError12,
36549
+ BadRequestError as BadRequestError40,
36550
+ InternalServerError as InternalServerError10,
36551
+ logger as logger22,
36552
+ makeCacheKey as makeCacheKey13,
36553
+ paginate as paginate12,
36554
+ useAtlas as useAtlas18,
36555
+ useCache as useCache13
36556
+ } from "@eeplatform/nodejs-utils";
36557
+ import { ObjectId as ObjectId24 } from "mongodb";
36558
+ function useSectionRepo() {
36559
+ const db = useAtlas18.getDb();
36560
+ if (!db) {
36561
+ throw new Error("Unable to connect to server.");
36562
+ }
36563
+ const namespace_collection = "deped.sections";
36564
+ const collection = db.collection(namespace_collection);
36565
+ const { getCache, setCache, delNamespace } = useCache13(namespace_collection);
36566
+ async function createIndexes() {
36567
+ try {
36568
+ await collection.createIndexes([
36569
+ { key: { name: 1 } },
36570
+ { key: { school: 1 } },
36571
+ { key: { schoolYear: 1 } },
36572
+ { key: { gradeLevel: 1 } },
36573
+ { key: { adviser: 1 } },
36574
+ { key: { createdAt: 1 } },
36575
+ { key: { name: "text", schoolYear: "text", gradeLevel: "text" } },
36576
+ {
36577
+ key: { school: 1, name: 1, schoolYear: 1, status: 1 },
36578
+ unique: true,
36579
+ name: "unique_section"
36580
+ }
36581
+ ]);
36582
+ } catch (error) {
36583
+ throw new Error("Failed to create index on sections.");
36584
+ }
36585
+ }
36586
+ function delCachedData() {
36587
+ delNamespace().then(() => {
36588
+ logger22.log({
36589
+ level: "info",
36590
+ message: `Cache namespace cleared for ${namespace_collection}`
36591
+ });
36592
+ }).catch((err) => {
36593
+ logger22.log({
36594
+ level: "error",
36595
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
36596
+ });
36597
+ });
36598
+ }
36599
+ async function add(value, session) {
36600
+ try {
36601
+ value = modelSection(value);
36602
+ const res = await collection.insertOne(value, { session });
36603
+ delCachedData();
36604
+ return res.insertedId;
36605
+ } catch (error) {
36606
+ logger22.log({
36607
+ level: "error",
36608
+ message: error.message
36609
+ });
36610
+ if (error instanceof AppError12) {
36611
+ throw error;
36612
+ } else {
36613
+ const isDuplicated = error.message.includes("duplicate");
36614
+ if (isDuplicated) {
36615
+ throw new BadRequestError40("Section already exists.");
36616
+ }
36617
+ throw new Error("Failed to create section.");
36618
+ }
36619
+ }
36620
+ }
36621
+ async function getAll({
36622
+ search = "",
36623
+ page = 1,
36624
+ limit = 10,
36625
+ sort = {},
36626
+ status = "active",
36627
+ school = "",
36628
+ schoolYear = "",
36629
+ gradeLevel = ""
36630
+ } = {}) {
36631
+ page = page > 0 ? page - 1 : 0;
36632
+ const query = {
36633
+ deletedAt: { $in: ["", null] },
36634
+ status
36635
+ };
36636
+ const cacheKeyOptions = {
36637
+ status,
36638
+ page,
36639
+ limit,
36640
+ sort: JSON.stringify(sort)
36641
+ };
36642
+ if (school) {
36643
+ try {
36644
+ query.school = new ObjectId24(school);
36645
+ } catch (error) {
36646
+ throw new BadRequestError40("Invalid school ID.");
36647
+ }
36648
+ cacheKeyOptions.school = school;
36649
+ }
36650
+ if (schoolYear) {
36651
+ query.schoolYear = schoolYear;
36652
+ cacheKeyOptions.schoolYear = schoolYear;
36653
+ }
36654
+ if (gradeLevel) {
36655
+ query.gradeLevel = gradeLevel;
36656
+ cacheKeyOptions.gradeLevel = gradeLevel;
36657
+ }
36658
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
36659
+ if (search) {
36660
+ query.$text = { $search: search };
36661
+ cacheKeyOptions.search = search;
36662
+ }
36663
+ const cacheKey = makeCacheKey13(namespace_collection, cacheKeyOptions);
36664
+ logger22.log({
36665
+ level: "info",
36666
+ message: `Cache key for getAll sections: ${cacheKey}`
36667
+ });
36668
+ try {
36669
+ const cached = await getCache(cacheKey);
36670
+ if (cached) {
36671
+ logger22.log({
36672
+ level: "info",
36673
+ message: `Cache hit for getAll sections: ${cacheKey}`
36674
+ });
36675
+ return cached;
36676
+ }
36677
+ const items = await collection.aggregate([
36678
+ { $match: query },
36679
+ { $sort: sort },
36680
+ { $skip: page * limit },
36681
+ { $limit: limit }
36682
+ ]).toArray();
36683
+ const length = await collection.countDocuments(query);
36684
+ const data = paginate12(items, page, limit, length);
36685
+ setCache(cacheKey, data, 600).then(() => {
36686
+ logger22.log({
36687
+ level: "info",
36688
+ message: `Cache set for getAll sections: ${cacheKey}`
36689
+ });
36690
+ }).catch((err) => {
36691
+ logger22.log({
36692
+ level: "error",
36693
+ message: `Failed to set cache for getAll sections: ${err.message}`
36694
+ });
36695
+ });
36696
+ return data;
36697
+ } catch (error) {
36698
+ logger22.log({ level: "error", message: `${error}` });
36699
+ throw error;
36700
+ }
36701
+ }
36702
+ async function getById(_id) {
36703
+ try {
36704
+ _id = new ObjectId24(_id);
36705
+ } catch (error) {
36706
+ throw new BadRequestError40("Invalid ID.");
36707
+ }
36708
+ const cacheKey = makeCacheKey13(namespace_collection, { _id: String(_id) });
36709
+ try {
36710
+ const cached = await getCache(cacheKey);
36711
+ if (cached) {
36712
+ logger22.log({
36713
+ level: "info",
36714
+ message: `Cache hit for getById section: ${cacheKey}`
36715
+ });
36716
+ return cached;
36717
+ }
36718
+ const result = await collection.findOne({
36719
+ _id,
36720
+ deletedAt: { $in: ["", null] }
36721
+ });
36722
+ if (!result) {
36723
+ throw new BadRequestError40("Section not found.");
36724
+ }
36725
+ setCache(cacheKey, result, 300).then(() => {
36726
+ logger22.log({
36727
+ level: "info",
36728
+ message: `Cache set for section by id: ${cacheKey}`
36729
+ });
36730
+ }).catch((err) => {
36731
+ logger22.log({
36732
+ level: "error",
36733
+ message: `Failed to set cache for section by id: ${err.message}`
36734
+ });
36735
+ });
36736
+ return result;
36737
+ } catch (error) {
36738
+ if (error instanceof AppError12) {
36739
+ throw error;
36740
+ } else {
36741
+ throw new InternalServerError10("Failed to get section.");
36742
+ }
36743
+ }
36744
+ }
36745
+ async function getByName(name) {
36746
+ const cacheKey = makeCacheKey13(namespace_collection, { name });
36747
+ try {
36748
+ const cached = await getCache(cacheKey);
36749
+ if (cached) {
36750
+ logger22.log({
36751
+ level: "info",
36752
+ message: `Cache hit for getByName section: ${cacheKey}`
36753
+ });
36754
+ return cached;
36755
+ }
36756
+ const result = await collection.findOne({
36757
+ name,
36758
+ deletedAt: { $in: ["", null] }
36759
+ });
36760
+ if (!result) {
36761
+ throw new BadRequestError40("Section not found.");
36762
+ }
36763
+ setCache(cacheKey, result, 300).then(() => {
36764
+ logger22.log({
36765
+ level: "info",
36766
+ message: `Cache set for section by name: ${cacheKey}`
36767
+ });
36768
+ }).catch((err) => {
36769
+ logger22.log({
36770
+ level: "error",
36771
+ message: `Failed to set cache for section by name: ${err.message}`
36772
+ });
36773
+ });
36774
+ return result;
36775
+ } catch (error) {
36776
+ if (error instanceof AppError12) {
36777
+ throw error;
36778
+ } else {
36779
+ throw new InternalServerError10("Failed to get section.");
36780
+ }
36781
+ }
36782
+ }
36783
+ async function getBySchool(school) {
36784
+ try {
36785
+ school = new ObjectId24(school);
36786
+ } catch (error) {
36787
+ throw new BadRequestError40("Invalid school ID.");
36788
+ }
36789
+ const cacheKey = makeCacheKey13(namespace_collection, {
36790
+ school: String(school)
36791
+ });
36792
+ try {
36793
+ const cached = await getCache(cacheKey);
36794
+ if (cached) {
36795
+ logger22.log({
36796
+ level: "info",
36797
+ message: `Cache hit for getBySchool sections: ${cacheKey}`
36798
+ });
36799
+ return cached;
36800
+ }
36801
+ const result = await collection.find({
36802
+ school,
36803
+ deletedAt: { $in: ["", null] }
36804
+ }).toArray();
36805
+ setCache(cacheKey, result, 300).then(() => {
36806
+ logger22.log({
36807
+ level: "info",
36808
+ message: `Cache set for sections by school: ${cacheKey}`
36809
+ });
36810
+ }).catch((err) => {
36811
+ logger22.log({
36812
+ level: "error",
36813
+ message: `Failed to set cache for sections by school: ${err.message}`
36814
+ });
36815
+ });
36816
+ return result;
36817
+ } catch (error) {
36818
+ if (error instanceof AppError12) {
36819
+ throw error;
36820
+ } else {
36821
+ throw new InternalServerError10("Failed to get sections by school.");
36822
+ }
36823
+ }
36824
+ }
36825
+ async function updateFieldById({ _id, field, value } = {}, session) {
36826
+ const allowedFields = [
36827
+ "name",
36828
+ "schoolYear",
36829
+ "gradeLevel",
36830
+ "adviser",
36831
+ "adviserName"
36832
+ ];
36833
+ if (!allowedFields.includes(field)) {
36834
+ throw new BadRequestError40(
36835
+ `Field "${field}" is not allowed to be updated.`
36836
+ );
36837
+ }
36838
+ try {
36839
+ _id = new ObjectId24(_id);
36840
+ } catch (error) {
36841
+ throw new BadRequestError40("Invalid ID.");
36842
+ }
36843
+ if (field === "adviser" && value) {
36844
+ try {
36845
+ value = new ObjectId24(value).toString();
36846
+ } catch (error) {
36847
+ throw new BadRequestError40("Invalid adviser ID.");
36848
+ }
36849
+ }
36850
+ try {
36851
+ const updateValue = field === "adviser" ? new ObjectId24(value) : value;
36852
+ await collection.updateOne(
36853
+ { _id, deletedAt: { $in: ["", null] } },
36854
+ { $set: { [field]: updateValue, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
36855
+ { session }
36856
+ );
36857
+ delCachedData();
36858
+ return `Successfully updated section ${field}.`;
36859
+ } catch (error) {
36860
+ throw new InternalServerError10(`Failed to update section ${field}.`);
36861
+ }
36862
+ }
36863
+ async function addStudentToSection(_id, studentId, session) {
36864
+ try {
36865
+ _id = new ObjectId24(_id);
36866
+ } catch (error) {
36867
+ throw new BadRequestError40("Invalid section ID.");
36868
+ }
36869
+ try {
36870
+ await collection.updateOne(
36871
+ { _id, deletedAt: { $in: ["", null] } },
36872
+ {
36873
+ $addToSet: { students: studentId },
36874
+ $set: { updatedAt: (/* @__PURE__ */ new Date()).toISOString() }
36875
+ },
36876
+ { session }
36877
+ );
36878
+ delCachedData();
36879
+ return "Successfully added student to section.";
36880
+ } catch (error) {
36881
+ throw new InternalServerError10("Failed to add student to section.");
36882
+ }
36883
+ }
36884
+ async function removeStudentFromSection(_id, studentId, session) {
36885
+ try {
36886
+ _id = new ObjectId24(_id);
36887
+ } catch (error) {
36888
+ throw new BadRequestError40("Invalid section ID.");
36889
+ }
36890
+ try {
36891
+ await collection.updateOne(
36892
+ { _id },
36893
+ {
36894
+ // @ts-ignore
36895
+ $pull: { students: studentId },
36896
+ $set: { updatedAt: (/* @__PURE__ */ new Date()).toISOString() }
36897
+ },
36898
+ { session }
36899
+ );
36900
+ delCachedData();
36901
+ return "Successfully removed student from section.";
36902
+ } catch (error) {
36903
+ throw new InternalServerError10("Failed to remove student from section.");
36904
+ }
36905
+ }
36906
+ async function deleteById(_id) {
36907
+ try {
36908
+ _id = new ObjectId24(_id);
36909
+ } catch (error) {
36910
+ throw new BadRequestError40("Invalid ID.");
36911
+ }
36912
+ try {
36913
+ await collection.updateOne(
36914
+ { _id },
36915
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
36916
+ );
36917
+ delCachedData();
36918
+ return "Successfully deleted section.";
36919
+ } catch (error) {
36920
+ throw new InternalServerError10("Failed to delete section.");
36921
+ }
36922
+ }
36923
+ return {
36924
+ createIndexes,
36925
+ add,
36926
+ getAll,
36927
+ getById,
36928
+ getByName,
36929
+ getBySchool,
36930
+ updateFieldById,
36931
+ addStudentToSection,
36932
+ removeStudentFromSection,
36933
+ deleteById
36934
+ };
36935
+ }
36936
+
36937
+ // src/resources/section/section.controller.ts
36938
+ import { BadRequestError as BadRequestError44 } from "@eeplatform/nodejs-utils";
36939
+ import Joi27 from "joi";
36940
+
36941
+ // src/resources/section/section.service.ts
36942
+ import {
36943
+ AppError as AppError14,
36944
+ BadRequestError as BadRequestError43,
36945
+ InternalServerError as InternalServerError12,
36946
+ useAtlas as useAtlas20
36947
+ } from "@eeplatform/nodejs-utils";
36948
+
36949
+ // src/resources/section-student/section.student.repository.ts
36950
+ import {
36951
+ AppError as AppError13,
36952
+ BadRequestError as BadRequestError42,
36953
+ InternalServerError as InternalServerError11,
36954
+ logger as logger23,
36955
+ useAtlas as useAtlas19,
36956
+ useCache as useCache14
36957
+ } from "@eeplatform/nodejs-utils";
36958
+
36959
+ // src/resources/section-student/section.student.model.ts
36960
+ import { BadRequestError as BadRequestError41 } from "@eeplatform/nodejs-utils";
36961
+ import Joi26 from "joi";
36962
+ import { ObjectId as ObjectId25 } from "mongodb";
36963
+ var allowedSectionStudentStatuses = [
36964
+ "active",
36965
+ "dropped",
36966
+ "section-transferred",
36967
+ "school-transferred"
36968
+ ];
36969
+ var schemaSectionStudent = Joi26.object({
36970
+ _id: Joi26.string().hex().optional().allow(null, ""),
36971
+ section: Joi26.string().hex().required(),
36972
+ student: Joi26.string().required(),
36973
+ studentName: Joi26.string().required(),
36974
+ status: Joi26.string().valid(...allowedSectionStudentStatuses).optional().allow(null, ""),
36975
+ assignedAt: Joi26.string().isoDate().optional().allow(null, ""),
36976
+ updatedAt: Joi26.string().isoDate().optional().allow(null, "")
36977
+ });
36978
+ function modelSectionStudent(value) {
36979
+ const { error } = schemaSectionStudent.validate(value);
36980
+ if (error) {
36981
+ throw new BadRequestError41(`Invalid section-student data: ${error.message}`);
36982
+ }
36983
+ if (value._id && typeof value._id === "string") {
36984
+ try {
36985
+ value._id = new ObjectId25(value._id);
36986
+ } catch (error2) {
36987
+ throw new Error("Invalid _id.");
36988
+ }
36989
+ }
36990
+ if (value.section && typeof value.section === "string") {
36991
+ try {
36992
+ value.section = new ObjectId25(value.section);
36993
+ } catch (error2) {
36994
+ throw new Error("Invalid section ID.");
36995
+ }
36996
+ }
36997
+ return {
36998
+ _id: value._id,
36999
+ section: value.section,
37000
+ student: value.student,
37001
+ studentName: value.studentName,
37002
+ status: value.status ?? "active",
37003
+ assignedAt: value.assignedAt ?? "",
37004
+ updatedAt: value.updatedAt ?? ""
37005
+ };
37006
+ }
37007
+
37008
+ // src/resources/section-student/section.student.repository.ts
37009
+ function useSectionStudentRepo() {
37010
+ const db = useAtlas19.getDb();
37011
+ if (!db) {
37012
+ throw new Error("Unable to connect to server.");
37013
+ }
37014
+ const namespace_collection = "deped.section.students";
37015
+ const collection = db.collection(namespace_collection);
37016
+ const { getCache, setCache, delNamespace } = useCache14(namespace_collection);
37017
+ async function createIndexes() {
37018
+ try {
37019
+ await collection.createIndexes([
37020
+ { key: { status: 1 } },
37021
+ { key: { school: 1, status: 1 } },
37022
+ { key: { "learnerInfo.lrn": 1 } },
37023
+ { key: { schoolYear: 1 } },
37024
+ { key: { gradeLevelToEnroll: 1 } },
37025
+ {
37026
+ key: {
37027
+ "learnerInfo.firstName": "text",
37028
+ "learnerInfo.lastName": "text"
37029
+ },
37030
+ name: "learner_name_text_index"
37031
+ }
37032
+ ]);
37033
+ } catch (error) {
37034
+ throw new Error("Failed to create index on learners.");
37035
+ }
37036
+ }
37037
+ function delCachedData() {
37038
+ delNamespace().then(() => {
37039
+ logger23.log({
37040
+ level: "info",
37041
+ message: `Cache cleared for namespace: ${namespace_collection}`
37042
+ });
37043
+ }).catch((error) => {
37044
+ logger23.log({
37045
+ level: "error",
37046
+ message: `Failed to clear cache for namespace ${namespace_collection}: ${error.message}`
37047
+ });
37048
+ });
37049
+ }
37050
+ async function add(value, session) {
37051
+ try {
37052
+ value = modelSectionStudent(value);
37053
+ const res = await collection.insertOne(value, { session });
37054
+ delCachedData();
37055
+ return res.insertedId;
37056
+ } catch (error) {
37057
+ logger23.log({
37058
+ level: "error",
37059
+ message: error.message
37060
+ });
37061
+ if (error instanceof AppError13) {
37062
+ throw error;
37063
+ } else {
37064
+ const isDuplicated = error.message.includes("duplicate");
37065
+ if (isDuplicated) {
37066
+ throw new BadRequestError42("Section student already exists.");
37067
+ }
37068
+ throw new InternalServerError11("Failed to create section student.");
37069
+ }
37070
+ }
37071
+ }
37072
+ return {
37073
+ createIndexes,
37074
+ delCachedData,
37075
+ add
37076
+ };
37077
+ }
37078
+
37079
+ // src/resources/section/section.service.ts
37080
+ function useSectionService() {
37081
+ const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
37082
+ const { getByGradeLevel } = useGradeLevelRepo();
37083
+ const { add: createSection } = useSectionRepo();
37084
+ const { add: assignStudent } = useSectionStudentRepo();
37085
+ function distributeStudents(total, minPer, maxPer) {
37086
+ if (total <= 0)
37087
+ return [];
37088
+ if (minPer <= 0 || maxPer <= 0)
37089
+ return [];
37090
+ if (minPer > maxPer) {
37091
+ throw new BadRequestError43(
37092
+ "Minimum students per section cannot be greater than maximum."
37093
+ );
37094
+ }
37095
+ const minSections = Math.ceil(total / maxPer);
37096
+ const maxSections = Math.floor(total / minPer);
37097
+ let sectionCount;
37098
+ if (minSections <= maxSections) {
37099
+ sectionCount = minSections;
37100
+ } else {
37101
+ sectionCount = minSections;
37102
+ }
37103
+ const base = Math.floor(total / sectionCount);
37104
+ const extra = total % sectionCount;
37105
+ const sizes = new Array(sectionCount).fill(base);
37106
+ for (let i = 0; i < extra; i++) {
37107
+ sizes[i] += 1;
37108
+ }
37109
+ for (const size of sizes) {
37110
+ if (size > maxPer) {
37111
+ throw new BadRequestError43(
37112
+ `Generated section exceeds max limit of ${maxPer}.`
37113
+ );
37114
+ }
37115
+ }
37116
+ return sizes;
37117
+ }
37118
+ async function generateSections(value) {
37119
+ const { error } = schemaGenerateSections.validate(value);
37120
+ if (error) {
37121
+ throw new BadRequestError43(
37122
+ `Invalid section generation data: ${error.message}`
37123
+ );
37124
+ }
37125
+ const session = useAtlas20.getClient()?.startSession();
37126
+ if (!session) {
37127
+ throw new Error("Unable to start database session.");
37128
+ }
37129
+ try {
37130
+ await session.startTransaction();
37131
+ const studentCount = await getCountByGradeLevel(
37132
+ {
37133
+ school: value.school,
37134
+ schoolYear: value.schoolYear,
37135
+ gradeLevel: value.gradeLevel
37136
+ },
37137
+ session
37138
+ );
37139
+ if (studentCount === 0) {
37140
+ throw new BadRequestError43("No learners found for this grade level.");
37141
+ }
37142
+ const gradeLevelData = await getByGradeLevel(
37143
+ {
37144
+ school: value.school,
37145
+ gradeLevel: value.gradeLevel
37146
+ },
37147
+ session
37148
+ );
37149
+ if (!gradeLevelData) {
37150
+ throw new BadRequestError43("Grade level not found.");
37151
+ }
37152
+ const minPerSection = gradeLevelData.minNumberOfLearners;
37153
+ const maxPerSection = gradeLevelData.maxNumberOfLearners;
37154
+ const sectionsNeeded = Math.ceil(studentCount / minPerSection);
37155
+ if (sectionsNeeded > value.set.length) {
37156
+ throw new BadRequestError43(
37157
+ "Insufficient number of section names in set[]."
37158
+ );
37159
+ }
37160
+ const sectionSizes = distributeStudents(
37161
+ studentCount,
37162
+ minPerSection,
37163
+ maxPerSection
37164
+ );
37165
+ if (sectionSizes.length === 0) {
37166
+ throw new BadRequestError43("Unable to compute section sizes.");
37167
+ }
37168
+ let pointer = 0;
37169
+ for (let i = 0; i < sectionSizes.length; i++) {
37170
+ const size = sectionSizes[i];
37171
+ const sectionName = value.set[i];
37172
+ const section = await createSection(
37173
+ {
37174
+ school: value.school,
37175
+ schoolYear: value.schoolYear,
37176
+ gradeLevel: value.gradeLevel,
37177
+ name: sectionName,
37178
+ students: size
37179
+ },
37180
+ session
37181
+ );
37182
+ const learners = await getLeanerByGradeLevel(
37183
+ {
37184
+ school: value.school,
37185
+ gradeLevel: value.gradeLevel,
37186
+ skip: pointer,
37187
+ limit: size
37188
+ },
37189
+ session
37190
+ );
37191
+ if (!learners.length) {
37192
+ throw new BadRequestError43(`No learners found for section #${i + 1}.`);
37193
+ }
37194
+ pointer += size;
37195
+ for (const student of learners) {
37196
+ if (!student._id) {
37197
+ throw new BadRequestError43("Learner ID is missing.");
37198
+ }
37199
+ await assignStudent(
37200
+ {
37201
+ section: section.toString(),
37202
+ student: student._id?.toString(),
37203
+ studentName: `${student.learnerInfo.firstName} ${student.learnerInfo.lastName}`,
37204
+ status: "active"
37205
+ },
37206
+ session
37207
+ );
37208
+ }
37209
+ }
37210
+ await session.commitTransaction();
37211
+ return "Sections generated successfully.";
37212
+ } catch (error2) {
37213
+ await session.abortTransaction();
37214
+ if (error2 instanceof AppError14) {
37215
+ throw error2;
37216
+ } else {
37217
+ throw new InternalServerError12("Failed to generate sections.");
37218
+ }
37219
+ } finally {
37220
+ await session?.endSession();
37221
+ }
37222
+ }
37223
+ return { generateSections };
37224
+ }
37225
+
37226
+ // src/resources/section/section.controller.ts
37227
+ function useSectionController() {
37228
+ const {
37229
+ add: _add,
37230
+ getAll: _getAll,
37231
+ getById: _getById,
37232
+ getByName: _getByName,
37233
+ getBySchool: _getBySchool,
37234
+ updateFieldById: _updateFieldById,
37235
+ addStudentToSection: _addStudentToSection,
37236
+ removeStudentFromSection: _removeStudentFromSection,
37237
+ deleteById: _deleteById
37238
+ } = useSectionRepo();
37239
+ const { generateSections: _generateSections } = useSectionService();
37240
+ async function add(req, res, next) {
37241
+ const value = req.body;
37242
+ const { error } = schemaSection.validate(value);
37243
+ if (error) {
37244
+ next(new BadRequestError44(error.message));
37245
+ return;
37246
+ }
37247
+ try {
37248
+ const data = await _add(value);
37249
+ res.json({
37250
+ message: "Successfully created section.",
37251
+ data
37252
+ });
37253
+ return;
37254
+ } catch (error2) {
37255
+ next(error2);
37256
+ }
37257
+ }
37258
+ async function generateSections(req, res, next) {
37259
+ const value = req.body;
37260
+ const { error } = schemaGenerateSections.validate(value);
37261
+ if (error) {
37262
+ next(new BadRequestError44(error.message));
37263
+ return;
37264
+ }
37265
+ try {
37266
+ const data = await _generateSections(value);
37267
+ res.json({
37268
+ message: "Successfully created section.",
37269
+ data
37270
+ });
37271
+ return;
37272
+ } catch (error2) {
37273
+ next(error2);
37274
+ }
37275
+ }
37276
+ async function getAll(req, res, next) {
37277
+ const query = req.query;
37278
+ const validation = Joi27.object({
37279
+ page: Joi27.number().min(1).optional().allow("", null),
37280
+ limit: Joi27.number().min(1).optional().allow("", null),
37281
+ search: Joi27.string().optional().allow("", null),
37282
+ status: Joi27.string().optional().allow("", null),
37283
+ school: Joi27.string().hex().optional().allow("", null),
37284
+ schoolYear: Joi27.string().optional().allow("", null),
37285
+ gradeLevel: Joi27.string().optional().allow("", null)
37286
+ });
37287
+ const { error } = validation.validate(query);
37288
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
37289
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
37290
+ const search = req.query.search ?? "";
37291
+ const status = req.query.status ?? "active";
37292
+ const school = req.query.school ?? "";
37293
+ const schoolYear = req.query.schoolYear ?? "";
37294
+ const gradeLevel = req.query.gradeLevel ?? "";
37295
+ const isPageNumber = isFinite(page);
37296
+ if (!isPageNumber) {
37297
+ next(new BadRequestError44("Invalid page number."));
37298
+ return;
37299
+ }
37300
+ const isLimitNumber = isFinite(limit);
37301
+ if (!isLimitNumber) {
37302
+ next(new BadRequestError44("Invalid limit number."));
37303
+ return;
37304
+ }
37305
+ if (error) {
37306
+ next(new BadRequestError44(error.message));
37307
+ return;
37308
+ }
37309
+ try {
37310
+ const data = await _getAll({
37311
+ page,
37312
+ limit,
37313
+ search,
37314
+ status,
37315
+ school,
37316
+ schoolYear,
37317
+ gradeLevel
37318
+ });
37319
+ res.json(data);
37320
+ return;
37321
+ } catch (error2) {
37322
+ next(error2);
37323
+ }
37324
+ }
37325
+ async function getById(req, res, next) {
37326
+ const id = req.params.id;
37327
+ const validation = Joi27.object({
37328
+ id: Joi27.string().hex().required()
37329
+ });
37330
+ const { error } = validation.validate({ id });
37331
+ if (error) {
37332
+ next(new BadRequestError44(error.message));
37333
+ return;
37334
+ }
37335
+ try {
37336
+ const data = await _getById(id);
37337
+ res.json({
37338
+ message: "Successfully retrieved section.",
37339
+ data
37340
+ });
37341
+ return;
37342
+ } catch (error2) {
37343
+ next(error2);
37344
+ }
37345
+ }
37346
+ async function getByName(req, res, next) {
37347
+ const name = req.params.name;
37348
+ const validation = Joi27.object({
37349
+ name: Joi27.string().required()
37350
+ });
37351
+ const { error } = validation.validate({ name });
37352
+ if (error) {
37353
+ next(new BadRequestError44(error.message));
37354
+ return;
37355
+ }
37356
+ try {
37357
+ const data = await _getByName(name);
37358
+ res.json({
37359
+ message: "Successfully retrieved section.",
37360
+ data
37361
+ });
37362
+ return;
37363
+ } catch (error2) {
37364
+ next(error2);
37365
+ }
37366
+ }
37367
+ async function getBySchool(req, res, next) {
37368
+ const school = req.params.school;
37369
+ const validation = Joi27.object({
37370
+ school: Joi27.string().hex().required()
37371
+ });
37372
+ const { error } = validation.validate({ school });
37373
+ if (error) {
37374
+ next(new BadRequestError44(error.message));
37375
+ return;
37376
+ }
37377
+ try {
37378
+ const data = await _getBySchool(school);
37379
+ res.json({
37380
+ message: "Successfully retrieved sections.",
37381
+ data
37382
+ });
37383
+ return;
37384
+ } catch (error2) {
37385
+ next(error2);
37386
+ }
37387
+ }
37388
+ async function updateField(req, res, next) {
37389
+ const _id = req.params.id;
37390
+ const { field, value } = req.body;
37391
+ const validation = Joi27.object({
37392
+ _id: Joi27.string().hex().required(),
37393
+ field: Joi27.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
37394
+ value: Joi27.string().required()
37395
+ });
37396
+ const { error } = validation.validate({ _id, field, value });
37397
+ if (error) {
37398
+ next(new BadRequestError44(error.message));
37399
+ return;
37400
+ }
37401
+ try {
37402
+ const message = await _updateFieldById({ _id, field, value });
37403
+ res.json({ message });
37404
+ return;
37405
+ } catch (error2) {
37406
+ next(error2);
37407
+ }
37408
+ }
37409
+ async function addStudent(req, res, next) {
37410
+ const _id = req.params.id;
37411
+ const { studentId } = req.body;
37412
+ const validation = Joi27.object({
37413
+ _id: Joi27.string().hex().required(),
37414
+ studentId: Joi27.string().required()
37415
+ });
37416
+ const { error } = validation.validate({ _id, studentId });
37417
+ if (error) {
37418
+ next(new BadRequestError44(error.message));
37419
+ return;
37420
+ }
37421
+ try {
37422
+ const message = await _addStudentToSection(_id, studentId);
37423
+ res.json({ message });
37424
+ return;
37425
+ } catch (error2) {
37426
+ next(error2);
37427
+ }
37428
+ }
37429
+ async function removeStudent(req, res, next) {
37430
+ const _id = req.params.id;
37431
+ const { studentId } = req.body;
37432
+ const validation = Joi27.object({
37433
+ _id: Joi27.string().hex().required(),
37434
+ studentId: Joi27.string().required()
37435
+ });
37436
+ const { error } = validation.validate({ _id, studentId });
37437
+ if (error) {
37438
+ next(new BadRequestError44(error.message));
37439
+ return;
37440
+ }
37441
+ try {
37442
+ const message = await _removeStudentFromSection(_id, studentId);
37443
+ res.json({ message });
37444
+ return;
37445
+ } catch (error2) {
37446
+ next(error2);
37447
+ }
37448
+ }
37449
+ async function deleteById(req, res, next) {
37450
+ const _id = req.params.id;
37451
+ const validation = Joi27.object({
37452
+ _id: Joi27.string().hex().required()
37453
+ });
37454
+ const { error } = validation.validate({ _id });
37455
+ if (error) {
37456
+ next(new BadRequestError44(error.message));
37457
+ return;
37458
+ }
37459
+ try {
37460
+ const message = await _deleteById(_id);
37461
+ res.json({ message });
37462
+ return;
37463
+ } catch (error2) {
37464
+ next(error2);
37465
+ }
37466
+ }
37467
+ return {
37468
+ add,
37469
+ generateSections,
37470
+ getAll,
37471
+ getById,
37472
+ getByName,
37473
+ getBySchool,
37474
+ updateField,
37475
+ addStudent,
37476
+ removeStudent,
37477
+ deleteById
37478
+ };
37479
+ }
37480
+
35819
37481
  // src/config.ts
35820
37482
  import * as dotenv from "dotenv";
35821
37483
  dotenv.config();
@@ -35830,6 +37492,8 @@ export {
35830
37492
  modelDivision,
35831
37493
  modelRegion,
35832
37494
  modelSchool,
37495
+ modelSection,
37496
+ modelSectionPreset,
35833
37497
  schemaAsset,
35834
37498
  schemaAssetUpdateOption,
35835
37499
  schemaBasicEduCount,
@@ -35837,11 +37501,14 @@ export {
35837
37501
  schemaDivision,
35838
37502
  schemaDivisionUpdate,
35839
37503
  schemaEnrollment,
37504
+ schemaGenerateSections,
35840
37505
  schemaGradeLevel,
35841
37506
  schemaPlantilla,
35842
37507
  schemaRegion,
35843
37508
  schemaSchool,
35844
37509
  schemaSchoolUpdate,
37510
+ schemaSection,
37511
+ schemaSectionPreset,
35845
37512
  schemaStockCard,
35846
37513
  schemaUpdateStatus,
35847
37514
  useAssetController,
@@ -35867,6 +37534,10 @@ export {
35867
37534
  useSchoolController,
35868
37535
  useSchoolRepo,
35869
37536
  useSchoolService,
37537
+ useSectionController,
37538
+ useSectionPresetController,
37539
+ useSectionPresetRepo,
37540
+ useSectionRepo,
35870
37541
  useStockCardController,
35871
37542
  useStockCardRepository,
35872
37543
  useStockCardService