@eeplatform/basic-edu 1.9.4 → 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,441 +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
- throw new BadRequestError64(
42985
- "Could not proceed, no teaching personnel found."
42986
- );
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;
42987
44424
  }
42988
- if (teachers.length) {
42989
- for (let index = 0; index < teachers.length; index++) {
42990
- const teacher = teachers[index];
42991
- if (!teacher._id) {
42992
- throw new BadRequestError64("Teacher ID is missing.");
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"
42993
44541
  }
42994
- await addTeachingLoad(
42995
- {
42996
- school: value.school,
42997
- schoolName: schoolData.name,
42998
- schoolYear: value.schoolYear,
42999
- teacher: teacher._id.toString(),
43000
- teacherName: `${teacher.firstName} ${teacher.lastName}`,
43001
- status: "draft"
43002
- },
43003
- session
43004
- );
43005
44542
  }
43006
- }
43007
- await session.commitTransaction();
43008
- return "Sections generated successfully.";
43009
- } catch (error2) {
43010
- await session.abortTransaction();
43011
- if (error2 instanceof AppError25) {
43012
- 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;
43013
44574
  } else {
43014
- throw new InternalServerError21("Failed to generate sections.");
44575
+ throw new Error("Failed to create building unit.");
43015
44576
  }
43016
- } finally {
43017
- await session?.endSession();
43018
44577
  }
43019
44578
  }
43020
- async function generateSectionPreview(value) {
43021
- const { error } = schemaGenerateSections.validate(value);
44579
+ async function updateById(_id, value, session) {
44580
+ const { error } = schemaUpdateOptions.validate(value);
43022
44581
  if (error) {
43023
- throw new BadRequestError64(
43024
- `Invalid section generation data: ${error.message}`
43025
- );
44582
+ throw new BadRequestError72(error.message);
43026
44583
  }
43027
44584
  try {
43028
- const studentCount = await getCountByGradeLevel({
43029
- school: value.school,
43030
- schoolYear: value.schoolYear,
43031
- gradeLevel: value.gradeLevel,
43032
- specialProgram: value.specialProgram
43033
- });
43034
- if (studentCount === 0) {
43035
- throw new BadRequestError64("No learners found for this grade level.");
43036
- }
43037
- const gradeLevelData = await getByGradeLevel({
43038
- school: value.school,
43039
- gradeLevel: value.gradeLevel
43040
- });
43041
- if (!gradeLevelData) {
43042
- throw new BadRequestError64("Grade level not found.");
43043
- }
43044
- const minPerSection = value.minStudents ?? gradeLevelData.minNumberOfLearners;
43045
- const maxPerSection = value.maxStudents ?? gradeLevelData.maxNumberOfLearners;
43046
- const sectionsNeeded = Math.ceil(studentCount / minPerSection);
43047
- if (sectionsNeeded > value.set.length) {
43048
- throw new BadRequestError64(
43049
- "Insufficient number of section names in set[]."
43050
- );
43051
- }
43052
- const sectionSizes = distributeStudents(
43053
- studentCount,
43054
- minPerSection,
43055
- 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 }
43056
44594
  );
43057
- if (sectionSizes.length === 0) {
43058
- throw new BadRequestError64("Unable to compute section sizes.");
43059
- }
43060
- const sections = sectionSizes.map((size, index) => ({
43061
- name: value.set[index],
43062
- value: size
43063
- }));
43064
- return {
43065
- totalSectionsGenerated: sectionSizes.length,
43066
- totalStudentsAssigned: studentCount,
43067
- sections
43068
- };
44595
+ delCachedData();
44596
+ return res;
43069
44597
  } catch (error2) {
43070
- if (error2 instanceof AppError25) {
44598
+ logger42.log({
44599
+ level: "error",
44600
+ message: error2.message
44601
+ });
44602
+ if (error2 instanceof AppError28) {
43071
44603
  throw error2;
43072
44604
  } else {
43073
- throw new InternalServerError21("Failed to generate section preview.");
44605
+ throw new Error("Failed to create building unit.");
43074
44606
  }
43075
44607
  }
43076
44608
  }
43077
- return { generateSections, generateSectionPreview };
43078
- }
43079
-
43080
- // src/resources/section/section.controller.ts
43081
- function useSectionController() {
43082
- const {
43083
- add: _add,
43084
- getAll: _getAll,
43085
- getById: _getById,
43086
- getByName: _getByName,
43087
- getBySchool: _getBySchool,
43088
- updateFieldById: _updateFieldById,
43089
- addStudentToSection: _addStudentToSection,
43090
- removeStudentFromSection: _removeStudentFromSection,
43091
- deleteById: _deleteById
43092
- } = useSectionRepo();
43093
- const {
43094
- generateSections: _generateSections,
43095
- generateSectionPreview: _generateSectionPreview
43096
- } = useSectionService();
43097
- async function add(req, res, next) {
43098
- const value = req.body;
43099
- const { error } = schemaSection.validate(value);
44609
+ async function updateByBuildingId(building, value, session) {
44610
+ const { error } = schemaUpdateOptions.validate(value);
43100
44611
  if (error) {
43101
- next(new BadRequestError65(error.message));
43102
- return;
44612
+ throw new BadRequestError72(error.message);
43103
44613
  }
43104
44614
  try {
43105
- const data = await _add(value);
43106
- res.json({
43107
- message: "Successfully created section.",
43108
- data
43109
- });
43110
- return;
44615
+ building = new ObjectId45(building);
43111
44616
  } catch (error2) {
43112
- 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
+ }
43113
44637
  }
43114
44638
  }
43115
- async function generateSections(req, res, next) {
43116
- const value = req.body;
43117
- const { error } = schemaGenerateSections.validate(value);
43118
- if (error) {
43119
- next(new BadRequestError65(error.message));
43120
- 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;
43121
44683
  }
44684
+ const cacheKey = makeCacheKey24(namespace_collection, cacheParams);
44685
+ logger42.log({
44686
+ level: "info",
44687
+ message: `Cache key for getAll building units: ${cacheKey}`
44688
+ });
43122
44689
  try {
43123
- const data = await _generateSections(value);
43124
- res.json({
43125
- message: "Successfully created section.",
43126
- 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
+ });
43127
44716
  });
43128
- return;
43129
- } catch (error2) {
43130
- next(error2);
44717
+ return data;
44718
+ } catch (error) {
44719
+ logger42.log({ level: "error", message: `${error}` });
44720
+ throw error;
43131
44721
  }
43132
44722
  }
43133
- async function generateSectionPreview(req, res, next) {
43134
- const value = req.body;
43135
- const { error } = schemaGenerateSections.validate(value);
43136
- if (error) {
43137
- next(new BadRequestError65(error.message));
43138
- return;
43139
- }
44723
+ async function countByBuilding(building, level) {
44724
+ const query = {
44725
+ status: "active"
44726
+ };
44727
+ const cacheKeyOptions = {
44728
+ ...query,
44729
+ tag: "countByBuilding"
44730
+ };
43140
44731
  try {
43141
- const data = await _generateSectionPreview(value);
43142
- res.json(data);
43143
- return;
43144
- } catch (error2) {
43145
- next(error2);
44732
+ query.building = new ObjectId45(building);
44733
+ cacheKeyOptions.building = String(building);
44734
+ } catch (error) {
44735
+ throw new BadRequestError72("Invalid building ID.");
43146
44736
  }
43147
- }
43148
- async function getAll(req, res, next) {
43149
- const query = req.query;
43150
- const validation = Joi43.object({
43151
- page: Joi43.number().min(1).optional().allow("", null),
43152
- limit: Joi43.number().min(1).optional().allow("", null),
43153
- search: Joi43.string().optional().allow("", null),
43154
- status: Joi43.string().optional().allow("", null),
43155
- school: Joi43.string().hex().optional().allow("", null),
43156
- schoolYear: Joi43.string().optional().allow("", null),
43157
- gradeLevel: Joi43.string().optional().allow("", null)
43158
- });
43159
- const { error } = validation.validate(query);
43160
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
43161
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
43162
- const search = req.query.search ?? "";
43163
- const status = req.query.status ?? "active";
43164
- const school = req.query.school ?? "";
43165
- const schoolYear = req.query.schoolYear ?? "";
43166
- const gradeLevel = req.query.gradeLevel ?? "";
43167
- const isPageNumber = isFinite(page);
43168
- if (!isPageNumber) {
43169
- next(new BadRequestError65("Invalid page number."));
43170
- return;
44737
+ if (level) {
44738
+ query.level = level;
44739
+ cacheKeyOptions.level = level;
43171
44740
  }
43172
- const isLimitNumber = isFinite(limit);
43173
- if (!isLimitNumber) {
43174
- next(new BadRequestError65("Invalid limit number."));
43175
- 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.");
43176
44746
  }
43177
- if (error) {
43178
- next(new BadRequestError65(error.message));
43179
- 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.");
43180
44753
  }
44754
+ const cacheKey = makeCacheKey24(namespace_collection, { _id: String(_id) });
43181
44755
  try {
43182
- const data = await _getAll({
43183
- page,
43184
- limit,
43185
- search,
43186
- status,
43187
- school,
43188
- schoolYear,
43189
- 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] }
43190
44767
  });
43191
- res.json(data);
43192
- return;
43193
- } catch (error2) {
43194
- 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
+ }
43195
44789
  }
