@eeplatform/basic-edu 1.9.3 → 1.10.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
@@ -39814,15 +39814,15 @@ function useSectionRepo() {
39814
39814
  }
39815
39815
 
39816
39816
  // src/resources/section/section.controller.ts
39817
- import { BadRequestError as BadRequestError65 } from "@eeplatform/nodejs-utils";
39818
- import Joi43 from "joi";
39817
+ import { BadRequestError as BadRequestError68 } from "@eeplatform/nodejs-utils";
39818
+ import Joi45 from "joi";
39819
39819
 
39820
39820
  // src/resources/section/section.service.ts
39821
39821
  import {
39822
- AppError as AppError25,
39823
- BadRequestError as BadRequestError64,
39824
- InternalServerError as InternalServerError21,
39825
- useAtlas as useAtlas30
39822
+ AppError as AppError26,
39823
+ BadRequestError as BadRequestError67,
39824
+ InternalServerError as InternalServerError22,
39825
+ useAtlas as useAtlas31
39826
39826
  } from "@eeplatform/nodejs-utils";
39827
39827
 
39828
39828
  // src/resources/section-student/section.student.repository.ts
@@ -41557,9 +41557,11 @@ var schemaTeachingLoadSlot = Joi39.object({
41557
41557
  gradeLevel: Joi39.string().required(),
41558
41558
  startTime: Joi39.string().required(),
41559
41559
  endTime: Joi39.string().required(),
41560
- subject: Joi39.string().hex().required(),
41560
+ subject: Joi39.string().hex().optional().allow("", null),
41561
41561
  subjectName: Joi39.string().optional().allow("", null),
41562
41562
  subjectCode: Joi39.string().optional().allow("", null),
41563
+ routine: Joi39.string().hex().optional().allow("", null),
41564
+ routineName: Joi39.string().optional().allow("", null),
41563
41565
  section: Joi39.string().hex().required(),
41564
41566
  sectionName: Joi39.string().optional().allow("", null),
41565
41567
  duration: Joi39.number().min(0).required(),
@@ -41595,6 +41597,13 @@ function modelTeachingLoadSlot(value) {
41595
41597
  throw new BadRequestError58("Invalid subject format");
41596
41598
  }
41597
41599
  }
41600
+ if (value.routine && typeof value.routine === "string") {
41601
+ try {
41602
+ value.routine = new ObjectId37(value.routine);
41603
+ } catch (error2) {
41604
+ throw new BadRequestError58("Invalid routine format");
41605
+ }
41606
+ }
41598
41607
  if (value.section && typeof value.section === "string") {
41599
41608
  try {
41600
41609
  value.section = new ObjectId37(value.section);
@@ -41612,9 +41621,11 @@ function modelTeachingLoadSlot(value) {
41612
41621
  gradeLevel: value.gradeLevel ?? "",
41613
41622
  startTime: value.startTime ?? "",
41614
41623
  endTime: value.endTime ?? "",
41615
- subject: value.subject,
41624
+ subject: value.subject ?? "",
41616
41625
  subjectName: value.subjectName ?? "",
41617
41626
  subjectCode: value.subjectCode ?? "",
41627
+ routine: value.routine ?? "",
41628
+ routineName: value.routineName ?? "",
41618
41629
  section: value.section,
41619
41630
  sectionName: value.sectionName ?? "",
41620
41631
  duration: value.duration ?? 0,
@@ -42786,142 +42797,834 @@ function usePersonnelController() {
42786
42797
  };
42787
42798
  }
42788
42799
 
42789
- // src/resources/section/section.service.ts
42790
- function useSectionService() {
42791
- const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
42792
- const { getByGradeLevel } = useGradeLevelRepo();
42793
- const { add: createSection } = useSectionRepo();
42794
- const { add: assignStudent } = useSectionStudentRepo();
42795
- const { getAll: getAllCurriculumSubjects } = useSubjectRepo();
42796
- const { add: addSectionSubject } = useSectionSubjectRepo();
42797
- const { getById: getSchoolById } = useSchoolRepo();
42798
- const { getAll: getAllPersonnel } = usePersonnelRepo();
42799
- const { add: addTeachingLoad } = useTeachingLoadRepo();
42800
- function distributeStudents(total, minPer, maxPer) {
42801
- if (total <= 0)
42802
- return [];
42803
- if (minPer <= 0 || maxPer <= 0)
42804
- return [];
42805
- if (minPer > maxPer) {
42806
- throw new BadRequestError64(
42807
- "Minimum students per section cannot be greater than maximum."
42808
- );
42809
- }
42810
- const minSections = Math.ceil(total / maxPer);
42811
- const maxSections = Math.floor(total / minPer);
42812
- let sectionCount;
42813
- if (minSections <= maxSections) {
42814
- sectionCount = minSections;
42815
- } else {
42816
- sectionCount = minSections;
42817
- }
42818
- const base = Math.floor(total / sectionCount);
42819
- const extra = total % sectionCount;
42820
- const sizes = new Array(sectionCount).fill(base);
42821
- for (let i = 0; i < extra; i++) {
42822
- sizes[i] += 1;
42800
+ // src/resources/kindergarten-routine/kindergarten.routine.model.ts
42801
+ import { BadRequestError as BadRequestError64 } from "@eeplatform/nodejs-utils";
42802
+ import Joi43 from "joi";
42803
+ import { ObjectId as ObjectId41 } from "mongodb";
42804
+ var schemaKindergartenRoutine = Joi43.object({
42805
+ _id: Joi43.string().hex().optional().allow(null, ""),
42806
+ title: Joi43.string().max(100).required(),
42807
+ section: Joi43.string().hex().optional().allow(null, ""),
42808
+ sectionName: Joi43.string().max(100).optional().allow(null, ""),
42809
+ classroom: Joi43.string().hex().optional().allow(null, ""),
42810
+ classroomName: Joi43.string().max(100).optional().allow(null, ""),
42811
+ schedule: Joi43.array().items(Joi43.string()).required(),
42812
+ blockTimes: Joi43.array().items(
42813
+ Joi43.object({
42814
+ title: Joi43.string().required(),
42815
+ startTime: Joi43.string().required(),
42816
+ endTime: Joi43.string().required(),
42817
+ durationMinutes: Joi43.number().required(),
42818
+ domains: Joi43.array().items(Joi43.string()).optional()
42819
+ })
42820
+ ).required(),
42821
+ type: Joi43.string().required(),
42822
+ durationMinutes: Joi43.number().optional().allow(null, 0),
42823
+ school: Joi43.string().hex().required(),
42824
+ createdAt: Joi43.string().isoDate().optional().allow(null, ""),
42825
+ updatedAt: Joi43.string().isoDate().optional().allow(null, ""),
42826
+ deletedAt: Joi43.string().isoDate().optional().allow(null, "")
42827
+ });
42828
+ var schemaKindergartenRoutineUpdate = Joi43.object({
42829
+ title: Joi43.string().max(100).optional().allow(null, ""),
42830
+ section: Joi43.string().hex().optional().allow(null, ""),
42831
+ sectionName: Joi43.string().max(100).optional().allow(null, ""),
42832
+ classroom: Joi43.string().hex().optional().allow(null, ""),
42833
+ classroomName: Joi43.string().max(100).optional().allow(null, ""),
42834
+ schedule: Joi43.array().items(Joi43.string()).optional().allow(null, ""),
42835
+ blockTimes: Joi43.array().items(
42836
+ Joi43.object({
42837
+ title: Joi43.string().required(),
42838
+ startTime: Joi43.string().required(),
42839
+ endTime: Joi43.string().required(),
42840
+ durationMinutes: Joi43.number().required(),
42841
+ domains: Joi43.array().items(Joi43.string()).optional()
42842
+ })
42843
+ ).optional(),
42844
+ durationMinutes: Joi43.number().optional().allow(null, 0)
42845
+ });
42846
+ function modelKindergartenRoutine(value) {
42847
+ const { error } = schemaKindergartenRoutine.validate(value);
42848
+ if (error) {
42849
+ throw new BadRequestError64(`Invalid kinder schedule data: ${error.message}`);
42850
+ }
42851
+ if (value._id && typeof value._id === "string") {
42852
+ try {
42853
+ value._id = new ObjectId41(value._id);
42854
+ } catch (error2) {
42855
+ throw new Error("Invalid _id.");
42823
42856
  }
42824
- for (const size of sizes) {
42825
- if (size > maxPer) {
42826
- throw new BadRequestError64(
42827
- `Generated section exceeds max limit of ${maxPer}.`
42828
- );
42829
- }
42857
+ }
42858
+ if (value.school && typeof value.school === "string") {
42859
+ try {
42860
+ value.school = new ObjectId41(value.school);
42861
+ } catch (error2) {
42862
+ throw new Error("Invalid school.");
42830
42863
  }
42831
- return sizes;
42832
42864
  }
42833
- async function generateSections(value) {
42834
- const { error } = schemaGenerateSections.validate(value);
42835
- if (error) {
42836
- throw new BadRequestError64(
42837
- `Invalid section generation data: ${error.message}`
42838
- );
42865
+ if (value.section && typeof value.section === "string") {
42866
+ try {
42867
+ value.section = new ObjectId41(value.section);
42868
+ } catch (error2) {
42869
+ throw new Error("Invalid section.");
42839
42870
  }
42840
- const session = useAtlas30.getClient()?.startSession();
42841
- if (!session) {
42842
- throw new Error("Unable to start database session.");
42871
+ }
42872
+ if (value.classroom && typeof value.classroom === "string") {
42873
+ try {
42874
+ value.classroom = new ObjectId41(value.classroom);
42875
+ } catch (error2) {
42876
+ throw new Error("Invalid classroom.");
42843
42877
  }
42878
+ }
42879
+ return {
42880
+ _id: value._id,
42881
+ title: value.title,
42882
+ section: value.section,
42883
+ sectionName: value.sectionName ?? "",
42884
+ classroom: value.classroom,
42885
+ classroomName: value.classroomName ?? "",
42886
+ schedule: value.schedule,
42887
+ blockTimes: value.blockTimes,
42888
+ type: value.type,
42889
+ durationMinutes: value.durationMinutes ?? 0,
42890
+ status: value.status ?? "active",
42891
+ school: value.school,
42892
+ createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
42893
+ updatedAt: value.updatedAt ?? "",
42894
+ deletedAt: value.deletedAt ?? ""
42895
+ };
42896
+ }
42897
+
42898
+ // src/resources/kindergarten-routine/kindergarten.routine.repository.ts
42899
+ import {
42900
+ AppError as AppError25,
42901
+ BadRequestError as BadRequestError65,
42902
+ InternalServerError as InternalServerError21,
42903
+ logger as logger39,
42904
+ makeCacheKey as makeCacheKey22,
42905
+ paginate as paginate21,
42906
+ useAtlas as useAtlas30,
42907
+ useCache as useCache22
42908
+ } from "@eeplatform/nodejs-utils";
42909
+ import { ObjectId as ObjectId42 } from "mongodb";
42910
+ function useKindergartenRoutineRepo() {
42911
+ const db = useAtlas30.getDb();
42912
+ if (!db) {
42913
+ throw new Error("Unable to connect to server.");
42914
+ }
42915
+ const namespace_collection = "deped.kindergarten.routines";
42916
+ const collection = db.collection(namespace_collection);
42917
+ const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
42918
+ async function createIndexes() {
42844
42919
  try {
42845
- await session.startTransaction();
42846
- const studentCount = await getCountByGradeLevel(
42920
+ await collection.createIndexes([
42921
+ { key: { section: 1 } },
42922
+ { key: { classroom: 1 } },
42923
+ { key: { schedule: 1 } },
42924
+ { key: { type: 1 } },
42925
+ { key: { createdAt: 1 } },
42926
+ { key: { createdBy: 1 } },
42927
+ { key: { sectionName: "text", classroomName: "text" } },
42847
42928
  {
42848
- school: value.school,
42849
- schoolYear: value.schoolYear,
42850
- gradeLevel: value.gradeLevel,
42851
- specialProgram: value.specialProgram
42852
- },
42853
- session
42854
- );
42855
- if (studentCount === 0) {
42856
- throw new BadRequestError64("No learners found for this grade level.");
42929
+ key: { title: 1, school: 1, type: 1, status: 1 },
42930
+ unique: true,
42931
+ name: "unique_kindergarten_routine"
42932
+ }
42933
+ ]);
42934
+ } catch (error) {
42935
+ throw new Error("Failed to create index on kindergarten routines.");
42936
+ }
42937
+ }
42938
+ function delCachedData() {
42939
+ delNamespace().then(() => {
42940
+ logger39.log({
42941
+ level: "info",
42942
+ message: `Cache namespace cleared for ${namespace_collection}`
42943
+ });
42944
+ }).catch((err) => {
42945
+ logger39.log({
42946
+ level: "error",
42947
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
42948
+ });
42949
+ });
42950
+ }
42951
+ async function add(value, session) {
42952
+ try {
42953
+ value = modelKindergartenRoutine(value);
42954
+ const res = await collection.insertOne(value, { session });
42955
+ delCachedData();
42956
+ return res.insertedId;
42957
+ } catch (error) {
42958
+ logger39.log({
42959
+ level: "error",
42960
+ message: error.message
42961
+ });
42962
+ if (error instanceof AppError25) {
42963
+ throw error;
42964
+ } else {
42965
+ const isDuplicated = error.message.includes("duplicate");
42966
+ if (isDuplicated) {
42967
+ throw new BadRequestError65("Kinder schedule already exists.");
42968
+ }
42969
+ throw new Error("Failed to create kindergarten routine.");
42857
42970
  }
42858
- const gradeLevelData = await getByGradeLevel(
42859
- {
42860
- school: value.school,
42861
- gradeLevel: value.gradeLevel
42862
- },
42863
- session
42864
- );
42865
- if (!gradeLevelData) {
42866
- throw new BadRequestError64("Grade level not found.");
42971
+ }
42972
+ }
42973
+ async function getAll({
42974
+ search = "",
42975
+ page = 1,
42976
+ limit = 10,
42977
+ sort = {},
42978
+ status = "active",
42979
+ createdBy,
42980
+ school = "",
42981
+ section = "",
42982
+ classroom = "",
42983
+ type = ""
42984
+ } = {}) {
42985
+ page = page > 0 ? page - 1 : 0;
42986
+ const query = {
42987
+ deletedAt: { $in: ["", null] },
42988
+ status
42989
+ };
42990
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
42991
+ const cacheKeyOptions = {
42992
+ status,
42993
+ page,
42994
+ limit,
42995
+ sort: JSON.stringify(sort)
42996
+ };
42997
+ if (createdBy) {
42998
+ try {
42999
+ query.createdBy = new ObjectId42(createdBy);
43000
+ } catch (error) {
43001
+ throw new BadRequestError65("Invalid createdBy ID.");
42867
43002
  }
42868
- const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
42869
- const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
42870
- const sectionsNeeded = Math.ceil(studentCount / minPerSection);
42871
- if (sectionsNeeded > value.set.length) {
42872
- throw new BadRequestError64(
42873
- "Insufficient number of section names in set[]."
42874
- );
43003
+ cacheKeyOptions.createdBy = createdBy;
43004
+ }
43005
+ if (search) {
43006
+ query.$text = { $search: search };
43007
+ cacheKeyOptions.search = search;
43008
+ }
43009
+ if (school) {
43010
+ try {
43011
+ query.school = new ObjectId42(school);
43012
+ } catch (error) {
43013
+ throw new BadRequestError65("Invalid school ID.");
42875
43014
  }
42876
- const sectionSizes = distributeStudents(
42877
- studentCount,
42878
- minPerSection,
42879
- maxPerSection
42880
- );
42881
- if (sectionSizes.length === 0) {
42882
- throw new BadRequestError64("Unable to compute section sizes.");
43015
+ cacheKeyOptions.school = school;
43016
+ }
43017
+ if (section) {
43018
+ try {
43019
+ query.section = new ObjectId42(section);
43020
+ } catch (error) {
43021
+ throw new BadRequestError65("Invalid section ID.");
42883
43022
  }
42884
- const schoolData = await getSchoolById(value.school);
42885
- if (!schoolData) {
42886
- throw new BadRequestError64("School not found.");
43023
+ cacheKeyOptions.section = section;
43024
+ }
43025
+ if (classroom) {
43026
+ try {
43027
+ query.classroom = new ObjectId42(classroom);
43028
+ } catch (error) {
43029
+ throw new BadRequestError65("Invalid classroom ID.");
42887
43030
  }
42888
- let totalStudentsProcessed = 0;
42889
- for (let i = 0; i < sectionSizes.length; i++) {
42890
- const size = sectionSizes[i];
42891
- const sectionName = value.set[i];
42892
- const section = await createSection(
42893
- {
42894
- school: value.school,
42895
- schoolYear: value.schoolYear,
42896
- gradeLevel: value.gradeLevel,
42897
- name: sectionName,
42898
- students: size
42899
- },
42900
- session
42901
- );
42902
- const skip = totalStudentsProcessed;
42903
- const learners = await getLeanerByGradeLevel(
42904
- {
42905
- school: value.school,
42906
- gradeLevel: value.gradeLevel,
42907
- skip,
42908
- limit: size
42909
- },
42910
- session
42911
- );
42912
- if (!learners.length) {
42913
- throw new BadRequestError64(`No learners found for section #${i + 1}.`);
42914
- }
42915
- totalStudentsProcessed += learners.length;
42916
- for (const student of learners) {
42917
- if (!student._id) {
42918
- throw new BadRequestError64("Learner ID is missing.");
42919
- }
42920
- if (!student.learnerInfo.lrn) {
42921
- throw new BadRequestError64("Learner LRN is missing.");
42922
- }
42923
- await assignStudent(
42924
- {
43031
+ cacheKeyOptions.classroom = classroom;
43032
+ }
43033
+ if (type) {
43034
+ query.type = type;
43035
+ cacheKeyOptions.type = type;
43036
+ }
43037
+ const cacheKey = makeCacheKey22(namespace_collection, cacheKeyOptions);
43038
+ logger39.log({
43039
+ level: "info",
43040
+ message: `Cache key for getAll kindergarten routines: ${cacheKey}`
43041
+ });
43042
+ try {
43043
+ const cached = await getCache(cacheKey);
43044
+ if (cached) {
43045
+ logger39.log({
43046
+ level: "info",
43047
+ message: `Cache hit for getAll kindergarten routines: ${cacheKey}`
43048
+ });
43049
+ return cached;
43050
+ }
43051
+ const items = await collection.aggregate([
43052
+ { $match: query },
43053
+ { $sort: sort },
43054
+ { $skip: page * limit },
43055
+ { $limit: limit }
43056
+ ]).toArray();
43057
+ const length = await collection.countDocuments(query);
43058
+ const data = paginate21(items, page, limit, length);
43059
+ setCache(cacheKey, data, 600).then(() => {
43060
+ logger39.log({
43061
+ level: "info",
43062
+ message: `Cache set for getAll kindergarten routines: ${cacheKey}`
43063
+ });
43064
+ }).catch((err) => {
43065
+ logger39.log({
43066
+ level: "error",
43067
+ message: `Failed to set cache for getAll kindergarten routines: ${err.message}`
43068
+ });
43069
+ });
43070
+ return data;
43071
+ } catch (error) {
43072
+ logger39.log({ level: "error", message: `${error}` });
43073
+ throw error;
43074
+ }
43075
+ }
43076
+ async function getById(_id) {
43077
+ try {
43078
+ _id = new ObjectId42(_id);
43079
+ } catch (error) {
43080
+ throw new BadRequestError65(namespace_collection + " Invalid ID.");
43081
+ }
43082
+ const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
43083
+ try {
43084
+ const cached = await getCache(cacheKey);
43085
+ if (cached) {
43086
+ logger39.log({
43087
+ level: "info",
43088
+ message: `Cache hit for getById kindergarten routine: ${cacheKey}`
43089
+ });
43090
+ return cached;
43091
+ }
43092
+ const result = await collection.findOne({
43093
+ _id,
43094
+ deletedAt: { $in: ["", null] }
43095
+ });
43096
+ setCache(cacheKey, result, 300).then(() => {
43097
+ logger39.log({
43098
+ level: "info",
43099
+ message: `Cache set for kindergarten routine by id: ${cacheKey}`
43100
+ });
43101
+ }).catch((err) => {
43102
+ logger39.log({
43103
+ level: "error",
43104
+ message: `Failed to set cache for kindergarten routine by id: ${err.message}`
43105
+ });
43106
+ });
43107
+ return result;
43108
+ } catch (error) {
43109
+ if (error instanceof AppError25) {
43110
+ throw error;
43111
+ } else {
43112
+ throw new InternalServerError21("Failed to get kindergarten routine.");
43113
+ }
43114
+ }
43115
+ }
43116
+ async function countByDomain(domain) {
43117
+ const cacheKey = makeCacheKey22(namespace_collection, {
43118
+ domain,
43119
+ tag: "getByDomain"
43120
+ });
43121
+ try {
43122
+ const cached = await getCache(cacheKey);
43123
+ if (cached) {
43124
+ logger39.log({
43125
+ level: "info",
43126
+ message: `Cache hit for getById kindergarten routine: ${cacheKey}`
43127
+ });
43128
+ return cached;
43129
+ }
43130
+ const result = await collection.countDocuments({
43131
+ domain,
43132
+ status: "active"
43133
+ });
43134
+ setCache(cacheKey, result, 300).then(() => {
43135
+ logger39.log({
43136
+ level: "info",
43137
+ message: `Cache set for kindergarten routine by id: ${cacheKey}`
43138
+ });
43139
+ }).catch((err) => {
43140
+ logger39.log({
43141
+ level: "error",
43142
+ message: `Failed to set cache for kindergarten routine by id: ${err.message}`
43143
+ });
43144
+ });
43145
+ return result;
43146
+ } catch (error) {
43147
+ if (error instanceof AppError25) {
43148
+ throw error;
43149
+ } else {
43150
+ throw new InternalServerError21("Failed to get kindergarten routine.");
43151
+ }
43152
+ }
43153
+ }
43154
+ async function getBySection(section) {
43155
+ try {
43156
+ section = new ObjectId42(section);
43157
+ } catch (error) {
43158
+ throw new BadRequestError65("Invalid section ID.");
43159
+ }
43160
+ const cacheKey = makeCacheKey22(namespace_collection, {
43161
+ section: String(section)
43162
+ });
43163
+ try {
43164
+ const cached = await getCache(cacheKey);
43165
+ if (cached) {
43166
+ logger39.log({
43167
+ level: "info",
43168
+ message: `Cache hit for getBySection kindergarten routine: ${cacheKey}`
43169
+ });
43170
+ return cached;
43171
+ }
43172
+ const result = await collection.find({
43173
+ section,
43174
+ deletedAt: { $in: ["", null] }
43175
+ }).toArray();
43176
+ setCache(cacheKey, result, 300).then(() => {
43177
+ logger39.log({
43178
+ level: "info",
43179
+ message: `Cache set for kindergarten routine by section: ${cacheKey}`
43180
+ });
43181
+ }).catch((err) => {
43182
+ logger39.log({
43183
+ level: "error",
43184
+ message: `Failed to set cache for kindergarten routine by section: ${err.message}`
43185
+ });
43186
+ });
43187
+ return result;
43188
+ } catch (error) {
43189
+ if (error instanceof AppError25) {
43190
+ throw error;
43191
+ } else {
43192
+ throw new InternalServerError21("Failed to get kindergarten routine.");
43193
+ }
43194
+ }
43195
+ }
43196
+ async function updateFieldById({ _id, field, value } = {}, session) {
43197
+ const allowedFields = [
43198
+ "sectionName",
43199
+ "classroomName",
43200
+ "schedule",
43201
+ "blockTimes",
43202
+ "type"
43203
+ ];
43204
+ if (!allowedFields.includes(field)) {
43205
+ throw new BadRequestError65(
43206
+ `Field "${field}" is not allowed to be updated.`
43207
+ );
43208
+ }
43209
+ try {
43210
+ _id = new ObjectId42(_id);
43211
+ } catch (error) {
43212
+ throw new BadRequestError65(namespace_collection + " Invalid ID.");
43213
+ }
43214
+ try {
43215
+ await collection.updateOne(
43216
+ { _id, deletedAt: { $in: ["", null] } },
43217
+ { $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
43218
+ { session }
43219
+ );
43220
+ delCachedData();
43221
+ return `Successfully updated kindergarten routine ${field}.`;
43222
+ } catch (error) {
43223
+ throw new InternalServerError21(
43224
+ `Failed to update kindergarten routine ${field}.`
43225
+ );
43226
+ }
43227
+ }
43228
+ async function updateById(_id, value, session) {
43229
+ const { error } = schemaKindergartenRoutineUpdate.validate(value);
43230
+ if (error) {
43231
+ throw new BadRequestError65(
43232
+ `Invalid kindergarten routine data: ${error.message}`
43233
+ );
43234
+ }
43235
+ try {
43236
+ _id = new ObjectId42(_id);
43237
+ } catch (error2) {
43238
+ throw new BadRequestError65(namespace_collection + " Invalid ID.");
43239
+ }
43240
+ try {
43241
+ await collection.updateOne(
43242
+ { _id },
43243
+ { $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
43244
+ { session }
43245
+ );
43246
+ delCachedData();
43247
+ return `Successfully updated kindergarten routine.`;
43248
+ } catch (error2) {
43249
+ throw new InternalServerError21("Failed to update kindergarten routine.");
43250
+ }
43251
+ }
43252
+ async function deleteById(_id) {
43253
+ try {
43254
+ _id = new ObjectId42(_id);
43255
+ } catch (error) {
43256
+ throw new BadRequestError65(namespace_collection + " Invalid ID.");
43257
+ }
43258
+ try {
43259
+ await collection.updateOne(
43260
+ { _id },
43261
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } }
43262
+ );
43263
+ delCachedData();
43264
+ return "Successfully deleted kindergarten routine.";
43265
+ } catch (error) {
43266
+ throw new InternalServerError21("Failed to delete kindergarten routine.");
43267
+ }
43268
+ }
43269
+ return {
43270
+ createIndexes,
43271
+ add,
43272
+ getAll,
43273
+ getById,
43274
+ countByDomain,
43275
+ getBySection,
43276
+ updateFieldById,
43277
+ updateById,
43278
+ deleteById
43279
+ };
43280
+ }
43281
+
43282
+ // src/resources/kindergarten-routine/kindergarten.routine.controller.ts
43283
+ import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
43284
+ import Joi44 from "joi";
43285
+ function useKindergartenRoutineController() {
43286
+ const {
43287
+ add: _add,
43288
+ getAll: _getAll,
43289
+ getById: _getById,
43290
+ getBySection: _getBySection,
43291
+ updateFieldById: _updateFieldById,
43292
+ deleteById: _deleteById,
43293
+ updateById: _updateById
43294
+ } = useKindergartenRoutineRepo();
43295
+ async function add(req, res, next) {
43296
+ const value = req.body;
43297
+ const { error } = schemaKindergartenRoutine.validate(value);
43298
+ if (error) {
43299
+ next(new BadRequestError66(error.message));
43300
+ return;
43301
+ }
43302
+ try {
43303
+ const data = await _add(value);
43304
+ res.json({
43305
+ message: "Successfully created kinder schedule.",
43306
+ data
43307
+ });
43308
+ return;
43309
+ } catch (error2) {
43310
+ next(error2);
43311
+ }
43312
+ }
43313
+ async function getAll(req, res, next) {
43314
+ const query = req.query;
43315
+ const validation = Joi44.object({
43316
+ page: Joi44.number().min(1).optional().allow("", null),
43317
+ limit: Joi44.number().min(1).optional().allow("", null),
43318
+ search: Joi44.string().optional().allow("", null),
43319
+ status: Joi44.string().optional().allow("", null),
43320
+ school: Joi44.string().hex().optional().allow("", null),
43321
+ section: Joi44.string().hex().optional().allow("", null),
43322
+ classroom: Joi44.string().hex().optional().allow("", null),
43323
+ type: Joi44.string().optional().allow("", null),
43324
+ createdBy: Joi44.string().hex().optional().allow("", null)
43325
+ });
43326
+ const { error } = validation.validate(query);
43327
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
43328
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
43329
+ const search = req.query.search ?? "";
43330
+ const status = req.query.status ?? "active";
43331
+ const school = req.query.school ?? "";
43332
+ const section = req.query.section ?? "";
43333
+ const classroom = req.query.classroom ?? "";
43334
+ const type = req.query.type ?? "";
43335
+ const createdBy = req.query.createdBy ?? "";
43336
+ const isPageNumber = isFinite(page);
43337
+ if (!isPageNumber) {
43338
+ next(new BadRequestError66("Invalid page number."));
43339
+ return;
43340
+ }
43341
+ const isLimitNumber = isFinite(limit);
43342
+ if (!isLimitNumber) {
43343
+ next(new BadRequestError66("Invalid limit number."));
43344
+ return;
43345
+ }
43346
+ if (error) {
43347
+ next(new BadRequestError66(error.message));
43348
+ return;
43349
+ }
43350
+ try {
43351
+ const data = await _getAll({
43352
+ page,
43353
+ limit,
43354
+ search,
43355
+ status,
43356
+ school,
43357
+ section,
43358
+ classroom,
43359
+ type,
43360
+ createdBy: createdBy || void 0
43361
+ });
43362
+ res.json(data);
43363
+ return;
43364
+ } catch (error2) {
43365
+ next(error2);
43366
+ }
43367
+ }
43368
+ async function getById(req, res, next) {
43369
+ const id = req.params.id;
43370
+ const validation = Joi44.object({
43371
+ id: Joi44.string().hex().required()
43372
+ });
43373
+ const { error } = validation.validate({ id });
43374
+ if (error) {
43375
+ next(new BadRequestError66(error.message));
43376
+ return;
43377
+ }
43378
+ try {
43379
+ const data = await _getById(id);
43380
+ res.json({
43381
+ message: "Successfully retrieved kinder schedule.",
43382
+ data
43383
+ });
43384
+ return;
43385
+ } catch (error2) {
43386
+ next(error2);
43387
+ }
43388
+ }
43389
+ async function getBySection(req, res, next) {
43390
+ const section = req.params.section;
43391
+ const validation = Joi44.object({
43392
+ section: Joi44.string().hex().required()
43393
+ });
43394
+ const { error } = validation.validate({ section });
43395
+ if (error) {
43396
+ next(new BadRequestError66(error.message));
43397
+ return;
43398
+ }
43399
+ try {
43400
+ const data = await _getBySection(section);
43401
+ res.json({
43402
+ message: "Successfully retrieved kinder schedules.",
43403
+ data
43404
+ });
43405
+ return;
43406
+ } catch (error2) {
43407
+ next(error2);
43408
+ }
43409
+ }
43410
+ async function updateField(req, res, next) {
43411
+ const _id = req.params.id;
43412
+ const { field, value } = req.body;
43413
+ const validation = Joi44.object({
43414
+ _id: Joi44.string().hex().required(),
43415
+ field: Joi44.string().valid("sectionName", "classroomName", "schedule", "blockTimes", "type").required(),
43416
+ value: Joi44.alternatives().try(Joi44.string(), Joi44.array(), Joi44.object()).required()
43417
+ });
43418
+ const { error } = validation.validate({ _id, field, value });
43419
+ if (error) {
43420
+ next(new BadRequestError66(error.message));
43421
+ return;
43422
+ }
43423
+ try {
43424
+ const message = await _updateFieldById({ _id, field, value });
43425
+ res.json({ message });
43426
+ return;
43427
+ } catch (error2) {
43428
+ next(error2);
43429
+ }
43430
+ }
43431
+ async function updateById(req, res, next) {
43432
+ const _id = req.params.id;
43433
+ const payload = req.body;
43434
+ const { error: errorId } = Joi44.string().hex().required().validate(_id);
43435
+ if (errorId) {
43436
+ next(new BadRequestError66(errorId.message));
43437
+ return;
43438
+ }
43439
+ const { error } = schemaKindergartenRoutineUpdate.validate(payload);
43440
+ if (error) {
43441
+ next(new BadRequestError66(error.message));
43442
+ return;
43443
+ }
43444
+ try {
43445
+ const message = await _updateById(_id, payload);
43446
+ res.json({ message });
43447
+ return;
43448
+ } catch (error2) {
43449
+ next(error2);
43450
+ }
43451
+ }
43452
+ async function deleteById(req, res, next) {
43453
+ const _id = req.params.id;
43454
+ const validation = Joi44.object({
43455
+ _id: Joi44.string().hex().required()
43456
+ });
43457
+ const { error } = validation.validate({ _id });
43458
+ if (error) {
43459
+ next(new BadRequestError66(error.message));
43460
+ return;
43461
+ }
43462
+ try {
43463
+ const message = await _deleteById(_id);
43464
+ res.json({ message });
43465
+ return;
43466
+ } catch (error2) {
43467
+ next(error2);
43468
+ }
43469
+ }
43470
+ return {
43471
+ add,
43472
+ getAll,
43473
+ getById,
43474
+ getBySection,
43475
+ updateField,
43476
+ updateById,
43477
+ deleteById
43478
+ };
43479
+ }
43480
+
43481
+ // src/resources/section/section.service.ts
43482
+ function useSectionService() {
43483
+ const { getCountByGradeLevel, getByGradeLevel: getLeanerByGradeLevel } = useLearnerRepo();
43484
+ const { getByGradeLevel } = useGradeLevelRepo();
43485
+ const { add: createSection } = useSectionRepo();
43486
+ const { add: assignStudent } = useSectionStudentRepo();
43487
+ const { getAll: getAllCurriculumSubjects } = useSubjectRepo();
43488
+ const { add: addSectionSubject } = useSectionSubjectRepo();
43489
+ const { getById: getSchoolById } = useSchoolRepo();
43490
+ const { getAll: getAllPersonnel } = usePersonnelRepo();
43491
+ const { add: addTeachingLoad } = useTeachingLoadRepo();
43492
+ const { getById: getKindergartenRoutineById, add: addKindergartenRoutine } = useKindergartenRoutineRepo();
43493
+ function distributeStudents(total, minPer, maxPer) {
43494
+ if (total <= 0)
43495
+ return [];
43496
+ if (minPer <= 0 || maxPer <= 0)
43497
+ return [];
43498
+ if (minPer > maxPer) {
43499
+ throw new BadRequestError67(
43500
+ "Minimum students per section cannot be greater than maximum."
43501
+ );
43502
+ }
43503
+ const minSections = Math.ceil(total / maxPer);
43504
+ const maxSections = Math.floor(total / minPer);
43505
+ let sectionCount;
43506
+ if (minSections <= maxSections) {
43507
+ sectionCount = minSections;
43508
+ } else {
43509
+ sectionCount = minSections;
43510
+ }
43511
+ const base = Math.floor(total / sectionCount);
43512
+ const extra = total % sectionCount;
43513
+ const sizes = new Array(sectionCount).fill(base);
43514
+ for (let i = 0; i < extra; i++) {
43515
+ sizes[i] += 1;
43516
+ }
43517
+ for (const size of sizes) {
43518
+ if (size > maxPer) {
43519
+ throw new BadRequestError67(
43520
+ `Generated section exceeds max limit of ${maxPer}.`
43521
+ );
43522
+ }
43523
+ }
43524
+ return sizes;
43525
+ }
43526
+ async function generateSections(value) {
43527
+ const { error } = schemaGenerateSections.validate(value);
43528
+ if (error) {
43529
+ throw new BadRequestError67(
43530
+ `Invalid section generation data: ${error.message}`
43531
+ );
43532
+ }
43533
+ const session = useAtlas31.getClient()?.startSession();
43534
+ if (!session) {
43535
+ throw new Error("Unable to start database session.");
43536
+ }
43537
+ try {
43538
+ await session.startTransaction();
43539
+ const isKindergarten = value.gradeLevel.toLowerCase() === "kindergarten";
43540
+ let kindergartenRoutine = null;
43541
+ if (isKindergarten) {
43542
+ kindergartenRoutine = await getKindergartenRoutineById(
43543
+ value.routine ?? ""
43544
+ );
43545
+ if (!kindergartenRoutine) {
43546
+ throw new BadRequestError67("Kindergarten routine not found.");
43547
+ }
43548
+ }
43549
+ const studentCount = await getCountByGradeLevel(
43550
+ {
43551
+ school: value.school,
43552
+ schoolYear: value.schoolYear,
43553
+ gradeLevel: value.gradeLevel,
43554
+ specialProgram: value.specialProgram
43555
+ },
43556
+ session
43557
+ );
43558
+ if (studentCount === 0) {
43559
+ throw new BadRequestError67("No learners found for this grade level.");
43560
+ }
43561
+ const gradeLevelData = await getByGradeLevel(
43562
+ {
43563
+ school: value.school,
43564
+ gradeLevel: value.gradeLevel
43565
+ },
43566
+ session
43567
+ );
43568
+ if (!gradeLevelData) {
43569
+ throw new BadRequestError67("Grade level not found.");
43570
+ }
43571
+ const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
43572
+ const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
43573
+ const sectionsNeeded = Math.ceil(studentCount / minPerSection);
43574
+ if (sectionsNeeded > value.set.length) {
43575
+ throw new BadRequestError67(
43576
+ "Insufficient number of section names in set[]."
43577
+ );
43578
+ }
43579
+ const sectionSizes = distributeStudents(
43580
+ studentCount,
43581
+ minPerSection,
43582
+ maxPerSection
43583
+ );
43584
+ if (sectionSizes.length === 0) {
43585
+ throw new BadRequestError67("Unable to compute section sizes.");
43586
+ }
43587
+ const schoolData = await getSchoolById(value.school);
43588
+ if (!schoolData) {
43589
+ throw new BadRequestError67("School not found.");
43590
+ }
43591
+ let totalStudentsProcessed = 0;
43592
+ for (let i = 0; i < sectionSizes.length; i++) {
43593
+ const size = sectionSizes[i];
43594
+ const sectionName = value.set[i];
43595
+ const section = await createSection(
43596
+ {
43597
+ school: value.school,
43598
+ schoolYear: value.schoolYear,
43599
+ gradeLevel: value.gradeLevel,
43600
+ name: sectionName,
43601
+ students: size
43602
+ },
43603
+ session
43604
+ );
43605
+ const skip = totalStudentsProcessed;
43606
+ const learners = await getLeanerByGradeLevel(
43607
+ {
43608
+ school: value.school,
43609
+ gradeLevel: value.gradeLevel,
43610
+ skip,
43611
+ limit: size
43612
+ },
43613
+ session
43614
+ );
43615
+ if (!learners.length) {
43616
+ throw new BadRequestError67(`No learners found for section #${i + 1}.`);
43617
+ }
43618
+ totalStudentsProcessed += learners.length;
43619
+ for (const student of learners) {
43620
+ if (!student._id) {
43621
+ throw new BadRequestError67("Learner ID is missing.");
43622
+ }
43623
+ if (!student.learnerInfo.lrn) {
43624
+ throw new BadRequestError67("Learner LRN is missing.");
43625
+ }
43626
+ await assignStudent(
43627
+ {
42925
43628
  section: section.toString(),
42926
43629
  lrn: student.learnerInfo.lrn,
42927
43630
  student: student._id?.toString(),
@@ -42931,436 +43634,1393 @@ function useSectionService() {
42931
43634
  gradeLevel: value.gradeLevel,
42932
43635
  educationLevel: gradeLevelData.educationLevel,
42933
43636
  schoolYear: value.schoolYear,
42934
- status: "active"
43637
+ status: "active"
43638
+ },
43639
+ session
43640
+ );
43641
+ }
43642
+ const curriculumSubjects = await getAllCurriculumSubjects({
43643
+ schoolYear: Number(value.schoolYear),
43644
+ gradeLevel: value.gradeLevel,
43645
+ limit: 20
43646
+ });
43647
+ for (const curriculumSubject of curriculumSubjects.items) {
43648
+ await addSectionSubject(
43649
+ {
43650
+ curriculum: curriculumSubject.curriculum.toString(),
43651
+ school: value.school,
43652
+ schoolName: schoolData.name,
43653
+ gradeLevel: value.gradeLevel,
43654
+ educationLevel: gradeLevelData.educationLevel,
43655
+ schoolYear: value.schoolYear,
43656
+ section: section.toString(),
43657
+ sectionName,
43658
+ subjectCode: curriculumSubject.subjectCode,
43659
+ subjectName: curriculumSubject.subjectName,
43660
+ teacher: "",
43661
+ teacherName: "",
43662
+ schedule: "",
43663
+ daysOfWeek: [],
43664
+ classroom: "",
43665
+ classroomName: "",
43666
+ sessionDuration: curriculumSubject.sessionDuration,
43667
+ sessionFrequency: curriculumSubject.sessionFrequency,
43668
+ status: "draft"
43669
+ },
43670
+ session
43671
+ );
43672
+ }
43673
+ if (isKindergarten && kindergartenRoutine) {
43674
+ kindergartenRoutine.section = section;
43675
+ kindergartenRoutine.sectionName = sectionName;
43676
+ kindergartenRoutine.type = "actual";
43677
+ await addKindergartenRoutine(kindergartenRoutine, session);
43678
+ }
43679
+ }
43680
+ let pageTeacher = 1;
43681
+ let pagesTeachers = 1;
43682
+ let teachers = [];
43683
+ do {
43684
+ const teachersData = await getAllPersonnel({
43685
+ school: value.school,
43686
+ limit: 100
43687
+ });
43688
+ pagesTeachers = teachersData.pages;
43689
+ teachers.push(...teachersData.items);
43690
+ pageTeacher++;
43691
+ } while (pageTeacher < pagesTeachers);
43692
+ if (!teachers.length) {
43693
+ throw new BadRequestError67(
43694
+ "Could not proceed, no teaching personnel found."
43695
+ );
43696
+ }
43697
+ if (teachers.length) {
43698
+ for (let index = 0; index < teachers.length; index++) {
43699
+ const teacher = teachers[index];
43700
+ if (!teacher._id) {
43701
+ throw new BadRequestError67("Teacher ID is missing.");
43702
+ }
43703
+ await addTeachingLoad(
43704
+ {
43705
+ school: value.school,
43706
+ schoolName: schoolData.name,
43707
+ schoolYear: value.schoolYear,
43708
+ teacher: teacher._id.toString(),
43709
+ teacherName: `${teacher.firstName} ${teacher.lastName}`,
43710
+ status: "draft"
42935
43711
  },
42936
43712
  session
42937
43713
  );
42938
43714
  }
42939
- const curriculumSubjects = await getAllCurriculumSubjects({
42940
- schoolYear: Number(value.schoolYear),
42941
- gradeLevel: value.gradeLevel,
42942
- limit: 20
43715
+ }
43716
+ await session.commitTransaction();
43717
+ return "Sections generated successfully.";
43718
+ } catch (error2) {
43719
+ await session.abortTransaction();
43720
+ if (error2 instanceof AppError26) {
43721
+ throw error2;
43722
+ } else {
43723
+ throw new InternalServerError22("Failed to generate sections.");
43724
+ }
43725
+ } finally {
43726
+ await session?.endSession();
43727
+ }
43728
+ }
43729
+ async function generateSectionPreview(value) {
43730
+ const { error } = schemaGenerateSections.validate(value);
43731
+ if (error) {
43732
+ throw new BadRequestError67(
43733
+ `Invalid section generation data: ${error.message}`
43734
+ );
43735
+ }
43736
+ try {
43737
+ const studentCount = await getCountByGradeLevel({
43738
+ school: value.school,
43739
+ schoolYear: value.schoolYear,
43740
+ gradeLevel: value.gradeLevel,
43741
+ specialProgram: value.specialProgram
43742
+ });
43743
+ if (studentCount === 0) {
43744
+ throw new BadRequestError67("No learners found for this grade level.");
43745
+ }
43746
+ const gradeLevelData = await getByGradeLevel({
43747
+ school: value.school,
43748
+ gradeLevel: value.gradeLevel
43749
+ });
43750
+ if (!gradeLevelData) {
43751
+ throw new BadRequestError67("Grade level not found.");
43752
+ }
43753
+ const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
43754
+ const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
43755
+ const sectionsNeeded = Math.ceil(studentCount / minPerSection);
43756
+ if (sectionsNeeded > value.set.length) {
43757
+ throw new BadRequestError67(
43758
+ "Insufficient number of section names in set[]."
43759
+ );
43760
+ }
43761
+ const sectionSizes = distributeStudents(
43762
+ studentCount,
43763
+ minPerSection,
43764
+ maxPerSection
43765
+ );
43766
+ if (sectionSizes.length === 0) {
43767
+ throw new BadRequestError67("Unable to compute section sizes.");
43768
+ }
43769
+ const sections = sectionSizes.map((size, index) => ({
43770
+ name: value.set[index],
43771
+ value: size
43772
+ }));
43773
+ return {
43774
+ totalSectionsGenerated: sectionSizes.length,
43775
+ totalStudentsAssigned: studentCount,
43776
+ sections
43777
+ };
43778
+ } catch (error2) {
43779
+ if (error2 instanceof AppError26) {
43780
+ throw error2;
43781
+ } else {
43782
+ throw new InternalServerError22("Failed to generate section preview.");
43783
+ }
43784
+ }
43785
+ }
43786
+ return { generateSections, generateSectionPreview };
43787
+ }
43788
+
43789
+ // src/resources/section/section.controller.ts
43790
+ function useSectionController() {
43791
+ const {
43792
+ add: _add,
43793
+ getAll: _getAll,
43794
+ getById: _getById,
43795
+ getByName: _getByName,
43796
+ getBySchool: _getBySchool,
43797
+ updateFieldById: _updateFieldById,
43798
+ addStudentToSection: _addStudentToSection,
43799
+ removeStudentFromSection: _removeStudentFromSection,
43800
+ deleteById: _deleteById
43801
+ } = useSectionRepo();
43802
+ const {
43803
+ generateSections: _generateSections,
43804
+ generateSectionPreview: _generateSectionPreview
43805
+ } = useSectionService();
43806
+ async function add(req, res, next) {
43807
+ const value = req.body;
43808
+ const { error } = schemaSection.validate(value);
43809
+ if (error) {
43810
+ next(new BadRequestError68(error.message));
43811
+ return;
43812
+ }
43813
+ try {
43814
+ const data = await _add(value);
43815
+ res.json({
43816
+ message: "Successfully created section.",
43817
+ data
43818
+ });
43819
+ return;
43820
+ } catch (error2) {
43821
+ next(error2);
43822
+ }
43823
+ }
43824
+ async function generateSections(req, res, next) {
43825
+ const value = req.body;
43826
+ const { error } = schemaGenerateSections.validate(value);
43827
+ if (error) {
43828
+ next(new BadRequestError68(error.message));
43829
+ return;
43830
+ }
43831
+ try {
43832
+ const data = await _generateSections(value);
43833
+ res.json({
43834
+ message: "Successfully created section.",
43835
+ data
43836
+ });
43837
+ return;
43838
+ } catch (error2) {
43839
+ next(error2);
43840
+ }
43841
+ }
43842
+ async function generateSectionPreview(req, res, next) {
43843
+ const value = req.body;
43844
+ const { error } = schemaGenerateSections.validate(value);
43845
+ if (error) {
43846
+ next(new BadRequestError68(error.message));
43847
+ return;
43848
+ }
43849
+ try {
43850
+ const data = await _generateSectionPreview(value);
43851
+ res.json(data);
43852
+ return;
43853
+ } catch (error2) {
43854
+ next(error2);
43855
+ }
43856
+ }
43857
+ async function getAll(req, res, next) {
43858
+ const query = req.query;
43859
+ const validation = Joi45.object({
43860
+ page: Joi45.number().min(1).optional().allow("", null),
43861
+ limit: Joi45.number().min(1).optional().allow("", null),
43862
+ search: Joi45.string().optional().allow("", null),
43863
+ status: Joi45.string().optional().allow("", null),
43864
+ school: Joi45.string().hex().optional().allow("", null),
43865
+ schoolYear: Joi45.string().optional().allow("", null),
43866
+ gradeLevel: Joi45.string().optional().allow("", null)
43867
+ });
43868
+ const { error } = validation.validate(query);
43869
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
43870
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
43871
+ const search = req.query.search ?? "";
43872
+ const status = req.query.status ?? "active";
43873
+ const school = req.query.school ?? "";
43874
+ const schoolYear = req.query.schoolYear ?? "";
43875
+ const gradeLevel = req.query.gradeLevel ?? "";
43876
+ const isPageNumber = isFinite(page);
43877
+ if (!isPageNumber) {
43878
+ next(new BadRequestError68("Invalid page number."));
43879
+ return;
43880
+ }
43881
+ const isLimitNumber = isFinite(limit);
43882
+ if (!isLimitNumber) {
43883
+ next(new BadRequestError68("Invalid limit number."));
43884
+ return;
43885
+ }
43886
+ if (error) {
43887
+ next(new BadRequestError68(error.message));
43888
+ return;
43889
+ }
43890
+ try {
43891
+ const data = await _getAll({
43892
+ page,
43893
+ limit,
43894
+ search,
43895
+ status,
43896
+ school,
43897
+ schoolYear,
43898
+ gradeLevel
43899
+ });
43900
+ res.json(data);
43901
+ return;
43902
+ } catch (error2) {
43903
+ next(error2);
43904
+ }
43905
+ }
43906
+ async function getById(req, res, next) {
43907
+ const id = req.params.id;
43908
+ const validation = Joi45.object({
43909
+ id: Joi45.string().hex().required()
43910
+ });
43911
+ const { error } = validation.validate({ id });
43912
+ if (error) {
43913
+ next(new BadRequestError68(error.message));
43914
+ return;
43915
+ }
43916
+ try {
43917
+ const data = await _getById(id);
43918
+ res.json(data);
43919
+ return;
43920
+ } catch (error2) {
43921
+ next(error2);
43922
+ }
43923
+ }
43924
+ async function getByName(req, res, next) {
43925
+ const name = req.params.name;
43926
+ const validation = Joi45.object({
43927
+ name: Joi45.string().required()
43928
+ });
43929
+ const { error } = validation.validate({ name });
43930
+ if (error) {
43931
+ next(new BadRequestError68(error.message));
43932
+ return;
43933
+ }
43934
+ try {
43935
+ const data = await _getByName(name);
43936
+ res.json({
43937
+ message: "Successfully retrieved section.",
43938
+ data
43939
+ });
43940
+ return;
43941
+ } catch (error2) {
43942
+ next(error2);
43943
+ }
43944
+ }
43945
+ async function getBySchool(req, res, next) {
43946
+ const school = req.params.school;
43947
+ const validation = Joi45.object({
43948
+ school: Joi45.string().hex().required()
43949
+ });
43950
+ const { error } = validation.validate({ school });
43951
+ if (error) {
43952
+ next(new BadRequestError68(error.message));
43953
+ return;
43954
+ }
43955
+ try {
43956
+ const data = await _getBySchool(school);
43957
+ res.json({
43958
+ message: "Successfully retrieved sections.",
43959
+ data
43960
+ });
43961
+ return;
43962
+ } catch (error2) {
43963
+ next(error2);
43964
+ }
43965
+ }
43966
+ async function updateField(req, res, next) {
43967
+ const _id = req.params.id;
43968
+ const { field, value } = req.body;
43969
+ const validation = Joi45.object({
43970
+ _id: Joi45.string().hex().required(),
43971
+ field: Joi45.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
43972
+ value: Joi45.string().required()
43973
+ });
43974
+ const { error } = validation.validate({ _id, field, value });
43975
+ if (error) {
43976
+ next(new BadRequestError68(error.message));
43977
+ return;
43978
+ }
43979
+ try {
43980
+ const message = await _updateFieldById({ _id, field, value });
43981
+ res.json({ message });
43982
+ return;
43983
+ } catch (error2) {
43984
+ next(error2);
43985
+ }
43986
+ }
43987
+ async function addStudent(req, res, next) {
43988
+ const _id = req.params.id;
43989
+ const { studentId } = req.body;
43990
+ const validation = Joi45.object({
43991
+ _id: Joi45.string().hex().required(),
43992
+ studentId: Joi45.string().required()
43993
+ });
43994
+ const { error } = validation.validate({ _id, studentId });
43995
+ if (error) {
43996
+ next(new BadRequestError68(error.message));
43997
+ return;
43998
+ }
43999
+ try {
44000
+ const message = await _addStudentToSection(_id, studentId);
44001
+ res.json({ message });
44002
+ return;
44003
+ } catch (error2) {
44004
+ next(error2);
44005
+ }
44006
+ }
44007
+ async function removeStudent(req, res, next) {
44008
+ const _id = req.params.id;
44009
+ const { studentId } = req.body;
44010
+ const validation = Joi45.object({
44011
+ _id: Joi45.string().hex().required(),
44012
+ studentId: Joi45.string().required()
44013
+ });
44014
+ const { error } = validation.validate({ _id, studentId });
44015
+ if (error) {
44016
+ next(new BadRequestError68(error.message));
44017
+ return;
44018
+ }
44019
+ try {
44020
+ const message = await _removeStudentFromSection(_id, studentId);
44021
+ res.json({ message });
44022
+ return;
44023
+ } catch (error2) {
44024
+ next(error2);
44025
+ }
44026
+ }
44027
+ async function deleteById(req, res, next) {
44028
+ const _id = req.params.id;
44029
+ const validation = Joi45.object({
44030
+ _id: Joi45.string().hex().required()
44031
+ });
44032
+ const { error } = validation.validate({ _id });
44033
+ if (error) {
44034
+ next(new BadRequestError68(error.message));
44035
+ return;
44036
+ }
44037
+ try {
44038
+ const message = await _deleteById(_id);
44039
+ res.json({ message });
44040
+ return;
44041
+ } catch (error2) {
44042
+ next(error2);
44043
+ }
44044
+ }
44045
+ return {
44046
+ add,
44047
+ generateSections,
44048
+ generateSectionPreview,
44049
+ getAll,
44050
+ getById,
44051
+ getByName,
44052
+ getBySchool,
44053
+ updateField,
44054
+ addStudent,
44055
+ removeStudent,
44056
+ deleteById
44057
+ };
44058
+ }
44059
+
44060
+ // src/resources/section-student/section.student.controller.ts
44061
+ import { BadRequestError as BadRequestError69 } from "@eeplatform/nodejs-utils";
44062
+ import Joi46 from "joi";
44063
+ function useSectionStudentController() {
44064
+ const { add: _add, getAll: _getAll } = useSectionStudentRepo();
44065
+ async function add(req, res, next) {
44066
+ const value = req.body;
44067
+ const { error } = schemaSectionStudent.validate(value);
44068
+ if (error) {
44069
+ next(new BadRequestError69(error.message));
44070
+ return;
44071
+ }
44072
+ try {
44073
+ const data = await _add(value);
44074
+ res.json({
44075
+ message: "Successfully created section student.",
44076
+ data
44077
+ });
44078
+ return;
44079
+ } catch (error2) {
44080
+ next(error2);
44081
+ }
44082
+ }
44083
+ async function getAll(req, res, next) {
44084
+ const query = req.query;
44085
+ const validation = Joi46.object({
44086
+ page: Joi46.number().min(1).optional().allow("", null),
44087
+ limit: Joi46.number().min(1).optional().allow("", null),
44088
+ search: Joi46.string().optional().allow("", null),
44089
+ status: Joi46.string().optional().allow("", null),
44090
+ school: Joi46.string().optional().allow("", null),
44091
+ gradeLevel: Joi46.string().optional().allow("", null),
44092
+ section: Joi46.string().optional().allow("", null),
44093
+ schoolYear: Joi46.string().optional().allow("", null)
44094
+ });
44095
+ const { error } = validation.validate(query);
44096
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
44097
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
44098
+ const search = req.query.search ?? "";
44099
+ const status = req.query.status ?? "active";
44100
+ const school = req.query.school ?? "";
44101
+ const gradeLevel = req.query.gradeLevel ?? "";
44102
+ const section = req.query.section ?? "";
44103
+ const schoolYear = req.query.schoolYear ?? "";
44104
+ const isPageNumber = isFinite(page);
44105
+ if (!isPageNumber) {
44106
+ next(new BadRequestError69("Invalid page number."));
44107
+ return;
44108
+ }
44109
+ const isLimitNumber = isFinite(limit);
44110
+ if (!isLimitNumber) {
44111
+ next(new BadRequestError69("Invalid limit number."));
44112
+ return;
44113
+ }
44114
+ if (error) {
44115
+ next(new BadRequestError69(error.message));
44116
+ return;
44117
+ }
44118
+ try {
44119
+ const data = await _getAll({
44120
+ page,
44121
+ limit,
44122
+ search,
44123
+ status,
44124
+ school,
44125
+ gradeLevel,
44126
+ section,
44127
+ schoolYear
44128
+ });
44129
+ res.json(data);
44130
+ return;
44131
+ } catch (error2) {
44132
+ next(error2);
44133
+ }
44134
+ }
44135
+ return {
44136
+ add,
44137
+ getAll
44138
+ };
44139
+ }
44140
+
44141
+ // src/resources/building/building.model.ts
44142
+ import { BadRequestError as BadRequestError70, logger as logger40 } from "@eeplatform/nodejs-utils";
44143
+ import Joi47 from "joi";
44144
+ import { ObjectId as ObjectId43 } from "mongodb";
44145
+ var schemaBuilding = Joi47.object({
44146
+ _id: Joi47.string().hex().optional(),
44147
+ school: Joi47.string().hex().required(),
44148
+ serial: Joi47.string().optional().allow("", null),
44149
+ name: Joi47.string().required(),
44150
+ levels: Joi47.number().integer().min(1).required(),
44151
+ createdAt: Joi47.date().optional().allow("", null),
44152
+ updatedAt: Joi47.date().optional().allow("", null),
44153
+ deletedAt: Joi47.date().optional().allow("", null),
44154
+ status: Joi47.string().optional().allow("", null)
44155
+ });
44156
+ var schemaBuildingUnit = Joi47.object({
44157
+ _id: Joi47.string().hex().optional(),
44158
+ school: Joi47.string().hex().required(),
44159
+ name: Joi47.string().optional().allow("", null),
44160
+ building: Joi47.string().hex().required(),
44161
+ buildingName: Joi47.string().optional().allow("", null),
44162
+ level: Joi47.number().integer().min(1).required(),
44163
+ category: Joi47.string().required(),
44164
+ type: Joi47.string().required(),
44165
+ seating_capacity: Joi47.number().integer().min(0).required(),
44166
+ standing_capacity: Joi47.number().integer().min(0).required(),
44167
+ description: Joi47.string().optional().allow("", null),
44168
+ unit_of_measurement: Joi47.string().valid("sqm").required(),
44169
+ area: Joi47.number().positive().required(),
44170
+ status: Joi47.string().optional().allow("", null)
44171
+ });
44172
+ var schemaUpdateOptions = Joi47.object({
44173
+ name: Joi47.string().optional().allow("", null),
44174
+ building: Joi47.string().hex().optional().allow("", null),
44175
+ buildingName: Joi47.string().optional().allow("", null),
44176
+ level: Joi47.number().integer().min(1).optional().allow("", null),
44177
+ category: Joi47.string().optional().allow("", null),
44178
+ type: Joi47.string().optional().allow("", null),
44179
+ seating_capacity: Joi47.number().integer().min(0).optional().allow("", null),
44180
+ standing_capacity: Joi47.number().integer().min(0).optional().allow("", null),
44181
+ area: Joi47.number().positive().optional().allow("", null)
44182
+ });
44183
+ function MBuilding(value) {
44184
+ const { error } = schemaBuilding.validate(value);
44185
+ if (error) {
44186
+ logger40.info(`Building Model: ${error.message}`);
44187
+ throw new BadRequestError70(error.message);
44188
+ }
44189
+ if (value._id && typeof value._id === "string") {
44190
+ try {
44191
+ value._id = new ObjectId43(value._id);
44192
+ } catch (error2) {
44193
+ throw new BadRequestError70("Invalid _id format");
44194
+ }
44195
+ }
44196
+ try {
44197
+ value.school = new ObjectId43(value.school);
44198
+ } catch (error2) {
44199
+ throw new BadRequestError70("Invalid school format");
44200
+ }
44201
+ return {
44202
+ _id: value._id ?? void 0,
44203
+ school: value.school,
44204
+ serial: value.serial ?? "",
44205
+ name: value.name ?? "",
44206
+ levels: value.levels ?? 0,
44207
+ status: value.status ?? "active",
44208
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
44209
+ updatedAt: value.updatedAt ?? "",
44210
+ deletedAt: value.deletedAt ?? ""
44211
+ };
44212
+ }
44213
+ function MBuildingUnit(value) {
44214
+ const { error } = schemaBuildingUnit.validate(value);
44215
+ if (error) {
44216
+ logger40.info(`Building Unit Model: ${error.message}`);
44217
+ throw new BadRequestError70(error.message);
44218
+ }
44219
+ if (value._id && typeof value._id === "string") {
44220
+ try {
44221
+ value._id = new ObjectId43(value._id);
44222
+ } catch (error2) {
44223
+ throw new BadRequestError70("Invalid ID");
44224
+ }
44225
+ }
44226
+ try {
44227
+ value.school = new ObjectId43(value.school);
44228
+ } catch (error2) {
44229
+ throw new BadRequestError70("Invalid school ID");
44230
+ }
44231
+ try {
44232
+ value.building = new ObjectId43(value.building);
44233
+ } catch (error2) {
44234
+ throw new BadRequestError70("Invalid building ID");
44235
+ }
44236
+ return {
44237
+ _id: value._id ?? void 0,
44238
+ school: value.school,
44239
+ name: value.name ?? "",
44240
+ building: value.building,
44241
+ buildingName: value.buildingName ?? "",
44242
+ level: value.level ?? 0,
44243
+ category: value.category ?? "",
44244
+ type: value.type ?? "",
44245
+ seating_capacity: value.seating_capacity ?? 0,
44246
+ standing_capacity: value.standing_capacity ?? 0,
44247
+ description: value.description ?? "",
44248
+ unit_of_measurement: value.unit_of_measurement ?? "sqm",
44249
+ area: value.area ?? 0,
44250
+ status: value.status ?? "active",
44251
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
44252
+ updatedAt: value.updatedAt ?? "",
44253
+ deletedAt: value.deletedAt ?? ""
44254
+ };
44255
+ }
44256
+
44257
+ // src/resources/building/building.repository.ts
44258
+ import {
44259
+ AppError as AppError27,
44260
+ BadRequestError as BadRequestError71,
44261
+ InternalServerError as InternalServerError23,
44262
+ logger as logger41,
44263
+ makeCacheKey as makeCacheKey23,
44264
+ paginate as paginate22,
44265
+ useAtlas as useAtlas32,
44266
+ useCache as useCache23
44267
+ } from "@eeplatform/nodejs-utils";
44268
+ import { ObjectId as ObjectId44 } from "mongodb";
44269
+ function useBuildingRepo() {
44270
+ const db = useAtlas32.getDb();
44271
+ if (!db) {
44272
+ throw new Error("Unable to connect to server.");
44273
+ }
44274
+ const namespace_collection = "deped.buildings";
44275
+ const collection = db.collection(namespace_collection);
44276
+ const { getCache, setCache, delNamespace } = useCache23(namespace_collection);
44277
+ async function createIndexes() {
44278
+ try {
44279
+ await collection.createIndexes([
44280
+ { key: { name: 1 }, unique: true, name: "unique_name_index" },
44281
+ { key: { school: 1 } },
44282
+ { key: { status: 1 } }
44283
+ ]);
44284
+ } catch (error) {
44285
+ throw new Error("Failed to create index on buildings.");
44286
+ }
44287
+ }
44288
+ async function add(value, session) {
44289
+ try {
44290
+ value = MBuilding(value);
44291
+ const res = await collection.insertOne(value, { session });
44292
+ delCachedData();
44293
+ return res.insertedId;
44294
+ } catch (error) {
44295
+ logger41.log({
44296
+ level: "error",
44297
+ message: error.message
44298
+ });
44299
+ if (error instanceof AppError27) {
44300
+ throw error;
44301
+ } else {
44302
+ const isDuplicated = error.message.includes("duplicate");
44303
+ if (isDuplicated) {
44304
+ throw new BadRequestError71("Building already exists.");
44305
+ }
44306
+ throw new Error("Failed to create building.");
44307
+ }
44308
+ }
44309
+ }
44310
+ async function updateById(_id, value, session) {
44311
+ try {
44312
+ _id = new ObjectId44(_id);
44313
+ } catch (error) {
44314
+ throw new BadRequestError71(namespace_collection + " Invalid ID.");
44315
+ }
44316
+ try {
44317
+ const res = await collection.updateOne(
44318
+ { _id },
44319
+ { $set: value },
44320
+ { session }
44321
+ );
44322
+ delCachedData();
44323
+ return res;
44324
+ } catch (error) {
44325
+ logger41.log({
44326
+ level: "error",
44327
+ message: error.message
44328
+ });
44329
+ if (error instanceof AppError27) {
44330
+ throw error;
44331
+ } else {
44332
+ throw new Error("Failed to update building.");
44333
+ }
44334
+ }
44335
+ }
44336
+ async function getAll({
44337
+ search = "",
44338
+ page = 1,
44339
+ limit = 10,
44340
+ sort = {},
44341
+ school = "",
44342
+ status = "active"
44343
+ } = {}) {
44344
+ page = page > 0 ? page - 1 : 0;
44345
+ const query = {
44346
+ status
44347
+ };
44348
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
44349
+ if (search) {
44350
+ query.$text = { $search: search };
44351
+ }
44352
+ if (school) {
44353
+ try {
44354
+ query.school = new ObjectId44(school);
44355
+ } catch (error) {
44356
+ throw new BadRequestError71("Invalid school ID.");
44357
+ }
44358
+ }
44359
+ const cacheParams = {
44360
+ page,
44361
+ limit,
44362
+ sort: JSON.stringify(sort)
44363
+ };
44364
+ if (search)
44365
+ cacheParams.search = search;
44366
+ if (school)
44367
+ cacheParams.school = school;
44368
+ if (status !== "active")
44369
+ cacheParams.status = status;
44370
+ const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
44371
+ logger41.log({
44372
+ level: "info",
44373
+ message: `Cache key for getAll buildings: ${cacheKey}`
44374
+ });
44375
+ try {
44376
+ const cached = await getCache(cacheKey);
44377
+ if (cached) {
44378
+ logger41.log({
44379
+ level: "info",
44380
+ message: `Cache hit for getAll buildings: ${cacheKey}`
42943
44381
  });
42944
- for (const curriculumSubject of curriculumSubjects.items) {
42945
- await addSectionSubject(
42946
- {
42947
- curriculum: curriculumSubject.curriculum.toString(),
42948
- school: value.school,
42949
- schoolName: schoolData.name,
42950
- gradeLevel: value.gradeLevel,
42951
- educationLevel: gradeLevelData.educationLevel,
42952
- schoolYear: value.schoolYear,
42953
- section: section.toString(),
42954
- sectionName,
42955
- subjectCode: curriculumSubject.subjectCode,
42956
- subjectName: curriculumSubject.subjectName,
42957
- teacher: "",
42958
- teacherName: "",
42959
- schedule: "",
42960
- daysOfWeek: [],
42961
- classroom: "",
42962
- classroomName: "",
42963
- sessionDuration: curriculumSubject.sessionDuration,
42964
- sessionFrequency: curriculumSubject.sessionFrequency,
42965
- status: "draft"
42966
- },
42967
- session
42968
- );
42969
- }
44382
+ return cached;
42970
44383
  }
42971
- let pageTeacher = 1;
42972
- let pagesTeachers = 1;
42973
- let teachers = [];
42974
- do {
42975
- const teachersData = await getAllPersonnel({
42976
- school: value.school,
42977
- limit: 100
44384
+ const items = await collection.aggregate([
44385
+ { $match: query },
44386
+ { $sort: sort },
44387
+ { $skip: page * limit },
44388
+ { $limit: limit }
44389
+ ]).toArray();
44390
+ const length = await collection.countDocuments(query);
44391
+ const data = paginate22(items, page, limit, length);
44392
+ setCache(cacheKey, data, 600).then(() => {
44393
+ logger41.log({
44394
+ level: "info",
44395
+ message: `Cache set for getAll buildings: ${cacheKey}`
42978
44396
  });
42979
- pagesTeachers = teachersData.pages;
42980
- teachers.push(...teachersData.items);
42981
- pageTeacher++;
42982
- } while (pageTeacher < pagesTeachers);
42983
- if (teachers.length) {
42984
- for (let index = 0; index < teachers.length; index++) {
42985
- const teacher = teachers[index];
42986
- if (!teacher._id) {
42987
- throw new BadRequestError64("Teacher ID is missing.");
44397
+ }).catch((err) => {
44398
+ logger41.log({
44399
+ level: "error",
44400
+ message: `Failed to set cache for getAll buildings: ${err.message}`
44401
+ });
44402
+ });
44403
+ return data;
44404
+ } catch (error) {
44405
+ logger41.log({ level: "error", message: `${error}` });
44406
+ throw error;
44407
+ }
44408
+ }
44409
+ async function getById(_id) {
44410
+ try {
44411
+ _id = new ObjectId44(_id);
44412
+ } catch (error) {
44413
+ throw new BadRequestError71(namespace_collection + " Invalid ID.");
44414
+ }
44415
+ const cacheKey = makeCacheKey23(namespace_collection, { _id: String(_id) });
44416
+ try {
44417
+ const cached = await getCache(cacheKey);
44418
+ if (cached) {
44419
+ logger41.log({
44420
+ level: "info",
44421
+ message: `Cache hit for getById building: ${cacheKey}`
44422
+ });
44423
+ return cached;
44424
+ }
44425
+ const result = await collection.findOne({
44426
+ _id
44427
+ });
44428
+ setCache(cacheKey, result, 300).then(() => {
44429
+ logger41.log({
44430
+ level: "info",
44431
+ message: `Cache set for building by id: ${cacheKey}`
44432
+ });
44433
+ }).catch((err) => {
44434
+ logger41.log({
44435
+ level: "error",
44436
+ message: `Failed to set cache for building by id: ${err.message}`
44437
+ });
44438
+ });
44439
+ return result;
44440
+ } catch (error) {
44441
+ if (error instanceof AppError27) {
44442
+ throw error;
44443
+ } else {
44444
+ throw new InternalServerError23("Failed to get building.");
44445
+ }
44446
+ }
44447
+ }
44448
+ async function deleteById(_id, session) {
44449
+ try {
44450
+ _id = new ObjectId44(_id);
44451
+ } catch (error) {
44452
+ throw new BadRequestError71(namespace_collection + " Invalid ID.");
44453
+ }
44454
+ try {
44455
+ const res = await collection.updateOne(
44456
+ { _id },
44457
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
44458
+ );
44459
+ delCachedData();
44460
+ return res;
44461
+ } catch (error) {
44462
+ logger41.log({
44463
+ level: "error",
44464
+ message: error.message
44465
+ });
44466
+ if (error instanceof AppError27) {
44467
+ throw error;
44468
+ } else {
44469
+ throw new InternalServerError23("Failed to delete building.");
44470
+ }
44471
+ }
44472
+ }
44473
+ function delCachedData() {
44474
+ delNamespace().then(() => {
44475
+ logger41.log({
44476
+ level: "info",
44477
+ message: `Cache namespace cleared for ${namespace_collection}`
44478
+ });
44479
+ }).catch((err) => {
44480
+ logger41.log({
44481
+ level: "error",
44482
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
44483
+ });
44484
+ });
44485
+ }
44486
+ return {
44487
+ createIndexes,
44488
+ add,
44489
+ getAll,
44490
+ getById,
44491
+ updateById,
44492
+ deleteById
44493
+ };
44494
+ }
44495
+
44496
+ // src/resources/building/building.service.ts
44497
+ import {
44498
+ BadRequestError as BadRequestError73,
44499
+ NotFoundError as NotFoundError3,
44500
+ useAtlas as useAtlas34
44501
+ } from "@eeplatform/nodejs-utils";
44502
+
44503
+ // src/resources/building/building-unit.repository.ts
44504
+ import {
44505
+ AppError as AppError28,
44506
+ BadRequestError as BadRequestError72,
44507
+ InternalServerError as InternalServerError24,
44508
+ logger as logger42,
44509
+ makeCacheKey as makeCacheKey24,
44510
+ paginate as paginate23,
44511
+ useAtlas as useAtlas33,
44512
+ useCache as useCache24
44513
+ } from "@eeplatform/nodejs-utils";
44514
+ import { ObjectId as ObjectId45 } from "mongodb";
44515
+ function useBuildingUnitRepo() {
44516
+ const db = useAtlas33.getDb();
44517
+ if (!db) {
44518
+ throw new Error("Unable to connect to server.");
44519
+ }
44520
+ const namespace_collection = "deped.building.units";
44521
+ const collection = db.collection(namespace_collection);
44522
+ const { getCache, setCache, delNamespace } = useCache24(namespace_collection);
44523
+ async function createIndexes() {
44524
+ try {
44525
+ await collection.createIndexes([
44526
+ {
44527
+ key: { name: 1, building: 1, level: 1 },
44528
+ unique: true,
44529
+ name: "unique_name_index"
44530
+ },
44531
+ { key: { school: 1 } },
44532
+ { key: { building: 1 } },
44533
+ { key: { status: 1 } },
44534
+ { key: { createdAt: 1 } },
44535
+ {
44536
+ key: {
44537
+ name: "text",
44538
+ buildingName: "text",
44539
+ category: "text",
44540
+ type: "text"
42988
44541
  }
42989
- await addTeachingLoad(
42990
- {
42991
- school: value.school,
42992
- schoolName: schoolData.name,
42993
- schoolYear: value.schoolYear,
42994
- teacher: teacher._id.toString(),
42995
- teacherName: `${teacher.firstName} ${teacher.lastName}`,
42996
- status: "draft"
42997
- },
42998
- session
42999
- );
43000
44542
  }
43001
- }
43002
- await session.commitTransaction();
43003
- return "Sections generated successfully.";
43004
- } catch (error2) {
43005
- await session.abortTransaction();
43006
- if (error2 instanceof AppError25) {
43007
- throw error2;
44543
+ ]);
44544
+ } catch (error) {
44545
+ throw new Error("Failed to create index on building units.");
44546
+ }
44547
+ }
44548
+ function delCachedData() {
44549
+ delNamespace().then(() => {
44550
+ logger42.log({
44551
+ level: "info",
44552
+ message: `Cache namespace cleared for ${namespace_collection}`
44553
+ });
44554
+ }).catch((err) => {
44555
+ logger42.log({
44556
+ level: "error",
44557
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
44558
+ });
44559
+ });
44560
+ }
44561
+ async function add(value, session) {
44562
+ try {
44563
+ value = MBuildingUnit(value);
44564
+ const res = await collection.insertOne(value, { session });
44565
+ delCachedData();
44566
+ return res.insertedId;
44567
+ } catch (error) {
44568
+ logger42.log({
44569
+ level: "error",
44570
+ message: error.message
44571
+ });
44572
+ if (error instanceof AppError28) {
44573
+ throw error;
43008
44574
  } else {
43009
- throw new InternalServerError21("Failed to generate sections.");
44575
+ throw new Error("Failed to create building unit.");
43010
44576
  }
43011
- } finally {
43012
- await session?.endSession();
43013
44577
  }
43014
44578
  }
43015
- async function generateSectionPreview(value) {
43016
- const { error } = schemaGenerateSections.validate(value);
44579
+ async function updateById(_id, value, session) {
44580
+ const { error } = schemaUpdateOptions.validate(value);
43017
44581
  if (error) {
43018
- throw new BadRequestError64(
43019
- `Invalid section generation data: ${error.message}`
43020
- );
44582
+ throw new BadRequestError72(error.message);
43021
44583
  }
43022
44584
  try {
43023
- const studentCount = await getCountByGradeLevel({
43024
- school: value.school,
43025
- schoolYear: value.schoolYear,
43026
- gradeLevel: value.gradeLevel,
43027
- specialProgram: value.specialProgram
43028
- });
43029
- if (studentCount === 0) {
43030
- throw new BadRequestError64("No learners found for this grade level.");
43031
- }
43032
- const gradeLevelData = await getByGradeLevel({
43033
- school: value.school,
43034
- gradeLevel: value.gradeLevel
43035
- });
43036
- if (!gradeLevelData) {
43037
- throw new BadRequestError64("Grade level not found.");
43038
- }
43039
- const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
43040
- const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
43041
- const sectionsNeeded = Math.ceil(studentCount / minPerSection);
43042
- if (sectionsNeeded > value.set.length) {
43043
- throw new BadRequestError64(
43044
- "Insufficient number of section names in set[]."
43045
- );
43046
- }
43047
- const sectionSizes = distributeStudents(
43048
- studentCount,
43049
- minPerSection,
43050
- maxPerSection
44585
+ _id = new ObjectId45(_id);
44586
+ } catch (error2) {
44587
+ throw new BadRequestError72(namespace_collection + " Invalid ID.");
44588
+ }
44589
+ try {
44590
+ const res = await collection.updateOne(
44591
+ { _id },
44592
+ { $set: value },
44593
+ { session }
43051
44594
  );
43052
- if (sectionSizes.length === 0) {
43053
- throw new BadRequestError64("Unable to compute section sizes.");
43054
- }
43055
- const sections = sectionSizes.map((size, index) => ({
43056
- name: value.set[index],
43057
- value: size
43058
- }));
43059
- return {
43060
- totalSectionsGenerated: sectionSizes.length,
43061
- totalStudentsAssigned: studentCount,
43062
- sections
43063
- };
44595
+ delCachedData();
44596
+ return res;
43064
44597
  } catch (error2) {
43065
- if (error2 instanceof AppError25) {
44598
+ logger42.log({
44599
+ level: "error",
44600
+ message: error2.message
44601
+ });
44602
+ if (error2 instanceof AppError28) {
43066
44603
  throw error2;
43067
44604
  } else {
43068
- throw new InternalServerError21("Failed to generate section preview.");
44605
+ throw new Error("Failed to create building unit.");
43069
44606
  }
43070
44607
  }
43071
44608
  }
43072
- return { generateSections, generateSectionPreview };
43073
- }
43074
-
43075
- // src/resources/section/section.controller.ts
43076
- function useSectionController() {
43077
- const {
43078
- add: _add,
43079
- getAll: _getAll,
43080
- getById: _getById,
43081
- getByName: _getByName,
43082
- getBySchool: _getBySchool,
43083
- updateFieldById: _updateFieldById,
43084
- addStudentToSection: _addStudentToSection,
43085
- removeStudentFromSection: _removeStudentFromSection,
43086
- deleteById: _deleteById
43087
- } = useSectionRepo();
43088
- const {
43089
- generateSections: _generateSections,
43090
- generateSectionPreview: _generateSectionPreview
43091
- } = useSectionService();
43092
- async function add(req, res, next) {
43093
- const value = req.body;
43094
- const { error } = schemaSection.validate(value);
44609
+ async function updateByBuildingId(building, value, session) {
44610
+ const { error } = schemaUpdateOptions.validate(value);
43095
44611
  if (error) {
43096
- next(new BadRequestError65(error.message));
43097
- return;
44612
+ throw new BadRequestError72(error.message);
43098
44613
  }
43099
44614
  try {
43100
- const data = await _add(value);
43101
- res.json({
43102
- message: "Successfully created section.",
43103
- data
43104
- });
43105
- return;
44615
+ building = new ObjectId45(building);
43106
44616
  } catch (error2) {
43107
- next(error2);
44617
+ throw new BadRequestError72("Invalid building ID.");
44618
+ }
44619
+ try {
44620
+ const res = await collection.updateMany(
44621
+ { building },
44622
+ { $set: value },
44623
+ { session }
44624
+ );
44625
+ delCachedData();
44626
+ return res;
44627
+ } catch (error2) {
44628
+ logger42.log({
44629
+ level: "error",
44630
+ message: error2.message
44631
+ });
44632
+ if (error2 instanceof AppError28) {
44633
+ throw error2;
44634
+ } else {
44635
+ throw new Error("Failed to update building unit.");
44636
+ }
43108
44637
  }
43109
44638
  }
43110
- async function generateSections(req, res, next) {
43111
- const value = req.body;
43112
- const { error } = schemaGenerateSections.validate(value);
43113
- if (error) {
43114
- next(new BadRequestError65(error.message));
43115
- return;
44639
+ async function getAll({
44640
+ search = "",
44641
+ page = 1,
44642
+ limit = 10,
44643
+ sort = {},
44644
+ school = "",
44645
+ building = "",
44646
+ type = "",
44647
+ status = "active"
44648
+ } = {}) {
44649
+ page = page > 0 ? page - 1 : 0;
44650
+ const query = {
44651
+ deletedAt: { $in: ["", null] },
44652
+ status: { $in: [status, "", null] }
44653
+ };
44654
+ const cacheParams = {
44655
+ page,
44656
+ limit,
44657
+ sort: JSON.stringify(sort)
44658
+ };
44659
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
44660
+ if (search) {
44661
+ query.$text = { $search: search };
44662
+ cacheParams.search = search;
44663
+ }
44664
+ if (school) {
44665
+ try {
44666
+ query.school = new ObjectId45(school);
44667
+ } catch (error) {
44668
+ throw new BadRequestError72("Invalid school ID.");
44669
+ }
44670
+ cacheParams.school = school;
44671
+ }
44672
+ if (building) {
44673
+ try {
44674
+ query.building = new ObjectId45(building);
44675
+ } catch (error) {
44676
+ throw new BadRequestError72("Invalid building ID.");
44677
+ }
44678
+ cacheParams.building = building;
44679
+ }
44680
+ if (type) {
44681
+ query.type = type;
44682
+ cacheParams.type = type;
43116
44683
  }
44684
+ const cacheKey = makeCacheKey24(namespace_collection, cacheParams);
44685
+ logger42.log({
44686
+ level: "info",
44687
+ message: `Cache key for getAll building units: ${cacheKey}`
44688
+ });
43117
44689
  try {
43118
- const data = await _generateSections(value);
43119
- res.json({
43120
- message: "Successfully created section.",
43121
- data
44690
+ const cached = await getCache(cacheKey);
44691
+ if (cached) {
44692
+ logger42.log({
44693
+ level: "info",
44694
+ message: `Cache hit for getAll building units: ${cacheKey}`
44695
+ });
44696
+ return cached;
44697
+ }
44698
+ const items = await collection.aggregate([
44699
+ { $match: query },
44700
+ { $sort: sort },
44701
+ { $skip: page * limit },
44702
+ { $limit: limit }
44703
+ ]).toArray();
44704
+ const length = await collection.countDocuments(query);
44705
+ const data = paginate23(items, page, limit, length);
44706
+ setCache(cacheKey, data, 600).then(() => {
44707
+ logger42.log({
44708
+ level: "info",
44709
+ message: `Cache set for getAll building units: ${cacheKey}`
44710
+ });
44711
+ }).catch((err) => {
44712
+ logger42.log({
44713
+ level: "error",
44714
+ message: `Failed to set cache for getAll building units: ${err.message}`
44715
+ });
43122
44716
  });
43123
- return;
43124
- } catch (error2) {
43125
- next(error2);
44717
+ return data;
44718
+ } catch (error) {
44719
+ logger42.log({ level: "error", message: `${error}` });
44720
+ throw error;
43126
44721
  }
43127
44722
  }
43128
- async function generateSectionPreview(req, res, next) {
43129
- const value = req.body;
43130
- const { error } = schemaGenerateSections.validate(value);
43131
- if (error) {
43132
- next(new BadRequestError65(error.message));
43133
- return;
43134
- }
44723
+ async function countByBuilding(building, level) {
44724
+ const query = {
44725
+ status: "active"
44726
+ };
44727
+ const cacheKeyOptions = {
44728
+ ...query,
44729
+ tag: "countByBuilding"
44730
+ };
43135
44731
  try {
43136
- const data = await _generateSectionPreview(value);
43137
- res.json(data);
43138
- return;
43139
- } catch (error2) {
43140
- next(error2);
44732
+ query.building = new ObjectId45(building);
44733
+ cacheKeyOptions.building = String(building);
44734
+ } catch (error) {
44735
+ throw new BadRequestError72("Invalid building ID.");
43141
44736
  }
43142
- }
43143
- async function getAll(req, res, next) {
43144
- const query = req.query;
43145
- const validation = Joi43.object({
43146
- page: Joi43.number().min(1).optional().allow("", null),
43147
- limit: Joi43.number().min(1).optional().allow("", null),
43148
- search: Joi43.string().optional().allow("", null),
43149
- status: Joi43.string().optional().allow("", null),
43150
- school: Joi43.string().hex().optional().allow("", null),
43151
- schoolYear: Joi43.string().optional().allow("", null),
43152
- gradeLevel: Joi43.string().optional().allow("", null)
43153
- });
43154
- const { error } = validation.validate(query);
43155
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
43156
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
43157
- const search = req.query.search ?? "";
43158
- const status = req.query.status ?? "active";
43159
- const school = req.query.school ?? "";
43160
- const schoolYear = req.query.schoolYear ?? "";
43161
- const gradeLevel = req.query.gradeLevel ?? "";
43162
- const isPageNumber = isFinite(page);
43163
- if (!isPageNumber) {
43164
- next(new BadRequestError65("Invalid page number."));
43165
- return;
44737
+ if (level) {
44738
+ query.level = level;
44739
+ cacheKeyOptions.level = level;
43166
44740
  }
43167
- const isLimitNumber = isFinite(limit);
43168
- if (!isLimitNumber) {
43169
- next(new BadRequestError65("Invalid limit number."));
43170
- return;
44741
+ try {
44742
+ return await collection.countDocuments(query);
44743
+ } catch (error) {
44744
+ logger42.log({ level: "error", message: `${error}` });
44745
+ throw new InternalServerError24("Failed to count building units.");
43171
44746
  }
43172
- if (error) {
43173
- next(new BadRequestError65(error.message));
43174
- return;
44747
+ }
44748
+ async function getById(_id) {
44749
+ try {
44750
+ _id = new ObjectId45(_id);
44751
+ } catch (error) {
44752
+ throw new BadRequestError72(namespace_collection + " Invalid ID.");
43175
44753
  }
44754
+ const cacheKey = makeCacheKey24(namespace_collection, { _id: String(_id) });
43176
44755
  try {
43177
- const data = await _getAll({
43178
- page,
43179
- limit,
43180
- search,
43181
- status,
43182
- school,
43183
- schoolYear,
43184
- gradeLevel
44756
+ const cached = await getCache(cacheKey);
44757
+ if (cached) {
44758
+ logger42.log({
44759
+ level: "info",
44760
+ message: `Cache hit for getById building unit: ${cacheKey}`
44761
+ });
44762
+ return cached;
44763
+ }
44764
+ const result = await collection.findOne({
44765
+ _id,
44766
+ deletedAt: { $in: ["", null] }
43185
44767
  });
43186
- res.json(data);
43187
- return;
43188
- } catch (error2) {
43189
- next(error2);
44768
+ if (!result) {
44769
+ throw new BadRequestError72("Building unit not found.");
44770
+ }
44771
+ setCache(cacheKey, result, 300).then(() => {
44772
+ logger42.log({
44773
+ level: "info",
44774
+ message: `Cache set for building unit by id: ${cacheKey}`
44775
+ });
44776
+ }).catch((err) => {
44777
+ logger42.log({
44778
+ level: "error",
44779
+ message: `Failed to set cache for building unit by id: ${err.message}`
44780
+ });
44781
+ });
44782
+ return result;
44783
+ } catch (error) {
44784
+ if (error instanceof AppError28) {
44785
+ throw error;
44786
+ } else {
44787
+ throw new InternalServerError24("Failed to get building unit.");
44788
+ }
43190
44789
  }
43191
44790
  }
43192
- async function getById(req, res, next) {
43193
- const id = req.params.id;
43194
- const validation = Joi43.object({
43195
- id: Joi43.string().hex().required()
43196
- });
43197
- const { error } = validation.validate({ id });
43198
- if (error) {
43199
- next(new BadRequestError65(error.message));
43200
- return;
43201
- }
44791
+ async function getByBuildingLevel(building, level) {
43202
44792
  try {
43203
- const data = await _getById(id);
43204
- res.json(data);
43205
- return;
43206
- } catch (error2) {
43207
- next(error2);
44793
+ building = new ObjectId45(building);
44794
+ } catch (error) {
44795
+ throw new BadRequestError72("Invalid building ID.");
43208
44796
  }
43209
- }
43210
- async function getByName(req, res, next) {
43211
- const name = req.params.name;
43212
- const validation = Joi43.object({
43213
- name: Joi43.string().required()
44797
+ const cacheKey = makeCacheKey24(namespace_collection, {
44798
+ building: String(building),
44799
+ level
43214
44800
  });
43215
- const { error } = validation.validate({ name });
43216
- if (error) {
43217
- next(new BadRequestError65(error.message));
43218
- return;
43219
- }
43220
44801
  try {
43221
- const data = await _getByName(name);
43222
- res.json({
43223
- message: "Successfully retrieved section.",
43224
- data
44802
+ const cached = await getCache(cacheKey);
44803
+ if (cached) {
44804
+ logger42.log({
44805
+ level: "info",
44806
+ message: `Cache hit for getById building unit: ${cacheKey}`
44807
+ });
44808
+ return cached;
44809
+ }
44810
+ const result = await collection.findOne({
44811
+ building,
44812
+ level,
44813
+ status: "active"
43225
44814
  });
43226
- return;
43227
- } catch (error2) {
43228
- next(error2);
44815
+ setCache(cacheKey, result, 300).then(() => {
44816
+ logger42.log({
44817
+ level: "info",
44818
+ message: `Cache set for building unit by id: ${cacheKey}`
44819
+ });
44820
+ }).catch((err) => {
44821
+ logger42.log({
44822
+ level: "error",
44823
+ message: `Failed to set cache for building unit by id: ${err.message}`
44824
+ });
44825
+ });
44826
+ return result;
44827
+ } catch (error) {
44828
+ if (error instanceof AppError28) {
44829
+ throw error;
44830
+ } else {
44831
+ throw new InternalServerError24("Failed to get building unit.");
44832
+ }
43229
44833
  }
43230
44834
  }
43231
- async function getBySchool(req, res, next) {
43232
- const school = req.params.school;
43233
- const validation = Joi43.object({
43234
- school: Joi43.string().hex().required()
43235
- });
43236
- const { error } = validation.validate({ school });
43237
- if (error) {
43238
- next(new BadRequestError65(error.message));
43239
- return;
44835
+ async function getByBuilding(building) {
44836
+ try {
44837
+ building = new ObjectId45(building);
44838
+ } catch (error) {
44839
+ throw new BadRequestError72("Invalid building ID.");
43240
44840
  }
44841
+ const cacheKey = makeCacheKey24(namespace_collection, {
44842
+ building: String(building)
44843
+ });
43241
44844
  try {
43242
- const data = await _getBySchool(school);
43243
- res.json({
43244
- message: "Successfully retrieved sections.",
43245
- data
44845
+ const cached = await getCache(cacheKey);
44846
+ if (cached) {
44847
+ logger42.log({
44848
+ level: "info",
44849
+ message: `Cache hit for getById building unit: ${cacheKey}`
44850
+ });
44851
+ return cached;
44852
+ }
44853
+ const result = await collection.findOne({
44854
+ building,
44855
+ status: "active"
43246
44856
  });
43247
- return;
43248
- } catch (error2) {
43249
- next(error2);
44857
+ setCache(cacheKey, result, 300).then(() => {
44858
+ logger42.log({
44859
+ level: "info",
44860
+ message: `Cache set for building unit by id: ${cacheKey}`
44861
+ });
44862
+ }).catch((err) => {
44863
+ logger42.log({
44864
+ level: "error",
44865
+ message: `Failed to set cache for building unit by id: ${err.message}`
44866
+ });
44867
+ });
44868
+ return result;
44869
+ } catch (error) {
44870
+ if (error instanceof AppError28) {
44871
+ throw error;
44872
+ } else {
44873
+ throw new InternalServerError24("Failed to get building unit.");
44874
+ }
43250
44875
  }
43251
44876
  }
43252
- async function updateField(req, res, next) {
43253
- const _id = req.params.id;
43254
- const { field, value } = req.body;
43255
- const validation = Joi43.object({
43256
- _id: Joi43.string().hex().required(),
43257
- field: Joi43.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
43258
- value: Joi43.string().required()
43259
- });
43260
- const { error } = validation.validate({ _id, field, value });
43261
- if (error) {
43262
- next(new BadRequestError65(error.message));
43263
- return;
44877
+ async function deleteById(_id, session) {
44878
+ try {
44879
+ _id = new ObjectId45(_id);
44880
+ } catch (error) {
44881
+ throw new BadRequestError72(namespace_collection + " Invalid ID.");
43264
44882
  }
43265
44883
  try {
43266
- const message = await _updateFieldById({ _id, field, value });
43267
- res.json({ message });
43268
- return;
43269
- } catch (error2) {
43270
- next(error2);
44884
+ const res = await collection.updateOne(
44885
+ { _id },
44886
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
44887
+ { session }
44888
+ );
44889
+ delCachedData();
44890
+ return "Room/Facility deleted successfully.";
44891
+ } catch (error) {
44892
+ logger42.log({
44893
+ level: "error",
44894
+ message: error.message
44895
+ });
44896
+ if (error instanceof AppError28) {
44897
+ throw error;
44898
+ } else {
44899
+ throw new Error("Failed to deleted room/facility.");
44900
+ }
43271
44901
  }
43272
44902
  }
43273
- async function addStudent(req, res, next) {
43274
- const _id = req.params.id;
43275
- const { studentId } = req.body;
43276
- const validation = Joi43.object({
43277
- _id: Joi43.string().hex().required(),
43278
- studentId: Joi43.string().required()
43279
- });
43280
- const { error } = validation.validate({ _id, studentId });
43281
- if (error) {
43282
- next(new BadRequestError65(error.message));
43283
- return;
43284
- }
43285
- try {
43286
- const message = await _addStudentToSection(_id, studentId);
43287
- res.json({ message });
43288
- return;
43289
- } catch (error2) {
43290
- next(error2);
44903
+ return {
44904
+ createIndexes,
44905
+ add,
44906
+ getAll,
44907
+ getById,
44908
+ getByBuildingLevel,
44909
+ updateById,
44910
+ getByBuilding,
44911
+ deleteById,
44912
+ updateByBuildingId,
44913
+ countByBuilding
44914
+ };
44915
+ }
44916
+
44917
+ // src/resources/building/building.service.ts
44918
+ function useBuildingService() {
44919
+ const {
44920
+ updateById: _updateById,
44921
+ getById: _getById,
44922
+ deleteById: _deleteById
44923
+ } = useBuildingRepo();
44924
+ const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
44925
+ async function updateById(id, data) {
44926
+ data.levels = Number(data.levels);
44927
+ const session = useAtlas34.getClient()?.startSession();
44928
+ try {
44929
+ const building = await _getById(id);
44930
+ if (!building) {
44931
+ throw new NotFoundError3("Building not found.");
44932
+ }
44933
+ if (data.levels < building.levels) {
44934
+ const unit = await getByBuildingLevel(id, building.levels);
44935
+ if (unit) {
44936
+ throw new BadRequestError73(
44937
+ "Cannot reduce floors, there are existing building units at higher floors."
44938
+ );
44939
+ }
44940
+ }
44941
+ session?.startTransaction();
44942
+ if (building.name !== data.name) {
44943
+ await updateByBuildingId(id, { buildingName: data.name }, session);
44944
+ }
44945
+ const result = await _updateById(id, data, session);
44946
+ await session?.commitTransaction();
44947
+ return result;
44948
+ } catch (error) {
44949
+ await session?.abortTransaction();
44950
+ throw error;
44951
+ } finally {
44952
+ session?.endSession();
43291
44953
  }
43292
44954
  }
43293
- async function removeStudent(req, res, next) {
43294
- const _id = req.params.id;
43295
- const { studentId } = req.body;
43296
- const validation = Joi43.object({
43297
- _id: Joi43.string().hex().required(),
43298
- studentId: Joi43.string().required()
43299
- });
43300
- const { error } = validation.validate({ _id, studentId });
43301
- if (error) {
43302
- next(new BadRequestError65(error.message));
43303
- return;
44955
+ async function deleteById(id) {
44956
+ const building = await getByBuilding(id);
44957
+ if (building) {
44958
+ throw new BadRequestError73(
44959
+ "Cannot delete building with existing room/facility. Please delete room/facility first."
44960
+ );
43304
44961
  }
43305
44962
  try {
43306
- const message = await _removeStudentFromSection(_id, studentId);
43307
- res.json({ message });
43308
- return;
43309
- } catch (error2) {
43310
- next(error2);
44963
+ await _deleteById(id);
44964
+ return "Building deleted successfully.";
44965
+ } catch (error) {
44966
+ throw error;
43311
44967
  }
43312
44968
  }
43313
- async function deleteById(req, res, next) {
43314
- const _id = req.params.id;
43315
- const validation = Joi43.object({
43316
- _id: Joi43.string().hex().required()
44969
+ return {
44970
+ updateById,
44971
+ deleteById
44972
+ };
44973
+ }
44974
+
44975
+ // src/resources/building/building.controller.ts
44976
+ import { BadRequestError as BadRequestError74, logger as logger43 } from "@eeplatform/nodejs-utils";
44977
+ import Joi48 from "joi";
44978
+ function useBuildingController() {
44979
+ const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
44980
+ const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
44981
+ async function createBuilding(req, res, next) {
44982
+ const value = req.body;
44983
+ const validation = Joi48.object({
44984
+ name: Joi48.string().required(),
44985
+ school: Joi48.string().hex().required(),
44986
+ levels: Joi48.number().integer().min(1).required(),
44987
+ serial: Joi48.string().optional().allow("", null),
44988
+ status: Joi48.string().optional().allow("", null)
43317
44989
  });
43318
- const { error } = validation.validate({ _id });
44990
+ const { error } = validation.validate(value);
43319
44991
  if (error) {
43320
- next(new BadRequestError65(error.message));
44992
+ next(new BadRequestError74(error.message));
44993
+ logger43.info(`Controller: ${error.message}`);
43321
44994
  return;
43322
44995
  }
43323
44996
  try {
43324
- const message = await _deleteById(_id);
43325
- res.json({ message });
44997
+ const result = await _add(value);
44998
+ res.json(result);
43326
44999
  return;
43327
45000
  } catch (error2) {
43328
45001
  next(error2);
43329
45002
  }
43330
45003
  }
43331
- return {
43332
- add,
43333
- generateSections,
43334
- generateSectionPreview,
43335
- getAll,
43336
- getById,
43337
- getByName,
43338
- getBySchool,
43339
- updateField,
43340
- addStudent,
43341
- removeStudent,
43342
- deleteById
43343
- };
43344
- }
43345
-
43346
- // src/resources/section-student/section.student.controller.ts
43347
- import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
43348
- import Joi44 from "joi";
43349
- function useSectionStudentController() {
43350
- const { add: _add, getAll: _getAll } = useSectionStudentRepo();
43351
- async function add(req, res, next) {
45004
+ async function updateById(req, res, next) {
43352
45005
  const value = req.body;
43353
- const { error } = schemaSectionStudent.validate(value);
45006
+ const id = req.params.id ?? "";
45007
+ const validation = Joi48.object({
45008
+ id: Joi48.string().hex().required(),
45009
+ value: Joi48.object({
45010
+ name: Joi48.string().required(),
45011
+ serial: Joi48.string().optional().allow("", null),
45012
+ levels: Joi48.number().integer().min(1).required()
45013
+ })
45014
+ });
45015
+ const { error } = validation.validate({ id, value });
43354
45016
  if (error) {
43355
- next(new BadRequestError66(error.message));
45017
+ next(new BadRequestError74(error.message));
45018
+ logger43.info(`Controller: ${error.message}`);
43356
45019
  return;
43357
45020
  }
43358
45021
  try {
43359
- const data = await _add(value);
43360
- res.json({
43361
- message: "Successfully created section student.",
43362
- data
43363
- });
45022
+ const result = await _updateById(id, value);
45023
+ res.json(result);
43364
45024
  return;
43365
45025
  } catch (error2) {
43366
45026
  next(error2);
@@ -43368,409 +45028,310 @@ function useSectionStudentController() {
43368
45028
  }
43369
45029
  async function getAll(req, res, next) {
43370
45030
  const query = req.query;
43371
- const validation = Joi44.object({
43372
- page: Joi44.number().min(1).optional().allow("", null),
43373
- limit: Joi44.number().min(1).optional().allow("", null),
43374
- search: Joi44.string().optional().allow("", null),
43375
- status: Joi44.string().optional().allow("", null),
43376
- school: Joi44.string().optional().allow("", null),
43377
- gradeLevel: Joi44.string().optional().allow("", null),
43378
- section: Joi44.string().optional().allow("", null),
43379
- schoolYear: Joi44.string().optional().allow("", null)
45031
+ const validation = Joi48.object({
45032
+ page: Joi48.number().min(1).optional().allow("", null),
45033
+ limit: Joi48.number().min(1).optional().allow("", null),
45034
+ search: Joi48.string().optional().allow("", null),
45035
+ school: Joi48.string().hex().optional().allow("", null),
45036
+ status: Joi48.string().optional().allow("", null)
43380
45037
  });
43381
45038
  const { error } = validation.validate(query);
43382
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
43383
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
43384
- const search = req.query.search ?? "";
43385
- const status = req.query.status ?? "active";
43386
- const school = req.query.school ?? "";
43387
- const gradeLevel = req.query.gradeLevel ?? "";
43388
- const section = req.query.section ?? "";
43389
- const schoolYear = req.query.schoolYear ?? "";
43390
- const isPageNumber = isFinite(page);
43391
- if (!isPageNumber) {
43392
- next(new BadRequestError66("Invalid page number."));
43393
- return;
43394
- }
43395
- const isLimitNumber = isFinite(limit);
43396
- if (!isLimitNumber) {
43397
- next(new BadRequestError66("Invalid limit number."));
43398
- return;
43399
- }
43400
45039
  if (error) {
43401
- next(new BadRequestError66(error.message));
45040
+ next(new BadRequestError74(error.message));
43402
45041
  return;
43403
45042
  }
45043
+ const page = parseInt(req.query.page) ?? 1;
45044
+ let limit = parseInt(req.query.limit) ?? 20;
45045
+ limit = isNaN(limit) ? 20 : limit;
45046
+ const sort = req.query.sort ? String(req.query.sort).split(",") : "";
45047
+ const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
45048
+ const sortObj = {};
45049
+ if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
45050
+ sort.forEach((field, index) => {
45051
+ sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
45052
+ });
45053
+ }
45054
+ const status = req.query.status ?? "active";
45055
+ const school = req.query.school ?? "";
45056
+ const search = req.query.search ?? "";
43404
45057
  try {
43405
- const data = await _getAll({
45058
+ const buildings = await _getAll({
43406
45059
  page,
43407
45060
  limit,
43408
- search,
45061
+ sort: sortObj,
43409
45062
  status,
43410
45063
  school,
43411
- gradeLevel,
43412
- section,
43413
- schoolYear
45064
+ search
43414
45065
  });
43415
- res.json(data);
45066
+ res.json(buildings);
43416
45067
  return;
43417
45068
  } catch (error2) {
43418
45069
  next(error2);
43419
45070
  }
43420
45071
  }
43421
- return {
43422
- add,
43423
- getAll
43424
- };
43425
- }
43426
-
43427
- // src/resources/building/building.model.ts
43428
- import { BadRequestError as BadRequestError67, logger as logger39 } from "@eeplatform/nodejs-utils";
43429
- import Joi45 from "joi";
43430
- import { ObjectId as ObjectId41 } from "mongodb";
43431
- var schemaBuilding = Joi45.object({
43432
- _id: Joi45.string().hex().optional(),
43433
- school: Joi45.string().hex().required(),
43434
- serial: Joi45.string().optional().allow("", null),
43435
- name: Joi45.string().required(),
43436
- levels: Joi45.number().integer().min(1).required(),
43437
- createdAt: Joi45.date().optional().allow("", null),
43438
- updatedAt: Joi45.date().optional().allow("", null),
43439
- deletedAt: Joi45.date().optional().allow("", null),
43440
- status: Joi45.string().optional().allow("", null)
43441
- });
43442
- var schemaBuildingUnit = Joi45.object({
43443
- _id: Joi45.string().hex().optional(),
43444
- school: Joi45.string().hex().required(),
43445
- name: Joi45.string().optional().allow("", null),
43446
- building: Joi45.string().hex().required(),
43447
- buildingName: Joi45.string().optional().allow("", null),
43448
- level: Joi45.number().integer().min(1).required(),
43449
- category: Joi45.string().required(),
43450
- type: Joi45.string().required(),
43451
- seating_capacity: Joi45.number().integer().min(0).required(),
43452
- standing_capacity: Joi45.number().integer().min(0).required(),
43453
- description: Joi45.string().optional().allow("", null),
43454
- unit_of_measurement: Joi45.string().valid("sqm").required(),
43455
- area: Joi45.number().positive().required(),
43456
- status: Joi45.string().optional().allow("", null)
43457
- });
43458
- var schemaUpdateOptions = Joi45.object({
43459
- name: Joi45.string().optional().allow("", null),
43460
- building: Joi45.string().hex().optional().allow("", null),
43461
- buildingName: Joi45.string().optional().allow("", null),
43462
- level: Joi45.number().integer().min(1).optional().allow("", null),
43463
- category: Joi45.string().optional().allow("", null),
43464
- type: Joi45.string().optional().allow("", null),
43465
- seating_capacity: Joi45.number().integer().min(0).optional().allow("", null),
43466
- standing_capacity: Joi45.number().integer().min(0).optional().allow("", null),
43467
- area: Joi45.number().positive().optional().allow("", null)
43468
- });
43469
- function MBuilding(value) {
43470
- const { error } = schemaBuilding.validate(value);
43471
- if (error) {
43472
- logger39.info(`Building Model: ${error.message}`);
43473
- throw new BadRequestError67(error.message);
43474
- }
43475
- if (value._id && typeof value._id === "string") {
43476
- try {
43477
- value._id = new ObjectId41(value._id);
43478
- } catch (error2) {
43479
- throw new BadRequestError67("Invalid _id format");
45072
+ async function getById(req, res, next) {
45073
+ const id = req.params.id;
45074
+ const validation = Joi48.object({
45075
+ id: Joi48.string().hex().required()
45076
+ });
45077
+ const { error } = validation.validate({ id });
45078
+ if (error) {
45079
+ next(new BadRequestError74(error.message));
45080
+ return;
43480
45081
  }
43481
- }
43482
- try {
43483
- value.school = new ObjectId41(value.school);
43484
- } catch (error2) {
43485
- throw new BadRequestError67("Invalid school format");
43486
- }
43487
- return {
43488
- _id: value._id ?? void 0,
43489
- school: value.school,
43490
- serial: value.serial ?? "",
43491
- name: value.name ?? "",
43492
- levels: value.levels ?? 0,
43493
- status: value.status ?? "active",
43494
- createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
43495
- updatedAt: value.updatedAt ?? "",
43496
- deletedAt: value.deletedAt ?? ""
43497
- };
43498
- }
43499
- function MBuildingUnit(value) {
43500
- const { error } = schemaBuildingUnit.validate(value);
43501
- if (error) {
43502
- logger39.info(`Building Unit Model: ${error.message}`);
43503
- throw new BadRequestError67(error.message);
43504
- }
43505
- if (value._id && typeof value._id === "string") {
43506
45082
  try {
43507
- value._id = new ObjectId41(value._id);
45083
+ const building = await _getById(id);
45084
+ res.json({
45085
+ message: "Successfully retrieved building.",
45086
+ data: { building }
45087
+ });
45088
+ return;
43508
45089
  } catch (error2) {
43509
- throw new BadRequestError67("Invalid ID");
43510
- }
43511
- }
43512
- try {
43513
- value.school = new ObjectId41(value.school);
43514
- } catch (error2) {
43515
- throw new BadRequestError67("Invalid school ID");
43516
- }
43517
- try {
43518
- value.building = new ObjectId41(value.building);
43519
- } catch (error2) {
43520
- throw new BadRequestError67("Invalid building ID");
43521
- }
43522
- return {
43523
- _id: value._id ?? void 0,
43524
- school: value.school,
43525
- name: value.name ?? "",
43526
- building: value.building,
43527
- buildingName: value.buildingName ?? "",
43528
- level: value.level ?? 0,
43529
- category: value.category ?? "",
43530
- type: value.type ?? "",
43531
- seating_capacity: value.seating_capacity ?? 0,
43532
- standing_capacity: value.standing_capacity ?? 0,
43533
- description: value.description ?? "",
43534
- unit_of_measurement: value.unit_of_measurement ?? "sqm",
43535
- area: value.area ?? 0,
43536
- status: value.status ?? "active",
43537
- createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
43538
- updatedAt: value.updatedAt ?? "",
43539
- deletedAt: value.deletedAt ?? ""
43540
- };
43541
- }
43542
-
43543
- // src/resources/building/building.repository.ts
43544
- import {
43545
- AppError as AppError26,
43546
- BadRequestError as BadRequestError68,
43547
- InternalServerError as InternalServerError22,
43548
- logger as logger40,
43549
- makeCacheKey as makeCacheKey22,
43550
- paginate as paginate21,
43551
- useAtlas as useAtlas31,
43552
- useCache as useCache22
43553
- } from "@eeplatform/nodejs-utils";
43554
- import { ObjectId as ObjectId42 } from "mongodb";
43555
- function useBuildingRepo() {
43556
- const db = useAtlas31.getDb();
43557
- if (!db) {
43558
- throw new Error("Unable to connect to server.");
43559
- }
43560
- const namespace_collection = "deped.buildings";
43561
- const collection = db.collection(namespace_collection);
43562
- const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
43563
- async function createIndexes() {
43564
- try {
43565
- await collection.createIndexes([
43566
- { key: { name: 1 }, unique: true, name: "unique_name_index" },
43567
- { key: { school: 1 } },
43568
- { key: { status: 1 } }
43569
- ]);
43570
- } catch (error) {
43571
- throw new Error("Failed to create index on buildings.");
45090
+ next(error2);
43572
45091
  }
43573
45092
  }
43574
- async function add(value, session) {
45093
+ async function deleteById(req, res, next) {
45094
+ const id = req.params.id;
45095
+ const validation = Joi48.object({
45096
+ id: Joi48.string().hex().required()
45097
+ });
45098
+ const { error } = validation.validate({ id });
45099
+ if (error) {
45100
+ next(new BadRequestError74(error.message));
45101
+ return;
45102
+ }
43575
45103
  try {
43576
- value = MBuilding(value);
43577
- const res = await collection.insertOne(value, { session });
43578
- delCachedData();
43579
- return res.insertedId;
43580
- } catch (error) {
43581
- logger40.log({
43582
- level: "error",
43583
- message: error.message
43584
- });
43585
- if (error instanceof AppError26) {
43586
- throw error;
43587
- } else {
43588
- const isDuplicated = error.message.includes("duplicate");
43589
- if (isDuplicated) {
43590
- throw new BadRequestError68("Building already exists.");
43591
- }
43592
- throw new Error("Failed to create building.");
43593
- }
45104
+ const message = await _deleteById(id);
45105
+ res.json(message);
45106
+ return;
45107
+ } catch (error2) {
45108
+ next(error2);
43594
45109
  }
43595
45110
  }
43596
- async function updateById(_id, value, session) {
43597
- try {
43598
- _id = new ObjectId42(_id);
43599
- } catch (error) {
43600
- throw new BadRequestError68(namespace_collection + " Invalid ID.");
45111
+ return {
45112
+ createBuilding,
45113
+ getAll,
45114
+ getById,
45115
+ updateById,
45116
+ deleteById
45117
+ };
45118
+ }
45119
+
45120
+ // src/resources/building/building-unit.service.ts
45121
+ import { useAtlas as useAtlas35 } from "@eeplatform/nodejs-utils";
45122
+ function useBuildingUnitService() {
45123
+ const {
45124
+ add: _add,
45125
+ countByBuilding,
45126
+ deleteById: _deleteById
45127
+ } = useBuildingUnitRepo();
45128
+ async function add(value) {
45129
+ const session = useAtlas35.getClient()?.startSession();
45130
+ if (!session) {
45131
+ throw new Error("Unable to start session for building unit service.");
43601
45132
  }
43602
45133
  try {
43603
- const res = await collection.updateOne(
43604
- { _id },
43605
- { $set: value },
43606
- { session }
45134
+ await session.startTransaction();
45135
+ const existingCount = await countByBuilding(
45136
+ value.building.building,
45137
+ value.building.level
43607
45138
  );
43608
- delCachedData();
43609
- return res;
43610
- } catch (error) {
43611
- logger40.log({
43612
- level: "error",
43613
- message: error.message
43614
- });
43615
- if (error instanceof AppError26) {
43616
- throw error;
43617
- } else {
43618
- throw new Error("Failed to update building.");
45139
+ for (let index = 0; index < value.qty; index++) {
45140
+ const unitNumber = existingCount ? existingCount + index + 1 : index + 1;
45141
+ await _add(
45142
+ { ...value.building, name: `${value.building.name} R${unitNumber}` },
45143
+ session
45144
+ );
43619
45145
  }
45146
+ await session.commitTransaction();
45147
+ return "Building unit added successfully.";
45148
+ } catch (error) {
45149
+ await session.abortTransaction();
45150
+ throw error;
45151
+ } finally {
45152
+ session.endSession();
43620
45153
  }
43621
45154
  }
43622
- async function getAll({
43623
- search = "",
43624
- page = 1,
43625
- limit = 10,
43626
- sort = {},
43627
- school = "",
43628
- status = "active"
43629
- } = {}) {
43630
- page = page > 0 ? page - 1 : 0;
43631
- const query = {
43632
- status
43633
- };
43634
- sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
43635
- if (search) {
43636
- query.$text = { $search: search };
45155
+ const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
45156
+ async function deleteById(id) {
45157
+ if (!id) {
45158
+ throw new Error("Invalid building unit ID.");
43637
45159
  }
43638
- if (school) {
43639
- try {
43640
- query.school = new ObjectId42(school);
43641
- } catch (error) {
43642
- throw new BadRequestError68("Invalid school ID.");
43643
- }
45160
+ const sectionSubject = await getSectionSubjectByClassroom(id);
45161
+ if (sectionSubject) {
45162
+ throw new Error(
45163
+ "Cannot delete building unit as it is assigned to a section subject."
45164
+ );
43644
45165
  }
43645
- const cacheParams = {
43646
- page,
43647
- limit,
43648
- sort: JSON.stringify(sort)
43649
- };
43650
- if (search)
43651
- cacheParams.search = search;
43652
- if (school)
43653
- cacheParams.school = school;
43654
- if (status !== "active")
43655
- cacheParams.status = status;
43656
- const cacheKey = makeCacheKey22(namespace_collection, cacheParams);
43657
- logger40.log({
43658
- level: "info",
43659
- message: `Cache key for getAll buildings: ${cacheKey}`
43660
- });
43661
45166
  try {
43662
- const cached = await getCache(cacheKey);
43663
- if (cached) {
43664
- logger40.log({
43665
- level: "info",
43666
- message: `Cache hit for getAll buildings: ${cacheKey}`
43667
- });
43668
- return cached;
43669
- }
43670
- const items = await collection.aggregate([
43671
- { $match: query },
43672
- { $sort: sort },
43673
- { $skip: page * limit },
43674
- { $limit: limit }
43675
- ]).toArray();
43676
- const length = await collection.countDocuments(query);
43677
- const data = paginate21(items, page, limit, length);
43678
- setCache(cacheKey, data, 600).then(() => {
43679
- logger40.log({
43680
- level: "info",
43681
- message: `Cache set for getAll buildings: ${cacheKey}`
43682
- });
43683
- }).catch((err) => {
43684
- logger40.log({
43685
- level: "error",
43686
- message: `Failed to set cache for getAll buildings: ${err.message}`
43687
- });
43688
- });
43689
- return data;
45167
+ await _deleteById(id);
45168
+ return "Building unit deleted successfully.";
43690
45169
  } catch (error) {
43691
- logger40.log({ level: "error", message: `${error}` });
43692
- throw error;
45170
+ throw new Error("Failed to delete building unit.");
43693
45171
  }
43694
45172
  }
43695
- async function getById(_id) {
45173
+ return {
45174
+ add,
45175
+ deleteById
45176
+ };
45177
+ }
45178
+
45179
+ // src/resources/building/building-unit.controller.ts
45180
+ import { BadRequestError as BadRequestError75 } from "@eeplatform/nodejs-utils";
45181
+ import Joi49 from "joi";
45182
+ function useBuildingUnitController() {
45183
+ const {
45184
+ getAll: _getAll,
45185
+ getById: _getById,
45186
+ updateById: _updateById
45187
+ } = useBuildingUnitRepo();
45188
+ const { add: _add, deleteById: _deleteById } = useBuildingUnitService();
45189
+ async function add(req, res, next) {
45190
+ const data = req.body;
45191
+ const validation = Joi49.object({
45192
+ building: Joi49.object({
45193
+ school: Joi49.string().hex().required(),
45194
+ name: Joi49.string().optional().allow("", null),
45195
+ building: Joi49.string().hex().required(),
45196
+ buildingName: Joi49.string().optional().allow("", null),
45197
+ level: Joi49.number().integer().min(1).required(),
45198
+ category: Joi49.string().required(),
45199
+ type: Joi49.string().required(),
45200
+ seating_capacity: Joi49.number().integer().min(0).required(),
45201
+ standing_capacity: Joi49.number().integer().min(0).required(),
45202
+ description: Joi49.string().optional().allow("", null),
45203
+ unit_of_measurement: Joi49.string().valid("sqm").required(),
45204
+ area: Joi49.number().positive().required(),
45205
+ status: Joi49.string().optional().allow("", null)
45206
+ }),
45207
+ qty: Joi49.number().integer().min(1).max(20).optional().default(1)
45208
+ });
45209
+ const { error } = validation.validate(data);
45210
+ if (error) {
45211
+ next(new BadRequestError75(error.message));
45212
+ return;
45213
+ }
43696
45214
  try {
43697
- _id = new ObjectId42(_id);
43698
- } catch (error) {
43699
- throw new BadRequestError68(namespace_collection + " Invalid ID.");
45215
+ const buildingUnit = await _add(data);
45216
+ res.json({
45217
+ message: "Building unit added successfully.",
45218
+ data: { buildingUnit }
45219
+ });
45220
+ } catch (error2) {
45221
+ next(error2);
45222
+ }
45223
+ }
45224
+ async function updateById(req, res, next) {
45225
+ const data = req.body;
45226
+ const id = req.params.id ?? "";
45227
+ const validation = Joi49.object({
45228
+ id: Joi49.string().hex().required(),
45229
+ value: schemaUpdateOptions
45230
+ });
45231
+ const { error } = validation.validate({ id, value: data });
45232
+ if (error) {
45233
+ next(new BadRequestError75(error.message));
45234
+ return;
43700
45235
  }
43701
- const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
43702
45236
  try {
43703
- const cached = await getCache(cacheKey);
43704
- if (cached) {
43705
- logger40.log({
43706
- level: "info",
43707
- message: `Cache hit for getById building: ${cacheKey}`
43708
- });
43709
- return cached;
43710
- }
43711
- const result = await collection.findOne({
43712
- _id
45237
+ const buildingUnit = await _updateById(id, data);
45238
+ res.json({
45239
+ message: "Building unit updated successfully.",
45240
+ data: { buildingUnit }
43713
45241
  });
43714
- setCache(cacheKey, result, 300).then(() => {
43715
- logger40.log({
43716
- level: "info",
43717
- message: `Cache set for building by id: ${cacheKey}`
43718
- });
43719
- }).catch((err) => {
43720
- logger40.log({
43721
- level: "error",
43722
- message: `Failed to set cache for building by id: ${err.message}`
43723
- });
45242
+ } catch (error2) {
45243
+ next(error2);
45244
+ }
45245
+ }
45246
+ async function getAll(req, res, next) {
45247
+ const query = req.query;
45248
+ const validation = Joi49.object({
45249
+ page: Joi49.number().min(1).optional().allow("", null),
45250
+ limit: Joi49.number().min(1).optional().allow("", null),
45251
+ search: Joi49.string().optional().allow("", null),
45252
+ school: Joi49.string().hex().optional().allow("", null),
45253
+ building: Joi49.string().hex().optional().allow("", null),
45254
+ status: Joi49.string().optional().allow("", null),
45255
+ type: Joi49.string().optional().allow("", null)
45256
+ });
45257
+ const { error } = validation.validate(query);
45258
+ if (error) {
45259
+ next(new BadRequestError75(error.message));
45260
+ return;
45261
+ }
45262
+ const page = parseInt(req.query.page) ?? 1;
45263
+ let limit = parseInt(req.query.limit) ?? 20;
45264
+ limit = isNaN(limit) ? 20 : limit;
45265
+ const sort = req.query.sort ? String(req.query.sort).split(",") : "";
45266
+ const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
45267
+ const sortObj = {};
45268
+ if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
45269
+ sort.forEach((field, index) => {
45270
+ sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
43724
45271
  });
43725
- return result;
43726
- } catch (error) {
43727
- if (error instanceof AppError26) {
43728
- throw error;
43729
- } else {
43730
- throw new InternalServerError22("Failed to get building.");
43731
- }
45272
+ }
45273
+ const status = req.query.status ?? "active";
45274
+ const school = req.query.school ?? "";
45275
+ const building = req.query.building ?? "";
45276
+ const search = req.query.search ?? "";
45277
+ const type = req.query.type ?? "";
45278
+ try {
45279
+ const buildings = await _getAll({
45280
+ page,
45281
+ limit,
45282
+ sort: sortObj,
45283
+ status,
45284
+ school,
45285
+ search,
45286
+ building,
45287
+ type
45288
+ });
45289
+ res.json(buildings);
45290
+ return;
45291
+ } catch (error2) {
45292
+ next(error2);
43732
45293
  }
43733
45294
  }
43734
- async function deleteById(_id, session) {
43735
- try {
43736
- _id = new ObjectId42(_id);
43737
- } catch (error) {
43738
- throw new BadRequestError68(namespace_collection + " Invalid ID.");
45295
+ async function getById(req, res, next) {
45296
+ const id = req.params.id;
45297
+ const validation = Joi49.object({
45298
+ id: Joi49.string().hex().required()
45299
+ });
45300
+ const { error } = validation.validate({ id });
45301
+ if (error) {
45302
+ next(new BadRequestError75(error.message));
45303
+ return;
43739
45304
  }
43740
45305
  try {
43741
- const res = await collection.updateOne(
43742
- { _id },
43743
- { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
43744
- );
43745
- delCachedData();
43746
- return res;
43747
- } catch (error) {
43748
- logger40.log({
43749
- level: "error",
43750
- message: error.message
45306
+ const buildingUnit = await _getById(id);
45307
+ res.json({
45308
+ message: "Successfully retrieved building unit.",
45309
+ data: { buildingUnit }
43751
45310
  });
43752
- if (error instanceof AppError26) {
43753
- throw error;
43754
- } else {
43755
- throw new InternalServerError22("Failed to delete building.");
43756
- }
45311
+ return;
45312
+ } catch (error2) {
45313
+ next(error2);
43757
45314
  }
43758
45315
  }
43759
- function delCachedData() {
43760
- delNamespace().then(() => {
43761
- logger40.log({
43762
- level: "info",
43763
- message: `Cache namespace cleared for ${namespace_collection}`
43764
- });
43765
- }).catch((err) => {
43766
- logger40.log({
43767
- level: "error",
43768
- message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
43769
- });
45316
+ async function deleteById(req, res, next) {
45317
+ const id = req.params.id;
45318
+ const validation = Joi49.object({
45319
+ id: Joi49.string().hex().required()
43770
45320
  });
45321
+ const { error } = validation.validate({ id });
45322
+ if (error) {
45323
+ next(new BadRequestError75(error.message));
45324
+ return;
45325
+ }
45326
+ try {
45327
+ const message = await _deleteById(id);
45328
+ res.json({ message });
45329
+ return;
45330
+ } catch (error2) {
45331
+ next(error2);
45332
+ }
43771
45333
  }
43772
45334
  return {
43773
- createIndexes,
43774
45335
  add,
43775
45336
  getAll,
43776
45337
  getById,
@@ -43779,66 +45340,97 @@ function useBuildingRepo() {
43779
45340
  };
43780
45341
  }
43781
45342
 
43782
- // src/resources/building/building.service.ts
43783
- import {
43784
- BadRequestError as BadRequestError70,
43785
- NotFoundError as NotFoundError3,
43786
- useAtlas as useAtlas33
43787
- } from "@eeplatform/nodejs-utils";
45343
+ // src/resources/kindergarten-domain/kindergarten.domain.model.ts
45344
+ import { BadRequestError as BadRequestError76 } from "@eeplatform/nodejs-utils";
45345
+ import Joi50 from "joi";
45346
+ import { ObjectId as ObjectId46 } from "mongodb";
45347
+ var schemaKindergartenDomain = Joi50.object({
45348
+ _id: Joi50.string().hex().optional().allow(null, ""),
45349
+ title: Joi50.string().max(100).required(),
45350
+ school: Joi50.string().hex().required(),
45351
+ status: Joi50.string().valid("active", "inactive", "deleted").optional(),
45352
+ createdAt: Joi50.string().isoDate().optional().allow(null, ""),
45353
+ updatedAt: Joi50.string().isoDate().optional().allow(null, ""),
45354
+ deletedAt: Joi50.string().isoDate().optional().allow(null, "")
45355
+ });
45356
+ function modelKindergartenDomain(value) {
45357
+ const { error } = schemaKindergartenDomain.validate(value);
45358
+ if (error) {
45359
+ throw new BadRequestError76(
45360
+ `Invalid kindergarten domain data: ${error.message}`
45361
+ );
45362
+ }
45363
+ if (value._id && typeof value._id === "string") {
45364
+ try {
45365
+ value._id = new ObjectId46(value._id);
45366
+ } catch (error2) {
45367
+ throw new Error("Invalid _id.");
45368
+ }
45369
+ }
45370
+ if (value.school && typeof value.school === "string") {
45371
+ try {
45372
+ value.school = new ObjectId46(value.school);
45373
+ } catch (error2) {
45374
+ throw new Error("Invalid school.");
45375
+ }
45376
+ }
45377
+ return {
45378
+ _id: value._id,
45379
+ title: value.title,
45380
+ school: value.school,
45381
+ status: value.status ?? "active",
45382
+ createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
45383
+ updatedAt: value.updatedAt ?? "",
45384
+ deletedAt: value.deletedAt ?? ""
45385
+ };
45386
+ }
43788
45387
 
43789
- // src/resources/building/building-unit.repository.ts
45388
+ // src/resources/kindergarten-domain/kindergarten.domain.repository.ts
43790
45389
  import {
43791
- AppError as AppError27,
43792
- BadRequestError as BadRequestError69,
43793
- InternalServerError as InternalServerError23,
43794
- logger as logger41,
43795
- makeCacheKey as makeCacheKey23,
43796
- paginate as paginate22,
43797
- useAtlas as useAtlas32,
43798
- useCache as useCache23
45390
+ AppError as AppError29,
45391
+ BadRequestError as BadRequestError77,
45392
+ InternalServerError as InternalServerError25,
45393
+ logger as logger44,
45394
+ makeCacheKey as makeCacheKey25,
45395
+ paginate as paginate24,
45396
+ useAtlas as useAtlas36,
45397
+ useCache as useCache25
43799
45398
  } from "@eeplatform/nodejs-utils";
43800
- import { ObjectId as ObjectId43 } from "mongodb";
43801
- function useBuildingUnitRepo() {
43802
- const db = useAtlas32.getDb();
45399
+ import { ObjectId as ObjectId47 } from "mongodb";
45400
+ function useKindergartenDomainRepo() {
45401
+ const db = useAtlas36.getDb();
43803
45402
  if (!db) {
43804
45403
  throw new Error("Unable to connect to server.");
43805
45404
  }
43806
- const namespace_collection = "deped.building.units";
45405
+ const namespace_collection = "deped.kindergarten.domains";
43807
45406
  const collection = db.collection(namespace_collection);
43808
- const { getCache, setCache, delNamespace } = useCache23(namespace_collection);
45407
+ const { getCache, setCache, delNamespace } = useCache25(namespace_collection);
43809
45408
  async function createIndexes() {
43810
45409
  try {
43811
45410
  await collection.createIndexes([
43812
- {
43813
- key: { name: 1, building: 1, level: 1 },
43814
- unique: true,
43815
- name: "unique_name_index"
43816
- },
45411
+ { key: { title: 1 } },
43817
45412
  { key: { school: 1 } },
43818
- { key: { building: 1 } },
43819
- { key: { status: 1 } },
43820
45413
  { key: { createdAt: 1 } },
45414
+ { key: { createdBy: 1 } },
45415
+ { key: { title: "text" } },
43821
45416
  {
43822
- key: {
43823
- name: "text",
43824
- buildingName: "text",
43825
- category: "text",
43826
- type: "text"
43827
- }
45417
+ key: { title: 1, school: 1, status: 1 },
45418
+ unique: true,
45419
+ name: "unique_kindergarten_domain"
43828
45420
  }
43829
45421
  ]);
43830
45422
  } catch (error) {
43831
- throw new Error("Failed to create index on building units.");
45423
+ throw new Error("Failed to create index on kindergarten domains.");
43832
45424
  }
43833
45425
  }
43834
45426
  function delCachedData() {
43835
45427
  delNamespace().then(() => {
43836
- logger41.log({
45428
+ logger44.log({
43837
45429
  level: "info",
43838
45430
  message: `Cache namespace cleared for ${namespace_collection}`
43839
45431
  });
43840
45432
  }).catch((err) => {
43841
- logger41.log({
45433
+ logger44.log({
43842
45434
  level: "error",
43843
45435
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
43844
45436
  });
@@ -43846,79 +45438,23 @@ function useBuildingUnitRepo() {
43846
45438
  }
43847
45439
  async function add(value, session) {
43848
45440
  try {
43849
- value = MBuildingUnit(value);
45441
+ value = modelKindergartenDomain(value);
43850
45442
  const res = await collection.insertOne(value, { session });
43851
45443
  delCachedData();
43852
45444
  return res.insertedId;
43853
45445
  } catch (error) {
43854
- logger41.log({
45446
+ logger44.log({
43855
45447
  level: "error",
43856
45448
  message: error.message
43857
45449
  });
43858
- if (error instanceof AppError27) {
45450
+ if (error instanceof AppError29) {
43859
45451
  throw error;
43860
45452
  } else {
43861
- throw new Error("Failed to create building unit.");
43862
- }
43863
- }
43864
- }
43865
- async function updateById(_id, value, session) {
43866
- const { error } = schemaUpdateOptions.validate(value);
43867
- if (error) {
43868
- throw new BadRequestError69(error.message);
43869
- }
43870
- try {
43871
- _id = new ObjectId43(_id);
43872
- } catch (error2) {
43873
- throw new BadRequestError69(namespace_collection + " Invalid ID.");
43874
- }
43875
- try {
43876
- const res = await collection.updateOne(
43877
- { _id },
43878
- { $set: value },
43879
- { session }
43880
- );
43881
- delCachedData();
43882
- return res;
43883
- } catch (error2) {
43884
- logger41.log({
43885
- level: "error",
43886
- message: error2.message
43887
- });
43888
- if (error2 instanceof AppError27) {
43889
- throw error2;
43890
- } else {
43891
- throw new Error("Failed to create building unit.");
43892
- }
43893
- }
43894
- }
43895
- async function updateByBuildingId(building, value, session) {
43896
- const { error } = schemaUpdateOptions.validate(value);
43897
- if (error) {
43898
- throw new BadRequestError69(error.message);
43899
- }
43900
- try {
43901
- building = new ObjectId43(building);
43902
- } catch (error2) {
43903
- throw new BadRequestError69("Invalid building ID.");
43904
- }
43905
- try {
43906
- const res = await collection.updateMany(
43907
- { building },
43908
- { $set: value },
43909
- { session }
43910
- );
43911
- delCachedData();
43912
- return res;
43913
- } catch (error2) {
43914
- logger41.log({
43915
- level: "error",
43916
- message: error2.message
43917
- });
43918
- if (error2 instanceof AppError27) {
43919
- throw error2;
43920
- } else {
43921
- throw new Error("Failed to update building unit.");
45453
+ const isDuplicated = error.message.includes("duplicate");
45454
+ if (isDuplicated) {
45455
+ throw new BadRequestError77("Kindergarten domain already exists.");
45456
+ }
45457
+ throw new Error("Failed to create kindergarten domain.");
43922
45458
  }
43923
45459
  }
43924
45460
  }
@@ -43927,652 +45463,368 @@ function useBuildingUnitRepo() {
43927
45463
  page = 1,
43928
45464
  limit = 10,
43929
45465
  sort = {},
43930
- school = "",
43931
- building = "",
43932
- type = "",
43933
- status = "active"
45466
+ status = "active",
45467
+ createdBy,
45468
+ school = ""
43934
45469
  } = {}) {
43935
45470
  page = page > 0 ? page - 1 : 0;
43936
45471
  const query = {
43937
- deletedAt: { $in: ["", null] },
43938
- status: { $in: [status, "", null] }
43939
- };
43940
- const cacheParams = {
43941
- page,
43942
- limit,
43943
- sort: JSON.stringify(sort)
43944
- };
43945
- sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
43946
- if (search) {
43947
- query.$text = { $search: search };
43948
- cacheParams.search = search;
43949
- }
43950
- if (school) {
43951
- try {
43952
- query.school = new ObjectId43(school);
43953
- } catch (error) {
43954
- throw new BadRequestError69("Invalid school ID.");
43955
- }
43956
- cacheParams.school = school;
43957
- }
43958
- if (building) {
43959
- try {
43960
- query.building = new ObjectId43(building);
43961
- } catch (error) {
43962
- throw new BadRequestError69("Invalid building ID.");
43963
- }
43964
- cacheParams.building = building;
43965
- }
43966
- if (type) {
43967
- query.type = type;
43968
- cacheParams.type = type;
43969
- }
43970
- const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
43971
- logger41.log({
43972
- level: "info",
43973
- message: `Cache key for getAll building units: ${cacheKey}`
43974
- });
43975
- try {
43976
- const cached = await getCache(cacheKey);
43977
- if (cached) {
43978
- logger41.log({
43979
- level: "info",
43980
- message: `Cache hit for getAll building units: ${cacheKey}`
43981
- });
43982
- return cached;
43983
- }
43984
- const items = await collection.aggregate([
43985
- { $match: query },
43986
- { $sort: sort },
43987
- { $skip: page * limit },
43988
- { $limit: limit }
43989
- ]).toArray();
43990
- const length = await collection.countDocuments(query);
43991
- const data = paginate22(items, page, limit, length);
43992
- setCache(cacheKey, data, 600).then(() => {
43993
- logger41.log({
43994
- level: "info",
43995
- message: `Cache set for getAll building units: ${cacheKey}`
43996
- });
43997
- }).catch((err) => {
43998
- logger41.log({
43999
- level: "error",
44000
- message: `Failed to set cache for getAll building units: ${err.message}`
44001
- });
44002
- });
44003
- return data;
44004
- } catch (error) {
44005
- logger41.log({ level: "error", message: `${error}` });
44006
- throw error;
44007
- }
44008
- }
44009
- async function countByBuilding(building, level) {
44010
- const query = {
44011
- status: "active"
45472
+ deletedAt: { $in: ["", null] },
45473
+ status
44012
45474
  };
45475
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
44013
45476
  const cacheKeyOptions = {
44014
- ...query,
44015
- tag: "countByBuilding"
45477
+ status,
45478
+ page,
45479
+ limit,
45480
+ sort: JSON.stringify(sort)
44016
45481
  };
44017
- try {
44018
- query.building = new ObjectId43(building);
44019
- cacheKeyOptions.building = String(building);
44020
- } catch (error) {
44021
- throw new BadRequestError69("Invalid building ID.");
44022
- }
44023
- if (level) {
44024
- query.level = level;
44025
- cacheKeyOptions.level = level;
45482
+ if (createdBy) {
45483
+ try {
45484
+ query.createdBy = new ObjectId47(createdBy);
45485
+ } catch (error) {
45486
+ throw new BadRequestError77("Invalid createdBy ID.");
45487
+ }
45488
+ cacheKeyOptions.createdBy = createdBy;
44026
45489
  }
44027
- try {
44028
- return await collection.countDocuments(query);
44029
- } catch (error) {
44030
- logger41.log({ level: "error", message: `${error}` });
44031
- throw new InternalServerError23("Failed to count building units.");
45490
+ if (search) {
45491
+ query.$text = { $search: search };
45492
+ cacheKeyOptions.search = search;
44032
45493
  }
44033
- }
44034
- async function getById(_id) {
44035
- try {
44036
- _id = new ObjectId43(_id);
44037
- } catch (error) {
44038
- throw new BadRequestError69(namespace_collection + " Invalid ID.");
45494
+ if (school) {
45495
+ try {
45496
+ query.school = new ObjectId47(school);
45497
+ } catch (error) {
45498
+ throw new BadRequestError77("Invalid school ID.");
45499
+ }
45500
+ cacheKeyOptions.school = school;
44039
45501
  }
44040
- const cacheKey = makeCacheKey23(namespace_collection, { _id: String(_id) });
45502
+ const cacheKey = makeCacheKey25(namespace_collection, cacheKeyOptions);
45503
+ logger44.log({
45504
+ level: "info",
45505
+ message: `Cache key for getAll kindergarten domains: ${cacheKey}`
45506
+ });
44041
45507
  try {
44042
45508
  const cached = await getCache(cacheKey);
44043
45509
  if (cached) {
44044
- logger41.log({
45510
+ logger44.log({
44045
45511
  level: "info",
44046
- message: `Cache hit for getById building unit: ${cacheKey}`
45512
+ message: `Cache hit for getAll kindergarten domains: ${cacheKey}`
44047
45513
  });
44048
45514
  return cached;
44049
45515
  }
44050
- const result = await collection.findOne({
44051
- _id,
44052
- deletedAt: { $in: ["", null] }
44053
- });
44054
- if (!result) {
44055
- throw new BadRequestError69("Building unit not found.");
44056
- }
45516
+ const items = await collection.aggregate([
45517
+ { $match: query },
45518
+ { $sort: sort },
45519
+ { $skip: page * limit },
45520
+ { $limit: limit }
45521
+ ]).toArray();
45522
+ const total = await collection.countDocuments(query);
45523
+ const result = paginate24(items, total, page, limit);
44057
45524
  setCache(cacheKey, result, 300).then(() => {
44058
- logger41.log({
45525
+ logger44.log({
44059
45526
  level: "info",
44060
- message: `Cache set for building unit by id: ${cacheKey}`
45527
+ message: `Cache set for getAll kindergarten domains: ${cacheKey}`
44061
45528
  });
44062
45529
  }).catch((err) => {
44063
- logger41.log({
45530
+ logger44.log({
44064
45531
  level: "error",
44065
- message: `Failed to set cache for building unit by id: ${err.message}`
45532
+ message: `Failed to set cache for getAll kindergarten domains: ${err.message}`
44066
45533
  });
44067
45534
  });
44068
45535
  return result;
44069
45536
  } catch (error) {
44070
- if (error instanceof AppError27) {
45537
+ if (error instanceof AppError29) {
44071
45538
  throw error;
44072
45539
  } else {
44073
- throw new InternalServerError23("Failed to get building unit.");
45540
+ throw new InternalServerError25("Failed to get kindergarten domains.");
44074
45541
  }
44075
45542
  }
44076
45543
  }
44077
- async function getByBuildingLevel(building, level) {
45544
+ async function getById(_id) {
44078
45545
  try {
44079
- building = new ObjectId43(building);
45546
+ _id = new ObjectId47(_id);
44080
45547
  } catch (error) {
44081
- throw new BadRequestError69("Invalid building ID.");
45548
+ throw new BadRequestError77(namespace_collection + " Invalid ID.");
44082
45549
  }
44083
- const cacheKey = makeCacheKey23(namespace_collection, {
44084
- building: String(building),
44085
- level
45550
+ const cacheKey = makeCacheKey25(namespace_collection, {
45551
+ _id: _id.toString()
45552
+ });
45553
+ logger44.log({
45554
+ level: "info",
45555
+ message: `Cache key for getById kindergarten domain: ${cacheKey}`
44086
45556
  });
44087
45557
  try {
44088
45558
  const cached = await getCache(cacheKey);
44089
45559
  if (cached) {
44090
- logger41.log({
45560
+ logger44.log({
44091
45561
  level: "info",
44092
- message: `Cache hit for getById building unit: ${cacheKey}`
45562
+ message: `Cache hit for getById kindergarten domain: ${cacheKey}`
44093
45563
  });
44094
45564
  return cached;
44095
45565
  }
44096
45566
  const result = await collection.findOne({
44097
- building,
44098
- level,
44099
- status: "active"
45567
+ _id,
45568
+ deletedAt: { $in: ["", null] }
44100
45569
  });
45570
+ if (!result) {
45571
+ throw new BadRequestError77("Kindergarten domain not found.");
45572
+ }
44101
45573
  setCache(cacheKey, result, 300).then(() => {
44102
- logger41.log({
45574
+ logger44.log({
44103
45575
  level: "info",
44104
- message: `Cache set for building unit by id: ${cacheKey}`
45576
+ message: `Cache set for getById kindergarten domain: ${cacheKey}`
44105
45577
  });
44106
45578
  }).catch((err) => {
44107
- logger41.log({
45579
+ logger44.log({
44108
45580
  level: "error",
44109
- message: `Failed to set cache for building unit by id: ${err.message}`
45581
+ message: `Failed to set cache for getById kindergarten domain: ${err.message}`
44110
45582
  });
44111
45583
  });
44112
45584
  return result;
44113
45585
  } catch (error) {
44114
- if (error instanceof AppError27) {
45586
+ if (error instanceof AppError29) {
44115
45587
  throw error;
44116
45588
  } else {
44117
- throw new InternalServerError23("Failed to get building unit.");
45589
+ throw new InternalServerError25("Failed to get kindergarten domain.");
44118
45590
  }
44119
45591
  }
44120
45592
  }
44121
- async function getByBuilding(building) {
45593
+ async function getBySchool(school) {
44122
45594
  try {
44123
- building = new ObjectId43(building);
45595
+ school = new ObjectId47(school);
44124
45596
  } catch (error) {
44125
- throw new BadRequestError69("Invalid building ID.");
45597
+ throw new BadRequestError77("Invalid school ID.");
44126
45598
  }
44127
- const cacheKey = makeCacheKey23(namespace_collection, {
44128
- building: String(building)
45599
+ const cacheKey = makeCacheKey25(namespace_collection, {
45600
+ school: school.toString()
45601
+ });
45602
+ logger44.log({
45603
+ level: "info",
45604
+ message: `Cache key for kindergarten domain by school: ${cacheKey}`
44129
45605
  });
44130
45606
  try {
44131
45607
  const cached = await getCache(cacheKey);
44132
45608
  if (cached) {
44133
- logger41.log({
45609
+ logger44.log({
44134
45610
  level: "info",
44135
- message: `Cache hit for getById building unit: ${cacheKey}`
45611
+ message: `Cache hit for kindergarten domain by school: ${cacheKey}`
44136
45612
  });
44137
45613
  return cached;
44138
45614
  }
44139
- const result = await collection.findOne({
44140
- building,
44141
- status: "active"
44142
- });
45615
+ const result = await collection.find({
45616
+ school,
45617
+ deletedAt: { $in: ["", null] }
45618
+ }).toArray();
44143
45619
  setCache(cacheKey, result, 300).then(() => {
44144
- logger41.log({
45620
+ logger44.log({
44145
45621
  level: "info",
44146
- message: `Cache set for building unit by id: ${cacheKey}`
45622
+ message: `Cache set for kindergarten domain by school: ${cacheKey}`
44147
45623
  });
44148
45624
  }).catch((err) => {
44149
- logger41.log({
45625
+ logger44.log({
44150
45626
  level: "error",
44151
- message: `Failed to set cache for building unit by id: ${err.message}`
45627
+ message: `Failed to set cache for kindergarten domain by school: ${err.message}`
44152
45628
  });
44153
45629
  });
44154
45630
  return result;
44155
45631
  } catch (error) {
44156
- if (error instanceof AppError27) {
44157
- throw error;
44158
- } else {
44159
- throw new InternalServerError23("Failed to get building unit.");
44160
- }
44161
- }
44162
- }
44163
- async function deleteById(_id, session) {
44164
- try {
44165
- _id = new ObjectId43(_id);
44166
- } catch (error) {
44167
- throw new BadRequestError69(namespace_collection + " Invalid ID.");
44168
- }
44169
- try {
44170
- const res = await collection.updateOne(
44171
- { _id },
44172
- { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
44173
- { session }
44174
- );
44175
- delCachedData();
44176
- return "Room/Facility deleted successfully.";
44177
- } catch (error) {
44178
- logger41.log({
44179
- level: "error",
44180
- message: error.message
44181
- });
44182
- if (error instanceof AppError27) {
45632
+ if (error instanceof AppError29) {
44183
45633
  throw error;
44184
45634
  } else {
44185
- throw new Error("Failed to deleted room/facility.");
44186
- }
44187
- }
44188
- }
44189
- return {
44190
- createIndexes,
44191
- add,
44192
- getAll,
44193
- getById,
44194
- getByBuildingLevel,
44195
- updateById,
44196
- getByBuilding,
44197
- deleteById,
44198
- updateByBuildingId,
44199
- countByBuilding
44200
- };
44201
- }
44202
-
44203
- // src/resources/building/building.service.ts
44204
- function useBuildingService() {
44205
- const {
44206
- updateById: _updateById,
44207
- getById: _getById,
44208
- deleteById: _deleteById
44209
- } = useBuildingRepo();
44210
- const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
44211
- async function updateById(id, data) {
44212
- data.levels = Number(data.levels);
44213
- const session = useAtlas33.getClient()?.startSession();
44214
- try {
44215
- const building = await _getById(id);
44216
- if (!building) {
44217
- throw new NotFoundError3("Building not found.");
44218
- }
44219
- if (data.levels < building.levels) {
44220
- const unit = await getByBuildingLevel(id, building.levels);
44221
- if (unit) {
44222
- throw new BadRequestError70(
44223
- "Cannot reduce floors, there are existing building units at higher floors."
44224
- );
44225
- }
44226
- }
44227
- session?.startTransaction();
44228
- if (building.name !== data.name) {
44229
- await updateByBuildingId(id, { buildingName: data.name }, session);
44230
- }
44231
- const result = await _updateById(id, data, session);
44232
- await session?.commitTransaction();
44233
- return result;
44234
- } catch (error) {
44235
- await session?.abortTransaction();
44236
- throw error;
44237
- } finally {
44238
- session?.endSession();
44239
- }
44240
- }
44241
- async function deleteById(id) {
44242
- const building = await getByBuilding(id);
44243
- if (building) {
44244
- throw new BadRequestError70(
44245
- "Cannot delete building with existing room/facility. Please delete room/facility first."
44246
- );
44247
- }
44248
- try {
44249
- await _deleteById(id);
44250
- return "Building deleted successfully.";
44251
- } catch (error) {
44252
- throw error;
44253
- }
44254
- }
44255
- return {
44256
- updateById,
44257
- deleteById
44258
- };
44259
- }
44260
-
44261
- // src/resources/building/building.controller.ts
44262
- import { BadRequestError as BadRequestError71, logger as logger42 } from "@eeplatform/nodejs-utils";
44263
- import Joi46 from "joi";
44264
- function useBuildingController() {
44265
- const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
44266
- const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
44267
- async function createBuilding(req, res, next) {
44268
- const value = req.body;
44269
- const validation = Joi46.object({
44270
- name: Joi46.string().required(),
44271
- school: Joi46.string().hex().required(),
44272
- levels: Joi46.number().integer().min(1).required(),
44273
- serial: Joi46.string().optional().allow("", null),
44274
- status: Joi46.string().optional().allow("", null)
44275
- });
44276
- const { error } = validation.validate(value);
44277
- if (error) {
44278
- next(new BadRequestError71(error.message));
44279
- logger42.info(`Controller: ${error.message}`);
44280
- return;
44281
- }
44282
- try {
44283
- const result = await _add(value);
44284
- res.json(result);
44285
- return;
44286
- } catch (error2) {
44287
- next(error2);
44288
- }
44289
- }
44290
- async function updateById(req, res, next) {
44291
- const value = req.body;
44292
- const id = req.params.id ?? "";
44293
- const validation = Joi46.object({
44294
- id: Joi46.string().hex().required(),
44295
- value: Joi46.object({
44296
- name: Joi46.string().required(),
44297
- serial: Joi46.string().optional().allow("", null),
44298
- levels: Joi46.number().integer().min(1).required()
44299
- })
44300
- });
44301
- const { error } = validation.validate({ id, value });
44302
- if (error) {
44303
- next(new BadRequestError71(error.message));
44304
- logger42.info(`Controller: ${error.message}`);
44305
- return;
44306
- }
44307
- try {
44308
- const result = await _updateById(id, value);
44309
- res.json(result);
44310
- return;
44311
- } catch (error2) {
44312
- next(error2);
44313
- }
44314
- }
44315
- async function getAll(req, res, next) {
44316
- const query = req.query;
44317
- const validation = Joi46.object({
44318
- page: Joi46.number().min(1).optional().allow("", null),
44319
- limit: Joi46.number().min(1).optional().allow("", null),
44320
- search: Joi46.string().optional().allow("", null),
44321
- school: Joi46.string().hex().optional().allow("", null),
44322
- status: Joi46.string().optional().allow("", null)
44323
- });
44324
- const { error } = validation.validate(query);
44325
- if (error) {
44326
- next(new BadRequestError71(error.message));
44327
- return;
44328
- }
44329
- const page = parseInt(req.query.page) ?? 1;
44330
- let limit = parseInt(req.query.limit) ?? 20;
44331
- limit = isNaN(limit) ? 20 : limit;
44332
- const sort = req.query.sort ? String(req.query.sort).split(",") : "";
44333
- const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
44334
- const sortObj = {};
44335
- if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
44336
- sort.forEach((field, index) => {
44337
- sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
44338
- });
45635
+ throw new InternalServerError25("Failed to get kindergarten domain.");
45636
+ }
45637
+ }
45638
+ }
45639
+ async function updateFieldById({ _id, field, value } = {}, session) {
45640
+ const allowedFields = ["title", "status"];
45641
+ if (!allowedFields.includes(field)) {
45642
+ throw new BadRequestError77(
45643
+ `Field "${field}" is not allowed to be updated.`
45644
+ );
44339
45645
  }
44340
- const status = req.query.status ?? "active";
44341
- const school = req.query.school ?? "";
44342
- const search = req.query.search ?? "";
44343
45646
  try {
44344
- const buildings = await _getAll({
44345
- page,
44346
- limit,
44347
- sort: sortObj,
44348
- status,
44349
- school,
44350
- search
44351
- });
44352
- res.json(buildings);
44353
- return;
44354
- } catch (error2) {
44355
- next(error2);
45647
+ _id = new ObjectId47(_id);
45648
+ } catch (error) {
45649
+ throw new BadRequestError77(namespace_collection + " Invalid ID.");
45650
+ }
45651
+ try {
45652
+ await collection.updateOne(
45653
+ { _id, deletedAt: { $in: ["", null] } },
45654
+ { $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
45655
+ { session }
45656
+ );
45657
+ delCachedData();
45658
+ return `Successfully updated kindergarten domain ${field}.`;
45659
+ } catch (error) {
45660
+ throw new InternalServerError25(
45661
+ `Failed to update kindergarten domain ${field}.`
45662
+ );
44356
45663
  }
44357
45664
  }
44358
- async function getById(req, res, next) {
44359
- const id = req.params.id;
44360
- const validation = Joi46.object({
44361
- id: Joi46.string().hex().required()
44362
- });
44363
- const { error } = validation.validate({ id });
45665
+ async function updateById(_id, value, session) {
45666
+ const { error } = schemaKindergartenDomain.validate(value);
44364
45667
  if (error) {
44365
- next(new BadRequestError71(error.message));
44366
- return;
45668
+ throw new BadRequestError77(
45669
+ `Invalid kindergarten domain data: ${error.message}`
45670
+ );
44367
45671
  }
44368
45672
  try {
44369
- const building = await _getById(id);
44370
- res.json({
44371
- message: "Successfully retrieved building.",
44372
- data: { building }
44373
- });
44374
- return;
45673
+ _id = new ObjectId47(_id);
44375
45674
  } catch (error2) {
44376
- next(error2);
45675
+ throw new BadRequestError77(namespace_collection + " Invalid ID.");
45676
+ }
45677
+ try {
45678
+ await collection.updateOne(
45679
+ { _id },
45680
+ { $set: { ...value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
45681
+ { session }
45682
+ );
45683
+ delCachedData();
45684
+ return `Successfully updated kindergarten domain.`;
45685
+ } catch (error2) {
45686
+ throw new InternalServerError25("Failed to update kindergarten domain.");
44377
45687
  }
44378
45688
  }
44379
- async function deleteById(req, res, next) {
44380
- const id = req.params.id;
44381
- const validation = Joi46.object({
44382
- id: Joi46.string().hex().required()
44383
- });
44384
- const { error } = validation.validate({ id });
44385
- if (error) {
44386
- next(new BadRequestError71(error.message));
44387
- return;
45689
+ async function deleteById(_id, session) {
45690
+ try {
45691
+ _id = new ObjectId47(_id);
45692
+ } catch (error) {
45693
+ throw new BadRequestError77(namespace_collection + " Invalid ID.");
44388
45694
  }
44389
45695
  try {
44390
- const message = await _deleteById(id);
44391
- res.json(message);
44392
- return;
44393
- } catch (error2) {
44394
- next(error2);
45696
+ await collection.updateOne(
45697
+ { _id },
45698
+ { $set: { status: "deleted", deletedAt: (/* @__PURE__ */ new Date()).toISOString() } },
45699
+ { session }
45700
+ );
45701
+ delCachedData();
45702
+ return "Successfully deleted kindergarten domain.";
45703
+ } catch (error) {
45704
+ throw new InternalServerError25("Failed to delete kindergarten domain.");
44395
45705
  }
44396
45706
  }
44397
45707
  return {
44398
- createBuilding,
45708
+ createIndexes,
45709
+ add,
44399
45710
  getAll,
44400
45711
  getById,
45712
+ getBySchool,
45713
+ updateFieldById,
44401
45714
  updateById,
44402
45715
  deleteById
44403
45716
  };
44404
45717
  }
44405
45718
 
44406
- // src/resources/building/building-unit.service.ts
44407
- import { useAtlas as useAtlas34 } from "@eeplatform/nodejs-utils";
44408
- function useBuildingUnitService() {
44409
- const {
44410
- add: _add,
44411
- countByBuilding,
44412
- deleteById: _deleteById
44413
- } = useBuildingUnitRepo();
44414
- async function add(value) {
44415
- const session = useAtlas34.getClient()?.startSession();
45719
+ // src/resources/kindergarten-domain/kindergarten.domain.service.ts
45720
+ import { AppError as AppError30, BadRequestError as BadRequestError78, useAtlas as useAtlas37 } from "@eeplatform/nodejs-utils";
45721
+ function useKindergartenDomainService() {
45722
+ const { deleteById: _deleteById, getById } = useKindergartenDomainRepo();
45723
+ const { countByDomain } = useKindergartenRoutineRepo();
45724
+ async function deleteById(id) {
45725
+ const session = useAtlas37.getClient()?.startSession();
44416
45726
  if (!session) {
44417
- throw new Error("Unable to start session for building unit service.");
45727
+ throw new Error("Failed to start database session.");
44418
45728
  }
44419
45729
  try {
44420
- await session.startTransaction();
44421
- const existingCount = await countByBuilding(
44422
- value.building.building,
44423
- value.building.level
44424
- );
44425
- for (let index = 0; index < value.qty; index++) {
44426
- const unitNumber = existingCount ? existingCount + index + 1 : index + 1;
44427
- await _add(
44428
- { ...value.building, name: `${value.building.name} R${unitNumber}` },
44429
- session
45730
+ session.startTransaction();
45731
+ const domain = await getById(id);
45732
+ if (!domain) {
45733
+ throw new BadRequestError78("Kindergarten domain not found.");
45734
+ }
45735
+ const usageCount = await countByDomain(domain.title);
45736
+ if (usageCount > 0) {
45737
+ throw new BadRequestError78(
45738
+ "Cannot delete domain as it is currently in use."
44430
45739
  );
44431
45740
  }
44432
- await session.commitTransaction();
44433
- return "Building unit added successfully.";
45741
+ await _deleteById(id, session);
44434
45742
  } catch (error) {
44435
45743
  await session.abortTransaction();
44436
- throw error;
45744
+ if (error instanceof AppError30) {
45745
+ throw error;
45746
+ } else {
45747
+ throw new AppError30("Failed to delete kindergarten domain.", 500);
45748
+ }
44437
45749
  } finally {
44438
- session.endSession();
44439
- }
44440
- }
44441
- const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
44442
- async function deleteById(id) {
44443
- if (!id) {
44444
- throw new Error("Invalid building unit ID.");
44445
- }
44446
- const sectionSubject = await getSectionSubjectByClassroom(id);
44447
- if (sectionSubject) {
44448
- throw new Error(
44449
- "Cannot delete building unit as it is assigned to a section subject."
44450
- );
44451
- }
44452
- try {
44453
- await _deleteById(id);
44454
- return "Building unit deleted successfully.";
44455
- } catch (error) {
44456
- throw new Error("Failed to delete building unit.");
45750
+ await session.endSession();
44457
45751
  }
44458
45752
  }
44459
45753
  return {
44460
- add,
44461
45754
  deleteById
44462
45755
  };
44463
45756
  }
44464
45757
 
44465
- // src/resources/building/building-unit.controller.ts
44466
- import { BadRequestError as BadRequestError72 } from "@eeplatform/nodejs-utils";
44467
- import Joi47 from "joi";
44468
- function useBuildingUnitController() {
45758
+ // src/resources/kindergarten-domain/kindergarten.domain.controller.ts
45759
+ import { BadRequestError as BadRequestError79 } from "@eeplatform/nodejs-utils";
45760
+ import Joi51 from "joi";
45761
+ function useKindergartenDomainController() {
44469
45762
  const {
45763
+ add: _add,
44470
45764
  getAll: _getAll,
44471
45765
  getById: _getById,
44472
- updateById: _updateById
44473
- } = useBuildingUnitRepo();
44474
- const { add: _add, deleteById: _deleteById } = useBuildingUnitService();
45766
+ getBySchool: _getBySchool,
45767
+ updateFieldById: _updateFieldById
45768
+ } = useKindergartenDomainRepo();
44475
45769
  async function add(req, res, next) {
44476
- const data = req.body;
44477
- const validation = Joi47.object({
44478
- building: Joi47.object({
44479
- school: Joi47.string().hex().required(),
44480
- name: Joi47.string().optional().allow("", null),
44481
- building: Joi47.string().hex().required(),
44482
- buildingName: Joi47.string().optional().allow("", null),
44483
- level: Joi47.number().integer().min(1).required(),
44484
- category: Joi47.string().required(),
44485
- type: Joi47.string().required(),
44486
- seating_capacity: Joi47.number().integer().min(0).required(),
44487
- standing_capacity: Joi47.number().integer().min(0).required(),
44488
- description: Joi47.string().optional().allow("", null),
44489
- unit_of_measurement: Joi47.string().valid("sqm").required(),
44490
- area: Joi47.number().positive().required(),
44491
- status: Joi47.string().optional().allow("", null)
44492
- }),
44493
- qty: Joi47.number().integer().min(1).max(20).optional().default(1)
44494
- });
44495
- const { error } = validation.validate(data);
45770
+ const value = req.body;
45771
+ const { error } = schemaKindergartenDomain.validate(value);
44496
45772
  if (error) {
44497
- next(new BadRequestError72(error.message));
45773
+ next(new BadRequestError79(error.message));
44498
45774
  return;
44499
45775
  }
44500
45776
  try {
44501
- const buildingUnit = await _add(data);
45777
+ const data = await _add(value);
44502
45778
  res.json({
44503
- message: "Building unit added successfully.",
44504
- data: { buildingUnit }
45779
+ message: "Successfully created kindergarten domain.",
45780
+ data
44505
45781
  });
44506
- } catch (error2) {
44507
- next(error2);
44508
- }
44509
- }
44510
- async function updateById(req, res, next) {
44511
- const data = req.body;
44512
- const id = req.params.id ?? "";
44513
- const validation = Joi47.object({
44514
- id: Joi47.string().hex().required(),
44515
- value: schemaUpdateOptions
44516
- });
44517
- const { error } = validation.validate({ id, value: data });
44518
- if (error) {
44519
- next(new BadRequestError72(error.message));
44520
45782
  return;
44521
- }
44522
- try {
44523
- const buildingUnit = await _updateById(id, data);
44524
- res.json({
44525
- message: "Building unit updated successfully.",
44526
- data: { buildingUnit }
44527
- });
44528
45783
  } catch (error2) {
44529
45784
  next(error2);
44530
45785
  }
44531
45786
  }
44532
45787
  async function getAll(req, res, next) {
44533
45788
  const query = req.query;
44534
- const validation = Joi47.object({
44535
- page: Joi47.number().min(1).optional().allow("", null),
44536
- limit: Joi47.number().min(1).optional().allow("", null),
44537
- search: Joi47.string().optional().allow("", null),
44538
- school: Joi47.string().hex().optional().allow("", null),
44539
- building: Joi47.string().hex().optional().allow("", null),
44540
- status: Joi47.string().optional().allow("", null),
44541
- type: Joi47.string().optional().allow("", null)
45789
+ const validation = Joi51.object({
45790
+ page: Joi51.number().min(1).optional().allow("", null),
45791
+ limit: Joi51.number().min(1).optional().allow("", null),
45792
+ search: Joi51.string().optional().allow("", null),
45793
+ status: Joi51.string().optional().allow("", null),
45794
+ school: Joi51.string().hex().optional().allow("", null),
45795
+ createdBy: Joi51.string().hex().optional().allow("", null)
44542
45796
  });
44543
45797
  const { error } = validation.validate(query);
44544
- if (error) {
44545
- next(new BadRequestError72(error.message));
45798
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
45799
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
45800
+ const search = req.query.search ?? "";
45801
+ const status = req.query.status ?? "active";
45802
+ const school = req.query.school ?? "";
45803
+ const createdBy = req.query.createdBy ?? "";
45804
+ const isPageNumber = isFinite(page);
45805
+ if (!isPageNumber) {
45806
+ next(new BadRequestError79("Invalid page number."));
44546
45807
  return;
44547
45808
  }
44548
- const page = parseInt(req.query.page) ?? 1;
44549
- let limit = parseInt(req.query.limit) ?? 20;
44550
- limit = isNaN(limit) ? 20 : limit;
44551
- const sort = req.query.sort ? String(req.query.sort).split(",") : "";
44552
- const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
44553
- const sortObj = {};
44554
- if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
44555
- sort.forEach((field, index) => {
44556
- sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
44557
- });
45809
+ const isLimitNumber = isFinite(limit);
45810
+ if (!isLimitNumber) {
45811
+ next(new BadRequestError79("Invalid limit number."));
45812
+ return;
45813
+ }
45814
+ if (error) {
45815
+ next(new BadRequestError79(error.message));
45816
+ return;
44558
45817
  }
44559
- const status = req.query.status ?? "active";
44560
- const school = req.query.school ?? "";
44561
- const building = req.query.building ?? "";
44562
- const search = req.query.search ?? "";
44563
- const type = req.query.type ?? "";
44564
45818
  try {
44565
- const buildings = await _getAll({
45819
+ const data = await _getAll({
44566
45820
  page,
44567
45821
  limit,
44568
- sort: sortObj,
45822
+ search,
44569
45823
  status,
44570
45824
  school,
44571
- search,
44572
- building,
44573
- type
45825
+ createdBy: createdBy || void 0
44574
45826
  });
44575
- res.json(buildings);
45827
+ res.json(data);
44576
45828
  return;
44577
45829
  } catch (error2) {
44578
45830
  next(error2);
@@ -44580,37 +45832,80 @@ function useBuildingUnitController() {
44580
45832
  }
44581
45833
  async function getById(req, res, next) {
44582
45834
  const id = req.params.id;
44583
- const validation = Joi47.object({
44584
- id: Joi47.string().hex().required()
45835
+ const validation = Joi51.object({
45836
+ id: Joi51.string().hex().required()
44585
45837
  });
44586
45838
  const { error } = validation.validate({ id });
44587
45839
  if (error) {
44588
- next(new BadRequestError72(error.message));
45840
+ next(new BadRequestError79(error.message));
44589
45841
  return;
44590
45842
  }
44591
45843
  try {
44592
- const buildingUnit = await _getById(id);
45844
+ const data = await _getById(id);
44593
45845
  res.json({
44594
- message: "Successfully retrieved building unit.",
44595
- data: { buildingUnit }
45846
+ message: "Successfully retrieved kindergarten domain.",
45847
+ data
45848
+ });
45849
+ return;
45850
+ } catch (error2) {
45851
+ next(error2);
45852
+ }
45853
+ }
45854
+ async function getBySchool(req, res, next) {
45855
+ const school = req.params.school;
45856
+ const validation = Joi51.object({
45857
+ school: Joi51.string().hex().required()
45858
+ });
45859
+ const { error } = validation.validate({ school });
45860
+ if (error) {
45861
+ next(new BadRequestError79(error.message));
45862
+ return;
45863
+ }
45864
+ try {
45865
+ const data = await _getBySchool(school);
45866
+ res.json({
45867
+ message: "Successfully retrieved kindergarten domains.",
45868
+ data
44596
45869
  });
44597
45870
  return;
44598
45871
  } catch (error2) {
44599
45872
  next(error2);
44600
45873
  }
44601
45874
  }
45875
+ async function updateField(req, res, next) {
45876
+ const _id = req.params.id;
45877
+ const { field, value } = req.body;
45878
+ const validation = Joi51.object({
45879
+ _id: Joi51.string().hex().required(),
45880
+ field: Joi51.string().valid("title", "status").required(),
45881
+ value: Joi51.alternatives().try(Joi51.string(), Joi51.array(), Joi51.object()).required()
45882
+ });
45883
+ const { error } = validation.validate({ _id, field, value });
45884
+ if (error) {
45885
+ next(new BadRequestError79(error.message));
45886
+ return;
45887
+ }
45888
+ try {
45889
+ const message = await _updateFieldById({ _id, field, value });
45890
+ res.json({ message });
45891
+ return;
45892
+ } catch (error2) {
45893
+ next(error2);
45894
+ }
45895
+ }
45896
+ const { deleteById: _deleteById } = useKindergartenDomainService();
44602
45897
  async function deleteById(req, res, next) {
44603
- const id = req.params.id;
44604
- const validation = Joi47.object({
44605
- id: Joi47.string().hex().required()
45898
+ const _id = req.params.id;
45899
+ const validation = Joi51.object({
45900
+ _id: Joi51.string().hex().required()
44606
45901
  });
44607
- const { error } = validation.validate({ id });
45902
+ const { error } = validation.validate({ _id });
44608
45903
  if (error) {
44609
- next(new BadRequestError72(error.message));
45904
+ next(new BadRequestError79(error.message));
44610
45905
  return;
44611
45906
  }
44612
45907
  try {
44613
- const message = await _deleteById(id);
45908
+ const message = await _deleteById(_id);
44614
45909
  res.json({ message });
44615
45910
  return;
44616
45911
  } catch (error2) {
@@ -44621,7 +45916,8 @@ function useBuildingUnitController() {
44621
45916
  add,
44622
45917
  getAll,
44623
45918
  getById,
44624
- updateById,
45919
+ getBySchool,
45920
+ updateField,
44625
45921
  deleteById
44626
45922
  };
44627
45923
  }
@@ -44642,6 +45938,8 @@ export {
44642
45938
  allowedSectionStudentStatuses,
44643
45939
  modelBasicEduCount,
44644
45940
  modelDivision,
45941
+ modelKindergartenDomain,
45942
+ modelKindergartenRoutine,
44645
45943
  modelProgram,
44646
45944
  modelProgramScreening,
44647
45945
  modelRegion,
@@ -44664,6 +45962,9 @@ export {
44664
45962
  schemaEnrollment,
44665
45963
  schemaGenerateSections,
44666
45964
  schemaGradeLevel,
45965
+ schemaKindergartenDomain,
45966
+ schemaKindergartenRoutine,
45967
+ schemaKindergartenRoutineUpdate,
44667
45968
  schemaPersonnel,
44668
45969
  schemaPlantilla,
44669
45970
  schemaProgram,
@@ -44705,6 +46006,11 @@ export {
44705
46006
  useEnrollmentService,
44706
46007
  useGradeLevelController,
44707
46008
  useGradeLevelRepo,
46009
+ useKindergartenDomainController,
46010
+ useKindergartenDomainRepo,
46011
+ useKindergartenDomainService,
46012
+ useKindergartenRoutineController,
46013
+ useKindergartenRoutineRepo,
44708
46014
  useLearnerController,
44709
46015
  useLearnerRepo,
44710
46016
  usePersonnelController,