@eeplatform/core 1.0.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11342,6 +11342,8 @@ __export(src_exports, {
11342
11342
  MAILER_TRANSPORT_PORT: () => MAILER_TRANSPORT_PORT,
11343
11343
  MAILER_TRANSPORT_SECURE: () => MAILER_TRANSPORT_SECURE,
11344
11344
  MAddress: () => MAddress,
11345
+ MBuilding: () => MBuilding,
11346
+ MBuildingUnit: () => MBuildingUnit,
11345
11347
  MDivision: () => MDivision,
11346
11348
  MEntity: () => MEntity,
11347
11349
  MFile: () => MFile,
@@ -11382,17 +11384,25 @@ __export(src_exports, {
11382
11384
  addressSchema: () => addressSchema,
11383
11385
  isDev: () => isDev,
11384
11386
  schema: () => schema,
11387
+ schemaBuilding: () => schemaBuilding,
11388
+ schemaBuildingUnit: () => schemaBuildingUnit,
11385
11389
  schemaDivision: () => schemaDivision,
11386
11390
  schemaRegion: () => schemaRegion,
11387
11391
  schemaSchool: () => schemaSchool,
11392
+ schemaUpdateOptions: () => schemaUpdateOptions,
11388
11393
  useAddressController: () => useAddressController,
11389
11394
  useAddressRepo: () => useAddressRepo,
11390
11395
  useAuthController: () => useAuthController,
11391
11396
  useAuthService: () => useAuthService,
11397
+ useBuildingController: () => useBuildingController,
11398
+ useBuildingRepo: () => useBuildingRepo,
11399
+ useBuildingUnitController: () => useBuildingUnitController,
11400
+ useBuildingUnitRepo: () => useBuildingUnitRepo,
11392
11401
  useCounterModel: () => useCounterModel,
11393
11402
  useCounterRepo: () => useCounterRepo,
11394
11403
  useDivisionController: () => useDivisionController,
11395
11404
  useDivisionRepo: () => useDivisionRepo,
11405
+ useDivisionService: () => useDivisionService,
11396
11406
  useEntityController: () => useEntityController,
11397
11407
  useEntityRepo: () => useEntityRepo,
11398
11408
  useFileController: () => useFileController,
@@ -11423,6 +11433,7 @@ __export(src_exports, {
11423
11433
  usePromoCodeRepo: () => usePromoCodeRepo,
11424
11434
  useRegionController: () => useRegionController,
11425
11435
  useRegionRepo: () => useRegionRepo,
11436
+ useRegionService: () => useRegionService,
11426
11437
  useRoleController: () => useRoleController,
11427
11438
  useRoleRepo: () => useRoleRepo,
11428
11439
  useSchoolController: () => useSchoolController,
@@ -25597,10 +25608,6 @@ function useRegionRepo() {
25597
25608
  };
25598
25609
  }
25599
25610
 
25600
- // src/controllers/region.controller.ts
25601
- var import_nodejs_utils58 = require("@eeplatform/nodejs-utils");
25602
- var import_joi28 = __toESM(require("joi"));
25603
-
25604
25611
  // src/services/region.service.ts
25605
25612
  var import_nodejs_utils57 = require("@eeplatform/nodejs-utils");
25606
25613
  function useRegionService() {
@@ -25640,6 +25647,8 @@ function useRegionService() {
25640
25647
  }
25641
25648
 
25642
25649
  // src/controllers/region.controller.ts
25650
+ var import_nodejs_utils58 = require("@eeplatform/nodejs-utils");
25651
+ var import_joi28 = __toESM(require("joi"));
25643
25652
  function useRegionController() {
25644
25653
  const {
25645
25654
  getAll: _getAll,
@@ -26151,10 +26160,6 @@ function useDivisionRepo() {
26151
26160
  };
26152
26161
  }
26153
26162
 
26154
- // src/controllers/division.controller.ts
26155
- var import_nodejs_utils62 = require("@eeplatform/nodejs-utils");
26156
- var import_joi30 = __toESM(require("joi"));
26157
-
26158
26163
  // src/services/division.service.ts
26159
26164
  var import_nodejs_utils61 = require("@eeplatform/nodejs-utils");
26160
26165
  function useDivisionService() {
@@ -26194,6 +26199,8 @@ function useDivisionService() {
26194
26199
  }
26195
26200
 
26196
26201
  // src/controllers/division.controller.ts
26202
+ var import_nodejs_utils62 = require("@eeplatform/nodejs-utils");
26203
+ var import_joi30 = __toESM(require("joi"));
26197
26204
  function useDivisionController() {
26198
26205
  const {
26199
26206
  getAll: _getAll,
@@ -26949,6 +26956,1093 @@ function useSchoolController() {
26949
26956
  approveSchool
26950
26957
  };
26951
26958
  }
26959
+
26960
+ // src/models/building.model.ts
26961
+ var import_nodejs_utils66 = require("@eeplatform/nodejs-utils");
26962
+ var import_joi33 = __toESM(require("joi"));
26963
+ var import_mongodb39 = require("mongodb");
26964
+ var schemaBuilding = import_joi33.default.object({
26965
+ _id: import_joi33.default.string().hex().optional(),
26966
+ school: import_joi33.default.string().hex().required(),
26967
+ serial: import_joi33.default.string().optional().allow("", null),
26968
+ name: import_joi33.default.string().required(),
26969
+ levels: import_joi33.default.number().integer().min(1).required(),
26970
+ createdAt: import_joi33.default.date().optional().allow("", null),
26971
+ updatedAt: import_joi33.default.date().optional().allow("", null),
26972
+ deletedAt: import_joi33.default.date().optional().allow("", null),
26973
+ status: import_joi33.default.string().optional().allow("", null)
26974
+ });
26975
+ var schemaBuildingUnit = import_joi33.default.object({
26976
+ _id: import_joi33.default.string().hex().optional(),
26977
+ school: import_joi33.default.string().hex().required(),
26978
+ name: import_joi33.default.string().optional().allow("", null),
26979
+ building: import_joi33.default.string().hex().required(),
26980
+ buildingName: import_joi33.default.string().optional().allow("", null),
26981
+ level: import_joi33.default.number().integer().min(1).required(),
26982
+ category: import_joi33.default.string().required(),
26983
+ type: import_joi33.default.string().required(),
26984
+ seating_capacity: import_joi33.default.number().integer().min(0).required(),
26985
+ standing_capacity: import_joi33.default.number().integer().min(0).required(),
26986
+ description: import_joi33.default.string().optional().allow("", null),
26987
+ unit_of_measurement: import_joi33.default.string().valid("sqm").required(),
26988
+ area: import_joi33.default.number().positive().required(),
26989
+ status: import_joi33.default.string().optional().allow("", null)
26990
+ });
26991
+ var schemaUpdateOptions = import_joi33.default.object({
26992
+ name: import_joi33.default.string().optional().allow("", null),
26993
+ building: import_joi33.default.string().hex().optional().allow("", null),
26994
+ level: import_joi33.default.number().integer().min(1).optional().allow("", null),
26995
+ category: import_joi33.default.string().optional().allow("", null),
26996
+ type: import_joi33.default.string().optional().allow("", null),
26997
+ seating_capacity: import_joi33.default.number().integer().min(0).optional().allow("", null),
26998
+ standing_capacity: import_joi33.default.number().integer().min(0).optional().allow("", null),
26999
+ area: import_joi33.default.number().positive().optional().allow("", null)
27000
+ });
27001
+ function MBuilding(value) {
27002
+ const { error } = schemaBuilding.validate(value);
27003
+ if (error) {
27004
+ import_nodejs_utils66.logger.info(`Building Model: ${error.message}`);
27005
+ throw new import_nodejs_utils66.BadRequestError(error.message);
27006
+ }
27007
+ if (value._id && typeof value._id === "string") {
27008
+ try {
27009
+ value._id = new import_mongodb39.ObjectId(value._id);
27010
+ } catch (error2) {
27011
+ throw new import_nodejs_utils66.BadRequestError("Invalid _id format");
27012
+ }
27013
+ }
27014
+ try {
27015
+ value.school = new import_mongodb39.ObjectId(value.school);
27016
+ } catch (error2) {
27017
+ throw new import_nodejs_utils66.BadRequestError("Invalid school format");
27018
+ }
27019
+ return {
27020
+ _id: value._id ?? void 0,
27021
+ school: value.school,
27022
+ serial: value.serial ?? "",
27023
+ name: value.name ?? "",
27024
+ levels: value.levels ?? 0,
27025
+ status: value.status ?? "active",
27026
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
27027
+ updatedAt: value.updatedAt ?? "",
27028
+ deletedAt: value.deletedAt ?? ""
27029
+ };
27030
+ }
27031
+ function MBuildingUnit(value) {
27032
+ const { error } = schemaBuildingUnit.validate(value);
27033
+ if (error) {
27034
+ import_nodejs_utils66.logger.info(`Building Unit Model: ${error.message}`);
27035
+ throw new import_nodejs_utils66.BadRequestError(error.message);
27036
+ }
27037
+ if (value._id && typeof value._id === "string") {
27038
+ try {
27039
+ value._id = new import_mongodb39.ObjectId(value._id);
27040
+ } catch (error2) {
27041
+ throw new import_nodejs_utils66.BadRequestError("Invalid ID");
27042
+ }
27043
+ }
27044
+ try {
27045
+ value.school = new import_mongodb39.ObjectId(value.school);
27046
+ } catch (error2) {
27047
+ throw new import_nodejs_utils66.BadRequestError("Invalid school ID");
27048
+ }
27049
+ try {
27050
+ value.building = new import_mongodb39.ObjectId(value.building);
27051
+ } catch (error2) {
27052
+ throw new import_nodejs_utils66.BadRequestError("Invalid building ID");
27053
+ }
27054
+ return {
27055
+ _id: value._id ?? void 0,
27056
+ school: value.school,
27057
+ name: value.name ?? "",
27058
+ building: value.building,
27059
+ buildingName: value.buildingName ?? "",
27060
+ level: value.level ?? 0,
27061
+ category: value.category ?? "",
27062
+ type: value.type ?? "",
27063
+ seating_capacity: value.seating_capacity ?? 0,
27064
+ standing_capacity: value.standing_capacity ?? 0,
27065
+ description: value.description ?? "",
27066
+ unit_of_measurement: value.unit_of_measurement ?? "sqm",
27067
+ area: value.area ?? 0,
27068
+ status: value.status ?? "active",
27069
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
27070
+ updatedAt: value.updatedAt ?? "",
27071
+ deletedAt: value.deletedAt ?? ""
27072
+ };
27073
+ }
27074
+
27075
+ // src/repositories/building.repository.ts
27076
+ var import_nodejs_utils67 = require("@eeplatform/nodejs-utils");
27077
+ var import_mongodb40 = require("mongodb");
27078
+ function useBuildingRepo() {
27079
+ const db = import_nodejs_utils67.useAtlas.getDb();
27080
+ if (!db) {
27081
+ throw new Error("Unable to connect to server.");
27082
+ }
27083
+ const namespace_collection = "school.buildings";
27084
+ const collection = db.collection(namespace_collection);
27085
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils67.useCache)(namespace_collection);
27086
+ async function createIndex() {
27087
+ try {
27088
+ await collection.createIndex([
27089
+ { name: 1 },
27090
+ { school: 1 },
27091
+ { createdAt: 1 }
27092
+ ]);
27093
+ } catch (error) {
27094
+ throw new Error("Failed to create index on buildings.");
27095
+ }
27096
+ }
27097
+ async function createTextIndex() {
27098
+ try {
27099
+ await collection.createIndex({
27100
+ name: "text"
27101
+ });
27102
+ } catch (error) {
27103
+ throw new Error("Failed to create text index on building name.");
27104
+ }
27105
+ }
27106
+ async function add(value, session) {
27107
+ try {
27108
+ value = MBuilding(value);
27109
+ const res = await collection.insertOne(value, { session });
27110
+ delCachedData();
27111
+ return res.insertedId;
27112
+ } catch (error) {
27113
+ import_nodejs_utils67.logger.log({
27114
+ level: "error",
27115
+ message: error.message
27116
+ });
27117
+ if (error instanceof import_nodejs_utils67.AppError) {
27118
+ throw error;
27119
+ } else {
27120
+ const isDuplicated = error.message.includes("duplicate");
27121
+ if (isDuplicated) {
27122
+ throw new import_nodejs_utils67.BadRequestError("Building already exists.");
27123
+ }
27124
+ throw new Error("Failed to create building.");
27125
+ }
27126
+ }
27127
+ }
27128
+ async function updateById(_id, value, session) {
27129
+ try {
27130
+ _id = new import_mongodb40.ObjectId(_id);
27131
+ } catch (error) {
27132
+ throw new import_nodejs_utils67.BadRequestError("Invalid ID.");
27133
+ }
27134
+ try {
27135
+ const res = await collection.updateOne(
27136
+ { _id },
27137
+ { $set: value },
27138
+ { session }
27139
+ );
27140
+ delCachedData();
27141
+ return res;
27142
+ } catch (error) {
27143
+ import_nodejs_utils67.logger.log({
27144
+ level: "error",
27145
+ message: error.message
27146
+ });
27147
+ if (error instanceof import_nodejs_utils67.AppError) {
27148
+ throw error;
27149
+ } else {
27150
+ throw new Error("Failed to update building.");
27151
+ }
27152
+ }
27153
+ }
27154
+ async function getAll({
27155
+ search = "",
27156
+ page = 1,
27157
+ limit = 10,
27158
+ sort = {},
27159
+ school = "",
27160
+ status = "active"
27161
+ } = {}) {
27162
+ page = page > 0 ? page - 1 : 0;
27163
+ const query = {
27164
+ status
27165
+ };
27166
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
27167
+ if (search) {
27168
+ query.$text = { $search: search };
27169
+ }
27170
+ if (school) {
27171
+ try {
27172
+ query.school = new import_mongodb40.ObjectId(school);
27173
+ } catch (error) {
27174
+ throw new import_nodejs_utils67.BadRequestError("Invalid school ID.");
27175
+ }
27176
+ }
27177
+ const cacheParams = {
27178
+ page,
27179
+ limit,
27180
+ sort: JSON.stringify(sort)
27181
+ };
27182
+ if (search)
27183
+ cacheParams.search = search;
27184
+ if (school)
27185
+ cacheParams.school = school;
27186
+ if (status !== "active")
27187
+ cacheParams.status = status;
27188
+ const cacheKey = (0, import_nodejs_utils67.makeCacheKey)(namespace_collection, cacheParams);
27189
+ import_nodejs_utils67.logger.log({
27190
+ level: "info",
27191
+ message: `Cache key for getAll buildings: ${cacheKey}`
27192
+ });
27193
+ try {
27194
+ const cached = await getCache(cacheKey);
27195
+ if (cached) {
27196
+ import_nodejs_utils67.logger.log({
27197
+ level: "info",
27198
+ message: `Cache hit for getAll buildings: ${cacheKey}`
27199
+ });
27200
+ return cached;
27201
+ }
27202
+ const items = await collection.aggregate([
27203
+ { $match: query },
27204
+ { $sort: sort },
27205
+ { $skip: page * limit },
27206
+ { $limit: limit }
27207
+ ]).toArray();
27208
+ const length = await collection.countDocuments(query);
27209
+ const data = (0, import_nodejs_utils67.paginate)(items, page, limit, length);
27210
+ setCache(cacheKey, data, 600).then(() => {
27211
+ import_nodejs_utils67.logger.log({
27212
+ level: "info",
27213
+ message: `Cache set for getAll buildings: ${cacheKey}`
27214
+ });
27215
+ }).catch((err) => {
27216
+ import_nodejs_utils67.logger.log({
27217
+ level: "error",
27218
+ message: `Failed to set cache for getAll buildings: ${err.message}`
27219
+ });
27220
+ });
27221
+ return data;
27222
+ } catch (error) {
27223
+ import_nodejs_utils67.logger.log({ level: "error", message: `${error}` });
27224
+ throw error;
27225
+ }
27226
+ }
27227
+ async function getById(_id) {
27228
+ try {
27229
+ _id = new import_mongodb40.ObjectId(_id);
27230
+ } catch (error) {
27231
+ throw new import_nodejs_utils67.BadRequestError("Invalid ID.");
27232
+ }
27233
+ const cacheKey = (0, import_nodejs_utils67.makeCacheKey)(namespace_collection, { _id: String(_id) });
27234
+ try {
27235
+ const cached = await getCache(cacheKey);
27236
+ if (cached) {
27237
+ import_nodejs_utils67.logger.log({
27238
+ level: "info",
27239
+ message: `Cache hit for getById building: ${cacheKey}`
27240
+ });
27241
+ return cached;
27242
+ }
27243
+ const result = await collection.findOne({
27244
+ _id
27245
+ });
27246
+ setCache(cacheKey, result, 300).then(() => {
27247
+ import_nodejs_utils67.logger.log({
27248
+ level: "info",
27249
+ message: `Cache set for building by id: ${cacheKey}`
27250
+ });
27251
+ }).catch((err) => {
27252
+ import_nodejs_utils67.logger.log({
27253
+ level: "error",
27254
+ message: `Failed to set cache for building by id: ${err.message}`
27255
+ });
27256
+ });
27257
+ return result;
27258
+ } catch (error) {
27259
+ if (error instanceof import_nodejs_utils67.AppError) {
27260
+ throw error;
27261
+ } else {
27262
+ throw new import_nodejs_utils67.InternalServerError("Failed to get building.");
27263
+ }
27264
+ }
27265
+ }
27266
+ async function deleteById(_id, session) {
27267
+ try {
27268
+ _id = new import_mongodb40.ObjectId(_id);
27269
+ } catch (error) {
27270
+ throw new import_nodejs_utils67.BadRequestError("Invalid ID.");
27271
+ }
27272
+ try {
27273
+ const res = await collection.updateOne(
27274
+ { _id },
27275
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
27276
+ );
27277
+ delCachedData();
27278
+ return res;
27279
+ } catch (error) {
27280
+ import_nodejs_utils67.logger.log({
27281
+ level: "error",
27282
+ message: error.message
27283
+ });
27284
+ if (error instanceof import_nodejs_utils67.AppError) {
27285
+ throw error;
27286
+ } else {
27287
+ throw new import_nodejs_utils67.InternalServerError("Failed to delete building.");
27288
+ }
27289
+ }
27290
+ }
27291
+ function delCachedData() {
27292
+ delNamespace().then(() => {
27293
+ import_nodejs_utils67.logger.log({
27294
+ level: "info",
27295
+ message: `Cache namespace cleared for ${namespace_collection}`
27296
+ });
27297
+ }).catch((err) => {
27298
+ import_nodejs_utils67.logger.log({
27299
+ level: "error",
27300
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
27301
+ });
27302
+ });
27303
+ }
27304
+ return {
27305
+ createIndex,
27306
+ createTextIndex,
27307
+ add,
27308
+ getAll,
27309
+ getById,
27310
+ updateById,
27311
+ deleteById
27312
+ };
27313
+ }
27314
+
27315
+ // src/repositories/building-unit.repository.ts
27316
+ var import_nodejs_utils68 = require("@eeplatform/nodejs-utils");
27317
+ var import_mongodb41 = require("mongodb");
27318
+ function useBuildingUnitRepo() {
27319
+ const db = import_nodejs_utils68.useAtlas.getDb();
27320
+ if (!db) {
27321
+ throw new Error("Unable to connect to server.");
27322
+ }
27323
+ const namespace_collection = "school.building-units";
27324
+ const collection = db.collection(namespace_collection);
27325
+ const { getCache, setCache, delNamespace } = (0, import_nodejs_utils68.useCache)(namespace_collection);
27326
+ async function createIndex() {
27327
+ try {
27328
+ await collection.createIndexes([
27329
+ { key: { school: 1 } },
27330
+ { key: { building: 1 } },
27331
+ { key: { status: 1 } },
27332
+ { key: { createdAt: 1 } },
27333
+ {
27334
+ key: {
27335
+ name: "text",
27336
+ buildingName: "text",
27337
+ category: "text",
27338
+ type: "text"
27339
+ }
27340
+ }
27341
+ ]);
27342
+ } catch (error) {
27343
+ throw new Error("Failed to create index on building units.");
27344
+ }
27345
+ }
27346
+ function delCachedData() {
27347
+ delNamespace().then(() => {
27348
+ import_nodejs_utils68.logger.log({
27349
+ level: "info",
27350
+ message: `Cache namespace cleared for ${namespace_collection}`
27351
+ });
27352
+ }).catch((err) => {
27353
+ import_nodejs_utils68.logger.log({
27354
+ level: "error",
27355
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
27356
+ });
27357
+ });
27358
+ }
27359
+ async function add(value, session) {
27360
+ try {
27361
+ value = MBuildingUnit(value);
27362
+ const res = await collection.insertOne(value, { session });
27363
+ delCachedData();
27364
+ return res.insertedId;
27365
+ } catch (error) {
27366
+ import_nodejs_utils68.logger.log({
27367
+ level: "error",
27368
+ message: error.message
27369
+ });
27370
+ if (error instanceof import_nodejs_utils68.AppError) {
27371
+ throw error;
27372
+ } else {
27373
+ throw new Error("Failed to create building unit.");
27374
+ }
27375
+ }
27376
+ }
27377
+ async function updateById(_id, value, session) {
27378
+ const { error } = schemaUpdateOptions.validate(value);
27379
+ if (error) {
27380
+ throw new import_nodejs_utils68.BadRequestError(error.message);
27381
+ }
27382
+ try {
27383
+ _id = new import_mongodb41.ObjectId(_id);
27384
+ } catch (error2) {
27385
+ throw new import_nodejs_utils68.BadRequestError("Invalid ID.");
27386
+ }
27387
+ try {
27388
+ const res = await collection.updateOne(
27389
+ { _id },
27390
+ { $set: value },
27391
+ { session }
27392
+ );
27393
+ delCachedData();
27394
+ return res;
27395
+ } catch (error2) {
27396
+ import_nodejs_utils68.logger.log({
27397
+ level: "error",
27398
+ message: error2.message
27399
+ });
27400
+ if (error2 instanceof import_nodejs_utils68.AppError) {
27401
+ throw error2;
27402
+ } else {
27403
+ throw new Error("Failed to create building unit.");
27404
+ }
27405
+ }
27406
+ }
27407
+ async function getAll({
27408
+ search = "",
27409
+ page = 1,
27410
+ limit = 10,
27411
+ sort = {},
27412
+ school = "",
27413
+ building = "",
27414
+ status = "active"
27415
+ } = {}) {
27416
+ page = page > 0 ? page - 1 : 0;
27417
+ const query = {
27418
+ deletedAt: { $in: ["", null] },
27419
+ status: { $in: [status, "", null] }
27420
+ };
27421
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
27422
+ if (search) {
27423
+ query.$text = { $search: search };
27424
+ }
27425
+ if (school) {
27426
+ try {
27427
+ query.school = new import_mongodb41.ObjectId(school);
27428
+ } catch (error) {
27429
+ throw new import_nodejs_utils68.BadRequestError("Invalid school ID.");
27430
+ }
27431
+ }
27432
+ if (building) {
27433
+ try {
27434
+ query.building = new import_mongodb41.ObjectId(building);
27435
+ } catch (error) {
27436
+ throw new import_nodejs_utils68.BadRequestError("Invalid building ID.");
27437
+ }
27438
+ }
27439
+ const cacheParams = {
27440
+ page,
27441
+ limit,
27442
+ sort: JSON.stringify(sort)
27443
+ };
27444
+ if (search)
27445
+ cacheParams.search = search;
27446
+ if (school)
27447
+ cacheParams.school = school;
27448
+ if (building)
27449
+ cacheParams.building = building;
27450
+ if (status !== "active")
27451
+ cacheParams.status = status;
27452
+ const cacheKey = (0, import_nodejs_utils68.makeCacheKey)(namespace_collection, cacheParams);
27453
+ import_nodejs_utils68.logger.log({
27454
+ level: "info",
27455
+ message: `Cache key for getAll building units: ${cacheKey}`
27456
+ });
27457
+ try {
27458
+ const cached = await getCache(cacheKey);
27459
+ if (cached) {
27460
+ import_nodejs_utils68.logger.log({
27461
+ level: "info",
27462
+ message: `Cache hit for getAll building units: ${cacheKey}`
27463
+ });
27464
+ return cached;
27465
+ }
27466
+ const items = await collection.aggregate([
27467
+ { $match: query },
27468
+ { $sort: sort },
27469
+ { $skip: page * limit },
27470
+ { $limit: limit }
27471
+ ]).toArray();
27472
+ const length = await collection.countDocuments(query);
27473
+ const data = (0, import_nodejs_utils68.paginate)(items, page, limit, length);
27474
+ setCache(cacheKey, data, 600).then(() => {
27475
+ import_nodejs_utils68.logger.log({
27476
+ level: "info",
27477
+ message: `Cache set for getAll building units: ${cacheKey}`
27478
+ });
27479
+ }).catch((err) => {
27480
+ import_nodejs_utils68.logger.log({
27481
+ level: "error",
27482
+ message: `Failed to set cache for getAll building units: ${err.message}`
27483
+ });
27484
+ });
27485
+ return data;
27486
+ } catch (error) {
27487
+ import_nodejs_utils68.logger.log({ level: "error", message: `${error}` });
27488
+ throw error;
27489
+ }
27490
+ }
27491
+ async function getById(_id) {
27492
+ try {
27493
+ _id = new import_mongodb41.ObjectId(_id);
27494
+ } catch (error) {
27495
+ throw new import_nodejs_utils68.BadRequestError("Invalid ID.");
27496
+ }
27497
+ const cacheKey = (0, import_nodejs_utils68.makeCacheKey)(namespace_collection, { _id: String(_id) });
27498
+ try {
27499
+ const cached = await getCache(cacheKey);
27500
+ if (cached) {
27501
+ import_nodejs_utils68.logger.log({
27502
+ level: "info",
27503
+ message: `Cache hit for getById building unit: ${cacheKey}`
27504
+ });
27505
+ return cached;
27506
+ }
27507
+ const result = await collection.findOne({
27508
+ _id,
27509
+ deletedAt: { $in: ["", null] }
27510
+ });
27511
+ if (!result) {
27512
+ throw new import_nodejs_utils68.BadRequestError("Building unit not found.");
27513
+ }
27514
+ setCache(cacheKey, result, 300).then(() => {
27515
+ import_nodejs_utils68.logger.log({
27516
+ level: "info",
27517
+ message: `Cache set for building unit by id: ${cacheKey}`
27518
+ });
27519
+ }).catch((err) => {
27520
+ import_nodejs_utils68.logger.log({
27521
+ level: "error",
27522
+ message: `Failed to set cache for building unit by id: ${err.message}`
27523
+ });
27524
+ });
27525
+ return result;
27526
+ } catch (error) {
27527
+ if (error instanceof import_nodejs_utils68.AppError) {
27528
+ throw error;
27529
+ } else {
27530
+ throw new import_nodejs_utils68.InternalServerError("Failed to get building unit.");
27531
+ }
27532
+ }
27533
+ }
27534
+ async function getByBuildingLevel(building, level) {
27535
+ try {
27536
+ building = new import_mongodb41.ObjectId(building);
27537
+ } catch (error) {
27538
+ throw new import_nodejs_utils68.BadRequestError("Invalid building ID.");
27539
+ }
27540
+ const cacheKey = (0, import_nodejs_utils68.makeCacheKey)(namespace_collection, {
27541
+ building: String(building),
27542
+ level
27543
+ });
27544
+ try {
27545
+ const cached = await getCache(cacheKey);
27546
+ if (cached) {
27547
+ import_nodejs_utils68.logger.log({
27548
+ level: "info",
27549
+ message: `Cache hit for getById building unit: ${cacheKey}`
27550
+ });
27551
+ return cached;
27552
+ }
27553
+ const result = await collection.findOne({
27554
+ building,
27555
+ level,
27556
+ status: "active"
27557
+ });
27558
+ setCache(cacheKey, result, 300).then(() => {
27559
+ import_nodejs_utils68.logger.log({
27560
+ level: "info",
27561
+ message: `Cache set for building unit by id: ${cacheKey}`
27562
+ });
27563
+ }).catch((err) => {
27564
+ import_nodejs_utils68.logger.log({
27565
+ level: "error",
27566
+ message: `Failed to set cache for building unit by id: ${err.message}`
27567
+ });
27568
+ });
27569
+ return result;
27570
+ } catch (error) {
27571
+ if (error instanceof import_nodejs_utils68.AppError) {
27572
+ throw error;
27573
+ } else {
27574
+ throw new import_nodejs_utils68.InternalServerError("Failed to get building unit.");
27575
+ }
27576
+ }
27577
+ }
27578
+ async function getByBuilding(building) {
27579
+ try {
27580
+ building = new import_mongodb41.ObjectId(building);
27581
+ } catch (error) {
27582
+ throw new import_nodejs_utils68.BadRequestError("Invalid building ID.");
27583
+ }
27584
+ const cacheKey = (0, import_nodejs_utils68.makeCacheKey)(namespace_collection, {
27585
+ building: String(building)
27586
+ });
27587
+ try {
27588
+ const cached = await getCache(cacheKey);
27589
+ if (cached) {
27590
+ import_nodejs_utils68.logger.log({
27591
+ level: "info",
27592
+ message: `Cache hit for getById building unit: ${cacheKey}`
27593
+ });
27594
+ return cached;
27595
+ }
27596
+ const result = await collection.findOne({
27597
+ building,
27598
+ status: "active"
27599
+ });
27600
+ setCache(cacheKey, result, 300).then(() => {
27601
+ import_nodejs_utils68.logger.log({
27602
+ level: "info",
27603
+ message: `Cache set for building unit by id: ${cacheKey}`
27604
+ });
27605
+ }).catch((err) => {
27606
+ import_nodejs_utils68.logger.log({
27607
+ level: "error",
27608
+ message: `Failed to set cache for building unit by id: ${err.message}`
27609
+ });
27610
+ });
27611
+ return result;
27612
+ } catch (error) {
27613
+ if (error instanceof import_nodejs_utils68.AppError) {
27614
+ throw error;
27615
+ } else {
27616
+ throw new import_nodejs_utils68.InternalServerError("Failed to get building unit.");
27617
+ }
27618
+ }
27619
+ }
27620
+ async function deleteById(_id, session) {
27621
+ try {
27622
+ _id = new import_mongodb41.ObjectId(_id);
27623
+ } catch (error) {
27624
+ throw new import_nodejs_utils68.BadRequestError("Invalid ID.");
27625
+ }
27626
+ try {
27627
+ const res = await collection.updateOne(
27628
+ { _id },
27629
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
27630
+ { session }
27631
+ );
27632
+ delCachedData();
27633
+ return "Room/Facility deleted successfully.";
27634
+ } catch (error) {
27635
+ import_nodejs_utils68.logger.log({
27636
+ level: "error",
27637
+ message: error.message
27638
+ });
27639
+ if (error instanceof import_nodejs_utils68.AppError) {
27640
+ throw error;
27641
+ } else {
27642
+ throw new Error("Failed to deleted room/facility.");
27643
+ }
27644
+ }
27645
+ }
27646
+ return {
27647
+ createIndex,
27648
+ add,
27649
+ getAll,
27650
+ getById,
27651
+ getByBuildingLevel,
27652
+ updateById,
27653
+ getByBuilding,
27654
+ deleteById
27655
+ };
27656
+ }
27657
+
27658
+ // src/controllers/building.controller.ts
27659
+ var import_nodejs_utils70 = require("@eeplatform/nodejs-utils");
27660
+ var import_joi34 = __toESM(require("joi"));
27661
+
27662
+ // src/services/building.service.ts
27663
+ var import_nodejs_utils69 = require("@eeplatform/nodejs-utils");
27664
+ function useBuildingService() {
27665
+ const {
27666
+ updateById: _updateById,
27667
+ getById: _getById,
27668
+ deleteById: _deleteById
27669
+ } = useBuildingRepo();
27670
+ const { getByBuildingLevel, getByBuilding } = useBuildingUnitRepo();
27671
+ async function updateById(id, data) {
27672
+ data.levels = Number(data.levels);
27673
+ try {
27674
+ const building = await _getById(id);
27675
+ if (!building) {
27676
+ throw new import_nodejs_utils69.NotFoundError("Building not found.");
27677
+ }
27678
+ if (data.levels < building.levels) {
27679
+ const unit = await getByBuildingLevel(id, building.levels);
27680
+ if (unit) {
27681
+ throw new import_nodejs_utils69.BadRequestError(
27682
+ "Cannot reduce floors, there are existing building units at higher floors."
27683
+ );
27684
+ }
27685
+ }
27686
+ const result = await _updateById(id, data);
27687
+ return result;
27688
+ } catch (error) {
27689
+ throw error;
27690
+ }
27691
+ }
27692
+ async function deleteById(id) {
27693
+ const building = await getByBuilding(id);
27694
+ if (building) {
27695
+ throw new import_nodejs_utils69.BadRequestError(
27696
+ "Cannot delete building with existing room/facility. Please delete room/facility first."
27697
+ );
27698
+ }
27699
+ try {
27700
+ await _deleteById(id);
27701
+ return "Building deleted successfully.";
27702
+ } catch (error) {
27703
+ throw error;
27704
+ }
27705
+ }
27706
+ return {
27707
+ updateById,
27708
+ deleteById
27709
+ };
27710
+ }
27711
+
27712
+ // src/controllers/building.controller.ts
27713
+ function useBuildingController() {
27714
+ const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
27715
+ const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
27716
+ async function createBuilding(req, res, next) {
27717
+ const value = req.body;
27718
+ const validation = import_joi34.default.object({
27719
+ name: import_joi34.default.string().required(),
27720
+ school: import_joi34.default.string().hex().required(),
27721
+ levels: import_joi34.default.number().integer().min(1).required(),
27722
+ serial: import_joi34.default.string().optional().allow("", null),
27723
+ status: import_joi34.default.string().optional().allow("", null)
27724
+ });
27725
+ const { error } = validation.validate(value);
27726
+ if (error) {
27727
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27728
+ import_nodejs_utils70.logger.info(`Controller: ${error.message}`);
27729
+ return;
27730
+ }
27731
+ try {
27732
+ const result = await _add(value);
27733
+ res.json(result);
27734
+ return;
27735
+ } catch (error2) {
27736
+ next(error2);
27737
+ }
27738
+ }
27739
+ async function updateById(req, res, next) {
27740
+ const value = req.body;
27741
+ const id = req.params.id ?? "";
27742
+ const validation = import_joi34.default.object({
27743
+ id: import_joi34.default.string().hex().required(),
27744
+ value: import_joi34.default.object({
27745
+ name: import_joi34.default.string().required(),
27746
+ serial: import_joi34.default.string().optional().allow("", null),
27747
+ levels: import_joi34.default.number().integer().min(1).required()
27748
+ })
27749
+ });
27750
+ const { error } = validation.validate({ id, value });
27751
+ if (error) {
27752
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27753
+ import_nodejs_utils70.logger.info(`Controller: ${error.message}`);
27754
+ return;
27755
+ }
27756
+ try {
27757
+ const result = await _updateById(id, value);
27758
+ res.json(result);
27759
+ return;
27760
+ } catch (error2) {
27761
+ next(error2);
27762
+ }
27763
+ }
27764
+ async function getAll(req, res, next) {
27765
+ const query = req.query;
27766
+ const validation = import_joi34.default.object({
27767
+ page: import_joi34.default.number().min(1).optional().allow("", null),
27768
+ limit: import_joi34.default.number().min(1).optional().allow("", null),
27769
+ search: import_joi34.default.string().optional().allow("", null),
27770
+ school: import_joi34.default.string().hex().optional().allow("", null),
27771
+ status: import_joi34.default.string().optional().allow("", null)
27772
+ });
27773
+ const { error } = validation.validate(query);
27774
+ if (error) {
27775
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27776
+ return;
27777
+ }
27778
+ const page = parseInt(req.query.page) ?? 1;
27779
+ let limit = parseInt(req.query.limit) ?? 20;
27780
+ limit = isNaN(limit) ? 20 : limit;
27781
+ const sort = req.query.sort ? String(req.query.sort).split(",") : "";
27782
+ const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
27783
+ const sortObj = {};
27784
+ if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
27785
+ sort.forEach((field, index) => {
27786
+ sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
27787
+ });
27788
+ }
27789
+ const status = req.query.status ?? "active";
27790
+ const school = req.query.school ?? "";
27791
+ const search = req.query.search ?? "";
27792
+ try {
27793
+ const buildings = await _getAll({
27794
+ page,
27795
+ limit,
27796
+ sort: sortObj,
27797
+ status,
27798
+ school,
27799
+ search
27800
+ });
27801
+ res.json(buildings);
27802
+ return;
27803
+ } catch (error2) {
27804
+ next(error2);
27805
+ }
27806
+ }
27807
+ async function getById(req, res, next) {
27808
+ const id = req.params.id;
27809
+ const validation = import_joi34.default.object({
27810
+ id: import_joi34.default.string().hex().required()
27811
+ });
27812
+ const { error } = validation.validate({ id });
27813
+ if (error) {
27814
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27815
+ return;
27816
+ }
27817
+ try {
27818
+ const building = await _getById(id);
27819
+ res.json({
27820
+ message: "Successfully retrieved building.",
27821
+ data: { building }
27822
+ });
27823
+ return;
27824
+ } catch (error2) {
27825
+ next(error2);
27826
+ }
27827
+ }
27828
+ async function deleteById(req, res, next) {
27829
+ const id = req.params.id;
27830
+ const validation = import_joi34.default.object({
27831
+ id: import_joi34.default.string().hex().required()
27832
+ });
27833
+ const { error } = validation.validate({ id });
27834
+ if (error) {
27835
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27836
+ return;
27837
+ }
27838
+ try {
27839
+ const message = await _deleteById(id);
27840
+ res.json(message);
27841
+ return;
27842
+ } catch (error2) {
27843
+ next(error2);
27844
+ }
27845
+ }
27846
+ return {
27847
+ createBuilding,
27848
+ getAll,
27849
+ getById,
27850
+ updateById,
27851
+ deleteById
27852
+ };
27853
+ }
27854
+
27855
+ // src/controllers/building-unit.controller.ts
27856
+ var import_nodejs_utils72 = require("@eeplatform/nodejs-utils");
27857
+ var import_joi35 = __toESM(require("joi"));
27858
+
27859
+ // src/services/building-unit.service.ts
27860
+ var import_nodejs_utils71 = require("@eeplatform/nodejs-utils");
27861
+ function useBuildingUnitService() {
27862
+ const { add: _add } = useBuildingUnitRepo();
27863
+ async function add(value) {
27864
+ const session = import_nodejs_utils71.useAtlas.getClient()?.startSession();
27865
+ if (!session) {
27866
+ throw new Error("Unable to start session for building unit service.");
27867
+ }
27868
+ try {
27869
+ await session.startTransaction();
27870
+ for (let index = 0; index < value.qty; index++) {
27871
+ await _add({ ...value.building }, session);
27872
+ }
27873
+ await session.commitTransaction();
27874
+ return "Building unit added successfully.";
27875
+ } catch (error) {
27876
+ await session.abortTransaction();
27877
+ throw error;
27878
+ } finally {
27879
+ session.endSession();
27880
+ }
27881
+ }
27882
+ return {
27883
+ add
27884
+ };
27885
+ }
27886
+
27887
+ // src/controllers/building-unit.controller.ts
27888
+ function useBuildingUnitController() {
27889
+ const {
27890
+ getAll: _getAll,
27891
+ getById: _getById,
27892
+ updateById: _updateById,
27893
+ deleteById: _deleteById
27894
+ } = useBuildingUnitRepo();
27895
+ const { add: _add } = useBuildingUnitService();
27896
+ async function add(req, res, next) {
27897
+ const data = req.body;
27898
+ const validation = import_joi35.default.object({
27899
+ building: import_joi35.default.object({
27900
+ school: import_joi35.default.string().hex().required(),
27901
+ name: import_joi35.default.string().optional().allow("", null),
27902
+ building: import_joi35.default.string().hex().required(),
27903
+ buildingName: import_joi35.default.string().optional().allow("", null),
27904
+ level: import_joi35.default.number().integer().min(1).required(),
27905
+ category: import_joi35.default.string().required(),
27906
+ type: import_joi35.default.string().required(),
27907
+ seating_capacity: import_joi35.default.number().integer().min(0).required(),
27908
+ standing_capacity: import_joi35.default.number().integer().min(0).required(),
27909
+ description: import_joi35.default.string().optional().allow("", null),
27910
+ unit_of_measurement: import_joi35.default.string().valid("sqm").required(),
27911
+ area: import_joi35.default.number().positive().required(),
27912
+ status: import_joi35.default.string().optional().allow("", null)
27913
+ }),
27914
+ qty: import_joi35.default.number().integer().min(1).max(20).optional().default(1)
27915
+ });
27916
+ const { error } = validation.validate(data);
27917
+ if (error) {
27918
+ next(new import_nodejs_utils72.BadRequestError(error.message));
27919
+ return;
27920
+ }
27921
+ try {
27922
+ const buildingUnit = await _add(data);
27923
+ res.json({
27924
+ message: "Building unit added successfully.",
27925
+ data: { buildingUnit }
27926
+ });
27927
+ } catch (error2) {
27928
+ next(error2);
27929
+ }
27930
+ }
27931
+ async function updateById(req, res, next) {
27932
+ const data = req.body;
27933
+ const id = req.params.id ?? "";
27934
+ const validation = import_joi35.default.object({
27935
+ id: import_joi35.default.string().hex().required(),
27936
+ value: schemaUpdateOptions
27937
+ });
27938
+ const { error } = validation.validate({ id, value: data });
27939
+ if (error) {
27940
+ next(new import_nodejs_utils72.BadRequestError(error.message));
27941
+ return;
27942
+ }
27943
+ try {
27944
+ const buildingUnit = await _updateById(id, data);
27945
+ res.json({
27946
+ message: "Building unit updated successfully.",
27947
+ data: { buildingUnit }
27948
+ });
27949
+ } catch (error2) {
27950
+ next(error2);
27951
+ }
27952
+ }
27953
+ async function getAll(req, res, next) {
27954
+ const query = req.query;
27955
+ const validation = import_joi35.default.object({
27956
+ page: import_joi35.default.number().min(1).optional().allow("", null),
27957
+ limit: import_joi35.default.number().min(1).optional().allow("", null),
27958
+ search: import_joi35.default.string().optional().allow("", null),
27959
+ school: import_joi35.default.string().hex().optional().allow("", null),
27960
+ building: import_joi35.default.string().hex().optional().allow("", null),
27961
+ status: import_joi35.default.string().optional().allow("", null)
27962
+ });
27963
+ const { error } = validation.validate(query);
27964
+ if (error) {
27965
+ next(new import_nodejs_utils72.BadRequestError(error.message));
27966
+ return;
27967
+ }
27968
+ const page = parseInt(req.query.page) ?? 1;
27969
+ let limit = parseInt(req.query.limit) ?? 20;
27970
+ limit = isNaN(limit) ? 20 : limit;
27971
+ const sort = req.query.sort ? String(req.query.sort).split(",") : "";
27972
+ const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
27973
+ const sortObj = {};
27974
+ if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
27975
+ sort.forEach((field, index) => {
27976
+ sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
27977
+ });
27978
+ }
27979
+ const status = req.query.status ?? "active";
27980
+ const school = req.query.school ?? "";
27981
+ const building = req.query.building ?? "";
27982
+ const search = req.query.search ?? "";
27983
+ try {
27984
+ const buildings = await _getAll({
27985
+ page,
27986
+ limit,
27987
+ sort: sortObj,
27988
+ status,
27989
+ school,
27990
+ search,
27991
+ building
27992
+ });
27993
+ res.json(buildings);
27994
+ return;
27995
+ } catch (error2) {
27996
+ next(error2);
27997
+ }
27998
+ }
27999
+ async function getById(req, res, next) {
28000
+ const id = req.params.id;
28001
+ const validation = import_joi35.default.object({
28002
+ id: import_joi35.default.string().hex().required()
28003
+ });
28004
+ const { error } = validation.validate({ id });
28005
+ if (error) {
28006
+ next(new import_nodejs_utils72.BadRequestError(error.message));
28007
+ return;
28008
+ }
28009
+ try {
28010
+ const buildingUnit = await _getById(id);
28011
+ res.json({
28012
+ message: "Successfully retrieved building unit.",
28013
+ data: { buildingUnit }
28014
+ });
28015
+ return;
28016
+ } catch (error2) {
28017
+ next(error2);
28018
+ }
28019
+ }
28020
+ async function deleteById(req, res, next) {
28021
+ const id = req.params.id;
28022
+ const validation = import_joi35.default.object({
28023
+ id: import_joi35.default.string().hex().required()
28024
+ });
28025
+ const { error } = validation.validate({ id });
28026
+ if (error) {
28027
+ next(new import_nodejs_utils72.BadRequestError(error.message));
28028
+ return;
28029
+ }
28030
+ try {
28031
+ const message = await _deleteById(id);
28032
+ res.json({ message });
28033
+ return;
28034
+ } catch (error2) {
28035
+ next(error2);
28036
+ }
28037
+ }
28038
+ return {
28039
+ add,
28040
+ getAll,
28041
+ getById,
28042
+ updateById,
28043
+ deleteById
28044
+ };
28045
+ }
26952
28046
  // Annotate the CommonJS export names for ESM import in node:
26953
28047
  0 && (module.exports = {
26954
28048
  ACCESS_TOKEN_EXPIRY,
@@ -26968,6 +28062,8 @@ function useSchoolController() {
26968
28062
  MAILER_TRANSPORT_PORT,
26969
28063
  MAILER_TRANSPORT_SECURE,
26970
28064
  MAddress,
28065
+ MBuilding,
28066
+ MBuildingUnit,
26971
28067
  MDivision,
26972
28068
  MEntity,
26973
28069
  MFile,
@@ -27008,17 +28104,25 @@ function useSchoolController() {
27008
28104
  addressSchema,
27009
28105
  isDev,
27010
28106
  schema,
28107
+ schemaBuilding,
28108
+ schemaBuildingUnit,
27011
28109
  schemaDivision,
27012
28110
  schemaRegion,
27013
28111
  schemaSchool,
28112
+ schemaUpdateOptions,
27014
28113
  useAddressController,
27015
28114
  useAddressRepo,
27016
28115
  useAuthController,
27017
28116
  useAuthService,
28117
+ useBuildingController,
28118
+ useBuildingRepo,
28119
+ useBuildingUnitController,
28120
+ useBuildingUnitRepo,
27018
28121
  useCounterModel,
27019
28122
  useCounterRepo,
27020
28123
  useDivisionController,
27021
28124
  useDivisionRepo,
28125
+ useDivisionService,
27022
28126
  useEntityController,
27023
28127
  useEntityRepo,
27024
28128
  useFileController,
@@ -27049,6 +28153,7 @@ function useSchoolController() {
27049
28153
  usePromoCodeRepo,
27050
28154
  useRegionController,
27051
28155
  useRegionRepo,
28156
+ useRegionService,
27052
28157
  useRoleController,
27053
28158
  useRoleRepo,
27054
28159
  useSchoolController,