43196
44790
  }
43197
- async function getById(req, res, next) {
43198
- const id = req.params.id;
43199
- const validation = Joi43.object({
43200
- id: Joi43.string().hex().required()
43201
- });
43202
- const { error } = validation.validate({ id });
43203
- if (error) {
43204
- next(new BadRequestError65(error.message));
43205
- return;
43206
- }
44791
+ async function getByBuildingLevel(building, level) {
43207
44792
  try {
43208
- const data = await _getById(id);
43209
- res.json(data);
43210
- return;
43211
- } catch (error2) {
43212
- next(error2);
44793
+ building = new ObjectId45(building);
44794
+ } catch (error) {
44795
+ throw new BadRequestError72("Invalid building ID.");
43213
44796
  }
43214
- }
43215
- async function getByName(req, res, next) {
43216
- const name = req.params.name;
43217
- const validation = Joi43.object({
43218
- name: Joi43.string().required()
44797
+ const cacheKey = makeCacheKey24(namespace_collection, {
44798
+ building: String(building),
44799
+ level
43219
44800
  });
43220
- const { error } = validation.validate({ name });
43221
- if (error) {
43222
- next(new BadRequestError65(error.message));
43223
- return;
43224
- }
43225
44801
  try {
43226
- const data = await _getByName(name);
43227
- res.json({
43228
- message: "Successfully retrieved section.",
43229
- 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"
43230
44814
  });
43231
- return;
43232
- } catch (error2) {
43233
- 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
+ }
43234
44833
  }
43235
44834
  }
43236
- async function getBySchool(req, res, next) {
43237
- const school = req.params.school;
43238
- const validation = Joi43.object({
43239
- school: Joi43.string().hex().required()
43240
- });
43241
- const { error } = validation.validate({ school });
43242
- if (error) {
43243
- next(new BadRequestError65(error.message));
43244
- return;
44835
+ async function getByBuilding(building) {
44836
+ try {
44837
+ building = new ObjectId45(building);
44838
+ } catch (error) {
44839
+ throw new BadRequestError72("Invalid building ID.");
43245
44840
  }
44841
+ const cacheKey = makeCacheKey24(namespace_collection, {
44842
+ building: String(building)
44843
+ });
43246
44844
  try {
43247
- const data = await _getBySchool(school);
43248
- res.json({
43249
- message: "Successfully retrieved sections.",
43250
- 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"
43251
44856
  });
43252
- return;
43253
- } catch (error2) {
43254
- 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
+ }
43255
44875
  }
43256
44876
  }
43257
- async function updateField(req, res, next) {
43258
- const _id = req.params.id;
43259
- const { field, value } = req.body;
43260
- const validation = Joi43.object({
43261
- _id: Joi43.string().hex().required(),
43262
- field: Joi43.string().valid("name", "schoolYear", "gradeLevel", "adviser", "adviserName").required(),
43263
- value: Joi43.string().required()
43264
- });
43265
- const { error } = validation.validate({ _id, field, value });
43266
- if (error) {
43267
- next(new BadRequestError65(error.message));
43268
- 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.");
43269
44882
  }
43270
44883
  try {
43271
- const message = await _updateFieldById({ _id, field, value });
43272
- res.json({ message });
43273
- return;
43274
- } catch (error2) {
43275
- 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
+ }
43276
44901
  }
43277
44902
  }
43278
- async function addStudent(req, res, next) {
43279
- const _id = req.params.id;
43280
- const { studentId } = req.body;
43281
- const validation = Joi43.object({
43282
- _id: Joi43.string().hex().required(),
43283
- studentId: Joi43.string().required()
43284
- });
43285
- const { error } = validation.validate({ _id, studentId });
43286
- if (error) {
43287
- next(new BadRequestError65(error.message));
43288
- return;
43289
- }
43290
- try {
43291
- const message = await _addStudentToSection(_id, studentId);
43292
- res.json({ message });
43293
- return;
43294
- } catch (error2) {
43295
- 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();
43296
44953
  }
43297
44954
  }
43298
- async function removeStudent(req, res, next) {
43299
- const _id = req.params.id;
43300
- const { studentId } = req.body;
43301
- const validation = Joi43.object({
43302
- _id: Joi43.string().hex().required(),
43303
- studentId: Joi43.string().required()
43304
- });
43305
- const { error } = validation.validate({ _id, studentId });
43306
- if (error) {
43307
- next(new BadRequestError65(error.message));
43308
- 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
+ );
43309
44961
  }
43310
44962
  try {
43311
- const message = await _removeStudentFromSection(_id, studentId);
43312
- res.json({ message });
43313
- return;
43314
- } catch (error2) {
43315
- next(error2);
44963
+ await _deleteById(id);
44964
+ return "Building deleted successfully.";
44965
+ } catch (error) {
44966
+ throw error;
43316
44967
  }
43317
44968
  }
43318
- async function deleteById(req, res, next) {
43319
- const _id = req.params.id;
43320
- const validation = Joi43.object({
43321
- _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)
43322
44989
  });
43323
- const { error } = validation.validate({ _id });
44990
+ const { error } = validation.validate(value);
43324
44991
  if (error) {
43325
- next(new BadRequestError65(error.message));
44992
+ next(new BadRequestError74(error.message));
44993
+ logger43.info(`Controller: ${error.message}`);
43326
44994
  return;
43327
44995
  }
43328
44996
  try {
43329
- const message = await _deleteById(_id);
43330
- res.json({ message });
44997
+ const result = await _add(value);
44998
+ res.json(result);
43331
44999
  return;
43332
45000
  } catch (error2) {
43333
45001
  next(error2);
43334
45002
  }
43335
45003
  }
