@eeplatform/core 1.1.0 → 1.2.1

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
@@ -11389,6 +11389,7 @@ __export(src_exports, {
11389
11389
  schemaDivision: () => schemaDivision,
11390
11390
  schemaRegion: () => schemaRegion,
11391
11391
  schemaSchool: () => schemaSchool,
11392
+ schemaUpdateOptions: () => schemaUpdateOptions,
11392
11393
  useAddressController: () => useAddressController,
11393
11394
  useAddressRepo: () => useAddressRepo,
11394
11395
  useAuthController: () => useAuthController,
@@ -26987,6 +26988,16 @@ var schemaBuildingUnit = import_joi33.default.object({
26987
26988
  area: import_joi33.default.number().positive().required(),
26988
26989
  status: import_joi33.default.string().optional().allow("", null)
26989
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
+ });
26990
27001
  function MBuilding(value) {
26991
27002
  const { error } = schemaBuilding.validate(value);
26992
27003
  if (error) {
@@ -27072,26 +27083,17 @@ function useBuildingRepo() {
27072
27083
  const namespace_collection = "school.buildings";
27073
27084
  const collection = db.collection(namespace_collection);
27074
27085
  const { getCache, setCache, delNamespace } = (0, import_nodejs_utils67.useCache)(namespace_collection);
27075
- async function createIndex() {
27086
+ async function createIndexes() {
27076
27087
  try {
27077
- await collection.createIndex([
27078
- { name: 1 },
27079
- { school: 1 },
27080
- { createdAt: 1 }
27088
+ await collection.createIndexes([
27089
+ { key: { name: 1 }, unique: true, name: "unique_name_index" },
27090
+ { key: { school: 1 } },
27091
+ { key: { status: 1 } }
27081
27092
  ]);
27082
27093
  } catch (error) {
27083
27094
  throw new Error("Failed to create index on buildings.");
27084
27095
  }
27085
27096
  }
27086
- async function createTextIndex() {
27087
- try {
27088
- await collection.createIndex({
27089
- name: "text"
27090
- });
27091
- } catch (error) {
27092
- throw new Error("Failed to create text index on building name.");
27093
- }
27094
- }
27095
27097
  async function add(value, session) {
27096
27098
  try {
27097
27099
  value = MBuilding(value);
@@ -27114,6 +27116,32 @@ function useBuildingRepo() {
27114
27116
  }
27115
27117
  }
27116
27118
  }
27119
+ async function updateById(_id, value, session) {
27120
+ try {
27121
+ _id = new import_mongodb40.ObjectId(_id);
27122
+ } catch (error) {
27123
+ throw new import_nodejs_utils67.BadRequestError("Invalid ID.");
27124
+ }
27125
+ try {
27126
+ const res = await collection.updateOne(
27127
+ { _id },
27128
+ { $set: value },
27129
+ { session }
27130
+ );
27131
+ delCachedData();
27132
+ return res;
27133
+ } catch (error) {
27134
+ import_nodejs_utils67.logger.log({
27135
+ level: "error",
27136
+ message: error.message
27137
+ });
27138
+ if (error instanceof import_nodejs_utils67.AppError) {
27139
+ throw error;
27140
+ } else {
27141
+ throw new Error("Failed to update building.");
27142
+ }
27143
+ }
27144
+ }
27117
27145
  async function getAll({
27118
27146
  search = "",
27119
27147
  page = 1,
@@ -27204,12 +27232,8 @@ function useBuildingRepo() {
27204
27232
  return cached;
27205
27233
  }
27206
27234
  const result = await collection.findOne({
27207
- _id,
27208
- deletedAt: { $in: ["", null] }
27235
+ _id
27209
27236
  });
27210
- if (!result) {
27211
- throw new import_nodejs_utils67.BadRequestError("Building not found.");
27212
- }
27213
27237
  setCache(cacheKey, result, 300).then(() => {
27214
27238
  import_nodejs_utils67.logger.log({
27215
27239
  level: "info",
@@ -27230,6 +27254,31 @@ function useBuildingRepo() {
27230
27254
  }
27231
27255
  }
27232
27256
  }
27257
+ async function deleteById(_id, session) {
27258
+ try {
27259
+ _id = new import_mongodb40.ObjectId(_id);
27260
+ } catch (error) {
27261
+ throw new import_nodejs_utils67.BadRequestError("Invalid ID.");
27262
+ }
27263
+ try {
27264
+ const res = await collection.updateOne(
27265
+ { _id },
27266
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
27267
+ );
27268
+ delCachedData();
27269
+ return res;
27270
+ } catch (error) {
27271
+ import_nodejs_utils67.logger.log({
27272
+ level: "error",
27273
+ message: error.message
27274
+ });
27275
+ if (error instanceof import_nodejs_utils67.AppError) {
27276
+ throw error;
27277
+ } else {
27278
+ throw new import_nodejs_utils67.InternalServerError("Failed to delete building.");
27279
+ }
27280
+ }
27281
+ }
27233
27282
  function delCachedData() {
27234
27283
  delNamespace().then(() => {
27235
27284
  import_nodejs_utils67.logger.log({
@@ -27244,11 +27293,12 @@ function useBuildingRepo() {
27244
27293
  });
27245
27294
  }
27246
27295
  return {
27247
- createIndex,
27248
- createTextIndex,
27296
+ createIndexes,
27249
27297
  add,
27250
27298
  getAll,
27251
- getById
27299
+ getById,
27300
+ updateById,
27301
+ deleteById
27252
27302
  };
27253
27303
  }
27254
27304
 
@@ -27263,9 +27313,14 @@ function useBuildingUnitRepo() {
27263
27313
  const namespace_collection = "school.building-units";
27264
27314
  const collection = db.collection(namespace_collection);
27265
27315
  const { getCache, setCache, delNamespace } = (0, import_nodejs_utils68.useCache)(namespace_collection);
27266
- async function createIndex() {
27316
+ async function createIndexes() {
27267
27317
  try {
27268
27318
  await collection.createIndexes([
27319
+ {
27320
+ key: { name: 1, building: 1, level: 1 },
27321
+ unique: true,
27322
+ name: "unique_name_index"
27323
+ },
27269
27324
  { key: { school: 1 } },
27270
27325
  { key: { building: 1 } },
27271
27326
  { key: { status: 1 } },
@@ -27314,6 +27369,36 @@ function useBuildingUnitRepo() {
27314
27369
  }
27315
27370
  }
27316
27371
  }
27372
+ async function updateById(_id, value, session) {
27373
+ const { error } = schemaUpdateOptions.validate(value);
27374
+ if (error) {
27375
+ throw new import_nodejs_utils68.BadRequestError(error.message);
27376
+ }
27377
+ try {
27378
+ _id = new import_mongodb41.ObjectId(_id);
27379
+ } catch (error2) {
27380
+ throw new import_nodejs_utils68.BadRequestError("Invalid ID.");
27381
+ }
27382
+ try {
27383
+ const res = await collection.updateOne(
27384
+ { _id },
27385
+ { $set: value },
27386
+ { session }
27387
+ );
27388
+ delCachedData();
27389
+ return res;
27390
+ } catch (error2) {
27391
+ import_nodejs_utils68.logger.log({
27392
+ level: "error",
27393
+ message: error2.message
27394
+ });
27395
+ if (error2 instanceof import_nodejs_utils68.AppError) {
27396
+ throw error2;
27397
+ } else {
27398
+ throw new Error("Failed to create building unit.");
27399
+ }
27400
+ }
27401
+ }
27317
27402
  async function getAll({
27318
27403
  search = "",
27319
27404
  page = 1,
@@ -27441,19 +27526,188 @@ function useBuildingUnitRepo() {
27441
27526
  }
27442
27527
  }
27443
27528
  }
27529
+ async function getByBuildingLevel(building, level) {
27530
+ try {
27531
+ building = new import_mongodb41.ObjectId(building);
27532
+ } catch (error) {
27533
+ throw new import_nodejs_utils68.BadRequestError("Invalid building ID.");
27534
+ }
27535
+ const cacheKey = (0, import_nodejs_utils68.makeCacheKey)(namespace_collection, {
27536
+ building: String(building),
27537
+ level
27538
+ });
27539
+ try {
27540
+ const cached = await getCache(cacheKey);
27541
+ if (cached) {
27542
+ import_nodejs_utils68.logger.log({
27543
+ level: "info",
27544
+ message: `Cache hit for getById building unit: ${cacheKey}`
27545
+ });
27546
+ return cached;
27547
+ }
27548
+ const result = await collection.findOne({
27549
+ building,
27550
+ level,
27551
+ status: "active"
27552
+ });
27553
+ setCache(cacheKey, result, 300).then(() => {
27554
+ import_nodejs_utils68.logger.log({
27555
+ level: "info",
27556
+ message: `Cache set for building unit by id: ${cacheKey}`
27557
+ });
27558
+ }).catch((err) => {
27559
+ import_nodejs_utils68.logger.log({
27560
+ level: "error",
27561
+ message: `Failed to set cache for building unit by id: ${err.message}`
27562
+ });
27563
+ });
27564
+ return result;
27565
+ } catch (error) {
27566
+ if (error instanceof import_nodejs_utils68.AppError) {
27567
+ throw error;
27568
+ } else {
27569
+ throw new import_nodejs_utils68.InternalServerError("Failed to get building unit.");
27570
+ }
27571
+ }
27572
+ }
27573
+ async function getByBuilding(building) {
27574
+ try {
27575
+ building = new import_mongodb41.ObjectId(building);
27576
+ } catch (error) {
27577
+ throw new import_nodejs_utils68.BadRequestError("Invalid building ID.");
27578
+ }
27579
+ const cacheKey = (0, import_nodejs_utils68.makeCacheKey)(namespace_collection, {
27580
+ building: String(building)
27581
+ });
27582
+ try {
27583
+ const cached = await getCache(cacheKey);
27584
+ if (cached) {
27585
+ import_nodejs_utils68.logger.log({
27586
+ level: "info",
27587
+ message: `Cache hit for getById building unit: ${cacheKey}`
27588
+ });
27589
+ return cached;
27590
+ }
27591
+ const result = await collection.findOne({
27592
+ building,
27593
+ status: "active"
27594
+ });
27595
+ setCache(cacheKey, result, 300).then(() => {
27596
+ import_nodejs_utils68.logger.log({
27597
+ level: "info",
27598
+ message: `Cache set for building unit by id: ${cacheKey}`
27599
+ });
27600
+ }).catch((err) => {
27601
+ import_nodejs_utils68.logger.log({
27602
+ level: "error",
27603
+ message: `Failed to set cache for building unit by id: ${err.message}`
27604
+ });
27605
+ });
27606
+ return result;
27607
+ } catch (error) {
27608
+ if (error instanceof import_nodejs_utils68.AppError) {
27609
+ throw error;
27610
+ } else {
27611
+ throw new import_nodejs_utils68.InternalServerError("Failed to get building unit.");
27612
+ }
27613
+ }
27614
+ }
27615
+ async function deleteById(_id, session) {
27616
+ try {
27617
+ _id = new import_mongodb41.ObjectId(_id);
27618
+ } catch (error) {
27619
+ throw new import_nodejs_utils68.BadRequestError("Invalid ID.");
27620
+ }
27621
+ try {
27622
+ const res = await collection.updateOne(
27623
+ { _id },
27624
+ { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
27625
+ { session }
27626
+ );
27627
+ delCachedData();
27628
+ return "Room/Facility deleted successfully.";
27629
+ } catch (error) {
27630
+ import_nodejs_utils68.logger.log({
27631
+ level: "error",
27632
+ message: error.message
27633
+ });
27634
+ if (error instanceof import_nodejs_utils68.AppError) {
27635
+ throw error;
27636
+ } else {
27637
+ throw new Error("Failed to deleted room/facility.");
27638
+ }
27639
+ }
27640
+ }
27444
27641
  return {
27445
- createIndex,
27642
+ createIndexes,
27446
27643
  add,
27447
27644
  getAll,
27448
- getById
27645
+ getById,
27646
+ getByBuildingLevel,
27647
+ updateById,
27648
+ getByBuilding,
27649
+ deleteById
27449
27650
  };
27450
27651
  }
27451
27652
 
27452
27653
  // src/controllers/building.controller.ts
27453
- var import_nodejs_utils69 = require("@eeplatform/nodejs-utils");
27654
+ var import_nodejs_utils70 = require("@eeplatform/nodejs-utils");
27454
27655
  var import_joi34 = __toESM(require("joi"));
27656
+
27657
+ // src/services/building.service.ts
27658
+ var import_nodejs_utils69 = require("@eeplatform/nodejs-utils");
27659
+ function useBuildingService() {
27660
+ const {
27661
+ updateById: _updateById,
27662
+ getById: _getById,
27663
+ deleteById: _deleteById
27664
+ } = useBuildingRepo();
27665
+ const { getByBuildingLevel, getByBuilding } = useBuildingUnitRepo();
27666
+ async function updateById(id, data) {
27667
+ data.levels = Number(data.levels);
27668
+ try {
27669
+ const building = await _getById(id);
27670
+ if (!building) {
27671
+ throw new import_nodejs_utils69.NotFoundError("Building not found.");
27672
+ }
27673
+ if (data.levels < building.levels) {
27674
+ const unit = await getByBuildingLevel(id, building.levels);
27675
+ if (unit) {
27676
+ throw new import_nodejs_utils69.BadRequestError(
27677
+ "Cannot reduce floors, there are existing building units at higher floors."
27678
+ );
27679
+ }
27680
+ }
27681
+ const result = await _updateById(id, data);
27682
+ return result;
27683
+ } catch (error) {
27684
+ throw error;
27685
+ }
27686
+ }
27687
+ async function deleteById(id) {
27688
+ const building = await getByBuilding(id);
27689
+ if (building) {
27690
+ throw new import_nodejs_utils69.BadRequestError(
27691
+ "Cannot delete building with existing room/facility. Please delete room/facility first."
27692
+ );
27693
+ }
27694
+ try {
27695
+ await _deleteById(id);
27696
+ return "Building deleted successfully.";
27697
+ } catch (error) {
27698
+ throw error;
27699
+ }
27700
+ }
27701
+ return {
27702
+ updateById,
27703
+ deleteById
27704
+ };
27705
+ }
27706
+
27707
+ // src/controllers/building.controller.ts
27455
27708
  function useBuildingController() {
27456
27709
  const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
27710
+ const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
27457
27711
  async function createBuilding(req, res, next) {
27458
27712
  const value = req.body;
27459
27713
  const validation = import_joi34.default.object({
@@ -27465,8 +27719,8 @@ function useBuildingController() {
27465
27719
  });
27466
27720
  const { error } = validation.validate(value);
27467
27721
  if (error) {
27468
- next(new import_nodejs_utils69.BadRequestError(error.message));
27469
- import_nodejs_utils69.logger.info(`Controller: ${error.message}`);
27722
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27723
+ import_nodejs_utils70.logger.info(`Controller: ${error.message}`);
27470
27724
  return;
27471
27725
  }
27472
27726
  try {
@@ -27477,6 +27731,31 @@ function useBuildingController() {
27477
27731
  next(error2);
27478
27732
  }
27479
27733
  }
27734
+ async function updateById(req, res, next) {
27735
+ const value = req.body;
27736
+ const id = req.params.id ?? "";
27737
+ const validation = import_joi34.default.object({
27738
+ id: import_joi34.default.string().hex().required(),
27739
+ value: import_joi34.default.object({
27740
+ name: import_joi34.default.string().required(),
27741
+ serial: import_joi34.default.string().optional().allow("", null),
27742
+ levels: import_joi34.default.number().integer().min(1).required()
27743
+ })
27744
+ });
27745
+ const { error } = validation.validate({ id, value });
27746
+ if (error) {
27747
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27748
+ import_nodejs_utils70.logger.info(`Controller: ${error.message}`);
27749
+ return;
27750
+ }
27751
+ try {
27752
+ const result = await _updateById(id, value);
27753
+ res.json(result);
27754
+ return;
27755
+ } catch (error2) {
27756
+ next(error2);
27757
+ }
27758
+ }
27480
27759
  async function getAll(req, res, next) {
27481
27760
  const query = req.query;
27482
27761
  const validation = import_joi34.default.object({
@@ -27488,7 +27767,7 @@ function useBuildingController() {
27488
27767
  });
27489
27768
  const { error } = validation.validate(query);
27490
27769
  if (error) {
27491
- next(new import_nodejs_utils69.BadRequestError(error.message));
27770
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27492
27771
  return;
27493
27772
  }
27494
27773
  const page = parseInt(req.query.page) ?? 1;
@@ -27527,7 +27806,7 @@ function useBuildingController() {
27527
27806
  });
27528
27807
  const { error } = validation.validate({ id });
27529
27808
  if (error) {
27530
- next(new import_nodejs_utils69.BadRequestError(error.message));
27809
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27531
27810
  return;
27532
27811
  }
27533
27812
  try {
@@ -27541,23 +27820,43 @@ function useBuildingController() {
27541
27820
  next(error2);
27542
27821
  }
27543
27822
  }
27823
+ async function deleteById(req, res, next) {
27824
+ const id = req.params.id;
27825
+ const validation = import_joi34.default.object({
27826
+ id: import_joi34.default.string().hex().required()
27827
+ });
27828
+ const { error } = validation.validate({ id });
27829
+ if (error) {
27830
+ next(new import_nodejs_utils70.BadRequestError(error.message));
27831
+ return;
27832
+ }
27833
+ try {
27834
+ const message = await _deleteById(id);
27835
+ res.json(message);
27836
+ return;
27837
+ } catch (error2) {
27838
+ next(error2);
27839
+ }
27840
+ }
27544
27841
  return {
27545
27842
  createBuilding,
27546
27843
  getAll,
27547
- getById
27844
+ getById,
27845
+ updateById,
27846
+ deleteById
27548
27847
  };
27549
27848
  }
27550
27849
 
27551
27850
  // src/controllers/building-unit.controller.ts
27552
- var import_nodejs_utils71 = require("@eeplatform/nodejs-utils");
27851
+ var import_nodejs_utils72 = require("@eeplatform/nodejs-utils");
27553
27852
  var import_joi35 = __toESM(require("joi"));
27554
27853
 
27555
27854
  // src/services/building-unit.service.ts
27556
- var import_nodejs_utils70 = require("@eeplatform/nodejs-utils");
27855
+ var import_nodejs_utils71 = require("@eeplatform/nodejs-utils");
27557
27856
  function useBuildingUnitService() {
27558
27857
  const { add: _add } = useBuildingUnitRepo();
27559
27858
  async function add(value) {
27560
- const session = import_nodejs_utils70.useAtlas.getClient()?.startSession();
27859
+ const session = import_nodejs_utils71.useAtlas.getClient()?.startSession();
27561
27860
  if (!session) {
27562
27861
  throw new Error("Unable to start session for building unit service.");
27563
27862
  }
@@ -27582,7 +27881,12 @@ function useBuildingUnitService() {
27582
27881
 
27583
27882
  // src/controllers/building-unit.controller.ts
27584
27883
  function useBuildingUnitController() {
27585
- const { getAll: _getAll, getById: _getById } = useBuildingUnitRepo();
27884
+ const {
27885
+ getAll: _getAll,
27886
+ getById: _getById,
27887
+ updateById: _updateById,
27888
+ deleteById: _deleteById
27889
+ } = useBuildingUnitRepo();
27586
27890
  const { add: _add } = useBuildingUnitService();
27587
27891
  async function add(req, res, next) {
27588
27892
  const data = req.body;
@@ -27606,7 +27910,7 @@ function useBuildingUnitController() {
27606
27910
  });
27607
27911
  const { error } = validation.validate(data);
27608
27912
  if (error) {
27609
- next(new import_nodejs_utils71.BadRequestError(error.message));
27913
+ next(new import_nodejs_utils72.BadRequestError(error.message));
27610
27914
  return;
27611
27915
  }
27612
27916
  try {
@@ -27619,6 +27923,28 @@ function useBuildingUnitController() {
27619
27923
  next(error2);
27620
27924
  }
27621
27925
  }
27926
+ async function updateById(req, res, next) {
27927
+ const data = req.body;
27928
+ const id = req.params.id ?? "";
27929
+ const validation = import_joi35.default.object({
27930
+ id: import_joi35.default.string().hex().required(),
27931
+ value: schemaUpdateOptions
27932
+ });
27933
+ const { error } = validation.validate({ id, value: data });
27934
+ if (error) {
27935
+ next(new import_nodejs_utils72.BadRequestError(error.message));
27936
+ return;
27937
+ }
27938
+ try {
27939
+ const buildingUnit = await _updateById(id, data);
27940
+ res.json({
27941
+ message: "Building unit updated successfully.",
27942
+ data: { buildingUnit }
27943
+ });
27944
+ } catch (error2) {
27945
+ next(error2);
27946
+ }
27947
+ }
27622
27948
  async function getAll(req, res, next) {
27623
27949
  const query = req.query;
27624
27950
  const validation = import_joi35.default.object({
@@ -27631,7 +27957,7 @@ function useBuildingUnitController() {
27631
27957
  });
27632
27958
  const { error } = validation.validate(query);
27633
27959
  if (error) {
27634
- next(new import_nodejs_utils71.BadRequestError(error.message));
27960
+ next(new import_nodejs_utils72.BadRequestError(error.message));
27635
27961
  return;
27636
27962
  }
27637
27963
  const page = parseInt(req.query.page) ?? 1;
@@ -27672,7 +27998,7 @@ function useBuildingUnitController() {
27672
27998
  });
27673
27999
  const { error } = validation.validate({ id });
27674
28000
  if (error) {
27675
- next(new import_nodejs_utils71.BadRequestError(error.message));
28001
+ next(new import_nodejs_utils72.BadRequestError(error.message));
27676
28002
  return;
27677
28003
  }
27678
28004
  try {
@@ -27686,10 +28012,30 @@ function useBuildingUnitController() {
27686
28012
  next(error2);
27687
28013
  }
27688
28014
  }
28015
+ async function deleteById(req, res, next) {
28016
+ const id = req.params.id;
28017
+ const validation = import_joi35.default.object({
28018
+ id: import_joi35.default.string().hex().required()
28019
+ });
28020
+ const { error } = validation.validate({ id });
28021
+ if (error) {
28022
+ next(new import_nodejs_utils72.BadRequestError(error.message));
28023
+ return;
28024
+ }
28025
+ try {
28026
+ const message = await _deleteById(id);
28027
+ res.json({ message });
28028
+ return;
28029
+ } catch (error2) {
28030
+ next(error2);
28031
+ }
28032
+ }
27689
28033
  return {
27690
28034
  add,
27691
28035
  getAll,
27692
- getById
28036
+ getById,
28037
+ updateById,
28038
+ deleteById
27693
28039
  };
27694
28040
  }
27695
28041
  // Annotate the CommonJS export names for ESM import in node:
@@ -27758,6 +28104,7 @@ function useBuildingUnitController() {
27758
28104
  schemaDivision,
27759
28105
  schemaRegion,
27760
28106
  schemaSchool,
28107
+ schemaUpdateOptions,
27761
28108
  useAddressController,
27762
28109
  useAddressRepo,
27763
28110
  useAuthController,