43336
- return {
43337
- add,
43338
- generateSections,
43339
- generateSectionPreview,
43340
- getAll,
43341
- getById,
43342
- getByName,
43343
- getBySchool,
43344
- updateField,
43345
- addStudent,
43346
- removeStudent,
43347
- deleteById
43348
- };
43349
- }
43350
-
43351
- // src/resources/section-student/section.student.controller.ts
43352
- import { BadRequestError as BadRequestError66 } from "@eeplatform/nodejs-utils";
43353
- import Joi44 from "joi";
43354
- function useSectionStudentController() {
43355
- const { add: _add, getAll: _getAll } = useSectionStudentRepo();
43356
- async function add(req, res, next) {
45004
+ async function updateById(req, res, next) {
43357
45005
  const value = req.body;
43358
- 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 });
43359
45016
  if (error) {
43360
- next(new BadRequestError66(error.message));
45017
+ next(new BadRequestError74(error.message));
45018
+ logger43.info(`Controller: ${error.message}`);
43361
45019
  return;
43362
45020
  }
43363
45021
  try {
43364
- const data = await _add(value);
43365
- res.json({
43366
- message: "Successfully created section student.",
43367
- data
43368
- });
45022
+ const result = await _updateById(id, value);
45023
+ res.json(result);
43369
45024
  return;
43370
45025
  } catch (error2) {
43371
45026
  next(error2);
@@ -43373,409 +45028,310 @@ function useSectionStudentController() {
43373
45028
  }
43374
45029
  async function getAll(req, res, next) {
43375
45030
  const query = req.query;
43376
- const validation = Joi44.object({
43377
- page: Joi44.number().min(1).optional().allow("", null),
43378
- limit: Joi44.number().min(1).optional().allow("", null),
43379
- search: Joi44.string().optional().allow("", null),
43380
- status: Joi44.string().optional().allow("", null),
43381
- school: Joi44.string().optional().allow("", null),
43382
- gradeLevel: Joi44.string().optional().allow("", null),
43383
- section: Joi44.string().optional().allow("", null),
43384
- 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)
43385
45037
  });
43386
45038
  const { error } = validation.validate(query);
43387
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
43388
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
43389
- const search = req.query.search ?? "";
43390
- const status = req.query.status ?? "active";
43391
- const school = req.query.school ?? "";
43392
- const gradeLevel = req.query.gradeLevel ?? "";
43393
- const section = req.query.section ?? "";
43394
- const schoolYear = req.query.schoolYear ?? "";
43395
- const isPageNumber = isFinite(page);
43396
- if (!isPageNumber) {
43397
- next(new BadRequestError66("Invalid page number."));
43398
- return;
43399
- }
43400
- const isLimitNumber = isFinite(limit);
43401
- if (!isLimitNumber) {
43402
- next(new BadRequestError66("Invalid limit number."));
43403
- return;
43404
- }
43405
45039
  if (error) {
43406
- next(new BadRequestError66(error.message));
45040
+ next(new BadRequestError74(error.message));
43407
45041
  return;
43408
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 ?? "";
43409
45057
  try {
43410
- const data = await _getAll({
45058
+ const buildings = await _getAll({
43411
45059
  page,
43412
45060
  limit,
43413
- search,
45061
+ sort: sortObj,
43414
45062
  status,
43415
45063
  school,
43416
- gradeLevel,
43417
- section,
43418
- schoolYear
45064
+ search
43419
45065
  });
43420
- res.json(data);
45066
+ res.json(buildings);
43421
45067
  return;
43422
45068
  } catch (error2) {
43423
45069
  next(error2);
43424
45070
  }
43425
45071
  }
43426
- return {
43427
- add,
43428
- getAll
43429
- };
43430
- }
43431
-
43432
- // src/resources/building/building.model.ts
43433
- import { BadRequestError as BadRequestError67, logger as logger39 } from "@eeplatform/nodejs-utils";
43434
- import Joi45 from "joi";
43435
- import { ObjectId as ObjectId41 } from "mongodb";
43436
- var schemaBuilding = Joi45.object({
43437
- _id: Joi45.string().hex().optional(),
43438
- school: Joi45.string().hex().required(),
43439
- serial: Joi45.string().optional().allow("", null),
43440
- name: Joi45.string().required(),
43441
- levels: Joi45.number().integer().min(1).required(),
43442
- createdAt: Joi45.date().optional().allow("", null),
43443
- updatedAt: Joi45.date().optional().allow("", null),
43444
- deletedAt: Joi45.date().optional().allow("", null),
43445
- status: Joi45.string().optional().allow("", null)
43446
- });
43447
- var schemaBuildingUnit = Joi45.object({
43448
- _id: Joi45.string().hex().optional(),
43449
- school: Joi45.string().hex().required(),
43450
- name: Joi45.string().optional().allow("", null),
43451
- building: Joi45.string().hex().required(),
43452
- buildingName: Joi45.string().optional().allow("", null),
43453
- level: Joi45.number().integer().min(1).required(),
43454
- category: Joi45.string().required(),
43455
- type: Joi45.string().required(),
43456
- seating_capacity: Joi45.number().integer().min(0).required(),
43457
- standing_capacity: Joi45.number().integer().min(0).required(),
43458
- description: Joi45.string().optional().allow("", null),
43459
- unit_of_measurement: Joi45.string().valid("sqm").required(),
43460
- area: Joi45.number().positive().required(),
43461
- status: Joi45.string().optional().allow("", null)
43462
- });
43463
- var schemaUpdateOptions = Joi45.object({
43464
- name: Joi45.string().optional().allow("", null),
43465
- building: Joi45.string().hex().optional().allow("", null),
43466
- buildingName: Joi45.string().optional().allow("", null),
43467
- level: Joi45.number().integer().min(1).optional().allow("", null),
43468
- category: Joi45.string().optional().allow("", null),
43469
- type: Joi45.string().optional().allow("", null),
43470
- seating_capacity: Joi45.number().integer().min(0).optional().allow("", null),
43471
- standing_capacity: Joi45.number().integer().min(0).optional().allow("", null),
43472
- area: Joi45.number().positive().optional().allow("", null)
43473
- });
43474
- function MBuilding(value) {
43475
- const { error } = schemaBuilding.validate(value);
43476
- if (error) {
43477
- logger39.info(`Building Model: ${error.message}`);
43478
- throw new BadRequestError67(error.message);
43479
- }
43480
- if (value._id && typeof value._id === "string") {
43481
- try {
43482
- value._id = new ObjectId41(value._id);
43483
- } catch (error2) {
43484
- 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;
43485
45081
  }
43486
- }
43487
- try {
43488
- value.school = new ObjectId41(value.school);
43489
- } catch (error2) {
43490
- throw new BadRequestError67("Invalid school format");
43491
- }
43492
- return {
43493
- _id: value._id ?? void 0,
43494
- school: value.school,
43495
- serial: value.serial ?? "",
43496
- name: value.name ?? "",
43497
- levels: value.levels ?? 0,
43498
- status: value.status ?? "active",
43499
- createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
43500
- updatedAt: value.updatedAt ?? "",
43501
- deletedAt: value.deletedAt ?? ""
43502
- };
43503
- }
43504
- function MBuildingUnit(value) {
43505
- const { error } = schemaBuildingUnit.validate(value);
43506
- if (error) {
43507
- logger39.info(`Building Unit Model: ${error.message}`);
43508
- throw new BadRequestError67(error.message);
43509
- }
43510
- if (value._id && typeof value._id === "string") {
43511
45082
  try {
43512
- 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;
43513
45089
  } catch (error2) {
43514
- throw new BadRequestError67("Invalid ID");
43515
- }
43516
- }
43517
- try {
43518
- value.school = new ObjectId41(value.school);
43519
- } catch (error2) {
43520
- throw new BadRequestError67("Invalid school ID");
43521
- }
43522
- try {
43523
- value.building = new ObjectId41(value.building);
43524
- } catch (error2) {
43525
- throw new BadRequestError67("Invalid building ID");
43526
- }
43527
- return {
43528
- _id: value._id ?? void 0,
43529
- school: value.school,
43530
- name: value.name ?? "",
43531
- building: value.building,
43532
- buildingName: value.buildingName ?? "",
43533
- level: value.level ?? 0,
43534
- category: value.category ?? "",
43535
- type: value.type ?? "",
43536
- seating_capacity: value.seating_capacity ?? 0,
43537
- standing_capacity: value.standing_capacity ?? 0,
43538
- description: value.description ?? "",
43539
- unit_of_measurement: value.unit_of_measurement ?? "sqm",
43540
- area: value.area ?? 0,
43541
- status: value.status ?? "active",
43542
- createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
43543
- updatedAt: value.updatedAt ?? "",
43544
- deletedAt: value.deletedAt ?? ""
43545
- };
43546
- }
43547
-
43548
- // src/resources/building/building.repository.ts
43549
- import {
43550
- AppError as AppError26,
43551
- BadRequestError as BadRequestError68,
43552
- InternalServerError as InternalServerError22,
43553
- logger as logger40,
43554
- makeCacheKey as makeCacheKey22,
43555
- paginate as paginate21,
43556
- useAtlas as useAtlas31,
43557
- useCache as useCache22
43558
- } from "@eeplatform/nodejs-utils";
43559
- import { ObjectId as ObjectId42 } from "mongodb";
43560
- function useBuildingRepo() {
43561
- const db = useAtlas31.getDb();
43562
- if (!db) {
43563
- throw new Error("Unable to connect to server.");
43564
- }
43565
- const namespace_collection = "deped.buildings";
43566
- const collection = db.collection(namespace_collection);
43567
- const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
43568
- async function createIndexes() {
43569
- try {
43570
- await collection.createIndexes([
43571
- { key: { name: 1 }, unique: true, name: "unique_name_index" },
43572
- { key: { school: 1 } },
43573
- { key: { status: 1 } }
43574
- ]);
43575
- } catch (error) {
43576
- throw new Error("Failed to create index on buildings.");
45090
+ next(error2);
43577
45091
  }
43578
45092
  }
43579
- 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
+ }
43580
45103
  try {
43581
- value = MBuilding(value);
43582
- const res = await collection.insertOne(value, { session });
43583
- delCachedData();
43584
- return res.insertedId;
43585
- } catch (error) {
43586
- logger40.log({
43587
- level: "error",
43588
- message: error.message
43589
- });
43590
- if (error instanceof AppError26) {
43591
- throw error;
43592
- } else {
43593
- const isDuplicated = error.message.includes("duplicate");
43594
- if (isDuplicated) {
43595
- throw new BadRequestError68("Building already exists.");
43596
- }
43597
- throw new Error("Failed to create building.");
43598
- }
45104
+ const message = await _deleteById(id);
45105
+ res.json(message);
45106
+ return;
45107
+ } catch (error2) {
45108
+ next(error2);
43599
45109
  }
43600
45110
  }
43601
- async function updateById(_id, value, session) {
43602
- try {
43603
- _id = new ObjectId42(_id);
43604
- } catch (error) {
43605
- 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.");
43606
45132
  }
43607
45133
  try {
43608
- const res = await collection.updateOne(
43609
- { _id },
43610
- { $set: value },
43611
- { session }
45134
+ await session.startTransaction();
45135
+ const existingCount = await countByBuilding(
45136
+ value.building.building,
45137
+ value.building.level
43612
45138
  );
43613
- delCachedData();
43614
- return res;
43615
- } catch (error) {
43616
- logger40.log({
43617
- level: "error",
43618
- message: error.message
43619
- });
43620
- if (error instanceof AppError26) {
43621
- throw error;
43622
- } else {
43623
- 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
+ );
43624
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();
43625
45153
  }
43626
45154
  }
43627
- async function getAll({
43628
- search = "",
43629
- page = 1,
43630
- limit = 10,
43631
- sort = {},
43632
- school = "",
43633
- status = "active"
43634
- } = {}) {
43635
- page = page > 0 ? page - 1 : 0;
43636
- const query = {
43637
- status
43638
- };
43639
- sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
43640
- if (search) {
43641
- 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.");
43642
45159
  }
43643
- if (school) {
43644
- try {
43645
- query.school = new ObjectId42(school);
43646
- } catch (error) {
43647
- throw new BadRequestError68("Invalid school ID.");
43648
- }
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
+ );
43649
45165
  }
43650
- const cacheParams = {
43651
- page,
43652
- limit,
43653
- sort: JSON.stringify(sort)
43654
- };
43655
- if (search)
43656
- cacheParams.search = search;
43657
- if (school)
43658
- cacheParams.school = school;
43659
- if (status !== "active")
43660
- cacheParams.status = status;
43661
- const cacheKey = makeCacheKey22(namespace_collection, cacheParams);
43662
- logger40.log({
43663
- level: "info",
43664
- message: `Cache key for getAll buildings: ${cacheKey}`
43665
- });
43666
45166
  try {
43667
- const cached = await getCache(cacheKey);
43668
- if (cached) {
43669
- logger40.log({
43670
- level: "info",
43671
- message: `Cache hit for getAll buildings: ${cacheKey}`
43672
- });
43673
- return cached;
43674
- }
43675
- const items = await collection.aggregate([
43676
- { $match: query },
43677
- { $sort: sort },
43678
- { $skip: page * limit },
43679
- { $limit: limit }
43680
- ]).toArray();
43681
- const length = await collection.countDocuments(query);
43682
- const data = paginate21(items, page, limit, length);
43683
- setCache(cacheKey, data, 600).then(() => {
43684
- logger40.log({
43685
- level: "info",
43686
- message: `Cache set for getAll buildings: ${cacheKey}`
43687
- });
43688
- }).catch((err) => {
43689
- logger40.log({
43690
- level: "error",
43691
- message: `Failed to set cache for getAll buildings: ${err.message}`
43692
- });
43693
- });
43694
- return data;
45167
+ await _deleteById(id);
45168
+ return "Building unit deleted successfully.";
43695
45169
  } catch (error) {
43696
- logger40.log({ level: "error", message: `${error}` });
43697
- throw error;
45170
+ throw new Error("Failed to delete building unit.");
43698
45171
  }
43699
45172
  }
43700
- 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
+ }
43701
45214
  try {
43702
- _id = new ObjectId42(_id);
43703
- } catch (error) {
43704
- 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;
43705
45235
  }
43706
- const cacheKey = makeCacheKey22(namespace_collection, { _id: String(_id) });
43707
45236
  try {
43708
- const cached = await getCache(cacheKey);
43709
- if (cached) {
43710
- logger40.log({
43711
- level: "info",
43712
- message: `Cache hit for getById building: ${cacheKey}`
43713
- });
43714
- return cached;
43715
- }
43716
- const result = await collection.findOne({
43717
- _id
45237
+ const buildingUnit = await _updateById(id, data);
45238
+ res.json({
45239
+ message: "Building unit updated successfully.",
45240
+ data: { buildingUnit }
43718
45241
  });
43719
- setCache(cacheKey, result, 300).then(() => {
43720
- logger40.log({
43721
- level: "info",
43722
- message: `Cache set for building by id: ${cacheKey}`
43723
- });
43724
- }).catch((err) => {
43725
- logger40.log({
43726
- level: "error",
43727
- message: `Failed to set cache for building by id: ${err.message}`
43728
- });
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;
43729
45271
  });
43730
- return result;
43731
- } catch (error) {
43732
- if (error instanceof AppError26) {
43733
- throw error;
43734
- } else {
43735
- throw new InternalServerError22("Failed to get building.");
43736
- }
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);
43737
45293
  }
43738
45294
  }
43739
- async function deleteById(_id, session) {
43740
- try {
43741
- _id = new ObjectId42(_id);
43742
- } catch (error) {
43743
- 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;
43744
45304
  }
43745
45305
  try {
43746
- const res = await collection.updateOne(
43747
- { _id },
43748
- { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
43749
- );
43750
- delCachedData();
43751
- return res;
43752
- } catch (error) {
43753
- logger40.log({
43754
- level: "error",
43755
- message: error.message
45306
+ const buildingUnit = await _getById(id);
45307
+ res.json({
45308
+ message: "Successfully retrieved building unit.",
45309
+ data: { buildingUnit }
43756
45310
  });
43757
- if (error instanceof AppError26) {
43758
- throw error;
43759
- } else {
43760
- throw new InternalServerError22("Failed to delete building.");
43761
- }
45311
+ return;
45312
+ } catch (error2) {
45313
+ next(error2);
43762
45314
  }
43763
45315
  }
43764
- function delCachedData() {
43765
- delNamespace().then(() => {
43766
- logger40.log({
43767
- level: "info",
43768
- message: `Cache namespace cleared for ${namespace_collection}`
43769
- });
43770
- }).catch((err) => {
43771
- logger40.log({
43772
- level: "error",
43773
- message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
43774
- });
45316
+ async function deleteById(req, res, next) {
45317
+ const id = req.params.id;
45318
+ const validation = Joi49.object({
45319
+ id: Joi49.string().hex().required()
43775
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
+ }
43776
45333
  }
43777
45334
  return {
43778
- createIndexes,
43779
45335
  add,
43780
45336
  getAll,
43781
45337
  getById,
@@ -43784,66 +45340,97 @@ function useBuildingRepo() {
43784
45340
  };
43785
45341
  }
43786
45342
 
43787
- // src/resources/building/building.service.ts
43788
- import {
43789
- BadRequestError as BadRequestError70,
43790
- NotFoundError as NotFoundError3,
43791
- useAtlas as useAtlas33
43792
- } 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
+ }
43793
45387
 
43794
- // src/resources/building/building-unit.repository.ts
45388
+ // src/resources/kindergarten-domain/kindergarten.domain.repository.ts
43795
45389
  import {
43796
- AppError as AppError27,
43797
- BadRequestError as BadRequestError69,
43798
- InternalServerError as InternalServerError23,
43799
- logger as logger41,
43800
- makeCacheKey as makeCacheKey23,
43801
- paginate as paginate22,
43802
- useAtlas as useAtlas32,
43803
- 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
43804
45398
  } from "@eeplatform/nodejs-utils";
43805
- import { ObjectId as ObjectId43 } from "mongodb";
43806
- function useBuildingUnitRepo() {
43807
- const db = useAtlas32.getDb();
45399
+ import { ObjectId as ObjectId47 } from "mongodb";
45400
+ function useKindergartenDomainRepo() {
45401
+ const db = useAtlas36.getDb();
43808
45402
  if (!db) {
43809
45403
  throw new Error("Unable to connect to server.");
43810
45404
  }
43811
- const namespace_collection = "deped.building.units";
45405
+ const namespace_collection = "deped.kindergarten.domains";
43812
45406
  const collection = db.collection(namespace_collection);
43813
- const { getCache, setCache, delNamespace } = useCache23(namespace_collection);
45407
+ const { getCache, setCache, delNamespace } = useCache25(namespace_collection);
43814
45408
  async function createIndexes() {
43815
45409
  try {
43816
45410
  await collection.createIndexes([
43817
- {
43818
- key: { name: 1, building: 1, level: 1 },
43819
- unique: true,
43820
- name: "unique_name_index"
43821
- },
45411
+ { key: { title: 1 } },
43822
45412
  { key: { school: 1 } },
43823
- { key: { building: 1 } },
43824
- { key: { status: 1 } },
43825
45413
  { key: { createdAt: 1 } },
45414
+ { key: { createdBy: 1 } },
45415
+ { key: { title: "text" } },
43826
45416
  {
43827
- key: {
43828
- name: "text",
43829
- buildingName: "text",
43830
- category: "text",
43831
- type: "text"
43832
- }
45417
+ key: { title: 1, school: 1, status: 1 },
45418
+ unique: true,
45419
+ name: "unique_kindergarten_domain"
43833
45420
  }
43834
45421
  ]);
43835
45422
  } catch (error) {
43836
- throw new Error("Failed to create index on building units.");
45423
+ throw new Error("Failed to create index on kindergarten domains.");
43837
45424
  }
43838
45425
  }
43839
45426
  function delCachedData() {
43840
45427
  delNamespace().then(() => {
43841
- logger41.log({
45428
+ logger44.log({
43842
45429
  level: "info",
43843
45430
  message: `Cache namespace cleared for ${namespace_collection}`
43844
45431
  });
43845
45432
  }).catch((err) => {
43846
- logger41.log({
45433
+ logger44.log({
43847
45434
  level: "error",
43848
45435
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
43849
45436
  });
@@ -43851,79 +45438,23 @@ function useBuildingUnitRepo() {
43851
45438
  }
43852
45439
  async function add(value, session) {
43853
45440
  try {
43854
- value = MBuildingUnit(value);
45441
+ value = modelKindergartenDomain(value);
43855
45442
  const res = await collection.insertOne(value, { session });
43856
45443
  delCachedData();
43857
45444
  return res.insertedId;
43858
45445
  } catch (error) {
43859
- logger41.log({
45446
+ logger44.log({
43860
45447
  level: "error",
43861
45448
  message: error.message
43862
45449
  });
43863
- if (error instanceof AppError27) {
45450
+ if (error instanceof AppError29) {
43864
45451
  throw error;
43865
45452
  } else {
43866
- throw new Error("Failed to create building unit.");
43867
- }
43868
- }
43869
- }
43870
- async function updateById(_id, value, session) {
43871
- const { error } = schemaUpdateOptions.validate(value);
43872
- if (error) {
43873
- throw new BadRequestError69(error.message);
43874
- }
43875
- try {
43876
- _id = new ObjectId43(_id);
43877
- } catch (error2) {
43878
- throw new BadRequestError69(namespace_collection + " Invalid ID.");
43879
- }
43880
- try {
43881
- const res = await collection.updateOne(
43882
- { _id },
43883
- { $set: value },
43884
- { session }
43885
- );
43886
- delCachedData();
43887
- return res;
43888
- } catch (error2) {
43889
- logger41.log({
43890
- level: "error",
43891
- message: error2.message
43892
- });
43893
- if (error2 instanceof AppError27) {
43894
- throw error2;
43895
- } else {
43896
- throw new Error("Failed to create building unit.");
43897
- }
43898
- }
43899
- }
43900
- async function updateByBuildingId(building, value, session) {
43901
- const { error } = schemaUpdateOptions.validate(value);
43902
- if (error) {
43903
- throw new BadRequestError69(error.message);
43904
- }
43905
- try {
43906
- building = new ObjectId43(building);
43907
- } catch (error2) {
43908
- throw new BadRequestError69("Invalid building ID.");
43909
- }
43910
- try {
43911
- const res = await collection.updateMany(
43912
- { building },
43913
- { $set: value },
43914
- { session }
43915
- );
43916
- delCachedData();
43917
- return res;
43918
- } catch (error2) {
43919
- logger41.log({
43920
- level: "error",
43921
- message: error2.message
43922
- });
43923
- if (error2 instanceof AppError27) {
43924
- throw error2;
43925
- } else {
43926
- 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.");
43927
45458
  }
43928
45459
  }
43929
45460
  }
@@ -43932,652 +45463,368 @@ function useBuildingUnitRepo() {
43932
45463
  page = 1,
43933
45464
  limit = 10,
43934
45465
  sort = {},
43935
- school = "",
43936
- building = "",
43937
- type = "",
43938
- status = "active"
45466
+ status = "active",
45467
+ createdBy,
45468
+ school = ""
43939
45469
  } = {}) {
43940
45470
  page = page > 0 ? page - 1 : 0;
43941
45471
  const query = {
43942
- deletedAt: { $in: ["", null] },
43943
- status: { $in: [status, "", null] }
43944
- };
43945
- const cacheParams = {
43946
- page,
43947
- limit,
43948
- sort: JSON.stringify(sort)
43949
- };
43950
- sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
43951
- if (search) {
43952
- query.$text = { $search: search };
43953
- cacheParams.search = search;
43954
- }
43955
- if (school) {
43956
- try {
43957
- query.school = new ObjectId43(school);
43958
- } catch (error) {
43959
- throw new BadRequestError69("Invalid school ID.");
43960
- }
43961
- cacheParams.school = school;
43962
- }
43963
- if (building) {
43964
- try {
43965
- query.building = new ObjectId43(building);
43966
- } catch (error) {
43967
- throw new BadRequestError69("Invalid building ID.");
43968
- }
43969
- cacheParams.building = building;
43970
- }
43971
- if (type) {
43972
- query.type = type;
43973
- cacheParams.type = type;
43974
- }
43975
- const cacheKey = makeCacheKey23(namespace_collection, cacheParams);
43976
- logger41.log({
43977
- level: "info",
43978
- message: `Cache key for getAll building units: ${cacheKey}`
43979
- });
43980
- try {
43981
- const cached = await getCache(cacheKey);
43982
- if (cached) {
43983
- logger41.log({
43984
- level: "info",
43985
- message: `Cache hit for getAll building units: ${cacheKey}`
43986
- });
43987
- return cached;
43988
- }
43989
- const items = await collection.aggregate([
43990
- { $match: query },
43991
- { $sort: sort },
43992
- { $skip: page * limit },
43993
- { $limit: limit }
43994
- ]).toArray();
43995
- const length = await collection.countDocuments(query);
43996
- const data = paginate22(items, page, limit, length);
43997
- setCache(cacheKey, data, 600).then(() => {
43998
- logger41.log({
43999
- level: "info",
44000
- message: `Cache set for getAll building units: ${cacheKey}`
44001
- });
44002
- }).catch((err) => {
44003
- logger41.log({
44004
- level: "error",
44005
- message: `Failed to set cache for getAll building units: ${err.message}`
44006
- });
44007
- });
44008
- return data;
44009
- } catch (error) {
44010
- logger41.log({ level: "error", message: `${error}` });
44011
- throw error;
44012
- }
44013
- }
44014
- async function countByBuilding(building, level) {
44015
- const query = {
44016
- status: "active"
45472
+ deletedAt: { $in: ["", null] },
45473
+ status
44017
45474
  };
45475
+ sort = Object.keys(sort).length > 0 ? sort : { _id: 1 };
44018
45476
  const cacheKeyOptions = {
44019
- ...query,
44020
- tag: "countByBuilding"
45477
+ status,
45478
+ page,
45479
+ limit,
45480
+ sort: JSON.stringify(sort)
44021
45481
  };
44022
- try {
44023
- query.building = new ObjectId43(building);
44024
- cacheKeyOptions.building = String(building);
44025
- } catch (error) {
44026
- throw new BadRequestError69("Invalid building ID.");
44027
- }
44028
- if (level) {
44029
- query.level = level;
44030
- 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;
44031
45489
  }
44032
- try {
44033
- return await collection.countDocuments(query);
44034
- } catch (error) {
44035
- logger41.log({ level: "error", message: `${error}` });
44036
- throw new InternalServerError23("Failed to count building units.");
45490
+ if (search) {
45491
+ query.$text = { $search: search };
45492
+ cacheKeyOptions.search = search;
44037
45493
  }
44038
- }
44039
- async function getById(_id) {
44040
- try {
44041
- _id = new ObjectId43(_id);
44042
- } catch (error) {
44043
- 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;
44044
45501
  }
44045
- 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
+ });
44046
45507
  try {
44047
45508
  const cached = await getCache(cacheKey);
44048
45509
  if (cached) {
44049
- logger41.log({
45510
+ logger44.log({
44050
45511
  level: "info",
44051
- message: `Cache hit for getById building unit: ${cacheKey}`
45512
+ message: `Cache hit for getAll kindergarten domains: ${cacheKey}`
44052
45513
  });
44053
45514
  return cached;
44054
45515
  }
44055
- const result = await collection.findOne({
44056
- _id,
44057
- deletedAt: { $in: ["", null] }
44058
- });
44059
- if (!result) {
44060
- throw new BadRequestError69("Building unit not found.");
44061
- }
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);
44062
45524
  setCache(cacheKey, result, 300).then(() => {
44063
- logger41.log({
45525
+ logger44.log({
44064
45526
  level: "info",
44065
- message: `Cache set for building unit by id: ${cacheKey}`
45527
+ message: `Cache set for getAll kindergarten domains: ${cacheKey}`
44066
45528
  });
44067
45529
  }).catch((err) => {
44068
- logger41.log({
45530
+ logger44.log({
44069
45531
  level: "error",
44070
- message: `Failed to set cache for building unit by id: ${err.message}`
45532
+ message: `Failed to set cache for getAll kindergarten domains: ${err.message}`
44071
45533
  });
44072
45534
  });
44073
45535
  return result;
44074
45536
  } catch (error) {
44075
- if (error instanceof AppError27) {
45537
+ if (error instanceof AppError29) {
44076
45538
  throw error;
44077
45539
  } else {
44078
- throw new InternalServerError23("Failed to get building unit.");
45540
+ throw new InternalServerError25("Failed to get kindergarten domains.");
44079
45541
  }
44080
45542
  }
44081
45543
  }
44082
- async function getByBuildingLevel(building, level) {
45544
+ async function getById(_id) {
44083
45545
  try {
44084
- building = new ObjectId43(building);
45546
+ _id = new ObjectId47(_id);
44085
45547
  } catch (error) {
44086
- throw new BadRequestError69("Invalid building ID.");
45548
+ throw new BadRequestError77(namespace_collection + " Invalid ID.");
44087
45549
  }
44088
- const cacheKey = makeCacheKey23(namespace_collection, {
44089
- building: String(building),
44090
- 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}`
44091
45556
  });
44092
45557
  try {
44093
45558
  const cached = await getCache(cacheKey);
44094
45559
  if (cached) {
44095
- logger41.log({
45560
+ logger44.log({
44096
45561
  level: "info",
44097
- message: `Cache hit for getById building unit: ${cacheKey}`
45562
+ message: `Cache hit for getById kindergarten domain: ${cacheKey}`
44098
45563
  });
44099
45564
  return cached;
44100
45565
  }
44101
45566
  const result = await collection.findOne({
44102
- building,
44103
- level,
44104
- status: "active"
45567
+ _id,
45568
+ deletedAt: { $in: ["", null] }
44105
45569
  });
45570
+ if (!result) {
45571
+ throw new BadRequestError77("Kindergarten domain not found.");
45572
+ }
44106
45573
  setCache(cacheKey, result, 300).then(() => {
44107
- logger41.log({
45574
+ logger44.log({
44108
45575
  level: "info",
44109
- message: `Cache set for building unit by id: ${cacheKey}`
45576
+ message: `Cache set for getById kindergarten domain: ${cacheKey}`
44110
45577
  });
44111
45578
  }).catch((err) => {
44112
- logger41.log({
45579
+ logger44.log({
44113
45580
  level: "error",
44114
- message: `Failed to set cache for building unit by id: ${err.message}`
45581
+ message: `Failed to set cache for getById kindergarten domain: ${err.message}`
44115
45582
  });
44116
45583
  });
44117
45584
  return result;
44118
45585
  } catch (error) {
44119
- if (error instanceof AppError27) {
45586
+ if (error instanceof AppError29) {
44120
45587
  throw error;
44121
45588
  } else {
44122
- throw new InternalServerError23("Failed to get building unit.");
45589
+ throw new InternalServerError25("Failed to get kindergarten domain.");
44123
45590
  }
44124
45591
  }
44125
45592
  }
44126
- async function getByBuilding(building) {
45593
+ async function getBySchool(school) {
44127
45594
  try {
44128
- building = new ObjectId43(building);
45595
+ school = new ObjectId47(school);
44129
45596
  } catch (error) {
44130
- throw new BadRequestError69("Invalid building ID.");
45597
+ throw new BadRequestError77("Invalid school ID.");
44131
45598
  }
44132
- const cacheKey = makeCacheKey23(namespace_collection, {
44133
- 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}`
44134
45605
  });
44135
45606
  try {
44136
45607
  const cached = await getCache(cacheKey);
44137
45608
  if (cached) {
44138
- logger41.log({
45609
+ logger44.log({
44139
45610
  level: "info",
44140
- message: `Cache hit for getById building unit: ${cacheKey}`
45611
+ message: `Cache hit for kindergarten domain by school: ${cacheKey}`
44141
45612
  });
44142
45613
  return cached;
44143
45614
  }
44144
- const result = await collection.findOne({
44145
- building,
44146
- status: "active"
44147
- });
45615
+ const result = await collection.find({
45616
+ school,
45617
+ deletedAt: { $in: ["", null] }
45618
+ }).toArray();
44148
45619
  setCache(cacheKey, result, 300).then(() => {
44149
- logger41.log({
45620
+ logger44.log({
44150
45621
  level: "info",
44151
- message: `Cache set for building unit by id: ${cacheKey}`
45622
+ message: `Cache set for kindergarten domain by school: ${cacheKey}`
44152
45623
  });
44153
45624
  }).catch((err) => {
44154
- logger41.log({
45625
+ logger44.log({
44155
45626
  level: "error",
44156
- 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}`
44157
45628
  });
44158
45629
  });
44159
45630
  return result;
44160
45631
  } catch (error) {
44161
- if (error instanceof AppError27) {
44162
- throw error;
44163
- } else {
44164
- throw new InternalServerError23("Failed to get building unit.");
44165
- }
44166
- }
44167
- }
44168
- async function deleteById(_id, session) {
44169
- try {
44170
- _id = new ObjectId43(_id);
44171
- } catch (error) {
44172
- throw new BadRequestError69(namespace_collection + " Invalid ID.");
44173
- }
44174
- try {
44175
- const res = await collection.updateOne(
44176
- { _id },
44177
- { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
44178
- { session }
44179
- );
44180
- delCachedData();
44181
- return "Room/Facility deleted successfully.";
44182
- } catch (error) {
44183
- logger41.log({
44184
- level: "error",
44185
- message: error.message
44186
- });
44187
- if (error instanceof AppError27) {
45632
+ if (error instanceof AppError29) {
44188
45633
  throw error;
44189
45634
  } else {
44190
- throw new Error("Failed to deleted room/facility.");
44191
- }
44192
- }
44193
- }
44194
- return {
44195
- createIndexes,
44196
- add,
44197
- getAll,
44198
- getById,
44199
- getByBuildingLevel,
44200
- updateById,
44201
- getByBuilding,
44202
- deleteById,
44203
- updateByBuildingId,
44204
- countByBuilding
44205
- };
44206
- }
44207
-
44208
- // src/resources/building/building.service.ts
44209
- function useBuildingService() {
44210
- const {
44211
- updateById: _updateById,
44212
- getById: _getById,
44213
- deleteById: _deleteById
44214
- } = useBuildingRepo();
44215
- const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
44216
- async function updateById(id, data) {
44217
- data.levels = Number(data.levels);
44218
- const session = useAtlas33.getClient()?.startSession();
44219
- try {
44220
- const building = await _getById(id);
44221
- if (!building) {
44222
- throw new NotFoundError3("Building not found.");
44223
- }
44224
- if (data.levels < building.levels) {
44225
- const unit = await getByBuildingLevel(id, building.levels);
44226
- if (unit) {
44227
- throw new BadRequestError70(
44228
- "Cannot reduce floors, there are existing building units at higher floors."
44229
- );
44230
- }
44231
- }
44232
- session?.startTransaction();
44233
- if (building.name !== data.name) {
44234
- await updateByBuildingId(id, { buildingName: data.name }, session);
44235
- }
44236
- const result = await _updateById(id, data, session);
44237
- await session?.commitTransaction();
44238
- return result;
44239
- } catch (error) {
44240
- await session?.abortTransaction();
44241
- throw error;
44242
- } finally {
44243
- session?.endSession();
44244
- }
44245
- }
44246
- async function deleteById(id) {
44247
- const building = await getByBuilding(id);
44248
- if (building) {
44249
- throw new BadRequestError70(
44250
- "Cannot delete building with existing room/facility. Please delete room/facility first."
44251
- );
44252
- }
44253
- try {
44254
- await _deleteById(id);
44255
- return "Building deleted successfully.";
44256
- } catch (error) {
44257
- throw error;
44258
- }
44259
- }
44260
- return {
44261
- updateById,
44262
- deleteById
44263
- };
44264
- }
44265
-
44266
- // src/resources/building/building.controller.ts
44267
- import { BadRequestError as BadRequestError71, logger as logger42 } from "@eeplatform/nodejs-utils";
44268
- import Joi46 from "joi";
44269
- function useBuildingController() {
44270
- const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
44271
- const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
44272
- async function createBuilding(req, res, next) {
44273
- const value = req.body;
44274
- const validation = Joi46.object({
44275
- name: Joi46.string().required(),
44276
- school: Joi46.string().hex().required(),
44277
- levels: Joi46.number().integer().min(1).required(),
44278
- serial: Joi46.string().optional().allow("", null),
44279
- status: Joi46.string().optional().allow("", null)
44280
- });
44281
- const { error } = validation.validate(value);
44282
- if (error) {
44283
- next(new BadRequestError71(error.message));
44284
- logger42.info(`Controller: ${error.message}`);
44285
- return;
44286
- }
44287
- try {
44288
- const result = await _add(value);
44289
- res.json(result);
44290
- return;
44291
- } catch (error2) {
44292
- next(error2);
44293
- }
44294
- }
44295
- async function updateById(req, res, next) {
44296
- const value = req.body;
44297
- const id = req.params.id ?? "";
44298
- const validation = Joi46.object({
44299
- id: Joi46.string().hex().required(),
44300
- value: Joi46.object({
44301
- name: Joi46.string().required(),
44302
- serial: Joi46.string().optional().allow("", null),
44303
- levels: Joi46.number().integer().min(1).required()
44304
- })
44305
- });
44306
- const { error } = validation.validate({ id, value });
44307
- if (error) {
44308
- next(new BadRequestError71(error.message));
44309
- logger42.info(`Controller: ${error.message}`);
44310
- return;
44311
- }
44312
- try {
44313
- const result = await _updateById(id, value);
44314
- res.json(result);
44315
- return;
44316
- } catch (error2) {
44317
- next(error2);
44318
- }
44319
- }
44320
- async function getAll(req, res, next) {
44321
- const query = req.query;
44322
- const validation = Joi46.object({
44323
- page: Joi46.number().min(1).optional().allow("", null),
44324
- limit: Joi46.number().min(1).optional().allow("", null),
44325
- search: Joi46.string().optional().allow("", null),
44326
- school: Joi46.string().hex().optional().allow("", null),
44327
- status: Joi46.string().optional().allow("", null)
44328
- });
44329
- const { error } = validation.validate(query);
44330
- if (error) {
44331
- next(new BadRequestError71(error.message));
44332
- return;
44333
- }
44334
- const page = parseInt(req.query.page) ?? 1;
44335
- let limit = parseInt(req.query.limit) ?? 20;
44336
- limit = isNaN(limit) ? 20 : limit;
44337
- const sort = req.query.sort ? String(req.query.sort).split(",") : "";
44338
- const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
44339
- const sortObj = {};
44340
- if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
44341
- sort.forEach((field, index) => {
44342
- sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
44343
- });
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
+ );
44344
45645
  }
44345
- const status = req.query.status ?? "active";
44346
- const school = req.query.school ?? "";
44347
- const search = req.query.search ?? "";
44348
45646
  try {
44349
- const buildings = await _getAll({
44350
- page,
44351
- limit,
44352
- sort: sortObj,
44353
- status,
44354
- school,
44355
- search
44356
- });
44357
- res.json(buildings);
44358
- return;
44359
- } catch (error2) {
44360
- 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
+ );
44361
45663
  }
44362
45664
  }
44363
- async function getById(req, res, next) {
44364
- const id = req.params.id;
44365
- const validation = Joi46.object({
44366
- id: Joi46.string().hex().required()
44367
- });
44368
- const { error } = validation.validate({ id });
45665
+ async function updateById(_id, value, session) {
45666
+ const { error } = schemaKindergartenDomain.validate(value);
44369
45667
  if (error) {
44370
- next(new BadRequestError71(error.message));
44371
- return;
45668
+ throw new BadRequestError77(
45669
+ `Invalid kindergarten domain data: ${error.message}`
45670
+ );
44372
45671
  }
44373
45672
  try {
44374
- const building = await _getById(id);
44375
- res.json({
44376
- message: "Successfully retrieved building.",
44377
- data: { building }
44378
- });
44379
- return;
45673
+ _id = new ObjectId47(_id);
44380
45674
  } catch (error2) {
44381
- 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.");
44382
45687
  }
44383
45688
  }
44384
- async function deleteById(req, res, next) {
44385
- const id = req.params.id;
44386
- const validation = Joi46.object({
44387
- id: Joi46.string().hex().required()
44388
- });
44389
- const { error } = validation.validate({ id });
44390
- if (error) {
44391
- next(new BadRequestError71(error.message));
44392
- 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.");
44393
45694
  }
44394
45695
  try {
44395
- const message = await _deleteById(id);
44396
- res.json(message);
44397
- return;
44398
- } catch (error2) {
44399
- 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.");
44400
45705
  }
44401
45706
  }
44402
45707
  return {
44403
- createBuilding,
45708
+ createIndexes,
45709
+ add,
44404
45710
  getAll,
44405
45711
  getById,
45712
+ getBySchool,
45713
+ updateFieldById,
44406
45714
  updateById,
44407
45715
  deleteById
44408
45716
  };
44409
45717
  }
44410
45718
 
44411
- // src/resources/building/building-unit.service.ts
44412
- import { useAtlas as useAtlas34 } from "@eeplatform/nodejs-utils";
44413
- function useBuildingUnitService() {
44414
- const {
44415
- add: _add,
44416
- countByBuilding,
44417
- deleteById: _deleteById
44418
- } = useBuildingUnitRepo();
44419
- async function add(value) {
44420
- 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();
44421
45726
  if (!session) {
44422
- throw new Error("Unable to start session for building unit service.");
45727
+ throw new Error("Failed to start database session.");
44423
45728
  }
44424
45729
  try {
44425
- await session.startTransaction();
44426
- const existingCount = await countByBuilding(
44427
- value.building.building,
44428
- value.building.level
44429
- );
44430
- for (let index = 0; index < value.qty; index++) {
44431
- const unitNumber = existingCount ? existingCount + index + 1 : index + 1;
44432
- await _add(
44433
- { ...value.building, name: `${value.building.name} R${unitNumber}` },
44434
- 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."
44435
45739
  );
44436
45740
  }
44437
- await session.commitTransaction();
44438
- return "Building unit added successfully.";
45741
+ await _deleteById(id, session);
44439
45742
  } catch (error) {
44440
45743
  await session.abortTransaction();
44441
- throw error;
45744
+ if (error instanceof AppError30) {
45745
+ throw error;
45746
+ } else {
45747
+ throw new AppError30("Failed to delete kindergarten domain.", 500);
45748
+ }
44442
45749
  } finally {
44443
- session.endSession();
44444
- }
44445
- }
44446
- const { getById: getSectionSubjectByClassroom } = useSectionSubjectRepo();
44447
- async function deleteById(id) {
44448
- if (!id) {
44449
- throw new Error("Invalid building unit ID.");
44450
- }
44451
- const sectionSubject = await getSectionSubjectByClassroom(id);
44452
- if (sectionSubject) {
44453
- throw new Error(
44454
- "Cannot delete building unit as it is assigned to a section subject."
44455
- );
44456
- }
44457
- try {
44458
- await _deleteById(id);
44459
- return "Building unit deleted successfully.";
44460
- } catch (error) {
44461
- throw new Error("Failed to delete building unit.");
45750
+ await session.endSession();
44462
45751
  }
44463
45752
  }
44464
45753
  return {
44465
- add,
44466
45754
  deleteById
44467
45755
  };
44468
45756
  }
44469
45757
 
44470
- // src/resources/building/building-unit.controller.ts
44471
- import { BadRequestError as BadRequestError72 } from "@eeplatform/nodejs-utils";
44472
- import Joi47 from "joi";
44473
- 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() {
44474
45762
  const {
45763
+ add: _add,
44475
45764
  getAll: _getAll,
44476
45765
  getById: _getById,
44477
- updateById: _updateById
44478
- } = useBuildingUnitRepo();
44479
- const { add: _add, deleteById: _deleteById } = useBuildingUnitService();
45766
+ getBySchool: _getBySchool,
45767
+ updateFieldById: _updateFieldById
45768
+ } = useKindergartenDomainRepo();
44480
45769
  async function add(req, res, next) {
44481
- const data = req.body;
44482
- const validation = Joi47.object({
44483
- building: Joi47.object({
44484
- school: Joi47.string().hex().required(),
44485
- name: Joi47.string().optional().allow("", null),
44486
- building: Joi47.string().hex().required(),
44487
- buildingName: Joi47.string().optional().allow("", null),
44488
- level: Joi47.number().integer().min(1).required(),
44489
- category: Joi47.string().required(),
44490
- type: Joi47.string().required(),
44491
- seating_capacity: Joi47.number().integer().min(0).required(),
44492
- standing_capacity: Joi47.number().integer().min(0).required(),
44493
- description: Joi47.string().optional().allow("", null),
44494
- unit_of_measurement: Joi47.string().valid("sqm").required(),
44495
- area: Joi47.number().positive().required(),
44496
- status: Joi47.string().optional().allow("", null)
44497
- }),
44498
- qty: Joi47.number().integer().min(1).max(20).optional().default(1)
44499
- });
44500
- const { error } = validation.validate(data);
45770
+ const value = req.body;
45771
+ const { error } = schemaKindergartenDomain.validate(value);
44501
45772
  if (error) {
44502
- next(new BadRequestError72(error.message));
45773
+ next(new BadRequestError79(error.message));
44503
45774
  return;
44504
45775
  }
44505
45776
  try {
44506
- const buildingUnit = await _add(data);
45777
+ const data = await _add(value);
44507
45778
  res.json({
44508
- message: "Building unit added successfully.",
44509
- data: { buildingUnit }
45779
+ message: "Successfully created kindergarten domain.",
45780
+ data
44510
45781
  });
44511
- } catch (error2) {
44512
- next(error2);
44513
- }
44514
- }
44515
- async function updateById(req, res, next) {
44516
- const data = req.body;
44517
- const id = req.params.id ?? "";
44518
- const validation = Joi47.object({
44519
- id: Joi47.string().hex().required(),
44520
- value: schemaUpdateOptions
44521
- });
44522
- const { error } = validation.validate({ id, value: data });
44523
- if (error) {
44524
- next(new BadRequestError72(error.message));
44525
45782
  return;
44526
- }
44527
- try {
44528
- const buildingUnit = await _updateById(id, data);
44529
- res.json({
44530
- message: "Building unit updated successfully.",
44531
- data: { buildingUnit }
44532
- });
44533
45783
  } catch (error2) {
44534
45784
  next(error2);
44535
45785
  }
44536
45786
  }
44537
45787
  async function getAll(req, res, next) {
44538
45788
  const query = req.query;
44539
- const validation = Joi47.object({
44540
- page: Joi47.number().min(1).optional().allow("", null),
44541
- limit: Joi47.number().min(1).optional().allow("", null),
44542
- search: Joi47.string().optional().allow("", null),
44543
- school: Joi47.string().hex().optional().allow("", null),
44544
- building: Joi47.string().hex().optional().allow("", null),
44545
- status: Joi47.string().optional().allow("", null),
44546
- 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)
44547
45796
  });
44548
45797
  const { error } = validation.validate(query);
44549
- if (error) {
44550
- 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."));
44551
45807
  return;
44552
45808
  }
44553
- const page = parseInt(req.query.page) ?? 1;
44554
- let limit = parseInt(req.query.limit) ?? 20;
44555
- limit = isNaN(limit) ? 20 : limit;
44556
- const sort = req.query.sort ? String(req.query.sort).split(",") : "";
44557
- const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
44558
- const sortObj = {};
44559
- if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
44560
- sort.forEach((field, index) => {
44561
- sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
44562
- });
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;
44563
45817
  }
44564
- const status = req.query.status ?? "active";
44565
- const school = req.query.school ?? "";
44566
- const building = req.query.building ?? "";
44567
- const search = req.query.search ?? "";
44568
- const type = req.query.type ?? "";
44569
45818
  try {
44570
- const buildings = await _getAll({
45819
+ const data = await _getAll({
44571
45820
  page,
44572
45821
  limit,
44573
- sort: sortObj,
45822
+ search,
44574
45823
  status,
44575
45824
  school,
44576
- search,
44577
- building,
44578
- type
45825
+ createdBy: createdBy || void 0
44579
45826
  });
44580
- res.json(buildings);
45827
+ res.json(data);
44581
45828
  return;
44582
45829
  } catch (error2) {
44583
45830
  next(error2);
@@ -44585,37 +45832,80 @@ function useBuildingUnitController() {
44585
45832
  }
44586
45833
  async function getById(req, res, next) {
44587
45834
  const id = req.params.id;
44588
- const validation = Joi47.object({
44589
- id: Joi47.string().hex().required()
45835
+ const validation = Joi51.object({
45836
+ id: Joi51.string().hex().required()
44590
45837
  });
44591
45838
  const { error } = validation.validate({ id });
44592
45839
  if (error) {
44593
- next(new BadRequestError72(error.message));
45840
+ next(new BadRequestError79(error.message));
44594
45841
  return;
44595
45842
  }
44596
45843
  try {
44597
- const buildingUnit = await _getById(id);
45844
+ const data = await _getById(id);
44598
45845
  res.json({
44599
- message: "Successfully retrieved building unit.",
44600
- 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
44601
45869
  });
44602
45870
  return;
44603
45871
  } catch (error2) {
44604
45872
  next(error2);
44605
45873
  }
44606
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();
44607
45897
  async function deleteById(req, res, next) {
44608
- const id = req.params.id;
44609
- const validation = Joi47.object({
44610
- id: Joi47.string().hex().required()
45898
+ const _id = req.params.id;
45899
+ const validation = Joi51.object({
45900
+ _id: Joi51.string().hex().required()
44611
45901
  });
44612
- const { error } = validation.validate({ id });
45902
+ const { error } = validation.validate({ _id });
44613
45903
  if (error) {
44614
- next(new BadRequestError72(error.message));
45904
+ next(new BadRequestError79(error.message));
44615
45905
  return;
44616
45906
  }
44617
45907
  try {
44618
- const message = await _deleteById(id);
45908
+ const message = await _deleteById(_id);
44619
45909
  res.json({ message });
44620
45910
  return;
44621
45911
  } catch (error2) {
@@ -44626,7 +45916,8 @@ function useBuildingUnitController() {
44626
45916
  add,
44627
45917
  getAll,
44628
45918
  getById,
44629
- updateById,
45919
+ getBySchool,
45920
+ updateField,
44630
45921
  deleteById
44631
45922
  };
44632
45923
  }
@@ -44647,6 +45938,8 @@ export {
44647
45938
  allowedSectionStudentStatuses,
44648
45939
  modelBasicEduCount,
44649
45940
  modelDivision,
45941
+ modelKindergartenDomain,
45942
+ modelKindergartenRoutine,
44650
45943
  modelProgram,
44651
45944
  modelProgramScreening,
44652
45945
  modelRegion,
@@ -44669,6 +45962,9 @@ export {
44669
45962
  schemaEnrollment,
44670
45963
  schemaGenerateSections,
44671
45964
  schemaGradeLevel,
45965
+ schemaKindergartenDomain,
45966
+ schemaKindergartenRoutine,
45967
+ schemaKindergartenRoutineUpdate,
44672
45968
  schemaPersonnel,
44673
45969
  schemaPlantilla,
44674
45970
  schemaProgram,
@@ -44710,6 +46006,11 @@ export {
44710
46006
  useEnrollmentService,
44711
46007
  useGradeLevelController,
44712
46008
  useGradeLevelRepo,
46009
+ useKindergartenDomainController,
46010
+ useKindergartenDomainRepo,
46011
+ useKindergartenDomainService,
46012
+ useKindergartenRoutineController,
46013
+ useKindergartenRoutineRepo,
44713
46014
  useLearnerController,
44714
46015
  useLearnerRepo,
44715
46016
  usePersonnelController,