@goweekdays/core 2.6.1 → 2.8.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
@@ -491,25 +491,25 @@ function useAuthService() {
491
491
  }
492
492
 
493
493
  // src/resources/auth/auth.controller.ts
494
- import Joi30 from "joi";
494
+ import Joi36 from "joi";
495
495
  import {
496
- AppError as AppError17,
497
- BadRequestError as BadRequestError39,
498
- InternalServerError as InternalServerError21,
499
- logger as logger20
496
+ AppError as AppError19,
497
+ BadRequestError as BadRequestError43,
498
+ InternalServerError as InternalServerError23,
499
+ logger as logger22
500
500
  } from "@goweekdays/utils";
501
501
 
502
502
  // src/resources/verification/verification.service.ts
503
503
  import {
504
504
  useMailer,
505
505
  compileHandlebar,
506
- logger as logger19,
506
+ logger as logger21,
507
507
  getDirectory,
508
- BadRequestError as BadRequestError38,
508
+ BadRequestError as BadRequestError42,
509
509
  NotFoundError as NotFoundError3,
510
- InternalServerError as InternalServerError20,
511
- useAtlas as useAtlas18,
512
- AppError as AppError16
510
+ InternalServerError as InternalServerError22,
511
+ useAtlas as useAtlas19,
512
+ AppError as AppError18
513
513
  } from "@goweekdays/utils";
514
514
 
515
515
  // src/resources/verification/verification.model.ts
@@ -532,7 +532,11 @@ var schemaVerification = Joi2.object({
532
532
  roleName: Joi2.string().optional().allow("", null),
533
533
  referralCode: Joi2.string().optional().allow("", null),
534
534
  org: Joi2.string().hex().optional().allow("", null),
535
- orgName: Joi2.string().optional().allow("", null)
535
+ orgName: Joi2.string().optional().allow("", null),
536
+ contact: Joi2.string().optional().allow("", null),
537
+ seats: Joi2.number().optional().allow("", null),
538
+ createdBy: Joi2.string().optional().allow("", null),
539
+ amount: Joi2.number().optional().allow("", null)
536
540
  }).optional(),
537
541
  expireAt: Joi2.date().optional().allow("", null)
538
542
  });
@@ -914,15 +918,15 @@ var APP_ORG = process.env.APP_ORG || "http://localhost/organizations/create";
914
918
 
915
919
  // src/resources/user/user.service.ts
916
920
  import {
917
- AppError as AppError14,
918
- BadRequestError as BadRequestError36,
919
- InternalServerError as InternalServerError18,
921
+ AppError as AppError16,
922
+ BadRequestError as BadRequestError40,
923
+ InternalServerError as InternalServerError20,
920
924
  NotFoundError as NotFoundError2,
921
925
  hashPassword,
922
- logger as logger18,
923
- makeCacheKey as makeCacheKey13,
924
- useAtlas as useAtlas17,
925
- useCache as useCache14,
926
+ logger as logger20,
927
+ makeCacheKey as makeCacheKey14,
928
+ useAtlas as useAtlas18,
929
+ useCache as useCache15,
926
930
  useS3
927
931
  } from "@goweekdays/utils";
928
932
 
@@ -1538,9 +1542,6 @@ function useMemberRepo() {
1538
1542
  {
1539
1543
  $match: query
1540
1544
  },
1541
- {
1542
- $sort: { _id: -1 }
1543
- },
1544
1545
  {
1545
1546
  $limit: limit
1546
1547
  },
@@ -4379,6 +4380,7 @@ import {
4379
4380
  useCache as useCache10
4380
4381
  } from "@goweekdays/utils";
4381
4382
  import { ObjectId as ObjectId14 } from "mongodb";
4383
+ import Joi16 from "joi";
4382
4384
  function useOrgRepo() {
4383
4385
  const db = useAtlas11.getDb();
4384
4386
  if (!db) {
@@ -4554,10 +4556,9 @@ function useOrgRepo() {
4554
4556
  });
4555
4557
  return cached;
4556
4558
  }
4557
- const result = await collection.findOne({ name });
4558
- if (!result) {
4559
- throw new BadRequestError21("Organization not found.");
4560
- }
4559
+ const result = await collection.findOne({
4560
+ name: { $regex: name, $options: "i" }
4561
+ });
4561
4562
  setCache(cacheKey, result, 300).then(() => {
4562
4563
  logger14.log({
4563
4564
  level: "info",
@@ -4578,6 +4579,42 @@ function useOrgRepo() {
4578
4579
  }
4579
4580
  }
4580
4581
  }
4582
+ async function getByEmail(email) {
4583
+ const { error } = Joi16.string().email().required().validate(email);
4584
+ if (error) {
4585
+ throw new BadRequestError21(error.message);
4586
+ }
4587
+ const cacheKey = makeCacheKey9(namespace_collection, { email });
4588
+ try {
4589
+ const cached = await getCache(cacheKey);
4590
+ if (cached) {
4591
+ logger14.log({
4592
+ level: "info",
4593
+ message: `Cache hit for getByEmail organization: ${cacheKey}`
4594
+ });
4595
+ return cached;
4596
+ }
4597
+ const result = await collection.findOne({ email });
4598
+ setCache(cacheKey, result, 300).then(() => {
4599
+ logger14.log({
4600
+ level: "info",
4601
+ message: `Cache set for organization by email: ${cacheKey}`
4602
+ });
4603
+ }).catch((err) => {
4604
+ logger14.log({
4605
+ level: "error",
4606
+ message: `Failed to set cache for organization by email: ${err.message}`
4607
+ });
4608
+ });
4609
+ return result;
4610
+ } catch (error2) {
4611
+ if (error2 instanceof AppError8) {
4612
+ throw error2;
4613
+ } else {
4614
+ throw new InternalServerError11("Failed to get organization.");
4615
+ }
4616
+ }
4617
+ }
4581
4618
  async function updateFieldById({ _id, field, value } = {}, session) {
4582
4619
  const allowedFields = ["name", "description"];
4583
4620
  if (!allowedFields.includes(field)) {
@@ -4652,15 +4689,16 @@ function useOrgRepo() {
4652
4689
  updateFieldById,
4653
4690
  deleteById,
4654
4691
  getByName,
4692
+ getByEmail,
4655
4693
  updateById
4656
4694
  };
4657
4695
  }
4658
4696
 
4659
4697
  // src/resources/organization/organization.service.ts
4660
- import { BadRequestError as BadRequestError34, useAtlas as useAtlas16 } from "@goweekdays/utils";
4698
+ import { BadRequestError as BadRequestError38, useAtlas as useAtlas17 } from "@goweekdays/utils";
4661
4699
 
4662
4700
  // src/resources/member/member.controller.ts
4663
- import Joi18 from "joi";
4701
+ import Joi19 from "joi";
4664
4702
  import { BadRequestError as BadRequestError25 } from "@goweekdays/utils";
4665
4703
 
4666
4704
  // src/resources/member/member.service.ts
@@ -4700,7 +4738,7 @@ function useRoleService() {
4700
4738
  }
4701
4739
 
4702
4740
  // src/resources/role/role.controller.ts
4703
- import Joi16 from "joi";
4741
+ import Joi17 from "joi";
4704
4742
  import { BadRequestError as BadRequestError23 } from "@goweekdays/utils";
4705
4743
  function useRoleController() {
4706
4744
  const {
@@ -4733,12 +4771,12 @@ function useRoleController() {
4733
4771
  const limit = parseInt(req.query.limit ?? "10");
4734
4772
  const app = req.query.app ?? "";
4735
4773
  const org = req.query.org ?? "";
4736
- const validation = Joi16.object({
4737
- search: Joi16.string().optional().allow("", null),
4738
- page: Joi16.number().required(),
4739
- limit: Joi16.number().required(),
4740
- app: Joi16.string().optional().allow("", null),
4741
- org: Joi16.string().hex().optional().allow("", null)
4774
+ const validation = Joi17.object({
4775
+ search: Joi17.string().optional().allow("", null),
4776
+ page: Joi17.number().required(),
4777
+ limit: Joi17.number().required(),
4778
+ app: Joi17.string().optional().allow("", null),
4779
+ org: Joi17.string().hex().optional().allow("", null)
4742
4780
  });
4743
4781
  const { error } = validation.validate({ search, page, limit, app, org });
4744
4782
  if (error) {
@@ -4755,8 +4793,8 @@ function useRoleController() {
4755
4793
  }
4756
4794
  async function getRoleByUserId(req, res, next) {
4757
4795
  const userId = req.params.userId;
4758
- const validation = Joi16.object({
4759
- userId: Joi16.string().required()
4796
+ const validation = Joi17.object({
4797
+ userId: Joi17.string().required()
4760
4798
  });
4761
4799
  const { error } = validation.validate({ userId });
4762
4800
  if (error) {
@@ -4773,8 +4811,8 @@ function useRoleController() {
4773
4811
  }
4774
4812
  async function getRoleById(req, res, next) {
4775
4813
  const _id = req.params.id;
4776
- const validation = Joi16.object({
4777
- _id: Joi16.string().hex().required()
4814
+ const validation = Joi17.object({
4815
+ _id: Joi17.string().hex().required()
4778
4816
  });
4779
4817
  const { error } = validation.validate({ _id });
4780
4818
  if (error) {
@@ -4793,10 +4831,10 @@ function useRoleController() {
4793
4831
  const _id = req.params.id;
4794
4832
  const name = req.body.name ?? "";
4795
4833
  const permissions = req.body.permissions ?? [];
4796
- const validation = Joi16.object({
4797
- _id: Joi16.string().required(),
4798
- name: Joi16.string().required(),
4799
- permissions: Joi16.array().items(Joi16.string()).required()
4834
+ const validation = Joi17.object({
4835
+ _id: Joi17.string().required(),
4836
+ name: Joi17.string().required(),
4837
+ permissions: Joi17.array().items(Joi17.string()).required()
4800
4838
  });
4801
4839
  const { error } = validation.validate({ _id, name, permissions });
4802
4840
  if (error) {
@@ -4814,9 +4852,9 @@ function useRoleController() {
4814
4852
  async function updatePermissionsById(req, res, next) {
4815
4853
  const _id = req.params.id;
4816
4854
  const permissions = req.body.permissions ?? [];
4817
- const validation = Joi16.object({
4818
- _id: Joi16.string().required(),
4819
- permissions: Joi16.array().items(Joi16.string()).required()
4855
+ const validation = Joi17.object({
4856
+ _id: Joi17.string().required(),
4857
+ permissions: Joi17.array().items(Joi17.string()).required()
4820
4858
  });
4821
4859
  const { error } = validation.validate({ _id, permissions });
4822
4860
  if (error) {
@@ -4833,8 +4871,8 @@ function useRoleController() {
4833
4871
  }
4834
4872
  async function deleteRole(req, res, next) {
4835
4873
  const _id = req.params.id;
4836
- const validation = Joi16.object({
4837
- _id: Joi16.string().required()
4874
+ const validation = Joi17.object({
4875
+ _id: Joi17.string().required()
4838
4876
  });
4839
4877
  const { error } = validation.validate({ _id });
4840
4878
  if (error) {
@@ -4861,7 +4899,7 @@ function useRoleController() {
4861
4899
  }
4862
4900
 
4863
4901
  // src/resources/member/member.service.ts
4864
- import Joi17 from "joi";
4902
+ import Joi18 from "joi";
4865
4903
  function useMemberService() {
4866
4904
  const { getById: getRoleById } = useRoleRepo();
4867
4905
  const {
@@ -4914,7 +4952,7 @@ function useMemberService() {
4914
4952
  }
4915
4953
  }
4916
4954
  async function deleteById(id) {
4917
- const { error } = Joi17.string().hex().required().validate(id);
4955
+ const { error } = Joi18.string().hex().required().validate(id);
4918
4956
  if (error) {
4919
4957
  throw new BadRequestError24(error.message);
4920
4958
  }
@@ -4957,8 +4995,8 @@ function useMemberController() {
4957
4995
  } = useMemberService();
4958
4996
  async function getByUserId(req, res, next) {
4959
4997
  const userId = req.params.id;
4960
- const validation = Joi18.object({
4961
- id: Joi18.string().hex().required()
4998
+ const validation = Joi19.object({
4999
+ id: Joi19.string().hex().required()
4962
5000
  });
4963
5001
  const { error } = validation.validate({ id: userId });
4964
5002
  if (error) {
@@ -4977,10 +5015,10 @@ function useMemberController() {
4977
5015
  }
4978
5016
  }
4979
5017
  async function getByUserType(req, res, next) {
4980
- const validation = Joi18.object({
4981
- org: Joi18.string().hex().optional().allow("", null),
4982
- user: Joi18.string().hex().required(),
4983
- app: Joi18.string().required()
5018
+ const validation = Joi19.object({
5019
+ org: Joi19.string().hex().optional().allow("", null),
5020
+ user: Joi19.string().hex().required(),
5021
+ app: Joi19.string().required()
4984
5022
  });
4985
5023
  const { error } = validation.validate({ ...req.params, ...req.query });
4986
5024
  if (error) {
@@ -5002,10 +5040,10 @@ function useMemberController() {
5002
5040
  }
5003
5041
  }
5004
5042
  async function getByApp(req, res, next) {
5005
- const validation = Joi18.object({
5006
- org: Joi18.string().hex().optional().allow("", null),
5007
- user: Joi18.string().hex().required(),
5008
- app: Joi18.string().required()
5043
+ const validation = Joi19.object({
5044
+ org: Joi19.string().hex().optional().allow("", null),
5045
+ user: Joi19.string().hex().required(),
5046
+ app: Joi19.string().required()
5009
5047
  });
5010
5048
  const app = req.params.app ?? "";
5011
5049
  const org = req.query.org;
@@ -5034,14 +5072,14 @@ function useMemberController() {
5034
5072
  const org = req.query.org ?? "";
5035
5073
  const app = req.params.app ?? "";
5036
5074
  const status = req.query.status ?? "active";
5037
- const validation = Joi18.object({
5038
- limit: Joi18.number().min(10).max(50).required(),
5039
- search: Joi18.string().optional().allow("", null),
5040
- page: Joi18.number().required(),
5041
- user: Joi18.string().hex().optional().allow("", null),
5042
- org: Joi18.string().hex().optional().allow("", null),
5043
- app: Joi18.string().required(),
5044
- status: Joi18.string().required()
5075
+ const validation = Joi19.object({
5076
+ limit: Joi19.number().min(10).max(50).required(),
5077
+ search: Joi19.string().optional().allow("", null),
5078
+ page: Joi19.number().required(),
5079
+ user: Joi19.string().hex().optional().allow("", null),
5080
+ org: Joi19.string().hex().optional().allow("", null),
5081
+ app: Joi19.string().required(),
5082
+ status: Joi19.string().required()
5045
5083
  });
5046
5084
  const { error } = validation.validate({
5047
5085
  search,
@@ -5078,12 +5116,12 @@ function useMemberController() {
5078
5116
  const page = Number(req.query.page) ?? 1;
5079
5117
  const user = req.params.user ?? "";
5080
5118
  const app = req.params.app ?? "";
5081
- const validation = Joi18.object({
5082
- limit: Joi18.number().min(10).max(50).allow(null, ""),
5083
- search: Joi18.string().optional().allow("", null),
5084
- page: Joi18.number().optional().allow(null, ""),
5085
- app: Joi18.string().required(),
5086
- user: Joi18.string().hex().required()
5119
+ const validation = Joi19.object({
5120
+ limit: Joi19.number().min(10).max(200).allow(null, ""),
5121
+ search: Joi19.string().optional().allow("", null),
5122
+ page: Joi19.number().optional().allow(null, ""),
5123
+ app: Joi19.string().required(),
5124
+ user: Joi19.string().hex().required()
5087
5125
  });
5088
5126
  const { error } = validation.validate({
5089
5127
  search,
@@ -5115,11 +5153,11 @@ function useMemberController() {
5115
5153
  const search = req.query.search ?? "";
5116
5154
  const page = Number(req.query.page) ?? 1;
5117
5155
  const user = req.query.user ?? "";
5118
- const validation = Joi18.object({
5119
- limit: Joi18.number().min(10).max(50).required(),
5120
- search: Joi18.string().optional().allow("", null),
5121
- page: Joi18.number().required(),
5122
- user: Joi18.string().hex().optional().allow("", null)
5156
+ const validation = Joi19.object({
5157
+ limit: Joi19.number().min(10).max(50).required(),
5158
+ search: Joi19.string().optional().allow("", null),
5159
+ page: Joi19.number().required(),
5160
+ user: Joi19.string().hex().optional().allow("", null)
5123
5161
  });
5124
5162
  const { error } = validation.validate({
5125
5163
  search,
@@ -5144,9 +5182,9 @@ function useMemberController() {
5144
5182
  }
5145
5183
  }
5146
5184
  async function updateStatusByUserId(req, res, next) {
5147
- const validation = Joi18.object({
5148
- id: Joi18.string().hex().required(),
5149
- status: Joi18.string().valid("active", "suspended", "deleted").required()
5185
+ const validation = Joi19.object({
5186
+ id: Joi19.string().hex().required(),
5187
+ status: Joi19.string().valid("active", "suspended", "deleted").required()
5150
5188
  });
5151
5189
  const { error } = validation.validate(req.params);
5152
5190
  if (error) {
@@ -5195,7 +5233,7 @@ function useMemberController() {
5195
5233
  async function deleteById(req, res, next) {
5196
5234
  const payload = req.body;
5197
5235
  const _id = req.params.id ?? "";
5198
- const { error } = Joi18.string().hex().required().validate(_id);
5236
+ const { error } = Joi19.string().hex().required().validate(_id);
5199
5237
  if (error) {
5200
5238
  next(new BadRequestError25(error.message));
5201
5239
  return;
@@ -5223,30 +5261,30 @@ function useMemberController() {
5223
5261
 
5224
5262
  // src/resources/subscription/subscription.model.ts
5225
5263
  import { BadRequestError as BadRequestError26 } from "@goweekdays/utils";
5226
- import Joi19 from "joi";
5264
+ import Joi20 from "joi";
5227
5265
  import { ObjectId as ObjectId15 } from "mongodb";
5228
5266
  var schema2 = {
5229
- seats: Joi19.number().integer().min(1).required(),
5230
- paidSeats: Joi19.number().integer().min(0).required(),
5231
- amount: Joi19.number().positive().required(),
5232
- promoCode: Joi19.string().optional().allow("", null),
5233
- nextBillingDate: Joi19.date().optional().allow("", null)
5267
+ seats: Joi20.number().integer().min(1).required(),
5268
+ paidSeats: Joi20.number().integer().min(0).required(),
5269
+ amount: Joi20.number().positive().required(),
5270
+ promoCode: Joi20.string().optional().allow("", null),
5271
+ nextBillingDate: Joi20.date().optional().allow("", null)
5234
5272
  };
5235
- var schemaSubscription = Joi19.object({
5273
+ var schemaSubscription = Joi20.object({
5236
5274
  ...schema2,
5237
- org: Joi19.string().hex().length(24).required(),
5238
- currency: Joi19.string().length(3).required(),
5239
- billingCycle: Joi19.string().valid("monthly", "yearly").required()
5275
+ org: Joi20.string().hex().length(24).required(),
5276
+ currency: Joi20.string().length(3).required(),
5277
+ billingCycle: Joi20.string().valid("monthly", "yearly").required()
5240
5278
  });
5241
- var schemaSubscriptionUpdate = Joi19.object({
5279
+ var schemaSubscriptionUpdate = Joi20.object({
5242
5280
  ...schema2,
5243
- status: Joi19.string().optional().allow("", null)
5281
+ status: Joi20.string().optional().allow("", null)
5244
5282
  });
5245
- var schemaSubscriptionSeats = Joi19.object({
5246
- id: Joi19.string().hex().length(24).required(),
5247
- seats: Joi19.number().integer().min(1).required(),
5248
- amount: Joi19.number().positive().optional().allow(null, 0),
5249
- user: Joi19.string().hex().length(24).required()
5283
+ var schemaSubscriptionSeats = Joi20.object({
5284
+ id: Joi20.string().hex().length(24).required(),
5285
+ seats: Joi20.number().integer().min(1).required(),
5286
+ amount: Joi20.number().positive().optional().allow(null, 0),
5287
+ user: Joi20.string().hex().length(24).required()
5250
5288
  });
5251
5289
  function modelSubscription(data) {
5252
5290
  const { error } = schemaSubscription.validate(data);
@@ -5292,7 +5330,7 @@ import {
5292
5330
  useAtlas as useAtlas12,
5293
5331
  useCache as useCache11
5294
5332
  } from "@goweekdays/utils";
5295
- import Joi20 from "joi";
5333
+ import Joi21 from "joi";
5296
5334
  import { ObjectId as ObjectId16 } from "mongodb";
5297
5335
  function useSubscriptionRepo() {
5298
5336
  const db = useAtlas12.getDb();
@@ -5402,7 +5440,7 @@ function useSubscriptionRepo() {
5402
5440
  }
5403
5441
  }
5404
5442
  async function getByOrg(org) {
5405
- const { error } = Joi20.string().hex().length(24).required().validate(org);
5443
+ const { error } = Joi21.string().hex().length(24).required().validate(org);
5406
5444
  if (error) {
5407
5445
  throw new Error(`Invalid org ID: ${error.message}`);
5408
5446
  }
@@ -5441,7 +5479,7 @@ function useSubscriptionRepo() {
5441
5479
  }
5442
5480
  }
5443
5481
  async function getById(_id) {
5444
- const { error } = Joi20.string().hex().length(24).required().validate(_id);
5482
+ const { error } = Joi21.string().hex().length(24).required().validate(_id);
5445
5483
  if (error) {
5446
5484
  throw new Error(`Invalid subscription ID: ${error.message}`);
5447
5485
  }
@@ -5480,7 +5518,7 @@ function useSubscriptionRepo() {
5480
5518
  }
5481
5519
  }
5482
5520
  async function deleteById(_id) {
5483
- const { error } = Joi20.string().hex().length(24).required().validate(_id);
5521
+ const { error } = Joi21.string().hex().length(24).required().validate(_id);
5484
5522
  if (error) {
5485
5523
  throw new Error(`Invalid subscription ID: ${error.message}`);
5486
5524
  }
@@ -5507,7 +5545,7 @@ function useSubscriptionRepo() {
5507
5545
  }
5508
5546
  }
5509
5547
  async function updateById(_id, options, session) {
5510
- const { error: errorId } = Joi20.string().hex().length(24).required().validate(_id);
5548
+ const { error: errorId } = Joi21.string().hex().length(24).required().validate(_id);
5511
5549
  if (errorId) {
5512
5550
  throw new Error(`Invalid subscription ID: ${errorId.message}`);
5513
5551
  }
@@ -5552,7 +5590,7 @@ function useSubscriptionRepo() {
5552
5590
  }
5553
5591
 
5554
5592
  // src/resources/subscription/subscription.controller.ts
5555
- import Joi22 from "joi";
5593
+ import Joi23 from "joi";
5556
5594
  import { BadRequestError as BadRequestError30 } from "@goweekdays/utils";
5557
5595
 
5558
5596
  // src/resources/subscription/subscription.service.ts
@@ -5571,16 +5609,16 @@ import {
5571
5609
 
5572
5610
  // src/resources/subscription/subscription.transaction.model.ts
5573
5611
  import { BadRequestError as BadRequestError28 } from "@goweekdays/utils";
5574
- import Joi21 from "joi";
5612
+ import Joi22 from "joi";
5575
5613
  import { ObjectId as ObjectId17 } from "mongodb";
5576
- var schemaSubscriptionTransaction = Joi21.object({
5577
- subscription: Joi21.string().hex().length(24).required(),
5578
- amount: Joi21.number().positive().required(),
5579
- currency: Joi21.string().length(3).required(),
5580
- type: Joi21.string().valid("initiate", "add-seat", "remove-seat", "renewal").required(),
5581
- description: Joi21.string().max(255).optional().allow("", null),
5582
- createdBy: Joi21.string().hex().length(24).required(),
5583
- createdByName: Joi21.string().optional().allow("", null)
5614
+ var schemaSubscriptionTransaction = Joi22.object({
5615
+ subscription: Joi22.string().hex().length(24).required(),
5616
+ amount: Joi22.number().positive().required(),
5617
+ currency: Joi22.string().length(3).required(),
5618
+ type: Joi22.string().valid("initiate", "add-seat", "remove-seat", "renewal").required(),
5619
+ description: Joi22.string().max(255).optional().allow("", null),
5620
+ createdBy: Joi22.string().hex().length(24).required(),
5621
+ createdByName: Joi22.string().optional().allow("", null)
5584
5622
  });
5585
5623
  function modelSubscriptionTransaction(data) {
5586
5624
  const { error } = schemaSubscriptionTransaction.validate(data);
@@ -5836,10 +5874,10 @@ function useSubscriptionController() {
5836
5874
  } = useSubscriptionRepo();
5837
5875
  const { updateSeats: _updateSeats } = useSubscriptionService();
5838
5876
  async function getAll(req, res, next) {
5839
- const validation = Joi22.object({
5840
- page: Joi22.number().min(1).max(100).optional().allow(null, "").default(1),
5841
- limit: Joi22.number().min(1).max(100).optional().allow(null, "").default(10),
5842
- status: Joi22.string().valid("active", "suspended").optional().default("active")
5877
+ const validation = Joi23.object({
5878
+ page: Joi23.number().min(1).max(100).optional().allow(null, "").default(1),
5879
+ limit: Joi23.number().min(1).max(100).optional().allow(null, "").default(10),
5880
+ status: Joi23.string().valid("active", "suspended").optional().default("active")
5843
5881
  });
5844
5882
  const query = req.query;
5845
5883
  const { error, value } = validation.validate(query);
@@ -5857,8 +5895,8 @@ function useSubscriptionController() {
5857
5895
  }
5858
5896
  async function getById(req, res, next) {
5859
5897
  const id = req.params.id ?? "";
5860
- const validation = Joi22.object({
5861
- id: Joi22.string().hex().length(24).required()
5898
+ const validation = Joi23.object({
5899
+ id: Joi23.string().hex().length(24).required()
5862
5900
  });
5863
5901
  const { error, value } = validation.validate({ id });
5864
5902
  if (error) {
@@ -5875,8 +5913,8 @@ function useSubscriptionController() {
5875
5913
  }
5876
5914
  async function getByOrg(req, res, next) {
5877
5915
  const org = req.params.org ?? "";
5878
- const validation = Joi22.object({
5879
- org: Joi22.string().hex().length(24).required()
5916
+ const validation = Joi23.object({
5917
+ org: Joi23.string().hex().length(24).required()
5880
5918
  });
5881
5919
  const { error, value } = validation.validate({ org });
5882
5920
  if (error) {
@@ -5919,15 +5957,15 @@ function useSubscriptionController() {
5919
5957
  }
5920
5958
 
5921
5959
  // src/resources/subscription/subscription.transaction.controller.ts
5922
- import Joi23 from "joi";
5960
+ import Joi24 from "joi";
5923
5961
  import { BadRequestError as BadRequestError31 } from "@goweekdays/utils";
5924
5962
  function useSubscriptionTransactionController() {
5925
5963
  const { getAll: _getAll } = useSubscriptionTransactionRepo();
5926
5964
  async function getAll(req, res, next) {
5927
- const validation = Joi23.object({
5928
- id: Joi23.string().hex().length(24).required(),
5929
- page: Joi23.number().min(1).max(100).optional().allow(null, "").default(1),
5930
- limit: Joi23.number().min(1).max(100).optional().allow(null, "").default(10)
5965
+ const validation = Joi24.object({
5966
+ id: Joi24.string().hex().length(24).required(),
5967
+ page: Joi24.number().min(1).max(100).optional().allow(null, "").default(1),
5968
+ limit: Joi24.number().min(1).max(100).optional().allow(null, "").default(10)
5931
5969
  });
5932
5970
  const query = req.query;
5933
5971
  const id = req.params.id ?? "";
@@ -5950,16 +5988,16 @@ function useSubscriptionTransactionController() {
5950
5988
  }
5951
5989
 
5952
5990
  // src/resources/plan/plan.model.ts
5953
- import Joi24 from "joi";
5991
+ import Joi25 from "joi";
5954
5992
  var currencies = ["USD", "PHP"];
5955
- var schemaPlan = Joi24.object({
5956
- name: Joi24.string().min(3).max(100).required(),
5957
- description: Joi24.string().max(255).optional().allow("", null),
5958
- features: Joi24.array().items(Joi24.string().max(100)).optional(),
5959
- price: Joi24.number().positive().required(),
5960
- currency: Joi24.string().length(3).allow(...currencies).required(),
5961
- default: Joi24.boolean().optional().allow(null, ""),
5962
- billingCycle: Joi24.string().valid("monthly", "yearly").required()
5993
+ var schemaPlan = Joi25.object({
5994
+ name: Joi25.string().min(3).max(100).required(),
5995
+ description: Joi25.string().max(255).optional().allow("", null),
5996
+ features: Joi25.array().items(Joi25.string().max(100)).optional(),
5997
+ price: Joi25.number().positive().required(),
5998
+ currency: Joi25.string().length(3).allow(...currencies).required(),
5999
+ default: Joi25.boolean().optional().allow(null, ""),
6000
+ billingCycle: Joi25.string().valid("monthly", "yearly").required()
5963
6001
  });
5964
6002
  function modelPlan(data) {
5965
6003
  const { error } = schemaPlan.validate(data);
@@ -5992,7 +6030,7 @@ import {
5992
6030
  useAtlas as useAtlas15,
5993
6031
  useCache as useCache13
5994
6032
  } from "@goweekdays/utils";
5995
- import Joi25 from "joi";
6033
+ import Joi26 from "joi";
5996
6034
  import { ObjectId as ObjectId19 } from "mongodb";
5997
6035
  function usePlanRepo() {
5998
6036
  const db = useAtlas15.getDb();
@@ -6112,7 +6150,7 @@ function usePlanRepo() {
6112
6150
  }
6113
6151
  }
6114
6152
  async function getById(_id) {
6115
- const { error } = Joi25.string().hex().length(24).required().validate(_id);
6153
+ const { error } = Joi26.string().hex().length(24).required().validate(_id);
6116
6154
  if (error) {
6117
6155
  throw new Error(`Invalid plan ID: ${error.message}`);
6118
6156
  }
@@ -6181,7 +6219,7 @@ function usePlanRepo() {
6181
6219
  }
6182
6220
  }
6183
6221
  async function deleteById(_id) {
6184
- const { error } = Joi25.string().hex().length(24).required().validate(_id);
6222
+ const { error } = Joi26.string().hex().length(24).required().validate(_id);
6185
6223
  if (error) {
6186
6224
  throw new Error(`Invalid plan ID: ${error.message}`);
6187
6225
  }
@@ -6240,7 +6278,7 @@ function usePlanService() {
6240
6278
  }
6241
6279
 
6242
6280
  // src/resources/plan/plan.controller.ts
6243
- import Joi26 from "joi";
6281
+ import Joi27 from "joi";
6244
6282
  import { BadRequestError as BadRequestError33 } from "@goweekdays/utils";
6245
6283
  function usePlanController() {
6246
6284
  const {
@@ -6252,13 +6290,13 @@ function usePlanController() {
6252
6290
  } = usePlanRepo();
6253
6291
  async function add(req, res, next) {
6254
6292
  const value = req.body;
6255
- const validation = Joi26.object({
6256
- name: Joi26.string().min(3).max(100).required(),
6257
- description: Joi26.string().max(255).optional().allow("", null),
6258
- features: Joi26.array().items(Joi26.string().max(100)).optional(),
6259
- price: Joi26.number().positive().required(),
6260
- currency: Joi26.string().length(3).required(),
6261
- billingCycle: Joi26.string().valid("monthly", "yearly").required()
6293
+ const validation = Joi27.object({
6294
+ name: Joi27.string().min(3).max(100).required(),
6295
+ description: Joi27.string().max(255).optional().allow("", null),
6296
+ features: Joi27.array().items(Joi27.string().max(100)).optional(),
6297
+ price: Joi27.number().positive().required(),
6298
+ currency: Joi27.string().length(3).required(),
6299
+ billingCycle: Joi27.string().valid("monthly", "yearly").required()
6262
6300
  });
6263
6301
  const { error } = validation.validate(value);
6264
6302
  if (error) {
@@ -6278,11 +6316,11 @@ function usePlanController() {
6278
6316
  const search = req.query.search ?? "";
6279
6317
  const page = Number(req.query.page) ?? 1;
6280
6318
  const limit = Number(req.query.limit) ?? 10;
6281
- const validation = Joi26.object({
6282
- status: Joi26.string().required(),
6283
- search: Joi26.string().optional().allow("", null),
6284
- page: Joi26.number().required(),
6285
- limit: Joi26.number().required()
6319
+ const validation = Joi27.object({
6320
+ status: Joi27.string().required(),
6321
+ search: Joi27.string().optional().allow("", null),
6322
+ page: Joi27.number().required(),
6323
+ limit: Joi27.number().required()
6286
6324
  });
6287
6325
  const { error } = validation.validate({ status, search, page, limit });
6288
6326
  if (error) {
@@ -6299,7 +6337,7 @@ function usePlanController() {
6299
6337
  }
6300
6338
  async function getById(req, res, next) {
6301
6339
  const id = req.params.id;
6302
- const validation = Joi26.string().hex().length(24).required();
6340
+ const validation = Joi27.string().hex().length(24).required();
6303
6341
  const { error } = validation.validate(id);
6304
6342
  if (error) {
6305
6343
  next(new BadRequestError33(error.message));
@@ -6315,7 +6353,7 @@ function usePlanController() {
6315
6353
  }
6316
6354
  async function deleteById(req, res, next) {
6317
6355
  const id = req.params.id;
6318
- const validation = Joi26.string().hex().length(24).required();
6356
+ const validation = Joi27.string().hex().length(24).required();
6319
6357
  const { error } = validation.validate(id);
6320
6358
  if (error) {
6321
6359
  next(new BadRequestError33(error.message));
@@ -6357,6 +6395,7 @@ import {
6357
6395
  } from "@paypal/paypal-server-sdk";
6358
6396
  import crypto3 from "crypto";
6359
6397
  import crc32 from "buffer-crc32";
6398
+ import { logger as logger18 } from "@goweekdays/utils";
6360
6399
  var certCache = /* @__PURE__ */ new Map();
6361
6400
  function usePaypalService() {
6362
6401
  const paypalClient = new Client({
@@ -6420,11 +6459,14 @@ function usePaypalService() {
6420
6459
  const certUrl = headers["paypal-cert-url"];
6421
6460
  const transmissionSig = headers["paypal-transmission-sig"];
6422
6461
  if (!transmissionId || !timeStamp || !certUrl || !transmissionSig) {
6462
+ logger18.log({
6463
+ level: "error",
6464
+ message: "Missing required PayPal webhook headers"
6465
+ });
6423
6466
  return false;
6424
6467
  }
6425
- const eventBuffer = Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(rawBody);
6426
- const crcValue = parseInt("0x" + crc32(eventBuffer).toString("hex"));
6427
- const message = `${transmissionId}|${timeStamp}|${webhookId}|${crcValue}`;
6468
+ const crc = parseInt("0x" + crc32(rawBody).toString("hex"));
6469
+ const message = `${transmissionId}|${timeStamp}|${webhookId}|${crc}`;
6428
6470
  try {
6429
6471
  const certPem = await downloadAndCacheCert(certUrl);
6430
6472
  const signatureBuffer = Buffer.from(transmissionSig, "base64");
@@ -6432,7 +6474,10 @@ function usePaypalService() {
6432
6474
  verifier.update(message);
6433
6475
  return verifier.verify(certPem, signatureBuffer);
6434
6476
  } catch (error) {
6435
- console.error("PayPal webhook verification error:", error);
6477
+ logger18.log({
6478
+ level: "error",
6479
+ message: `PayPal webhook verification error: ${error}`
6480
+ });
6436
6481
  throw new Error("Failed to verify PayPal webhook signature.");
6437
6482
  }
6438
6483
  }
@@ -6444,330 +6489,1077 @@ function usePaypalService() {
6444
6489
  }
6445
6490
 
6446
6491
  // src/resources/organization/organization.service.ts
6447
- function useOrgService() {
6448
- const { add: addOrg } = useOrgRepo();
6449
- const { addRole } = useRoleRepo();
6450
- const { getAll: getAllPermission } = usePermissionRepo();
6451
- const { add: addMember, updateRoleById: _updateRoleById } = useMemberRepo();
6452
- const { getUserById } = useUserRepo();
6453
- const { getDefault } = usePlanRepo();
6454
- const { add: addSubscription } = useSubscriptionRepo();
6455
- const { add: addSubscriptionTransaction } = useSubscriptionTransactionRepo();
6456
- const { addOrder: addPaypalOrder } = usePaypalService();
6457
- async function add(value) {
6458
- const { error } = schemaOrgAdd.validate(value);
6492
+ import Joi32 from "joi";
6493
+
6494
+ // src/resources/verification/verification.controller.ts
6495
+ import {
6496
+ AppError as AppError14,
6497
+ BadRequestError as BadRequestError34,
6498
+ InternalServerError as InternalServerError18
6499
+ } from "@goweekdays/utils";
6500
+ import Joi28 from "joi";
6501
+ function useVerificationController() {
6502
+ const {
6503
+ createUserInvite: _createUserInvite,
6504
+ createForgetPassword: _createForgetPassword,
6505
+ cancelUserInvitation: _cancelUserInvitation,
6506
+ verify: _verify,
6507
+ inviteMember: _inviteMember,
6508
+ signUp: _signUp,
6509
+ cancelInviteMember: _cancelInviteMember,
6510
+ forgetPassword: _forgetPassword,
6511
+ orgSetupFee: _orgSetupFee
6512
+ } = useVerificationService();
6513
+ const { getVerifications: _getVerifications } = useVerificationRepo();
6514
+ async function createUserInvite(req, res, next) {
6515
+ const validation = Joi28.object({
6516
+ email: Joi28.string().email().required(),
6517
+ app: Joi28.string().required(),
6518
+ role: Joi28.string().hex().required(),
6519
+ roleName: Joi28.string().required(),
6520
+ org: Joi28.string().hex().optional().optional().allow("", null),
6521
+ orgName: Joi28.string().optional().optional().allow("", null)
6522
+ });
6523
+ const { error } = validation.validate(req.body);
6459
6524
  if (error) {
6460
- throw new BadRequestError34(error.message);
6461
- }
6462
- const session = useAtlas16.getClient()?.startSession();
6463
- if (!session) {
6464
- throw new BadRequestError34("Unable to start database session.");
6525
+ next(new BadRequestError34(error.message));
6526
+ return;
6465
6527
  }
6528
+ const email = req.body.email ?? "";
6529
+ const app = req.body.app ?? "";
6530
+ const role = req.body.role ?? "";
6531
+ const roleName = req.body.roleName ?? "";
6532
+ const org = req.body.org ?? "";
6533
+ const orgName = req.body.orgName ?? "";
6466
6534
  try {
6467
- session?.startTransaction();
6468
- const org = await addOrg(
6469
- {
6470
- email: value.email,
6471
- name: value.name,
6472
- contact: value.contact,
6473
- createdBy: value.createdBy
6474
- },
6475
- session
6476
- );
6477
- const plan = await getDefault();
6478
- if (!plan) {
6479
- throw new BadRequestError34(
6480
- "Failed to create organization, plan not found."
6481
- );
6482
- }
6483
- const currentDate = /* @__PURE__ */ new Date();
6484
- const nextBillingDate = new Date(currentDate);
6485
- nextBillingDate.setMonth(currentDate.getMonth() + 1);
6486
- const amount = plan.price * value.seats;
6487
- const subscriptionId = await addSubscription(
6488
- {
6489
- amount,
6490
- org: String(org),
6491
- seats: value.seats,
6492
- paidSeats: value.seats,
6493
- currency: plan.currency,
6494
- billingCycle: plan.billingCycle,
6495
- nextBillingDate
6496
- },
6497
- session
6498
- );
6499
- const createdBy = String(value.createdBy);
6500
- const user = await getUserById(createdBy);
6501
- if (!user) {
6502
- throw new BadRequestError34("User is required to create org member.");
6503
- }
6504
- await addSubscriptionTransaction(
6505
- {
6506
- subscription: subscriptionId,
6507
- type: "initiate",
6508
- amount,
6509
- currency: plan.currency,
6510
- description: "Initial subscription transaction",
6511
- createdBy: value.createdBy,
6512
- createdByName: `${user.firstName} ${user.lastName}`
6513
- },
6514
- session
6515
- );
6516
- const allPermissions = await getAllPermission({
6517
- app: "org",
6518
- limit: 100
6519
- });
6520
- let permissions = [];
6521
- if (allPermissions && allPermissions.items && allPermissions.items.length) {
6522
- permissions = allPermissions.items.map((perm) => perm.key);
6523
- }
6524
- if (permissions.length === 0) {
6525
- throw new Error("No permissions found for the organization type.");
6526
- }
6527
- const roleData = {
6528
- org: String(org),
6529
- name: "Owner",
6530
- description: "Owner of the organization",
6531
- permissions,
6532
- createdBy,
6533
- app: "org"
6534
- };
6535
- const role = await addRole(roleData, session);
6536
- if (!role) {
6537
- throw new BadRequestError34("Role is required to create org member.");
6538
- }
6539
- await addMember(
6540
- {
6541
- role: String(role),
6542
- roleName: roleData.name,
6543
- org: String(org),
6544
- orgName: value.name,
6545
- name: `${user.firstName} ${user.lastName}`,
6546
- user: createdBy,
6547
- app: "org"
6548
- },
6549
- session
6550
- );
6551
- const order = await addPaypalOrder({
6552
- amount,
6553
- currency: plan.currency,
6554
- customId: subscriptionId,
6555
- returnUrl: `${APP_ORG}/organizations/success`,
6556
- cancelUrl: `${APP_ORG}/organizations/cancel`,
6557
- action: "pay"
6535
+ await _createUserInvite({
6536
+ email,
6537
+ metadata: {
6538
+ app,
6539
+ role,
6540
+ roleName,
6541
+ org,
6542
+ orgName
6543
+ }
6558
6544
  });
6559
- await session?.commitTransaction();
6560
- const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
6561
- (link) => link.rel === "approve"
6562
- );
6563
- return {
6564
- org: String(org),
6565
- paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
6566
- };
6545
+ res.json({ message: "Successfully invited user." });
6546
+ return;
6567
6547
  } catch (error2) {
6568
- await session?.abortTransaction();
6569
- throw error2;
6570
- } finally {
6571
- await session?.endSession();
6548
+ next(error2);
6572
6549
  }
6573
6550
  }
6574
- return {
6575
- add
6576
- };
6577
- }
6578
-
6579
- // src/resources/organization/organization.controller.ts
6580
- import { BadRequestError as BadRequestError35 } from "@goweekdays/utils";
6581
- import Joi27 from "joi";
6582
- function useOrgController() {
6583
- const { add: _add } = useOrgService();
6584
- const { getOrgsByMembership } = useMemberRepo();
6585
- const {
6586
- getByName: _getByName,
6587
- getAll: getAllOrg,
6588
- getById: _getById,
6589
- updateById: _updateById
6590
- } = useOrgRepo();
6591
- async function add(req, res, next) {
6592
- const value = req.body;
6593
- const { error } = schemaOrgAdd.validate(value);
6551
+ async function createForgetPassword(req, res, next) {
6552
+ const email = req.body.email || "";
6553
+ const validation = Joi28.string().email().required();
6554
+ const { error } = validation.validate(email);
6594
6555
  if (error) {
6595
- next(new BadRequestError35(error.message));
6556
+ next(new BadRequestError34(error.message));
6596
6557
  return;
6597
6558
  }
6598
6559
  try {
6599
- const data = await _add(value);
6560
+ await _createForgetPassword(email);
6600
6561
  res.json({
6601
- message: "Organization created successfully.",
6602
- data
6562
+ message: "Check your email to verify it before resetting your password."
6603
6563
  });
6604
6564
  return;
6605
6565
  } catch (error2) {
6606
- next(error2);
6566
+ if (error2 instanceof AppError14) {
6567
+ next(error2);
6568
+ } else {
6569
+ next(new InternalServerError18("An unexpected error occurred"));
6570
+ }
6607
6571
  }
6608
6572
  }
6609
- async function getOrgsByUserId(req, res, next) {
6610
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
6611
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
6612
- const search = req.query.search ?? "";
6613
- const user = req.params.user ?? "";
6614
- const isPageNumber = isFinite(page);
6615
- if (!isPageNumber) {
6616
- next(new BadRequestError35("Invalid page number."));
6573
+ async function getVerifications(req, res, next) {
6574
+ const validation = Joi28.object({
6575
+ status: Joi28.string().required(),
6576
+ search: Joi28.string().optional().allow("", null),
6577
+ page: Joi28.number().required(),
6578
+ type: Joi28.string().optional().allow("", null),
6579
+ email: Joi28.string().optional().allow("", null),
6580
+ app: Joi28.string().optional().allow("", null),
6581
+ org: Joi28.string().optional().allow("", null)
6582
+ });
6583
+ const { error } = validation.validate(req.query);
6584
+ if (error) {
6585
+ next(new BadRequestError34(error.message));
6617
6586
  return;
6618
6587
  }
6619
- const isLimitNumber = isFinite(limit);
6620
- if (!isLimitNumber) {
6621
- next(new BadRequestError35("Invalid limit number."));
6588
+ const status = req.query.status ?? "";
6589
+ const search = req.query.search ?? "";
6590
+ const page = Number(req.query.page) ?? 1;
6591
+ let type = req.query.type ?? "";
6592
+ const email = req.query.email ?? "";
6593
+ const app = req.query.app ?? "";
6594
+ const org = req.query.org ?? "";
6595
+ const hasMultipleTypes = type.includes(",");
6596
+ let splitType = [];
6597
+ if (hasMultipleTypes) {
6598
+ splitType = type.split(",");
6599
+ }
6600
+ try {
6601
+ const items = await _getVerifications({
6602
+ status,
6603
+ search,
6604
+ page,
6605
+ type: hasMultipleTypes ? splitType : type,
6606
+ email,
6607
+ app,
6608
+ org
6609
+ });
6610
+ res.json(items);
6622
6611
  return;
6612
+ } catch (error2) {
6613
+ next(error2);
6623
6614
  }
6624
- const validation = Joi27.object({
6625
- user: Joi27.string().hex().required(),
6626
- page: Joi27.number().min(1).optional().allow("", null),
6627
- limit: Joi27.number().min(1).optional().allow("", null),
6628
- search: Joi27.string().optional().allow("", null)
6629
- });
6630
- const { error } = validation.validate({ user, page, limit, search });
6615
+ }
6616
+ async function verify(req, res, next) {
6617
+ const id = req.params.id || "";
6618
+ const validation = Joi28.string().hex().required();
6619
+ const { error } = validation.validate(id);
6631
6620
  if (error) {
6632
- next(new BadRequestError35(error.message));
6621
+ next(new BadRequestError34(error.message));
6633
6622
  return;
6634
6623
  }
6635
6624
  try {
6636
- const orgs = await getOrgsByMembership({ user, page, limit, search });
6637
- res.json(orgs);
6625
+ const message = await _verify(id);
6626
+ res.json(message);
6638
6627
  return;
6639
6628
  } catch (error2) {
6640
6629
  next(error2);
6641
6630
  }
6642
6631
  }
6643
- async function getAll(req, res, next) {
6644
- const query = req.query;
6645
- const validation = Joi27.object({
6646
- page: Joi27.number().min(1).optional().allow("", null),
6647
- limit: Joi27.number().min(1).optional().allow("", null),
6648
- search: Joi27.string().optional().allow("", null),
6649
- status: Joi27.string().valid("active", "suspended", "inactive", "deleted").optional()
6650
- });
6651
- const { error } = validation.validate(query);
6652
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
6653
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
6654
- const search = req.query.search ?? "";
6655
- const status = req.query.status ?? "active";
6656
- const isPageNumber = isFinite(page);
6657
- if (!isPageNumber) {
6658
- next(new BadRequestError35("Invalid page number."));
6632
+ async function cancelUserInvitation(req, res, next) {
6633
+ const otpId = req.params.id || "";
6634
+ const validation = Joi28.string().hex().required();
6635
+ const { error } = validation.validate(otpId);
6636
+ if (error) {
6637
+ next(new BadRequestError34(error.message));
6659
6638
  return;
6660
6639
  }
6661
- const isLimitNumber = isFinite(limit);
6662
- if (!isLimitNumber) {
6663
- next(new BadRequestError35("Invalid limit number."));
6664
- return;
6640
+ try {
6641
+ await _cancelUserInvitation(otpId);
6642
+ return res.json({
6643
+ message: "User invite has been cancelled."
6644
+ });
6645
+ } catch (error2) {
6646
+ throw error2;
6665
6647
  }
6648
+ }
6649
+ async function signUp(req, res, next) {
6650
+ const validation = Joi28.string().email().required();
6651
+ const { error } = validation.validate(req.body.email);
6666
6652
  if (error) {
6667
- next(new BadRequestError35(error.message));
6653
+ next(new BadRequestError34(error.message));
6668
6654
  return;
6669
6655
  }
6656
+ const email = req.body.email ?? "";
6670
6657
  try {
6671
- const orgs = await getAllOrg({ page, limit, search, status });
6672
- res.json(orgs);
6658
+ await _signUp({ email });
6659
+ res.json({ message: "Successfully signed up user." });
6673
6660
  return;
6674
6661
  } catch (error2) {
6675
6662
  next(error2);
6676
6663
  }
6677
6664
  }
6678
- async function getByName(req, res, next) {
6679
- const name = req.params.name;
6680
- const validation = Joi27.object({
6681
- name: Joi27.string().required()
6682
- });
6683
- const { error } = validation.validate({ name });
6665
+ async function inviteMember(req, res, next) {
6666
+ const { error } = schemaInviteMember.validate(req.body);
6684
6667
  if (error) {
6685
- next(new BadRequestError35(error.message));
6668
+ next(new BadRequestError34(error.message));
6686
6669
  return;
6687
6670
  }
6688
6671
  try {
6689
- const org = await _getByName(name);
6690
- res.json(org);
6672
+ await _inviteMember(req.body);
6673
+ res.json({ message: "Successfully invited member." });
6691
6674
  return;
6692
6675
  } catch (error2) {
6693
6676
  next(error2);
6694
6677
  }
6695
6678
  }
6696
- async function getById(req, res, next) {
6697
- const id = req.params.id;
6698
- const validation = Joi27.object({
6699
- id: Joi27.string().hex().required()
6700
- });
6701
- const { error } = validation.validate({ id });
6679
+ async function cancelInviteMember(req, res, next) {
6680
+ const id = req.params.id || "";
6681
+ const validation = Joi28.string().hex().required();
6682
+ const { error } = validation.validate(id);
6702
6683
  if (error) {
6703
- next(new BadRequestError35(error.message));
6684
+ next(new BadRequestError34(error.message));
6704
6685
  return;
6705
6686
  }
6706
6687
  try {
6707
- const org = await _getById(id);
6708
- res.json(org);
6688
+ const message = await _cancelInviteMember(id);
6689
+ res.json({ message });
6709
6690
  return;
6710
6691
  } catch (error2) {
6711
6692
  next(error2);
6712
6693
  }
6713
6694
  }
6714
- async function updateById(req, res, next) {
6715
- const _id = req.params.id ?? "";
6716
- const payload = req.body;
6717
- const { error } = schemaOrgUpdate.validate({ _id, ...payload });
6695
+ async function forgetPassword(req, res, next) {
6696
+ const email = req.body.email ?? "";
6697
+ const validation = Joi28.string().email().required();
6698
+ const { error } = validation.validate(email);
6718
6699
  if (error) {
6719
- next(new BadRequestError35(error.message));
6700
+ next(new BadRequestError34(error.message));
6720
6701
  return;
6721
6702
  }
6722
6703
  try {
6723
- const message = await _updateById(_id, payload);
6724
- res.json({ message });
6704
+ const message = await _forgetPassword(email);
6705
+ res.json({
6706
+ message
6707
+ });
6708
+ return;
6709
+ } catch (error2) {
6710
+ if (error2 instanceof AppError14) {
6711
+ next(error2);
6712
+ } else {
6713
+ next(new InternalServerError18("An unexpected error occurred"));
6714
+ }
6715
+ }
6716
+ }
6717
+ async function orgSetupFee(req, res, next) {
6718
+ const value = req.body;
6719
+ const { error } = schemaOrgAdd.validate(value);
6720
+ if (error) {
6721
+ next(new BadRequestError34(error.message));
6722
+ return;
6723
+ }
6724
+ try {
6725
+ const data = await _orgSetupFee(value);
6726
+ res.json(data);
6725
6727
  return;
6726
6728
  } catch (error2) {
6727
6729
  next(error2);
6728
6730
  }
6729
6731
  }
6730
6732
  return {
6731
- add,
6732
- getOrgsByUserId,
6733
- getByName,
6734
- getAll,
6735
- getById,
6736
- updateById
6733
+ getVerifications,
6734
+ createUserInvite,
6735
+ createForgetPassword,
6736
+ verify,
6737
+ cancelUserInvitation,
6738
+ inviteMember,
6739
+ signUp,
6740
+ cancelInviteMember,
6741
+ forgetPassword,
6742
+ orgSetupFee
6737
6743
  };
6738
6744
  }
6739
6745
 
6740
- // src/resources/user/user.service.ts
6741
- function useUserService() {
6742
- const {
6743
- add: addUser,
6744
- getUserByEmail,
6745
- getUserById: _getById,
6746
- updateName: _updateName,
6747
- updateBirthday: _updateBirthday,
6748
- updateUserFieldById: _updateUserFieldById
6749
- } = useUserRepo();
6750
- const { addRole, getById: getRoleById } = useRoleRepo();
6751
- const { add: addMember } = useMemberRepo();
6752
- const { getAll: getAllPermission } = usePermissionRepo();
6753
- const { getById: getOrgById } = useOrgRepo();
6754
- async function createDefaultUser() {
6755
- const session = useAtlas17.getClient()?.startSession();
6746
+ // src/resources/ledger/ledger.billing.model.ts
6747
+ import { BadRequestError as BadRequestError35 } from "@goweekdays/utils";
6748
+ import Joi29 from "joi";
6749
+ import { ObjectId as ObjectId20 } from "mongodb";
6750
+ var ledgerBillTypes = ["setup-fee", "subscription"];
6751
+ var ledgerBillStatuses = ["pending", "paid", "overdue"];
6752
+ var schemaLedgerBill = Joi29.object({
6753
+ org: Joi29.string().hex().length(24).required(),
6754
+ type: Joi29.string().valid(...ledgerBillTypes).required(),
6755
+ description: Joi29.string().max(255).required(),
6756
+ amount: Joi29.number().positive().required(),
6757
+ currency: Joi29.string().length(3).required(),
6758
+ status: Joi29.string().valid(...ledgerBillStatuses).required(),
6759
+ billingFrom: Joi29.date().optional().allow("", null),
6760
+ billingTo: Joi29.date().optional().allow("", null),
6761
+ paidAt: Joi29.date().optional().allow("", null),
6762
+ dueDate: Joi29.date().optional().allow("", null)
6763
+ });
6764
+ var schemaLedgerBillingSummary = Joi29.object({
6765
+ status: Joi29.string().valid(...ledgerBillStatuses).required(),
6766
+ org: Joi29.string().hex().length(24).required()
6767
+ });
6768
+ function modelLedgerBill(value) {
6769
+ const { error } = schemaLedgerBill.validate(value);
6770
+ if (error) {
6771
+ throw new Error(`Ledger bill model validation error: ${error.message}`);
6772
+ }
6773
+ try {
6774
+ value.org = new ObjectId20(value.org);
6775
+ } catch (error2) {
6776
+ throw new BadRequestError35("Invalid org ID.");
6777
+ }
6778
+ return {
6779
+ _id: value._id,
6780
+ org: value.org,
6781
+ type: value.type,
6782
+ description: value.description,
6783
+ amount: value.amount,
6784
+ currency: value.currency,
6785
+ status: value.status,
6786
+ billingFrom: value.billingFrom ?? "",
6787
+ billingTo: value.billingTo ?? "",
6788
+ paidAt: value.paidAt ?? "",
6789
+ dueDate: value.dueDate ?? "",
6790
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date()
6791
+ };
6792
+ }
6793
+
6794
+ // src/resources/ledger/ledger.billing.repository.ts
6795
+ import {
6796
+ AppError as AppError15,
6797
+ BadRequestError as BadRequestError36,
6798
+ InternalServerError as InternalServerError19,
6799
+ logger as logger19,
6800
+ makeCacheKey as makeCacheKey13,
6801
+ paginate as paginate12,
6802
+ useAtlas as useAtlas16,
6803
+ useCache as useCache14
6804
+ } from "@goweekdays/utils";
6805
+ import { ObjectId as ObjectId21 } from "mongodb";
6806
+ import Joi30 from "joi";
6807
+ function useLedgerBillingRepo() {
6808
+ const db = useAtlas16.getDb();
6809
+ if (!db) {
6810
+ throw new Error("Unable to connect to server.");
6811
+ }
6812
+ const namespace_collection = "ledger.billings";
6813
+ const collection = db.collection(namespace_collection);
6814
+ const { getCache, setCache, delNamespace } = useCache14(namespace_collection);
6815
+ function delCachedData() {
6816
+ delNamespace().then(() => {
6817
+ logger19.log({
6818
+ level: "info",
6819
+ message: `Cache namespace cleared for ${namespace_collection}`
6820
+ });
6821
+ }).catch((err) => {
6822
+ logger19.log({
6823
+ level: "error",
6824
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
6825
+ });
6826
+ });
6827
+ }
6828
+ async function createIndexes() {
6756
6829
  try {
6757
- session?.startTransaction();
6758
- const _user = await getUserByEmail(DEFAULT_USER_EMAIL);
6759
- if (_user) {
6760
- throw new BadRequestError36(
6761
- `User already exists: ${DEFAULT_USER_EMAIL}.`
6762
- );
6830
+ await collection.createIndexes([
6831
+ { key: { org: 1 } },
6832
+ { key: { status: 1 } },
6833
+ { key: { description: "text" }, name: "text_index" }
6834
+ ]);
6835
+ return "Successfully created ledger billing indexes.";
6836
+ } catch (error) {
6837
+ throw new BadRequestError36("Failed to create ledger billing indexes.");
6838
+ }
6839
+ }
6840
+ async function add(value, session) {
6841
+ try {
6842
+ value = modelLedgerBill(value);
6843
+ const result = await collection.insertOne(value, { session });
6844
+ delCachedData();
6845
+ return result.insertedId;
6846
+ } catch (error) {
6847
+ if (error instanceof AppError15) {
6848
+ throw error;
6763
6849
  }
6764
- const hashedPassword = await hashPassword(DEFAULT_USER_PASSWORD);
6765
- const userId = await addUser(
6766
- {
6767
- email: DEFAULT_USER_EMAIL,
6768
- password: hashedPassword,
6769
- firstName: DEFAULT_USER_FIRST_NAME,
6770
- lastName: DEFAULT_USER_LAST_NAME
6850
+ throw new BadRequestError36(
6851
+ `Failed to add ledger billing: ${error.message}`
6852
+ );
6853
+ }
6854
+ }
6855
+ async function getAll({
6856
+ org = "",
6857
+ search = "",
6858
+ page = 1,
6859
+ limit = 10,
6860
+ status = ""
6861
+ } = {}) {
6862
+ page = page > 0 ? page - 1 : 0;
6863
+ const query = { status: { $ne: "deleted" } };
6864
+ const cacheKeyOptions = {
6865
+ search,
6866
+ page,
6867
+ limit,
6868
+ tag: "getAll"
6869
+ };
6870
+ try {
6871
+ query.org = new ObjectId21(org);
6872
+ cacheKeyOptions.org = org;
6873
+ } catch (error) {
6874
+ throw new BadRequestError36("Invalid organization ID.");
6875
+ }
6876
+ if (status) {
6877
+ query.status = status;
6878
+ cacheKeyOptions.status = status;
6879
+ }
6880
+ if (search) {
6881
+ query.$text = { $search: search };
6882
+ }
6883
+ const cacheKey = makeCacheKey13(namespace_collection, cacheKeyOptions);
6884
+ logger19.log({
6885
+ level: "info",
6886
+ message: `Cache key for getAll ledger billings: ${cacheKey}`
6887
+ });
6888
+ try {
6889
+ const cached = await getCache(cacheKey);
6890
+ if (cached) {
6891
+ logger19.log({
6892
+ level: "info",
6893
+ message: `Cache hit for getAll ledger billings: ${cacheKey}`
6894
+ });
6895
+ return cached;
6896
+ }
6897
+ const items = await collection.aggregate([
6898
+ { $match: query },
6899
+ { $skip: page * limit },
6900
+ { $limit: limit }
6901
+ ]).toArray();
6902
+ const length = await collection.countDocuments(query);
6903
+ const data = paginate12(items, page, limit, length);
6904
+ setCache(cacheKey, data, 600).then(() => {
6905
+ logger19.log({
6906
+ level: "info",
6907
+ message: `Cache set for getAll ledger billings: ${cacheKey}`
6908
+ });
6909
+ }).catch((err) => {
6910
+ logger19.log({
6911
+ level: "error",
6912
+ message: `Failed to set cache for getAll ledger billings: ${err.message}`
6913
+ });
6914
+ });
6915
+ return data;
6916
+ } catch (error) {
6917
+ logger19.log({ level: "error", message: `${error}` });
6918
+ throw error;
6919
+ }
6920
+ }
6921
+ async function getById(_id) {
6922
+ const { error } = Joi30.string().hex().length(24).required().validate(_id);
6923
+ if (error) {
6924
+ throw new Error(`Invalid ledger billing ID: ${error.message}`);
6925
+ }
6926
+ try {
6927
+ _id = new ObjectId21(_id);
6928
+ } catch (error2) {
6929
+ throw new BadRequestError36("Invalid ledger billing ID.");
6930
+ }
6931
+ try {
6932
+ const cacheKey = makeCacheKey13(namespace_collection, {
6933
+ _id: String(_id),
6934
+ tag: "getById"
6935
+ });
6936
+ const cachedData = await getCache(cacheKey);
6937
+ if (cachedData) {
6938
+ return cachedData;
6939
+ }
6940
+ const data = await collection.findOne({
6941
+ _id,
6942
+ status: { $ne: "deleted" }
6943
+ });
6944
+ setCache(cacheKey, data).then(() => {
6945
+ logger19.log({
6946
+ level: "info",
6947
+ message: `Cache set for getById ledger billing: ${cacheKey}`
6948
+ });
6949
+ }).catch((err) => {
6950
+ logger19.log({
6951
+ level: "error",
6952
+ message: `Failed to set cache for getById ledger billing: ${err.message}`
6953
+ });
6954
+ });
6955
+ return data;
6956
+ } catch (error2) {
6957
+ throw new InternalServerError19("Failed to get ledger billing.");
6958
+ }
6959
+ }
6960
+ async function getSummary(status, org) {
6961
+ const { error } = schemaLedgerBillingSummary.validate({ status, org });
6962
+ if (error) {
6963
+ throw new Error(`Invalid ledger billing ID: ${error.message}`);
6964
+ }
6965
+ try {
6966
+ org = new ObjectId21(org);
6967
+ } catch (error2) {
6968
+ throw new BadRequestError36("Invalid ledger billing org.");
6969
+ }
6970
+ try {
6971
+ const cacheKey = makeCacheKey13(namespace_collection, {
6972
+ org: String(org),
6973
+ status,
6974
+ tag: "getSummaryByOrgStatus"
6975
+ });
6976
+ const cachedData = await getCache(cacheKey);
6977
+ if (cachedData) {
6978
+ return cachedData;
6979
+ }
6980
+ const data = await collection.aggregate([
6981
+ { $match: { org, status } },
6982
+ {
6983
+ $group: {
6984
+ _id: "$status",
6985
+ totalAmount: { $sum: "$amount" },
6986
+ count: { $sum: 1 }
6987
+ }
6988
+ }
6989
+ ]).toArray();
6990
+ setCache(cacheKey, data[0]).then(() => {
6991
+ logger19.log({
6992
+ level: "info",
6993
+ message: `Cache set for ledger billing summary: ${cacheKey}`
6994
+ });
6995
+ }).catch((err) => {
6996
+ logger19.log({
6997
+ level: "error",
6998
+ message: `Failed to set cache for ledger billing summary: ${err.message}`
6999
+ });
7000
+ });
7001
+ return data[0];
7002
+ } catch (error2) {
7003
+ throw new InternalServerError19("Failed to get ledger billing summary.");
7004
+ }
7005
+ }
7006
+ return {
7007
+ delCachedData,
7008
+ createIndexes,
7009
+ add,
7010
+ getAll,
7011
+ getById,
7012
+ getSummary
7013
+ };
7014
+ }
7015
+
7016
+ // src/resources/ledger/ledger.billing.controller.ts
7017
+ import Joi31 from "joi";
7018
+ import { BadRequestError as BadRequestError37 } from "@goweekdays/utils";
7019
+ function useLedgerBillingController() {
7020
+ const {
7021
+ getAll: _getAll,
7022
+ getById: _getById,
7023
+ getSummary: _getSummary
7024
+ } = useLedgerBillingRepo();
7025
+ async function getAll(req, res, next) {
7026
+ const query = req.query;
7027
+ const validation = Joi31.object({
7028
+ org: Joi31.string().hex().optional().allow("", null),
7029
+ page: Joi31.number().min(1).optional().allow("", null),
7030
+ limit: Joi31.number().min(1).optional().allow("", null),
7031
+ search: Joi31.string().optional().allow("", null),
7032
+ status: Joi31.string().optional().allow("", null)
7033
+ });
7034
+ const { error } = validation.validate(query);
7035
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
7036
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
7037
+ const search = req.query.search ?? "";
7038
+ const org = req.query.org ?? "";
7039
+ const status = req.query.status ?? "";
7040
+ const isPageNumber = isFinite(page);
7041
+ if (!isPageNumber) {
7042
+ next(new BadRequestError37("Invalid page number."));
7043
+ return;
7044
+ }
7045
+ const isLimitNumber = isFinite(limit);
7046
+ if (!isLimitNumber) {
7047
+ next(new BadRequestError37("Invalid limit number."));
7048
+ return;
7049
+ }
7050
+ if (error) {
7051
+ next(new BadRequestError37(error.message));
7052
+ return;
7053
+ }
7054
+ try {
7055
+ const orgs = await _getAll({ org, page, limit, search, status });
7056
+ res.json(orgs);
7057
+ return;
7058
+ } catch (error2) {
7059
+ next(error2);
7060
+ }
7061
+ }
7062
+ async function getById(req, res, next) {
7063
+ const id = req.params.id;
7064
+ const validation = Joi31.object({
7065
+ id: Joi31.string().hex().required()
7066
+ });
7067
+ const { error } = validation.validate({ id });
7068
+ if (error) {
7069
+ next(new BadRequestError37(error.message));
7070
+ return;
7071
+ }
7072
+ try {
7073
+ const org = await _getById(id);
7074
+ res.json(org);
7075
+ return;
7076
+ } catch (error2) {
7077
+ next(error2);
7078
+ }
7079
+ }
7080
+ async function getSummary(req, res, next) {
7081
+ const params = req.params;
7082
+ const { error } = schemaLedgerBillingSummary.validate(params);
7083
+ const org = req.params.org ?? "";
7084
+ const status = req.params.status ?? "";
7085
+ if (error) {
7086
+ next(new BadRequestError37(error.message));
7087
+ return;
7088
+ }
7089
+ try {
7090
+ const summary = await _getSummary(status, org);
7091
+ res.json(summary);
7092
+ return;
7093
+ } catch (error2) {
7094
+ next(error2);
7095
+ }
7096
+ }
7097
+ return {
7098
+ getAll,
7099
+ getById,
7100
+ getSummary
7101
+ };
7102
+ }
7103
+
7104
+ // src/resources/organization/organization.service.ts
7105
+ function useOrgService() {
7106
+ const { add: addOrg } = useOrgRepo();
7107
+ const { addRole } = useRoleRepo();
7108
+ const { getAll: getAllPermission } = usePermissionRepo();
7109
+ const { add: addMember, updateRoleById: _updateRoleById } = useMemberRepo();
7110
+ const { getUserById } = useUserRepo();
7111
+ const { getDefault } = usePlanRepo();
7112
+ const { add: addSubscription } = useSubscriptionRepo();
7113
+ const { add: addSubscriptionTransaction } = useSubscriptionTransactionRepo();
7114
+ const { addOrder: addPaypalOrder } = usePaypalService();
7115
+ async function add(value) {
7116
+ const { error } = schemaOrgAdd.validate(value);
7117
+ if (error) {
7118
+ throw new BadRequestError38(error.message);
7119
+ }
7120
+ const session = useAtlas17.getClient()?.startSession();
7121
+ if (!session) {
7122
+ throw new BadRequestError38("Unable to start database session.");
7123
+ }
7124
+ try {
7125
+ session?.startTransaction();
7126
+ const org = await addOrg(
7127
+ {
7128
+ email: value.email,
7129
+ name: value.name,
7130
+ contact: value.contact,
7131
+ createdBy: value.createdBy
7132
+ },
7133
+ session
7134
+ );
7135
+ const plan = await getDefault();
7136
+ if (!plan) {
7137
+ throw new BadRequestError38(
7138
+ "Failed to create organization, plan not found."
7139
+ );
7140
+ }
7141
+ const currentDate = /* @__PURE__ */ new Date();
7142
+ const nextBillingDate = new Date(currentDate);
7143
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
7144
+ const amount = plan.price * value.seats;
7145
+ const subscriptionId = await addSubscription(
7146
+ {
7147
+ amount,
7148
+ org: String(org),
7149
+ seats: value.seats,
7150
+ paidSeats: value.seats,
7151
+ currency: plan.currency,
7152
+ billingCycle: plan.billingCycle,
7153
+ nextBillingDate
7154
+ },
7155
+ session
7156
+ );
7157
+ const createdBy = String(value.createdBy);
7158
+ const user = await getUserById(createdBy);
7159
+ if (!user) {
7160
+ throw new BadRequestError38("User is required to create org member.");
7161
+ }
7162
+ await addSubscriptionTransaction(
7163
+ {
7164
+ subscription: subscriptionId,
7165
+ type: "initiate",
7166
+ amount,
7167
+ currency: plan.currency,
7168
+ description: "Initial subscription transaction",
7169
+ createdBy: value.createdBy,
7170
+ createdByName: `${user.firstName} ${user.lastName}`
7171
+ },
7172
+ session
7173
+ );
7174
+ const allPermissions = await getAllPermission({
7175
+ app: "org",
7176
+ limit: 100
7177
+ });
7178
+ let permissions = [];
7179
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
7180
+ permissions = allPermissions.items.map((perm) => perm.key);
7181
+ }
7182
+ if (permissions.length === 0) {
7183
+ throw new Error("No permissions found for the organization type.");
7184
+ }
7185
+ const roleData = {
7186
+ org: String(org),
7187
+ name: "Owner",
7188
+ description: "Owner of the organization",
7189
+ permissions,
7190
+ createdBy,
7191
+ app: "org"
7192
+ };
7193
+ const role = await addRole(roleData, session);
7194
+ if (!role) {
7195
+ throw new BadRequestError38("Role is required to create org member.");
7196
+ }
7197
+ await addMember(
7198
+ {
7199
+ role: String(role),
7200
+ roleName: roleData.name,
7201
+ org: String(org),
7202
+ orgName: value.name,
7203
+ name: `${user.firstName} ${user.lastName}`,
7204
+ user: createdBy,
7205
+ app: "org"
7206
+ },
7207
+ session
7208
+ );
7209
+ const order = await addPaypalOrder({
7210
+ amount,
7211
+ currency: plan.currency,
7212
+ customId: subscriptionId,
7213
+ returnUrl: `${APP_ORG}/organizations/success`,
7214
+ cancelUrl: `${APP_ORG}/organizations/cancel`,
7215
+ action: "pay"
7216
+ });
7217
+ await session?.commitTransaction();
7218
+ const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
7219
+ (link) => link.rel === "approve"
7220
+ );
7221
+ return {
7222
+ org: String(org),
7223
+ paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
7224
+ };
7225
+ } catch (error2) {
7226
+ await session?.abortTransaction();
7227
+ throw error2;
7228
+ } finally {
7229
+ await session?.endSession();
7230
+ }
7231
+ }
7232
+ const { getById, updateStatusById: updateVerificationStatus } = useVerificationRepo();
7233
+ const { add: addLedgerBilling } = useLedgerBillingRepo();
7234
+ async function addWithVerification(id) {
7235
+ const { error } = Joi32.string().hex().required().validate(id);
7236
+ if (error) {
7237
+ throw new BadRequestError38(error.message);
7238
+ }
7239
+ const session = useAtlas17.getClient()?.startSession();
7240
+ if (!session) {
7241
+ throw new BadRequestError38("Unable to start database session.");
7242
+ }
7243
+ try {
7244
+ session?.startTransaction();
7245
+ const verification = await getById(id);
7246
+ await updateVerificationStatus(id, "complete", session);
7247
+ if (!verification) {
7248
+ throw new BadRequestError38("Verification not found.");
7249
+ }
7250
+ if (!verification.metadata?.orgName) {
7251
+ throw new BadRequestError38("Organization name is required.");
7252
+ }
7253
+ if (!verification.metadata?.seats) {
7254
+ throw new BadRequestError38("Number of seats is required.");
7255
+ }
7256
+ if (!verification.metadata?.createdBy) {
7257
+ throw new BadRequestError38("CreatedBy is required.");
7258
+ }
7259
+ if (!verification.metadata?.contact) {
7260
+ throw new BadRequestError38("Contact is required.");
7261
+ }
7262
+ const org = await addOrg(
7263
+ {
7264
+ email: verification.email,
7265
+ name: verification.metadata.orgName,
7266
+ contact: verification.metadata.contact,
7267
+ createdBy: verification.metadata.createdBy
7268
+ },
7269
+ session
7270
+ );
7271
+ const plan = await getDefault();
7272
+ if (!plan) {
7273
+ throw new BadRequestError38(
7274
+ "Failed to create organization, plan not found."
7275
+ );
7276
+ }
7277
+ const currentDate = /* @__PURE__ */ new Date();
7278
+ const nextBillingDate = new Date(currentDate);
7279
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
7280
+ const amount = plan.price * verification.metadata.seats;
7281
+ const subscriptionId = await addSubscription(
7282
+ {
7283
+ amount,
7284
+ org: String(org),
7285
+ seats: verification.metadata.seats,
7286
+ paidSeats: verification.metadata.seats,
7287
+ currency: plan.currency,
7288
+ billingCycle: plan.billingCycle,
7289
+ nextBillingDate
7290
+ },
7291
+ session
7292
+ );
7293
+ const createdBy = String(verification.metadata.createdBy);
7294
+ const user = await getUserById(createdBy);
7295
+ if (!user) {
7296
+ throw new BadRequestError38("User is required to create org member.");
7297
+ }
7298
+ await addSubscriptionTransaction(
7299
+ {
7300
+ subscription: subscriptionId,
7301
+ type: "initiate",
7302
+ amount,
7303
+ currency: plan.currency,
7304
+ description: "Initial subscription transaction",
7305
+ createdBy,
7306
+ createdByName: `${user.firstName} ${user.lastName}`
7307
+ },
7308
+ session
7309
+ );
7310
+ await addLedgerBilling(
7311
+ {
7312
+ org: String(org),
7313
+ amount: verification.metadata?.amount ?? 0,
7314
+ description: "Setup payment during organization creation",
7315
+ currency: plan.currency,
7316
+ type: "setup-fee",
7317
+ status: "paid"
7318
+ },
7319
+ session
7320
+ );
7321
+ const allPermissions = await getAllPermission({
7322
+ app: "org",
7323
+ limit: 100
7324
+ });
7325
+ let permissions = [];
7326
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
7327
+ permissions = allPermissions.items.map((perm) => perm.key);
7328
+ }
7329
+ if (permissions.length === 0) {
7330
+ throw new Error("No permissions found for the organization type.");
7331
+ }
7332
+ const roleData = {
7333
+ org: String(org),
7334
+ name: "Owner",
7335
+ description: "Owner of the organization",
7336
+ permissions,
7337
+ createdBy,
7338
+ app: "org"
7339
+ };
7340
+ const role = await addRole(roleData, session);
7341
+ if (!role) {
7342
+ throw new BadRequestError38("Role is required to create org member.");
7343
+ }
7344
+ await addMember(
7345
+ {
7346
+ role: String(role),
7347
+ roleName: roleData.name,
7348
+ org: String(org),
7349
+ orgName: verification.metadata.orgName,
7350
+ name: `${user.firstName} ${user.lastName}`,
7351
+ user: createdBy,
7352
+ app: "org"
7353
+ },
7354
+ session
7355
+ );
7356
+ await session?.commitTransaction();
7357
+ return "Successfully created organization with verification.";
7358
+ } catch (error2) {
7359
+ await session?.abortTransaction();
7360
+ throw error2;
7361
+ } finally {
7362
+ await session?.endSession();
7363
+ }
7364
+ }
7365
+ return {
7366
+ add,
7367
+ addWithVerification
7368
+ };
7369
+ }
7370
+
7371
+ // src/resources/organization/organization.controller.ts
7372
+ import { BadRequestError as BadRequestError39 } from "@goweekdays/utils";
7373
+ import Joi33 from "joi";
7374
+ function useOrgController() {
7375
+ const { add: _add } = useOrgService();
7376
+ const { getOrgsByMembership } = useMemberRepo();
7377
+ const {
7378
+ getByName: _getByName,
7379
+ getAll: getAllOrg,
7380
+ getById: _getById,
7381
+ updateById: _updateById
7382
+ } = useOrgRepo();
7383
+ async function add(req, res, next) {
7384
+ const value = req.body;
7385
+ const { error } = schemaOrgAdd.validate(value);
7386
+ if (error) {
7387
+ next(new BadRequestError39(error.message));
7388
+ return;
7389
+ }
7390
+ try {
7391
+ const data = await _add(value);
7392
+ res.json({
7393
+ message: "Organization created successfully.",
7394
+ data
7395
+ });
7396
+ return;
7397
+ } catch (error2) {
7398
+ next(error2);
7399
+ }
7400
+ }
7401
+ async function getOrgsByUserId(req, res, next) {
7402
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
7403
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
7404
+ const search = req.query.search ?? "";
7405
+ const user = req.params.user ?? "";
7406
+ const isPageNumber = isFinite(page);
7407
+ if (!isPageNumber) {
7408
+ next(new BadRequestError39("Invalid page number."));
7409
+ return;
7410
+ }
7411
+ const isLimitNumber = isFinite(limit);
7412
+ if (!isLimitNumber) {
7413
+ next(new BadRequestError39("Invalid limit number."));
7414
+ return;
7415
+ }
7416
+ const validation = Joi33.object({
7417
+ user: Joi33.string().hex().required(),
7418
+ page: Joi33.number().min(1).optional().allow("", null),
7419
+ limit: Joi33.number().min(1).optional().allow("", null),
7420
+ search: Joi33.string().optional().allow("", null)
7421
+ });
7422
+ const { error } = validation.validate({ user, page, limit, search });
7423
+ if (error) {
7424
+ next(new BadRequestError39(error.message));
7425
+ return;
7426
+ }
7427
+ try {
7428
+ const orgs = await getOrgsByMembership({ user, page, limit, search });
7429
+ res.json(orgs);
7430
+ return;
7431
+ } catch (error2) {
7432
+ next(error2);
7433
+ }
7434
+ }
7435
+ async function getAll(req, res, next) {
7436
+ const query = req.query;
7437
+ const validation = Joi33.object({
7438
+ page: Joi33.number().min(1).optional().allow("", null),
7439
+ limit: Joi33.number().min(1).optional().allow("", null),
7440
+ search: Joi33.string().optional().allow("", null),
7441
+ status: Joi33.string().valid("active", "suspended", "inactive", "deleted").optional()
7442
+ });
7443
+ const { error } = validation.validate(query);
7444
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
7445
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
7446
+ const search = req.query.search ?? "";
7447
+ const status = req.query.status ?? "active";
7448
+ const isPageNumber = isFinite(page);
7449
+ if (!isPageNumber) {
7450
+ next(new BadRequestError39("Invalid page number."));
7451
+ return;
7452
+ }
7453
+ const isLimitNumber = isFinite(limit);
7454
+ if (!isLimitNumber) {
7455
+ next(new BadRequestError39("Invalid limit number."));
7456
+ return;
7457
+ }
7458
+ if (error) {
7459
+ next(new BadRequestError39(error.message));
7460
+ return;
7461
+ }
7462
+ try {
7463
+ const orgs = await getAllOrg({ page, limit, search, status });
7464
+ res.json(orgs);
7465
+ return;
7466
+ } catch (error2) {
7467
+ next(error2);
7468
+ }
7469
+ }
7470
+ async function getByName(req, res, next) {
7471
+ const name = req.params.name;
7472
+ const validation = Joi33.object({
7473
+ name: Joi33.string().required()
7474
+ });
7475
+ const { error } = validation.validate({ name });
7476
+ if (error) {
7477
+ next(new BadRequestError39(error.message));
7478
+ return;
7479
+ }
7480
+ try {
7481
+ const org = await _getByName(name);
7482
+ res.json(org);
7483
+ return;
7484
+ } catch (error2) {
7485
+ next(error2);
7486
+ }
7487
+ }
7488
+ async function getById(req, res, next) {
7489
+ const id = req.params.id;
7490
+ const validation = Joi33.object({
7491
+ id: Joi33.string().hex().required()
7492
+ });
7493
+ const { error } = validation.validate({ id });
7494
+ if (error) {
7495
+ next(new BadRequestError39(error.message));
7496
+ return;
7497
+ }
7498
+ try {
7499
+ const org = await _getById(id);
7500
+ res.json(org);
7501
+ return;
7502
+ } catch (error2) {
7503
+ next(error2);
7504
+ }
7505
+ }
7506
+ async function updateById(req, res, next) {
7507
+ const _id = req.params.id ?? "";
7508
+ const payload = req.body;
7509
+ const { error } = schemaOrgUpdate.validate({ _id, ...payload });
7510
+ if (error) {
7511
+ next(new BadRequestError39(error.message));
7512
+ return;
7513
+ }
7514
+ try {
7515
+ const message = await _updateById(_id, payload);
7516
+ res.json({ message });
7517
+ return;
7518
+ } catch (error2) {
7519
+ next(error2);
7520
+ }
7521
+ }
7522
+ return {
7523
+ add,
7524
+ getOrgsByUserId,
7525
+ getByName,
7526
+ getAll,
7527
+ getById,
7528
+ updateById
7529
+ };
7530
+ }
7531
+
7532
+ // src/resources/user/user.service.ts
7533
+ function useUserService() {
7534
+ const {
7535
+ add: addUser,
7536
+ getUserByEmail,
7537
+ getUserById: _getById,
7538
+ updateName: _updateName,
7539
+ updateBirthday: _updateBirthday,
7540
+ updateUserFieldById: _updateUserFieldById
7541
+ } = useUserRepo();
7542
+ const { addRole, getById: getRoleById } = useRoleRepo();
7543
+ const { add: addMember } = useMemberRepo();
7544
+ const { getAll: getAllPermission } = usePermissionRepo();
7545
+ const { getById: getOrgById } = useOrgRepo();
7546
+ async function createDefaultUser() {
7547
+ const session = useAtlas18.getClient()?.startSession();
7548
+ try {
7549
+ session?.startTransaction();
7550
+ const _user = await getUserByEmail(DEFAULT_USER_EMAIL);
7551
+ if (_user) {
7552
+ throw new BadRequestError40(
7553
+ `User already exists: ${DEFAULT_USER_EMAIL}.`
7554
+ );
7555
+ }
7556
+ const hashedPassword = await hashPassword(DEFAULT_USER_PASSWORD);
7557
+ const userId = await addUser(
7558
+ {
7559
+ email: DEFAULT_USER_EMAIL,
7560
+ password: hashedPassword,
7561
+ firstName: DEFAULT_USER_FIRST_NAME,
7562
+ lastName: DEFAULT_USER_LAST_NAME
6771
7563
  },
6772
7564
  session
6773
7565
  );
@@ -6807,7 +7599,7 @@ function useUserService() {
6807
7599
  try {
6808
7600
  const _user = await getUserByEmail(value.email);
6809
7601
  if (_user) {
6810
- throw new BadRequestError36(`User already exists: ${value.email}.`);
7602
+ throw new BadRequestError40(`User already exists: ${value.email}.`);
6811
7603
  }
6812
7604
  const hashedPassword = await hashPassword(value.password);
6813
7605
  const insertedId = await addUser({
@@ -6819,10 +7611,10 @@ function useUserService() {
6819
7611
  });
6820
7612
  return insertedId;
6821
7613
  } catch (error) {
6822
- if (error instanceof AppError14) {
7614
+ if (error instanceof AppError16) {
6823
7615
  throw error;
6824
7616
  } else {
6825
- throw new InternalServerError18(`Error creating user: ${error}`);
7617
+ throw new InternalServerError20(`Error creating user: ${error}`);
6826
7618
  }
6827
7619
  }
6828
7620
  }
@@ -6833,22 +7625,22 @@ function useUserService() {
6833
7625
  lastName = "",
6834
7626
  password = ""
6835
7627
  } = {}) {
6836
- const session = useAtlas17.getClient()?.startSession();
7628
+ const session = useAtlas18.getClient()?.startSession();
6837
7629
  session?.startTransaction();
6838
7630
  try {
6839
7631
  const invitation = await _getVerificationById(id);
6840
7632
  if (!invitation || !invitation.metadata?.app || !invitation.metadata?.role) {
6841
- throw new BadRequestError36("Invalid invitation.");
7633
+ throw new BadRequestError40("Invalid invitation.");
6842
7634
  }
6843
7635
  if (invitation.status === "complete") {
6844
- throw new BadRequestError36("Invitation already used.");
7636
+ throw new BadRequestError40("Invitation already used.");
6845
7637
  }
6846
7638
  if (!invitation.expireAt) {
6847
- throw new BadRequestError36("Expiration date is required.");
7639
+ throw new BadRequestError40("Expiration date is required.");
6848
7640
  }
6849
7641
  const expired = new Date(invitation.expireAt) < /* @__PURE__ */ new Date();
6850
7642
  if (invitation.status === "expired" || expired) {
6851
- throw new BadRequestError36("Invitation expired.");
7643
+ throw new BadRequestError40("Invitation expired.");
6852
7644
  }
6853
7645
  const email = invitation.email;
6854
7646
  const user = await getUserByEmail(invitation.email);
@@ -6899,10 +7691,10 @@ function useUserService() {
6899
7691
  return userId;
6900
7692
  } catch (error) {
6901
7693
  await session?.abortTransaction();
6902
- if (error instanceof AppError14) {
7694
+ if (error instanceof AppError16) {
6903
7695
  throw error;
6904
7696
  } else {
6905
- throw new InternalServerError18("Failed to create user by invite.");
7697
+ throw new InternalServerError20("Failed to create user by invite.");
6906
7698
  }
6907
7699
  } finally {
6908
7700
  session?.endSession();
@@ -6914,29 +7706,29 @@ function useUserService() {
6914
7706
  lastName = "",
6915
7707
  password = ""
6916
7708
  } = {}) {
6917
- const session = useAtlas17.getClient()?.startSession();
7709
+ const session = useAtlas18.getClient()?.startSession();
6918
7710
  session?.startTransaction();
6919
7711
  try {
6920
7712
  const signUp = await _getVerificationById(id);
6921
7713
  if (!signUp) {
6922
- throw new BadRequestError36("Invalid sign up link.");
7714
+ throw new BadRequestError40("Invalid sign up link.");
6923
7715
  }
6924
7716
  if (signUp.status === "complete") {
6925
- throw new BadRequestError36(
7717
+ throw new BadRequestError40(
6926
7718
  "You have already an account created using this link."
6927
7719
  );
6928
7720
  }
6929
7721
  if (!signUp.expireAt) {
6930
- throw new BadRequestError36("Expiration date is required.");
7722
+ throw new BadRequestError40("Expiration date is required.");
6931
7723
  }
6932
7724
  const expired = new Date(signUp.expireAt) < /* @__PURE__ */ new Date();
6933
7725
  if (signUp.status === "expired" || expired) {
6934
- throw new BadRequestError36("Sign up link expired.");
7726
+ throw new BadRequestError40("Sign up link expired.");
6935
7727
  }
6936
7728
  const email = signUp.email;
6937
7729
  const _user = await getUserByEmail(signUp.email);
6938
7730
  if (_user) {
6939
- throw new BadRequestError36(`User already exists: ${email}.`);
7731
+ throw new BadRequestError40(`User already exists: ${email}.`);
6940
7732
  }
6941
7733
  const hashedPassword = await hashPassword(password);
6942
7734
  const userId = await addUser(
@@ -6962,17 +7754,17 @@ function useUserService() {
6962
7754
  const { updateStatusById: updateVerificationStatusById } = useVerificationRepo();
6963
7755
  async function resetPassword(value) {
6964
7756
  if (value.newPassword !== value.confirmPassword) {
6965
- throw new BadRequestError36("Passwords do not match.");
7757
+ throw new BadRequestError40("Passwords do not match.");
6966
7758
  }
6967
7759
  let hashedPassword = "";
6968
7760
  try {
6969
7761
  hashedPassword = await hashPassword(value.newPassword);
6970
7762
  } catch (error) {
6971
- throw new InternalServerError18(`Error hashing password: ${error}`);
7763
+ throw new InternalServerError20(`Error hashing password: ${error}`);
6972
7764
  }
6973
- const session = useAtlas17.getClient()?.startSession();
7765
+ const session = useAtlas18.getClient()?.startSession();
6974
7766
  if (!session) {
6975
- throw new InternalServerError18("Failed to start database session.");
7767
+ throw new InternalServerError20("Failed to start database session.");
6976
7768
  }
6977
7769
  try {
6978
7770
  session.startTransaction();
@@ -6988,7 +7780,7 @@ function useUserService() {
6988
7780
  throw new NotFoundError2("User ID is invalid.");
6989
7781
  }
6990
7782
  if (otpDoc.status === "used") {
6991
- throw new BadRequestError36("This link has already been invalidated.");
7783
+ throw new BadRequestError40("This link has already been invalidated.");
6992
7784
  }
6993
7785
  await updateVerificationStatusById(value.id, "used", session);
6994
7786
  await _updateUserFieldById(
@@ -6999,31 +7791,31 @@ function useUserService() {
6999
7791
  return "Successfully reset password.";
7000
7792
  } catch (error) {
7001
7793
  await session.abortTransaction();
7002
- if (error instanceof AppError14) {
7794
+ if (error instanceof AppError16) {
7003
7795
  throw error;
7004
7796
  }
7005
- throw new InternalServerError18("Failed to reset password.");
7797
+ throw new InternalServerError20("Failed to reset password.");
7006
7798
  }
7007
7799
  }
7008
7800
  const { updateName: updateMemberName } = useMemberRepo();
7009
7801
  async function updateName(_id, firstName, lastName) {
7010
7802
  if (!_id) {
7011
- throw new BadRequestError36("Invalid user ID");
7803
+ throw new BadRequestError40("Invalid user ID");
7012
7804
  }
7013
7805
  if (!firstName) {
7014
- throw new BadRequestError36("Invalid firstName");
7806
+ throw new BadRequestError40("Invalid firstName");
7015
7807
  }
7016
7808
  if (!lastName) {
7017
- throw new BadRequestError36("Invalid lastName");
7809
+ throw new BadRequestError40("Invalid lastName");
7018
7810
  }
7019
- const session = useAtlas17.getClient()?.startSession();
7811
+ const session = useAtlas18.getClient()?.startSession();
7020
7812
  session?.startTransaction();
7021
- const cacheKey = makeCacheKey13("users", { user: _id });
7813
+ const cacheKey = makeCacheKey14("users", { user: _id });
7022
7814
  try {
7023
- useCache14().delCache(cacheKey).then(() => {
7024
- logger18.info(`Cache cleared for user: ${_id}`);
7815
+ useCache15().delCache(cacheKey).then(() => {
7816
+ logger20.info(`Cache cleared for user: ${_id}`);
7025
7817
  }).catch((error) => {
7026
- logger18.error(`Failed to clear cache for user: ${_id}`, error);
7818
+ logger20.error(`Failed to clear cache for user: ${_id}`, error);
7027
7819
  });
7028
7820
  await _updateName({ _id, firstName, lastName }, session);
7029
7821
  await updateMemberName(
@@ -7041,16 +7833,16 @@ function useUserService() {
7041
7833
  }
7042
7834
  async function updateBirthday(_id, month, day, year) {
7043
7835
  if (!_id) {
7044
- throw new BadRequestError36("Invalid user ID");
7836
+ throw new BadRequestError40("Invalid user ID");
7045
7837
  }
7046
7838
  if (!month) {
7047
- throw new BadRequestError36("Invalid birth month.");
7839
+ throw new BadRequestError40("Invalid birth month.");
7048
7840
  }
7049
7841
  if (!day) {
7050
- throw new BadRequestError36("Invalid birthday.");
7842
+ throw new BadRequestError40("Invalid birthday.");
7051
7843
  }
7052
7844
  if (!year) {
7053
- throw new BadRequestError36("Invalid birth year.");
7845
+ throw new BadRequestError40("Invalid birth year.");
7054
7846
  }
7055
7847
  try {
7056
7848
  await _updateBirthday({ _id, month, day, year });
@@ -7075,7 +7867,7 @@ function useUserService() {
7075
7867
  bucket: SPACES_BUCKET
7076
7868
  });
7077
7869
  async function updateUserProfile({ file, user, previousProfile } = {}) {
7078
- const session = useAtlas17.getClient()?.startSession();
7870
+ const session = useAtlas18.getClient()?.startSession();
7079
7871
  session?.startTransaction();
7080
7872
  const _file = {
7081
7873
  name: file.originalname,
@@ -7120,11 +7912,11 @@ function useUserService() {
7120
7912
 
7121
7913
  // src/resources/user/user.controller.ts
7122
7914
  import {
7123
- AppError as AppError15,
7124
- BadRequestError as BadRequestError37,
7125
- InternalServerError as InternalServerError19
7915
+ AppError as AppError17,
7916
+ BadRequestError as BadRequestError41,
7917
+ InternalServerError as InternalServerError21
7126
7918
  } from "@goweekdays/utils";
7127
- import Joi28 from "joi";
7919
+ import Joi34 from "joi";
7128
7920
  function useUserController() {
7129
7921
  const {
7130
7922
  updateName: _updateName,
@@ -7140,14 +7932,14 @@ function useUserController() {
7140
7932
  const status = req.query.status ?? "";
7141
7933
  const search = req.query.search ?? "";
7142
7934
  const page = Number(req.query.page) ?? 1;
7143
- const validation = Joi28.object({
7144
- status: Joi28.string().required(),
7145
- search: Joi28.string().optional().allow("", null),
7146
- page: Joi28.number().required()
7935
+ const validation = Joi34.object({
7936
+ status: Joi34.string().required(),
7937
+ search: Joi34.string().optional().allow("", null),
7938
+ page: Joi34.number().required()
7147
7939
  });
7148
7940
  const { error } = validation.validate({ status, search, page });
7149
7941
  if (error) {
7150
- next(new BadRequestError37(error.message));
7942
+ next(new BadRequestError41(error.message));
7151
7943
  return;
7152
7944
  }
7153
7945
  try {
@@ -7160,14 +7952,14 @@ function useUserController() {
7160
7952
  }
7161
7953
  async function getUserById(req, res, next) {
7162
7954
  const id = req.params.id || "";
7163
- const validation = Joi28.string().hex().validate(id);
7955
+ const validation = Joi34.string().hex().validate(id);
7164
7956
  if (validation.error) {
7165
- throw new BadRequestError37("Invalid id.");
7957
+ throw new BadRequestError41("Invalid id.");
7166
7958
  }
7167
7959
  try {
7168
7960
  const user = await _getUserById(id);
7169
7961
  if (!user) {
7170
- throw new BadRequestError37("User not found.");
7962
+ throw new BadRequestError41("User not found.");
7171
7963
  }
7172
7964
  res.json(user);
7173
7965
  } catch (error) {
@@ -7178,13 +7970,13 @@ function useUserController() {
7178
7970
  const id = req.headers.user ?? "";
7179
7971
  const firstName = req.body.firstName ?? "";
7180
7972
  const lastName = req.body.lastName ?? "";
7181
- const validation = Joi28.object({
7182
- firstName: Joi28.string().required(),
7183
- lastName: Joi28.string().required()
7973
+ const validation = Joi34.object({
7974
+ firstName: Joi34.string().required(),
7975
+ lastName: Joi34.string().required()
7184
7976
  });
7185
7977
  const { error } = validation.validate({ firstName, lastName });
7186
7978
  if (error) {
7187
- next(new BadRequestError37(error.message));
7979
+ next(new BadRequestError41(error.message));
7188
7980
  return;
7189
7981
  }
7190
7982
  try {
@@ -7200,14 +7992,14 @@ function useUserController() {
7200
7992
  const month = req.body.month ?? "";
7201
7993
  const day = req.body.day ?? 0;
7202
7994
  const year = req.body.year ?? 0;
7203
- const validation = Joi28.object({
7204
- month: Joi28.string().required(),
7205
- day: Joi28.number().integer().min(1).max(31).required(),
7206
- year: Joi28.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
7995
+ const validation = Joi34.object({
7996
+ month: Joi34.string().required(),
7997
+ day: Joi34.number().integer().min(1).max(31).required(),
7998
+ year: Joi34.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
7207
7999
  });
7208
8000
  const { error } = validation.validate({ month, day, year });
7209
8001
  if (error) {
7210
- next(new BadRequestError37(error.message));
8002
+ next(new BadRequestError41(error.message));
7211
8003
  return;
7212
8004
  }
7213
8005
  try {
@@ -7221,18 +8013,18 @@ function useUserController() {
7221
8013
  async function updateUserFieldById(req, res, next) {
7222
8014
  const _id = req.params.id;
7223
8015
  const { field, value } = req.body;
7224
- const validation = Joi28.object({
7225
- _id: Joi28.string().hex().required(),
7226
- field: Joi28.string().valid("gender", "email", "contact", "profile").required(),
7227
- value: Joi28.alternatives().conditional("field", {
8016
+ const validation = Joi34.object({
8017
+ _id: Joi34.string().hex().required(),
8018
+ field: Joi34.string().valid("gender", "email", "contact", "profile").required(),
8019
+ value: Joi34.alternatives().conditional("field", {
7228
8020
  is: "email",
7229
- then: Joi28.string().email().required(),
7230
- otherwise: Joi28.string().required()
8021
+ then: Joi34.string().email().required(),
8022
+ otherwise: Joi34.string().required()
7231
8023
  })
7232
8024
  });
7233
8025
  const { error } = validation.validate({ _id, field, value });
7234
8026
  if (error) {
7235
- next(new BadRequestError37(error.message));
8027
+ next(new BadRequestError41(error.message));
7236
8028
  return;
7237
8029
  }
7238
8030
  try {
@@ -7248,12 +8040,12 @@ function useUserController() {
7248
8040
  return;
7249
8041
  }
7250
8042
  const previousProfile = req.body.previousProfile ?? "";
7251
- const validation = Joi28.object({
7252
- previousProfile: Joi28.string().hex().optional().allow("", null)
8043
+ const validation = Joi34.object({
8044
+ previousProfile: Joi34.string().hex().optional().allow("", null)
7253
8045
  });
7254
8046
  const { error } = validation.validate({ previousProfile });
7255
8047
  if (error) {
7256
- next(new BadRequestError37(error.message));
8048
+ next(new BadRequestError41(error.message));
7257
8049
  return;
7258
8050
  }
7259
8051
  const user = req.headers["user"] ?? "";
@@ -7266,10 +8058,10 @@ function useUserController() {
7266
8058
  res.json({ message: "Successfully updated profile picture." });
7267
8059
  return;
7268
8060
  } catch (error2) {
7269
- if (error2 instanceof AppError15) {
8061
+ if (error2 instanceof AppError17) {
7270
8062
  next(error2);
7271
8063
  } else {
7272
- next(new InternalServerError19(error2));
8064
+ next(new InternalServerError21(error2));
7273
8065
  }
7274
8066
  }
7275
8067
  }
@@ -7279,12 +8071,12 @@ function useUserController() {
7279
8071
  const password = req.body.password ?? "";
7280
8072
  const id = req.params.id ?? "";
7281
8073
  const type = req.body.type ?? "";
7282
- const validation = Joi28.object({
7283
- firstName: Joi28.string().required(),
7284
- lastName: Joi28.string().required(),
7285
- password: Joi28.string().required(),
7286
- id: Joi28.string().hex().required(),
7287
- type: Joi28.string().required()
8074
+ const validation = Joi34.object({
8075
+ firstName: Joi34.string().required(),
8076
+ lastName: Joi34.string().required(),
8077
+ password: Joi34.string().required(),
8078
+ id: Joi34.string().hex().required(),
8079
+ type: Joi34.string().required()
7288
8080
  });
7289
8081
  const { error } = validation.validate({
7290
8082
  firstName,
@@ -7294,7 +8086,7 @@ function useUserController() {
7294
8086
  type
7295
8087
  });
7296
8088
  if (error) {
7297
- next(new BadRequestError37(error.message));
8089
+ next(new BadRequestError41(error.message));
7298
8090
  return;
7299
8091
  }
7300
8092
  try {
@@ -7317,14 +8109,14 @@ function useUserController() {
7317
8109
  }
7318
8110
  async function resetPassword(req, res, next) {
7319
8111
  const payload = req.body;
7320
- const validation = Joi28.object({
7321
- id: Joi28.string().hex().required(),
7322
- newPassword: Joi28.string().min(8).required(),
7323
- confirmPassword: Joi28.string().min(8).required()
8112
+ const validation = Joi34.object({
8113
+ id: Joi34.string().hex().required(),
8114
+ newPassword: Joi34.string().min(8).required(),
8115
+ confirmPassword: Joi34.string().min(8).required()
7324
8116
  });
7325
8117
  const { error } = validation.validate(payload);
7326
8118
  if (error) {
7327
- next(new BadRequestError37(error.message));
8119
+ next(new BadRequestError41(error.message));
7328
8120
  return;
7329
8121
  }
7330
8122
  try {
@@ -7349,7 +8141,7 @@ function useUserController() {
7349
8141
  }
7350
8142
 
7351
8143
  // src/resources/verification/verification.service.ts
7352
- import Joi29 from "joi";
8144
+ import Joi35 from "joi";
7353
8145
  function useVerificationService() {
7354
8146
  const MailerConfig = {
7355
8147
  host: MAILER_TRANSPORT_HOST,
@@ -7384,7 +8176,7 @@ function useVerificationService() {
7384
8176
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
7385
8177
  };
7386
8178
  if (!metadata.app) {
7387
- throw new BadRequestError38("App metadata is required.");
8179
+ throw new BadRequestError42("App metadata is required.");
7388
8180
  }
7389
8181
  try {
7390
8182
  const user = await getUserByEmail(email);
@@ -7407,7 +8199,7 @@ function useVerificationService() {
7407
8199
  html: emailContent2,
7408
8200
  from: "GoWeekdays"
7409
8201
  }).catch((error) => {
7410
- logger19.log({
8202
+ logger21.log({
7411
8203
  level: "error",
7412
8204
  message: `Error sending user invite email: ${error}`
7413
8205
  });
@@ -7429,7 +8221,7 @@ function useVerificationService() {
7429
8221
  html: emailContent,
7430
8222
  from: "GoWeekdays"
7431
8223
  }).catch((error) => {
7432
- logger19.log({
8224
+ logger21.log({
7433
8225
  level: "error",
7434
8226
  message: `Error sending user invite email: ${error}`
7435
8227
  });
@@ -7464,14 +8256,14 @@ function useVerificationService() {
7464
8256
  from: "GoWeekdays",
7465
8257
  html: emailContent
7466
8258
  }).catch((error) => {
7467
- logger19.log({
8259
+ logger21.log({
7468
8260
  level: "error",
7469
8261
  message: `Error sending forget password email: ${error}`
7470
8262
  });
7471
8263
  });
7472
8264
  return "Successfully created a link to reset password. Please check your email.";
7473
8265
  } catch (error) {
7474
- throw new InternalServerError20("Failed to create forget password link.");
8266
+ throw new InternalServerError22("Failed to create forget password link.");
7475
8267
  }
7476
8268
  }
7477
8269
  async function getById(id) {
@@ -7510,34 +8302,34 @@ function useVerificationService() {
7510
8302
  }
7511
8303
  function errorByType(type, status) {
7512
8304
  if (type === "user-invite" && status === "expired") {
7513
- throw new BadRequestError38(
8305
+ throw new BadRequestError42(
7514
8306
  "Invitation has already expired, please contact admin to resend the invitation."
7515
8307
  );
7516
8308
  }
7517
8309
  if (type === "user-sign-up" && status === "expired") {
7518
- throw new BadRequestError38(
8310
+ throw new BadRequestError42(
7519
8311
  "Sign up verification has expired, please sign up again to get a new verification link."
7520
8312
  );
7521
8313
  }
7522
8314
  if (type === "user-invite" && status === "complete") {
7523
- throw new BadRequestError38(
8315
+ throw new BadRequestError42(
7524
8316
  "User already registered, please login to continue."
7525
8317
  );
7526
8318
  }
7527
8319
  if (type === "forget-password" && status === "complete") {
7528
- throw new BadRequestError38(
8320
+ throw new BadRequestError42(
7529
8321
  "Forget password verification has already been used, please request a new one."
7530
8322
  );
7531
8323
  }
7532
8324
  if (type === "forget-password" && status === "expired") {
7533
- throw new BadRequestError38(
8325
+ throw new BadRequestError42(
7534
8326
  "Forget password verification has expired, please request a new one."
7535
8327
  );
7536
8328
  }
7537
- throw new BadRequestError38("Invalid verification.");
8329
+ throw new BadRequestError42("Invalid verification.");
7538
8330
  }
7539
8331
  async function verify(id) {
7540
- const session = useAtlas18.getClient()?.startSession();
8332
+ const session = useAtlas19.getClient()?.startSession();
7541
8333
  session?.startTransaction();
7542
8334
  try {
7543
8335
  const _id = await _getById(id);
@@ -7548,10 +8340,10 @@ function useVerificationService() {
7548
8340
  errorByType(_id.type, "expired");
7549
8341
  }
7550
8342
  if (_id.status === "complete") {
7551
- throw new BadRequestError38("Verification already completed.");
8343
+ throw new BadRequestError42("Verification already completed.");
7552
8344
  }
7553
8345
  if (!_id.expireAt) {
7554
- throw new BadRequestError38("Expiration date is required.");
8346
+ throw new BadRequestError42("Expiration date is required.");
7555
8347
  }
7556
8348
  const expiration = new Date(_id.expireAt).getTime();
7557
8349
  const now = (/* @__PURE__ */ new Date()).getTime();
@@ -7567,12 +8359,12 @@ function useVerificationService() {
7567
8359
  throw new NotFoundError3("User not found for member invite.");
7568
8360
  }
7569
8361
  if (!_id.metadata?.app) {
7570
- throw new BadRequestError38(
8362
+ throw new BadRequestError42(
7571
8363
  "App metadata is required for member invite."
7572
8364
  );
7573
8365
  }
7574
8366
  if (!_id.metadata?.role || !_id.metadata?.roleName) {
7575
- throw new BadRequestError38(
8367
+ throw new BadRequestError42(
7576
8368
  "Role metadata is required for member invite."
7577
8369
  );
7578
8370
  }
@@ -7594,7 +8386,7 @@ function useVerificationService() {
7594
8386
  return _id;
7595
8387
  } catch (error) {
7596
8388
  await session?.abortTransaction();
7597
- logger19.log({
8389
+ logger21.log({
7598
8390
  level: "info",
7599
8391
  message: `Error verifying user invitation: ${error}`
7600
8392
  });
@@ -7607,7 +8399,7 @@ function useVerificationService() {
7607
8399
  try {
7608
8400
  await updateStatusById(id, "cancelled");
7609
8401
  } catch (error) {
7610
- throw new InternalServerError20(
8402
+ throw new InternalServerError22(
7611
8403
  `Error cancelling user invitation: ${error}`
7612
8404
  );
7613
8405
  }
@@ -7627,7 +8419,7 @@ function useVerificationService() {
7627
8419
  try {
7628
8420
  const user = await getUserByEmail(email);
7629
8421
  if (user) {
7630
- throw new BadRequestError38(
8422
+ throw new BadRequestError42(
7631
8423
  `Email ${email} is already registered, please login to continue.`
7632
8424
  );
7633
8425
  }
@@ -7654,7 +8446,7 @@ function useVerificationService() {
7654
8446
  html: emailContent,
7655
8447
  from: "GoWeekdays"
7656
8448
  }).catch((error) => {
7657
- logger19.log({
8449
+ logger21.log({
7658
8450
  level: "error",
7659
8451
  message: `Error sending user invite email: ${error}`
7660
8452
  });
@@ -7667,7 +8459,7 @@ function useVerificationService() {
7667
8459
  async function inviteMember(value) {
7668
8460
  const { error } = schemaInviteMember.validate(value);
7669
8461
  if (error) {
7670
- throw new BadRequestError38(error.message);
8462
+ throw new BadRequestError42(error.message);
7671
8463
  }
7672
8464
  const role = await getRoleById(value.role);
7673
8465
  if (!role) {
@@ -7712,7 +8504,7 @@ function useVerificationService() {
7712
8504
  html: emailContent2,
7713
8505
  from: "GoWeekdays"
7714
8506
  }).catch((error2) => {
7715
- logger19.log({
8507
+ logger21.log({
7716
8508
  level: "error",
7717
8509
  message: `Error sending user invite email: ${error2}`
7718
8510
  });
@@ -7734,24 +8526,24 @@ function useVerificationService() {
7734
8526
  html: emailContent,
7735
8527
  from: "GoWeekdays"
7736
8528
  }).catch((error2) => {
7737
- logger19.log({
8529
+ logger21.log({
7738
8530
  level: "error",
7739
8531
  message: `Error sending user invite email: ${error2}`
7740
8532
  });
7741
8533
  });
7742
8534
  return verificationId;
7743
8535
  } catch (error2) {
7744
- if (error2 instanceof AppError16) {
8536
+ if (error2 instanceof AppError18) {
7745
8537
  throw error2;
7746
8538
  } else {
7747
- throw new InternalServerError20("Failed to invite member.");
8539
+ throw new InternalServerError22("Failed to invite member.");
7748
8540
  }
7749
8541
  }
7750
8542
  }
7751
8543
  async function cancelInviteMember(id) {
7752
- const { error } = Joi29.string().hex().required().validate(id);
8544
+ const { error } = Joi35.string().hex().required().validate(id);
7753
8545
  if (error) {
7754
- throw new BadRequestError38("Invalid verification ID.");
8546
+ throw new BadRequestError42("Invalid verification ID.");
7755
8547
  }
7756
8548
  try {
7757
8549
  const invite = await _getById(id);
@@ -7759,25 +8551,25 @@ function useVerificationService() {
7759
8551
  throw new NotFoundError3("Invitation not found.");
7760
8552
  }
7761
8553
  if (invite.status === "cancelled") {
7762
- throw new BadRequestError38("Invitation already cancelled.");
8554
+ throw new BadRequestError42("Invitation already cancelled.");
7763
8555
  }
7764
8556
  if (invite.status === "complete") {
7765
- throw new BadRequestError38("Cannot cancel a completed invitation.");
8557
+ throw new BadRequestError42("Cannot cancel a completed invitation.");
7766
8558
  }
7767
8559
  await _updateStatusById(id, "cancelled");
7768
8560
  return "Successfully cancelled the invitation.";
7769
8561
  } catch (error2) {
7770
- if (error2 instanceof AppError16) {
8562
+ if (error2 instanceof AppError18) {
7771
8563
  throw error2;
7772
8564
  } else {
7773
- throw new InternalServerError20("Failed to cancel the invitation.");
8565
+ throw new InternalServerError22("Failed to cancel the invitation.");
7774
8566
  }
7775
8567
  }
7776
8568
  }
7777
8569
  async function forgetPassword(email) {
7778
- const { error } = Joi29.string().email().required().validate(email);
8570
+ const { error } = Joi35.string().email().required().validate(email);
7779
8571
  if (error) {
7780
- throw new BadRequestError38("Invalid email address.");
8572
+ throw new BadRequestError42("Invalid email address.");
7781
8573
  }
7782
8574
  try {
7783
8575
  const member = await getUserByEmail(email);
@@ -7806,20 +8598,76 @@ function useVerificationService() {
7806
8598
  from: "GoWeekdays",
7807
8599
  html: emailContent
7808
8600
  }).catch((error2) => {
7809
- logger19.log({
8601
+ logger21.log({
7810
8602
  level: "error",
7811
8603
  message: `Error sending forget password email: ${error2}`
7812
8604
  });
7813
8605
  });
7814
- return "Successfully created a link to reset password. Please check your email.";
7815
- } catch (error2) {
7816
- if (error2 instanceof AppError16) {
7817
- throw error2;
7818
- } else {
7819
- throw new InternalServerError20(
7820
- "Failed to process forget password request."
7821
- );
8606
+ return "Successfully created a link to reset password. Please check your email.";
8607
+ } catch (error2) {
8608
+ if (error2 instanceof AppError18) {
8609
+ throw error2;
8610
+ } else {
8611
+ throw new InternalServerError22(
8612
+ "Failed to process forget password request."
8613
+ );
8614
+ }
8615
+ }
8616
+ }
8617
+ const { addOrder: addPaypalOrder } = usePaypalService();
8618
+ const { getByEmail: getOrgByEmail, getByName: getOrgByName } = useOrgRepo();
8619
+ async function orgSetupFee(value) {
8620
+ const session = useAtlas19.getClient()?.startSession();
8621
+ if (!session) {
8622
+ throw new BadRequestError42("Unable to start database session.");
8623
+ }
8624
+ try {
8625
+ session.startTransaction();
8626
+ const orgExistingByName = await getOrgByName(value.name);
8627
+ if (orgExistingByName) {
8628
+ throw new BadRequestError42(`Name ${value.name} is already taken.`);
8629
+ }
8630
+ const orgExistingByEmail = await getOrgByEmail(value.email);
8631
+ if (orgExistingByEmail) {
8632
+ throw new BadRequestError42(`Email ${value.email} is already taken.`);
8633
+ }
8634
+ const amount = 100;
8635
+ const verificationId = await add(
8636
+ {
8637
+ type: "org-setup-fee",
8638
+ email: value.email,
8639
+ metadata: {
8640
+ seats: value.seats,
8641
+ contact: value.contact,
8642
+ orgName: value.name,
8643
+ createdBy: value.createdBy,
8644
+ amount
8645
+ }
8646
+ },
8647
+ session
8648
+ );
8649
+ const order = await addPaypalOrder({
8650
+ amount,
8651
+ currency: "PHP",
8652
+ customId: String(verificationId),
8653
+ returnUrl: `${APP_ORG}/organizations/success`,
8654
+ cancelUrl: `${APP_ORG}/organizations/cancel`,
8655
+ action: "pay"
8656
+ });
8657
+ await session?.commitTransaction();
8658
+ const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
8659
+ (link) => link.rel === "approve"
8660
+ );
8661
+ return {
8662
+ paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
8663
+ };
8664
+ } catch (error) {
8665
+ if (error instanceof AppError18) {
8666
+ throw error;
7822
8667
  }
8668
+ throw new InternalServerError22(
8669
+ "Failed to process organization setup fee."
8670
+ );
7823
8671
  }
7824
8672
  }
7825
8673
  return {
@@ -7833,7 +8681,8 @@ function useVerificationService() {
7833
8681
  signUp,
7834
8682
  inviteMember,
7835
8683
  cancelInviteMember,
7836
- forgetPassword
8684
+ forgetPassword,
8685
+ orgSetupFee
7837
8686
  };
7838
8687
  }
7839
8688
 
@@ -7843,13 +8692,13 @@ function useAuthController() {
7843
8692
  async function login(req, res, next) {
7844
8693
  const email = req.body.email;
7845
8694
  const password = req.body.password;
7846
- const validation = Joi30.object({
7847
- email: Joi30.string().email().required(),
7848
- password: Joi30.string().required()
8695
+ const validation = Joi36.object({
8696
+ email: Joi36.string().email().required(),
8697
+ password: Joi36.string().required()
7849
8698
  });
7850
8699
  const { error } = validation.validate({ email, password });
7851
8700
  if (error) {
7852
- next(new BadRequestError39(error.message));
8701
+ next(new BadRequestError43(error.message));
7853
8702
  return;
7854
8703
  }
7855
8704
  try {
@@ -7865,14 +8714,14 @@ function useAuthController() {
7865
8714
  res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json({ message: "Login successful" });
7866
8715
  return;
7867
8716
  } catch (error2) {
7868
- logger20.log({
8717
+ logger22.log({
7869
8718
  level: "error",
7870
8719
  message: `Error during login: ${error2.message}`
7871
8720
  });
7872
- if (error2 instanceof AppError17) {
8721
+ if (error2 instanceof AppError19) {
7873
8722
  next(error2);
7874
8723
  } else {
7875
- next(new InternalServerError21("An unexpected error occurred"));
8724
+ next(new InternalServerError23("An unexpected error occurred"));
7876
8725
  }
7877
8726
  return;
7878
8727
  }
@@ -7880,17 +8729,17 @@ function useAuthController() {
7880
8729
  async function logout(req, res, next) {
7881
8730
  const sid = req.headers["authorization"] ?? "";
7882
8731
  if (!sid) {
7883
- next(new BadRequestError39("Session ID is required"));
8732
+ next(new BadRequestError43("Session ID is required"));
7884
8733
  return;
7885
8734
  }
7886
8735
  try {
7887
8736
  await useAuthService().logout(sid);
7888
8737
  res.json({ message: "Logged out successfully" });
7889
8738
  } catch (error) {
7890
- if (error instanceof AppError17) {
8739
+ if (error instanceof AppError19) {
7891
8740
  next(error);
7892
8741
  } else {
7893
- next(new InternalServerError21("An unexpected error occurred"));
8742
+ next(new InternalServerError23("An unexpected error occurred"));
7894
8743
  }
7895
8744
  }
7896
8745
  }
@@ -7901,64 +8750,64 @@ function useAuthController() {
7901
8750
  }
7902
8751
 
7903
8752
  // src/resources/building/building.model.ts
7904
- import { BadRequestError as BadRequestError40, logger as logger21 } from "@goweekdays/utils";
7905
- import Joi31 from "joi";
7906
- import { ObjectId as ObjectId20 } from "mongodb";
7907
- var schemaBuilding = Joi31.object({
7908
- _id: Joi31.string().hex().optional(),
7909
- school: Joi31.string().hex().required(),
7910
- serial: Joi31.string().optional().allow("", null),
7911
- name: Joi31.string().required(),
7912
- levels: Joi31.number().integer().min(1).required(),
7913
- createdAt: Joi31.date().optional().allow("", null),
7914
- updatedAt: Joi31.date().optional().allow("", null),
7915
- deletedAt: Joi31.date().optional().allow("", null),
7916
- status: Joi31.string().optional().allow("", null)
8753
+ import { BadRequestError as BadRequestError44, logger as logger23 } from "@goweekdays/utils";
8754
+ import Joi37 from "joi";
8755
+ import { ObjectId as ObjectId22 } from "mongodb";
8756
+ var schemaBuilding = Joi37.object({
8757
+ _id: Joi37.string().hex().optional(),
8758
+ school: Joi37.string().hex().required(),
8759
+ serial: Joi37.string().optional().allow("", null),
8760
+ name: Joi37.string().required(),
8761
+ levels: Joi37.number().integer().min(1).required(),
8762
+ createdAt: Joi37.date().optional().allow("", null),
8763
+ updatedAt: Joi37.date().optional().allow("", null),
8764
+ deletedAt: Joi37.date().optional().allow("", null),
8765
+ status: Joi37.string().optional().allow("", null)
7917
8766
  });
7918
- var schemaBuildingUnit = Joi31.object({
7919
- _id: Joi31.string().hex().optional(),
7920
- school: Joi31.string().hex().required(),
7921
- name: Joi31.string().optional().allow("", null),
7922
- building: Joi31.string().hex().required(),
7923
- buildingName: Joi31.string().optional().allow("", null),
7924
- level: Joi31.number().integer().min(1).required(),
7925
- category: Joi31.string().required(),
7926
- type: Joi31.string().required(),
7927
- seating_capacity: Joi31.number().integer().min(0).required(),
7928
- standing_capacity: Joi31.number().integer().min(0).required(),
7929
- description: Joi31.string().optional().allow("", null),
7930
- unit_of_measurement: Joi31.string().valid("sqm").required(),
7931
- area: Joi31.number().positive().required(),
7932
- status: Joi31.string().optional().allow("", null)
8767
+ var schemaBuildingUnit = Joi37.object({
8768
+ _id: Joi37.string().hex().optional(),
8769
+ school: Joi37.string().hex().required(),
8770
+ name: Joi37.string().optional().allow("", null),
8771
+ building: Joi37.string().hex().required(),
8772
+ buildingName: Joi37.string().optional().allow("", null),
8773
+ level: Joi37.number().integer().min(1).required(),
8774
+ category: Joi37.string().required(),
8775
+ type: Joi37.string().required(),
8776
+ seating_capacity: Joi37.number().integer().min(0).required(),
8777
+ standing_capacity: Joi37.number().integer().min(0).required(),
8778
+ description: Joi37.string().optional().allow("", null),
8779
+ unit_of_measurement: Joi37.string().valid("sqm").required(),
8780
+ area: Joi37.number().positive().required(),
8781
+ status: Joi37.string().optional().allow("", null)
7933
8782
  });
7934
- var schemaUpdateOptions = Joi31.object({
7935
- name: Joi31.string().optional().allow("", null),
7936
- building: Joi31.string().hex().optional().allow("", null),
7937
- buildingName: Joi31.string().optional().allow("", null),
7938
- level: Joi31.number().integer().min(1).optional().allow("", null),
7939
- category: Joi31.string().optional().allow("", null),
7940
- type: Joi31.string().optional().allow("", null),
7941
- seating_capacity: Joi31.number().integer().min(0).optional().allow("", null),
7942
- standing_capacity: Joi31.number().integer().min(0).optional().allow("", null),
7943
- area: Joi31.number().positive().optional().allow("", null)
8783
+ var schemaUpdateOptions = Joi37.object({
8784
+ name: Joi37.string().optional().allow("", null),
8785
+ building: Joi37.string().hex().optional().allow("", null),
8786
+ buildingName: Joi37.string().optional().allow("", null),
8787
+ level: Joi37.number().integer().min(1).optional().allow("", null),
8788
+ category: Joi37.string().optional().allow("", null),
8789
+ type: Joi37.string().optional().allow("", null),
8790
+ seating_capacity: Joi37.number().integer().min(0).optional().allow("", null),
8791
+ standing_capacity: Joi37.number().integer().min(0).optional().allow("", null),
8792
+ area: Joi37.number().positive().optional().allow("", null)
7944
8793
  });
7945
8794
  function MBuilding(value) {
7946
8795
  const { error } = schemaBuilding.validate(value);
7947
8796
  if (error) {
7948
- logger21.info(`Building Model: ${error.message}`);
7949
- throw new BadRequestError40(error.message);
8797
+ logger23.info(`Building Model: ${error.message}`);
8798
+ throw new BadRequestError44(error.message);
7950
8799
  }
7951
8800
  if (value._id && typeof value._id === "string") {
7952
8801
  try {
7953
- value._id = new ObjectId20(value._id);
8802
+ value._id = new ObjectId22(value._id);
7954
8803
  } catch (error2) {
7955
- throw new BadRequestError40("Invalid _id format");
8804
+ throw new BadRequestError44("Invalid _id format");
7956
8805
  }
7957
8806
  }
7958
8807
  try {
7959
- value.school = new ObjectId20(value.school);
8808
+ value.school = new ObjectId22(value.school);
7960
8809
  } catch (error2) {
7961
- throw new BadRequestError40("Invalid school format");
8810
+ throw new BadRequestError44("Invalid school format");
7962
8811
  }
7963
8812
  return {
7964
8813
  _id: value._id ?? void 0,
@@ -7975,25 +8824,25 @@ function MBuilding(value) {
7975
8824
  function MBuildingUnit(value) {
7976
8825
  const { error } = schemaBuildingUnit.validate(value);
7977
8826
  if (error) {
7978
- logger21.info(`Building Unit Model: ${error.message}`);
7979
- throw new BadRequestError40(error.message);
8827
+ logger23.info(`Building Unit Model: ${error.message}`);
8828
+ throw new BadRequestError44(error.message);
7980
8829
  }
7981
8830
  if (value._id && typeof value._id === "string") {
7982
8831
  try {
7983
- value._id = new ObjectId20(value._id);
8832
+ value._id = new ObjectId22(value._id);
7984
8833
  } catch (error2) {
7985
- throw new BadRequestError40("Invalid ID");
8834
+ throw new BadRequestError44("Invalid ID");
7986
8835
  }
7987
8836
  }
7988
8837
  try {
7989
- value.school = new ObjectId20(value.school);
8838
+ value.school = new ObjectId22(value.school);
7990
8839
  } catch (error2) {
7991
- throw new BadRequestError40("Invalid school ID");
8840
+ throw new BadRequestError44("Invalid school ID");
7992
8841
  }
7993
8842
  try {
7994
- value.building = new ObjectId20(value.building);
8843
+ value.building = new ObjectId22(value.building);
7995
8844
  } catch (error2) {
7996
- throw new BadRequestError40("Invalid building ID");
8845
+ throw new BadRequestError44("Invalid building ID");
7997
8846
  }
7998
8847
  return {
7999
8848
  _id: value._id ?? void 0,
@@ -8018,24 +8867,24 @@ function MBuildingUnit(value) {
8018
8867
 
8019
8868
  // src/resources/building/building.repository.ts
8020
8869
  import {
8021
- AppError as AppError18,
8022
- BadRequestError as BadRequestError41,
8023
- InternalServerError as InternalServerError22,
8024
- logger as logger22,
8025
- makeCacheKey as makeCacheKey14,
8026
- paginate as paginate12,
8027
- useAtlas as useAtlas19,
8028
- useCache as useCache15
8870
+ AppError as AppError20,
8871
+ BadRequestError as BadRequestError45,
8872
+ InternalServerError as InternalServerError24,
8873
+ logger as logger24,
8874
+ makeCacheKey as makeCacheKey15,
8875
+ paginate as paginate13,
8876
+ useAtlas as useAtlas20,
8877
+ useCache as useCache16
8029
8878
  } from "@goweekdays/utils";
8030
- import { ObjectId as ObjectId21 } from "mongodb";
8879
+ import { ObjectId as ObjectId23 } from "mongodb";
8031
8880
  function useBuildingRepo() {
8032
- const db = useAtlas19.getDb();
8881
+ const db = useAtlas20.getDb();
8033
8882
  if (!db) {
8034
8883
  throw new Error("Unable to connect to server.");
8035
8884
  }
8036
8885
  const namespace_collection = "school.buildings";
8037
8886
  const collection = db.collection(namespace_collection);
8038
- const { getCache, setCache, delNamespace } = useCache15(namespace_collection);
8887
+ const { getCache, setCache, delNamespace } = useCache16(namespace_collection);
8039
8888
  async function createIndexes() {
8040
8889
  try {
8041
8890
  await collection.createIndexes([
@@ -8054,16 +8903,16 @@ function useBuildingRepo() {
8054
8903
  delCachedData();
8055
8904
  return res.insertedId;
8056
8905
  } catch (error) {
8057
- logger22.log({
8906
+ logger24.log({
8058
8907
  level: "error",
8059
8908
  message: error.message
8060
8909
  });
8061
- if (error instanceof AppError18) {
8910
+ if (error instanceof AppError20) {
8062
8911
  throw error;
8063
8912
  } else {
8064
8913
  const isDuplicated = error.message.includes("duplicate");
8065
8914
  if (isDuplicated) {
8066
- throw new BadRequestError41("Building already exists.");
8915
+ throw new BadRequestError45("Building already exists.");
8067
8916
  }
8068
8917
  throw new Error("Failed to create building.");
8069
8918
  }
@@ -8071,9 +8920,9 @@ function useBuildingRepo() {
8071
8920
  }
8072
8921
  async function updateById(_id, value, session) {
8073
8922
  try {
8074
- _id = new ObjectId21(_id);
8923
+ _id = new ObjectId23(_id);
8075
8924
  } catch (error) {
8076
- throw new BadRequestError41("Invalid ID.");
8925
+ throw new BadRequestError45("Invalid ID.");
8077
8926
  }
8078
8927
  try {
8079
8928
  const res = await collection.updateOne(
@@ -8084,11 +8933,11 @@ function useBuildingRepo() {
8084
8933
  delCachedData();
8085
8934
  return res;
8086
8935
  } catch (error) {
8087
- logger22.log({
8936
+ logger24.log({
8088
8937
  level: "error",
8089
8938
  message: error.message
8090
8939
  });
8091
- if (error instanceof AppError18) {
8940
+ if (error instanceof AppError20) {
8092
8941
  throw error;
8093
8942
  } else {
8094
8943
  throw new Error("Failed to update building.");
@@ -8113,9 +8962,9 @@ function useBuildingRepo() {
8113
8962
  }
8114
8963
  if (school) {
8115
8964
  try {
8116
- query.school = new ObjectId21(school);
8965
+ query.school = new ObjectId23(school);
8117
8966
  } catch (error) {
8118
- throw new BadRequestError41("Invalid school ID.");
8967
+ throw new BadRequestError45("Invalid school ID.");
8119
8968
  }
8120
8969
  }
8121
8970
  const cacheParams = {
@@ -8129,15 +8978,15 @@ function useBuildingRepo() {
8129
8978
  cacheParams.school = school;
8130
8979
  if (status !== "active")
8131
8980
  cacheParams.status = status;
8132
- const cacheKey = makeCacheKey14(namespace_collection, cacheParams);
8133
- logger22.log({
8981
+ const cacheKey = makeCacheKey15(namespace_collection, cacheParams);
8982
+ logger24.log({
8134
8983
  level: "info",
8135
8984
  message: `Cache key for getAll buildings: ${cacheKey}`
8136
8985
  });
8137
8986
  try {
8138
8987
  const cached = await getCache(cacheKey);
8139
8988
  if (cached) {
8140
- logger22.log({
8989
+ logger24.log({
8141
8990
  level: "info",
8142
8991
  message: `Cache hit for getAll buildings: ${cacheKey}`
8143
8992
  });
@@ -8150,35 +8999,35 @@ function useBuildingRepo() {
8150
8999
  { $limit: limit }
8151
9000
  ]).toArray();
8152
9001
  const length = await collection.countDocuments(query);
8153
- const data = paginate12(items, page, limit, length);
9002
+ const data = paginate13(items, page, limit, length);
8154
9003
  setCache(cacheKey, data, 600).then(() => {
8155
- logger22.log({
9004
+ logger24.log({
8156
9005
  level: "info",
8157
9006
  message: `Cache set for getAll buildings: ${cacheKey}`
8158
9007
  });
8159
9008
  }).catch((err) => {
8160
- logger22.log({
9009
+ logger24.log({
8161
9010
  level: "error",
8162
9011
  message: `Failed to set cache for getAll buildings: ${err.message}`
8163
9012
  });
8164
9013
  });
8165
9014
  return data;
8166
9015
  } catch (error) {
8167
- logger22.log({ level: "error", message: `${error}` });
9016
+ logger24.log({ level: "error", message: `${error}` });
8168
9017
  throw error;
8169
9018
  }
8170
9019
  }
8171
9020
  async function getById(_id) {
8172
9021
  try {
8173
- _id = new ObjectId21(_id);
9022
+ _id = new ObjectId23(_id);
8174
9023
  } catch (error) {
8175
- throw new BadRequestError41("Invalid ID.");
9024
+ throw new BadRequestError45("Invalid ID.");
8176
9025
  }
8177
- const cacheKey = makeCacheKey14(namespace_collection, { _id: String(_id) });
9026
+ const cacheKey = makeCacheKey15(namespace_collection, { _id: String(_id) });
8178
9027
  try {
8179
9028
  const cached = await getCache(cacheKey);
8180
9029
  if (cached) {
8181
- logger22.log({
9030
+ logger24.log({
8182
9031
  level: "info",
8183
9032
  message: `Cache hit for getById building: ${cacheKey}`
8184
9033
  });
@@ -8188,30 +9037,30 @@ function useBuildingRepo() {
8188
9037
  _id
8189
9038
  });
8190
9039
  setCache(cacheKey, result, 300).then(() => {
8191
- logger22.log({
9040
+ logger24.log({
8192
9041
  level: "info",
8193
9042
  message: `Cache set for building by id: ${cacheKey}`
8194
9043
  });
8195
9044
  }).catch((err) => {
8196
- logger22.log({
9045
+ logger24.log({
8197
9046
  level: "error",
8198
9047
  message: `Failed to set cache for building by id: ${err.message}`
8199
9048
  });
8200
9049
  });
8201
9050
  return result;
8202
9051
  } catch (error) {
8203
- if (error instanceof AppError18) {
9052
+ if (error instanceof AppError20) {
8204
9053
  throw error;
8205
9054
  } else {
8206
- throw new InternalServerError22("Failed to get building.");
9055
+ throw new InternalServerError24("Failed to get building.");
8207
9056
  }
8208
9057
  }
8209
9058
  }
8210
9059
  async function deleteById(_id, session) {
8211
9060
  try {
8212
- _id = new ObjectId21(_id);
9061
+ _id = new ObjectId23(_id);
8213
9062
  } catch (error) {
8214
- throw new BadRequestError41("Invalid ID.");
9063
+ throw new BadRequestError45("Invalid ID.");
8215
9064
  }
8216
9065
  try {
8217
9066
  const res = await collection.updateOne(
@@ -8221,25 +9070,25 @@ function useBuildingRepo() {
8221
9070
  delCachedData();
8222
9071
  return res;
8223
9072
  } catch (error) {
8224
- logger22.log({
9073
+ logger24.log({
8225
9074
  level: "error",
8226
9075
  message: error.message
8227
9076
  });
8228
- if (error instanceof AppError18) {
9077
+ if (error instanceof AppError20) {
8229
9078
  throw error;
8230
9079
  } else {
8231
- throw new InternalServerError22("Failed to delete building.");
9080
+ throw new InternalServerError24("Failed to delete building.");
8232
9081
  }
8233
9082
  }
8234
9083
  }
8235
9084
  function delCachedData() {
8236
9085
  delNamespace().then(() => {
8237
- logger22.log({
9086
+ logger24.log({
8238
9087
  level: "info",
8239
9088
  message: `Cache namespace cleared for ${namespace_collection}`
8240
9089
  });
8241
9090
  }).catch((err) => {
8242
- logger22.log({
9091
+ logger24.log({
8243
9092
  level: "error",
8244
9093
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
8245
9094
  });
@@ -8256,28 +9105,28 @@ function useBuildingRepo() {
8256
9105
  }
8257
9106
 
8258
9107
  // src/resources/building/building.service.ts
8259
- import { BadRequestError as BadRequestError43, NotFoundError as NotFoundError4, useAtlas as useAtlas21 } from "@goweekdays/utils";
9108
+ import { BadRequestError as BadRequestError47, NotFoundError as NotFoundError4, useAtlas as useAtlas22 } from "@goweekdays/utils";
8260
9109
 
8261
9110
  // src/resources/building/building-unit.repository.ts
8262
9111
  import {
8263
- AppError as AppError19,
8264
- BadRequestError as BadRequestError42,
8265
- InternalServerError as InternalServerError23,
8266
- logger as logger23,
8267
- makeCacheKey as makeCacheKey15,
8268
- paginate as paginate13,
8269
- useAtlas as useAtlas20,
8270
- useCache as useCache16
9112
+ AppError as AppError21,
9113
+ BadRequestError as BadRequestError46,
9114
+ InternalServerError as InternalServerError25,
9115
+ logger as logger25,
9116
+ makeCacheKey as makeCacheKey16,
9117
+ paginate as paginate14,
9118
+ useAtlas as useAtlas21,
9119
+ useCache as useCache17
8271
9120
  } from "@goweekdays/utils";
8272
- import { ObjectId as ObjectId22 } from "mongodb";
9121
+ import { ObjectId as ObjectId24 } from "mongodb";
8273
9122
  function useBuildingUnitRepo() {
8274
- const db = useAtlas20.getDb();
9123
+ const db = useAtlas21.getDb();
8275
9124
  if (!db) {
8276
9125
  throw new Error("Unable to connect to server.");
8277
9126
  }
8278
9127
  const namespace_collection = "school.building-units";
8279
9128
  const collection = db.collection(namespace_collection);
8280
- const { getCache, setCache, delNamespace } = useCache16(namespace_collection);
9129
+ const { getCache, setCache, delNamespace } = useCache17(namespace_collection);
8281
9130
  async function createIndexes() {
8282
9131
  try {
8283
9132
  await collection.createIndexes([
@@ -8305,12 +9154,12 @@ function useBuildingUnitRepo() {
8305
9154
  }
8306
9155
  function delCachedData() {
8307
9156
  delNamespace().then(() => {
8308
- logger23.log({
9157
+ logger25.log({
8309
9158
  level: "info",
8310
9159
  message: `Cache namespace cleared for ${namespace_collection}`
8311
9160
  });
8312
9161
  }).catch((err) => {
8313
- logger23.log({
9162
+ logger25.log({
8314
9163
  level: "error",
8315
9164
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
8316
9165
  });
@@ -8323,11 +9172,11 @@ function useBuildingUnitRepo() {
8323
9172
  delCachedData();
8324
9173
  return res.insertedId;
8325
9174
  } catch (error) {
8326
- logger23.log({
9175
+ logger25.log({
8327
9176
  level: "error",
8328
9177
  message: error.message
8329
9178
  });
8330
- if (error instanceof AppError19) {
9179
+ if (error instanceof AppError21) {
8331
9180
  throw error;
8332
9181
  } else {
8333
9182
  throw new Error("Failed to create building unit.");
@@ -8337,12 +9186,12 @@ function useBuildingUnitRepo() {
8337
9186
  async function updateById(_id, value, session) {
8338
9187
  const { error } = schemaUpdateOptions.validate(value);
8339
9188
  if (error) {
8340
- throw new BadRequestError42(error.message);
9189
+ throw new BadRequestError46(error.message);
8341
9190
  }
8342
9191
  try {
8343
- _id = new ObjectId22(_id);
9192
+ _id = new ObjectId24(_id);
8344
9193
  } catch (error2) {
8345
- throw new BadRequestError42("Invalid ID.");
9194
+ throw new BadRequestError46("Invalid ID.");
8346
9195
  }
8347
9196
  try {
8348
9197
  const res = await collection.updateOne(
@@ -8353,11 +9202,11 @@ function useBuildingUnitRepo() {
8353
9202
  delCachedData();
8354
9203
  return res;
8355
9204
  } catch (error2) {
8356
- logger23.log({
9205
+ logger25.log({
8357
9206
  level: "error",
8358
9207
  message: error2.message
8359
9208
  });
8360
- if (error2 instanceof AppError19) {
9209
+ if (error2 instanceof AppError21) {
8361
9210
  throw error2;
8362
9211
  } else {
8363
9212
  throw new Error("Failed to create building unit.");
@@ -8367,12 +9216,12 @@ function useBuildingUnitRepo() {
8367
9216
  async function updateByBuildingId(building, value, session) {
8368
9217
  const { error } = schemaUpdateOptions.validate(value);
8369
9218
  if (error) {
8370
- throw new BadRequestError42(error.message);
9219
+ throw new BadRequestError46(error.message);
8371
9220
  }
8372
9221
  try {
8373
- building = new ObjectId22(building);
9222
+ building = new ObjectId24(building);
8374
9223
  } catch (error2) {
8375
- throw new BadRequestError42("Invalid building ID.");
9224
+ throw new BadRequestError46("Invalid building ID.");
8376
9225
  }
8377
9226
  try {
8378
9227
  const res = await collection.updateMany(
@@ -8383,11 +9232,11 @@ function useBuildingUnitRepo() {
8383
9232
  delCachedData();
8384
9233
  return res;
8385
9234
  } catch (error2) {
8386
- logger23.log({
9235
+ logger25.log({
8387
9236
  level: "error",
8388
9237
  message: error2.message
8389
9238
  });
8390
- if (error2 instanceof AppError19) {
9239
+ if (error2 instanceof AppError21) {
8391
9240
  throw error2;
8392
9241
  } else {
8393
9242
  throw new Error("Failed to update building unit.");
@@ -8414,16 +9263,16 @@ function useBuildingUnitRepo() {
8414
9263
  }
8415
9264
  if (school) {
8416
9265
  try {
8417
- query.school = new ObjectId22(school);
9266
+ query.school = new ObjectId24(school);
8418
9267
  } catch (error) {
8419
- throw new BadRequestError42("Invalid school ID.");
9268
+ throw new BadRequestError46("Invalid school ID.");
8420
9269
  }
8421
9270
  }
8422
9271
  if (building) {
8423
9272
  try {
8424
- query.building = new ObjectId22(building);
9273
+ query.building = new ObjectId24(building);
8425
9274
  } catch (error) {
8426
- throw new BadRequestError42("Invalid building ID.");
9275
+ throw new BadRequestError46("Invalid building ID.");
8427
9276
  }
8428
9277
  }
8429
9278
  const cacheParams = {
@@ -8439,15 +9288,15 @@ function useBuildingUnitRepo() {
8439
9288
  cacheParams.building = building;
8440
9289
  if (status !== "active")
8441
9290
  cacheParams.status = status;
8442
- const cacheKey = makeCacheKey15(namespace_collection, cacheParams);
8443
- logger23.log({
9291
+ const cacheKey = makeCacheKey16(namespace_collection, cacheParams);
9292
+ logger25.log({
8444
9293
  level: "info",
8445
9294
  message: `Cache key for getAll building units: ${cacheKey}`
8446
9295
  });
8447
9296
  try {
8448
9297
  const cached = await getCache(cacheKey);
8449
9298
  if (cached) {
8450
- logger23.log({
9299
+ logger25.log({
8451
9300
  level: "info",
8452
9301
  message: `Cache hit for getAll building units: ${cacheKey}`
8453
9302
  });
@@ -8460,35 +9309,35 @@ function useBuildingUnitRepo() {
8460
9309
  { $limit: limit }
8461
9310
  ]).toArray();
8462
9311
  const length = await collection.countDocuments(query);
8463
- const data = paginate13(items, page, limit, length);
9312
+ const data = paginate14(items, page, limit, length);
8464
9313
  setCache(cacheKey, data, 600).then(() => {
8465
- logger23.log({
9314
+ logger25.log({
8466
9315
  level: "info",
8467
9316
  message: `Cache set for getAll building units: ${cacheKey}`
8468
9317
  });
8469
9318
  }).catch((err) => {
8470
- logger23.log({
9319
+ logger25.log({
8471
9320
  level: "error",
8472
9321
  message: `Failed to set cache for getAll building units: ${err.message}`
8473
9322
  });
8474
9323
  });
8475
9324
  return data;
8476
9325
  } catch (error) {
8477
- logger23.log({ level: "error", message: `${error}` });
9326
+ logger25.log({ level: "error", message: `${error}` });
8478
9327
  throw error;
8479
9328
  }
8480
9329
  }
8481
9330
  async function getById(_id) {
8482
9331
  try {
8483
- _id = new ObjectId22(_id);
9332
+ _id = new ObjectId24(_id);
8484
9333
  } catch (error) {
8485
- throw new BadRequestError42("Invalid ID.");
9334
+ throw new BadRequestError46("Invalid ID.");
8486
9335
  }
8487
- const cacheKey = makeCacheKey15(namespace_collection, { _id: String(_id) });
9336
+ const cacheKey = makeCacheKey16(namespace_collection, { _id: String(_id) });
8488
9337
  try {
8489
9338
  const cached = await getCache(cacheKey);
8490
9339
  if (cached) {
8491
- logger23.log({
9340
+ logger25.log({
8492
9341
  level: "info",
8493
9342
  message: `Cache hit for getById building unit: ${cacheKey}`
8494
9343
  });
@@ -8499,42 +9348,42 @@ function useBuildingUnitRepo() {
8499
9348
  deletedAt: { $in: ["", null] }
8500
9349
  });
8501
9350
  if (!result) {
8502
- throw new BadRequestError42("Building unit not found.");
9351
+ throw new BadRequestError46("Building unit not found.");
8503
9352
  }
8504
9353
  setCache(cacheKey, result, 300).then(() => {
8505
- logger23.log({
9354
+ logger25.log({
8506
9355
  level: "info",
8507
9356
  message: `Cache set for building unit by id: ${cacheKey}`
8508
9357
  });
8509
9358
  }).catch((err) => {
8510
- logger23.log({
9359
+ logger25.log({
8511
9360
  level: "error",
8512
9361
  message: `Failed to set cache for building unit by id: ${err.message}`
8513
9362
  });
8514
9363
  });
8515
9364
  return result;
8516
9365
  } catch (error) {
8517
- if (error instanceof AppError19) {
9366
+ if (error instanceof AppError21) {
8518
9367
  throw error;
8519
9368
  } else {
8520
- throw new InternalServerError23("Failed to get building unit.");
9369
+ throw new InternalServerError25("Failed to get building unit.");
8521
9370
  }
8522
9371
  }
8523
9372
  }
8524
9373
  async function getByBuildingLevel(building, level) {
8525
9374
  try {
8526
- building = new ObjectId22(building);
9375
+ building = new ObjectId24(building);
8527
9376
  } catch (error) {
8528
- throw new BadRequestError42("Invalid building ID.");
9377
+ throw new BadRequestError46("Invalid building ID.");
8529
9378
  }
8530
- const cacheKey = makeCacheKey15(namespace_collection, {
9379
+ const cacheKey = makeCacheKey16(namespace_collection, {
8531
9380
  building: String(building),
8532
9381
  level
8533
9382
  });
8534
9383
  try {
8535
9384
  const cached = await getCache(cacheKey);
8536
9385
  if (cached) {
8537
- logger23.log({
9386
+ logger25.log({
8538
9387
  level: "info",
8539
9388
  message: `Cache hit for getById building unit: ${cacheKey}`
8540
9389
  });
@@ -8546,38 +9395,38 @@ function useBuildingUnitRepo() {
8546
9395
  status: "active"
8547
9396
  });
8548
9397
  setCache(cacheKey, result, 300).then(() => {
8549
- logger23.log({
9398
+ logger25.log({
8550
9399
  level: "info",
8551
9400
  message: `Cache set for building unit by id: ${cacheKey}`
8552
9401
  });
8553
9402
  }).catch((err) => {
8554
- logger23.log({
9403
+ logger25.log({
8555
9404
  level: "error",
8556
9405
  message: `Failed to set cache for building unit by id: ${err.message}`
8557
9406
  });
8558
9407
  });
8559
9408
  return result;
8560
9409
  } catch (error) {
8561
- if (error instanceof AppError19) {
9410
+ if (error instanceof AppError21) {
8562
9411
  throw error;
8563
9412
  } else {
8564
- throw new InternalServerError23("Failed to get building unit.");
9413
+ throw new InternalServerError25("Failed to get building unit.");
8565
9414
  }
8566
9415
  }
8567
9416
  }
8568
9417
  async function getByBuilding(building) {
8569
9418
  try {
8570
- building = new ObjectId22(building);
9419
+ building = new ObjectId24(building);
8571
9420
  } catch (error) {
8572
- throw new BadRequestError42("Invalid building ID.");
9421
+ throw new BadRequestError46("Invalid building ID.");
8573
9422
  }
8574
- const cacheKey = makeCacheKey15(namespace_collection, {
9423
+ const cacheKey = makeCacheKey16(namespace_collection, {
8575
9424
  building: String(building)
8576
9425
  });
8577
9426
  try {
8578
9427
  const cached = await getCache(cacheKey);
8579
9428
  if (cached) {
8580
- logger23.log({
9429
+ logger25.log({
8581
9430
  level: "info",
8582
9431
  message: `Cache hit for getById building unit: ${cacheKey}`
8583
9432
  });
@@ -8588,30 +9437,30 @@ function useBuildingUnitRepo() {
8588
9437
  status: "active"
8589
9438
  });
8590
9439
  setCache(cacheKey, result, 300).then(() => {
8591
- logger23.log({
9440
+ logger25.log({
8592
9441
  level: "info",
8593
9442
  message: `Cache set for building unit by id: ${cacheKey}`
8594
9443
  });
8595
9444
  }).catch((err) => {
8596
- logger23.log({
9445
+ logger25.log({
8597
9446
  level: "error",
8598
9447
  message: `Failed to set cache for building unit by id: ${err.message}`
8599
9448
  });
8600
9449
  });
8601
9450
  return result;
8602
9451
  } catch (error) {
8603
- if (error instanceof AppError19) {
9452
+ if (error instanceof AppError21) {
8604
9453
  throw error;
8605
9454
  } else {
8606
- throw new InternalServerError23("Failed to get building unit.");
9455
+ throw new InternalServerError25("Failed to get building unit.");
8607
9456
  }
8608
9457
  }
8609
9458
  }
8610
9459
  async function deleteById(_id, session) {
8611
9460
  try {
8612
- _id = new ObjectId22(_id);
9461
+ _id = new ObjectId24(_id);
8613
9462
  } catch (error) {
8614
- throw new BadRequestError42("Invalid ID.");
9463
+ throw new BadRequestError46("Invalid ID.");
8615
9464
  }
8616
9465
  try {
8617
9466
  const res = await collection.updateOne(
@@ -8622,11 +9471,11 @@ function useBuildingUnitRepo() {
8622
9471
  delCachedData();
8623
9472
  return "Room/Facility deleted successfully.";
8624
9473
  } catch (error) {
8625
- logger23.log({
9474
+ logger25.log({
8626
9475
  level: "error",
8627
9476
  message: error.message
8628
9477
  });
8629
- if (error instanceof AppError19) {
9478
+ if (error instanceof AppError21) {
8630
9479
  throw error;
8631
9480
  } else {
8632
9481
  throw new Error("Failed to deleted room/facility.");
@@ -8656,7 +9505,7 @@ function useBuildingService() {
8656
9505
  const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
8657
9506
  async function updateById(id, data) {
8658
9507
  data.levels = Number(data.levels);
8659
- const session = useAtlas21.getClient()?.startSession();
9508
+ const session = useAtlas22.getClient()?.startSession();
8660
9509
  try {
8661
9510
  const building = await _getById(id);
8662
9511
  if (!building) {
@@ -8665,7 +9514,7 @@ function useBuildingService() {
8665
9514
  if (data.levels < building.levels) {
8666
9515
  const unit = await getByBuildingLevel(id, building.levels);
8667
9516
  if (unit) {
8668
- throw new BadRequestError43(
9517
+ throw new BadRequestError47(
8669
9518
  "Cannot reduce floors, there are existing building units at higher floors."
8670
9519
  );
8671
9520
  }
@@ -8687,7 +9536,7 @@ function useBuildingService() {
8687
9536
  async function deleteById(id) {
8688
9537
  const building = await getByBuilding(id);
8689
9538
  if (building) {
8690
- throw new BadRequestError43(
9539
+ throw new BadRequestError47(
8691
9540
  "Cannot delete building with existing room/facility. Please delete room/facility first."
8692
9541
  );
8693
9542
  }
@@ -8705,24 +9554,24 @@ function useBuildingService() {
8705
9554
  }
8706
9555
 
8707
9556
  // src/resources/building/building.controller.ts
8708
- import { BadRequestError as BadRequestError44, logger as logger24 } from "@goweekdays/utils";
8709
- import Joi32 from "joi";
9557
+ import { BadRequestError as BadRequestError48, logger as logger26 } from "@goweekdays/utils";
9558
+ import Joi38 from "joi";
8710
9559
  function useBuildingController() {
8711
9560
  const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
8712
9561
  const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
8713
9562
  async function createBuilding(req, res, next) {
8714
9563
  const value = req.body;
8715
- const validation = Joi32.object({
8716
- name: Joi32.string().required(),
8717
- school: Joi32.string().hex().required(),
8718
- levels: Joi32.number().integer().min(1).required(),
8719
- serial: Joi32.string().optional().allow("", null),
8720
- status: Joi32.string().optional().allow("", null)
9564
+ const validation = Joi38.object({
9565
+ name: Joi38.string().required(),
9566
+ school: Joi38.string().hex().required(),
9567
+ levels: Joi38.number().integer().min(1).required(),
9568
+ serial: Joi38.string().optional().allow("", null),
9569
+ status: Joi38.string().optional().allow("", null)
8721
9570
  });
8722
9571
  const { error } = validation.validate(value);
8723
9572
  if (error) {
8724
- next(new BadRequestError44(error.message));
8725
- logger24.info(`Controller: ${error.message}`);
9573
+ next(new BadRequestError48(error.message));
9574
+ logger26.info(`Controller: ${error.message}`);
8726
9575
  return;
8727
9576
  }
8728
9577
  try {
@@ -8736,18 +9585,18 @@ function useBuildingController() {
8736
9585
  async function updateById(req, res, next) {
8737
9586
  const value = req.body;
8738
9587
  const id = req.params.id ?? "";
8739
- const validation = Joi32.object({
8740
- id: Joi32.string().hex().required(),
8741
- value: Joi32.object({
8742
- name: Joi32.string().required(),
8743
- serial: Joi32.string().optional().allow("", null),
8744
- levels: Joi32.number().integer().min(1).required()
9588
+ const validation = Joi38.object({
9589
+ id: Joi38.string().hex().required(),
9590
+ value: Joi38.object({
9591
+ name: Joi38.string().required(),
9592
+ serial: Joi38.string().optional().allow("", null),
9593
+ levels: Joi38.number().integer().min(1).required()
8745
9594
  })
8746
9595
  });
8747
9596
  const { error } = validation.validate({ id, value });
8748
9597
  if (error) {
8749
- next(new BadRequestError44(error.message));
8750
- logger24.info(`Controller: ${error.message}`);
9598
+ next(new BadRequestError48(error.message));
9599
+ logger26.info(`Controller: ${error.message}`);
8751
9600
  return;
8752
9601
  }
8753
9602
  try {
@@ -8760,16 +9609,16 @@ function useBuildingController() {
8760
9609
  }
8761
9610
  async function getAll(req, res, next) {
8762
9611
  const query = req.query;
8763
- const validation = Joi32.object({
8764
- page: Joi32.number().min(1).optional().allow("", null),
8765
- limit: Joi32.number().min(1).optional().allow("", null),
8766
- search: Joi32.string().optional().allow("", null),
8767
- school: Joi32.string().hex().optional().allow("", null),
8768
- status: Joi32.string().optional().allow("", null)
9612
+ const validation = Joi38.object({
9613
+ page: Joi38.number().min(1).optional().allow("", null),
9614
+ limit: Joi38.number().min(1).optional().allow("", null),
9615
+ search: Joi38.string().optional().allow("", null),
9616
+ school: Joi38.string().hex().optional().allow("", null),
9617
+ status: Joi38.string().optional().allow("", null)
8769
9618
  });
8770
9619
  const { error } = validation.validate(query);
8771
9620
  if (error) {
8772
- next(new BadRequestError44(error.message));
9621
+ next(new BadRequestError48(error.message));
8773
9622
  return;
8774
9623
  }
8775
9624
  const page = parseInt(req.query.page) ?? 1;
@@ -8803,12 +9652,12 @@ function useBuildingController() {
8803
9652
  }
8804
9653
  async function getById(req, res, next) {
8805
9654
  const id = req.params.id;
8806
- const validation = Joi32.object({
8807
- id: Joi32.string().hex().required()
9655
+ const validation = Joi38.object({
9656
+ id: Joi38.string().hex().required()
8808
9657
  });
8809
9658
  const { error } = validation.validate({ id });
8810
9659
  if (error) {
8811
- next(new BadRequestError44(error.message));
9660
+ next(new BadRequestError48(error.message));
8812
9661
  return;
8813
9662
  }
8814
9663
  try {
@@ -8824,12 +9673,12 @@ function useBuildingController() {
8824
9673
  }
8825
9674
  async function deleteById(req, res, next) {
8826
9675
  const id = req.params.id;
8827
- const validation = Joi32.object({
8828
- id: Joi32.string().hex().required()
9676
+ const validation = Joi38.object({
9677
+ id: Joi38.string().hex().required()
8829
9678
  });
8830
9679
  const { error } = validation.validate({ id });
8831
9680
  if (error) {
8832
- next(new BadRequestError44(error.message));
9681
+ next(new BadRequestError48(error.message));
8833
9682
  return;
8834
9683
  }
8835
9684
  try {
@@ -8850,11 +9699,11 @@ function useBuildingController() {
8850
9699
  }
8851
9700
 
8852
9701
  // src/resources/building/building-unit.service.ts
8853
- import { useAtlas as useAtlas22 } from "@goweekdays/utils";
9702
+ import { useAtlas as useAtlas23 } from "@goweekdays/utils";
8854
9703
  function useBuildingUnitService() {
8855
9704
  const { add: _add } = useBuildingUnitRepo();
8856
9705
  async function add(value) {
8857
- const session = useAtlas22.getClient()?.startSession();
9706
+ const session = useAtlas23.getClient()?.startSession();
8858
9707
  if (!session) {
8859
9708
  throw new Error("Unable to start session for building unit service.");
8860
9709
  }
@@ -8881,8 +9730,8 @@ function useBuildingUnitService() {
8881
9730
  }
8882
9731
 
8883
9732
  // src/resources/building/building-unit.controller.ts
8884
- import { BadRequestError as BadRequestError45 } from "@goweekdays/utils";
8885
- import Joi33 from "joi";
9733
+ import { BadRequestError as BadRequestError49 } from "@goweekdays/utils";
9734
+ import Joi39 from "joi";
8886
9735
  function useBuildingUnitController() {
8887
9736
  const {
8888
9737
  getAll: _getAll,
@@ -8893,27 +9742,27 @@ function useBuildingUnitController() {
8893
9742
  const { add: _add } = useBuildingUnitService();
8894
9743
  async function add(req, res, next) {
8895
9744
  const data = req.body;
8896
- const validation = Joi33.object({
8897
- building: Joi33.object({
8898
- school: Joi33.string().hex().required(),
8899
- name: Joi33.string().optional().allow("", null),
8900
- building: Joi33.string().hex().required(),
8901
- buildingName: Joi33.string().optional().allow("", null),
8902
- level: Joi33.number().integer().min(1).required(),
8903
- category: Joi33.string().required(),
8904
- type: Joi33.string().required(),
8905
- seating_capacity: Joi33.number().integer().min(0).required(),
8906
- standing_capacity: Joi33.number().integer().min(0).required(),
8907
- description: Joi33.string().optional().allow("", null),
8908
- unit_of_measurement: Joi33.string().valid("sqm").required(),
8909
- area: Joi33.number().positive().required(),
8910
- status: Joi33.string().optional().allow("", null)
9745
+ const validation = Joi39.object({
9746
+ building: Joi39.object({
9747
+ school: Joi39.string().hex().required(),
9748
+ name: Joi39.string().optional().allow("", null),
9749
+ building: Joi39.string().hex().required(),
9750
+ buildingName: Joi39.string().optional().allow("", null),
9751
+ level: Joi39.number().integer().min(1).required(),
9752
+ category: Joi39.string().required(),
9753
+ type: Joi39.string().required(),
9754
+ seating_capacity: Joi39.number().integer().min(0).required(),
9755
+ standing_capacity: Joi39.number().integer().min(0).required(),
9756
+ description: Joi39.string().optional().allow("", null),
9757
+ unit_of_measurement: Joi39.string().valid("sqm").required(),
9758
+ area: Joi39.number().positive().required(),
9759
+ status: Joi39.string().optional().allow("", null)
8911
9760
  }),
8912
- qty: Joi33.number().integer().min(1).max(20).optional().default(1)
9761
+ qty: Joi39.number().integer().min(1).max(20).optional().default(1)
8913
9762
  });
8914
9763
  const { error } = validation.validate(data);
8915
9764
  if (error) {
8916
- next(new BadRequestError45(error.message));
9765
+ next(new BadRequestError49(error.message));
8917
9766
  return;
8918
9767
  }
8919
9768
  try {
@@ -8929,13 +9778,13 @@ function useBuildingUnitController() {
8929
9778
  async function updateById(req, res, next) {
8930
9779
  const data = req.body;
8931
9780
  const id = req.params.id ?? "";
8932
- const validation = Joi33.object({
8933
- id: Joi33.string().hex().required(),
9781
+ const validation = Joi39.object({
9782
+ id: Joi39.string().hex().required(),
8934
9783
  value: schemaUpdateOptions
8935
9784
  });
8936
9785
  const { error } = validation.validate({ id, value: data });
8937
9786
  if (error) {
8938
- next(new BadRequestError45(error.message));
9787
+ next(new BadRequestError49(error.message));
8939
9788
  return;
8940
9789
  }
8941
9790
  try {
@@ -8950,17 +9799,17 @@ function useBuildingUnitController() {
8950
9799
  }
8951
9800
  async function getAll(req, res, next) {
8952
9801
  const query = req.query;
8953
- const validation = Joi33.object({
8954
- page: Joi33.number().min(1).optional().allow("", null),
8955
- limit: Joi33.number().min(1).optional().allow("", null),
8956
- search: Joi33.string().optional().allow("", null),
8957
- school: Joi33.string().hex().optional().allow("", null),
8958
- building: Joi33.string().hex().optional().allow("", null),
8959
- status: Joi33.string().optional().allow("", null)
9802
+ const validation = Joi39.object({
9803
+ page: Joi39.number().min(1).optional().allow("", null),
9804
+ limit: Joi39.number().min(1).optional().allow("", null),
9805
+ search: Joi39.string().optional().allow("", null),
9806
+ school: Joi39.string().hex().optional().allow("", null),
9807
+ building: Joi39.string().hex().optional().allow("", null),
9808
+ status: Joi39.string().optional().allow("", null)
8960
9809
  });
8961
9810
  const { error } = validation.validate(query);
8962
9811
  if (error) {
8963
- next(new BadRequestError45(error.message));
9812
+ next(new BadRequestError49(error.message));
8964
9813
  return;
8965
9814
  }
8966
9815
  const page = parseInt(req.query.page) ?? 1;
@@ -8996,12 +9845,12 @@ function useBuildingUnitController() {
8996
9845
  }
8997
9846
  async function getById(req, res, next) {
8998
9847
  const id = req.params.id;
8999
- const validation = Joi33.object({
9000
- id: Joi33.string().hex().required()
9848
+ const validation = Joi39.object({
9849
+ id: Joi39.string().hex().required()
9001
9850
  });
9002
9851
  const { error } = validation.validate({ id });
9003
9852
  if (error) {
9004
- next(new BadRequestError45(error.message));
9853
+ next(new BadRequestError49(error.message));
9005
9854
  return;
9006
9855
  }
9007
9856
  try {
@@ -9017,12 +9866,12 @@ function useBuildingUnitController() {
9017
9866
  }
9018
9867
  async function deleteById(req, res, next) {
9019
9868
  const id = req.params.id;
9020
- const validation = Joi33.object({
9021
- id: Joi33.string().hex().required()
9869
+ const validation = Joi39.object({
9870
+ id: Joi39.string().hex().required()
9022
9871
  });
9023
9872
  const { error } = validation.validate({ id });
9024
9873
  if (error) {
9025
- next(new BadRequestError45(error.message));
9874
+ next(new BadRequestError49(error.message));
9026
9875
  return;
9027
9876
  }
9028
9877
  try {
@@ -9043,14 +9892,14 @@ function useBuildingUnitController() {
9043
9892
  }
9044
9893
 
9045
9894
  // src/resources/counter/counter.model.ts
9046
- import { BadRequestError as BadRequestError46 } from "@goweekdays/utils";
9047
- import { ObjectId as ObjectId23 } from "mongodb";
9895
+ import { BadRequestError as BadRequestError50 } from "@goweekdays/utils";
9896
+ import { ObjectId as ObjectId25 } from "mongodb";
9048
9897
  import { z } from "zod";
9049
9898
  var TCounter = z.object({
9050
9899
  _id: z.union([
9051
9900
  z.string().length(24, "Invalid ObjectId hex string"),
9052
- z.instanceof(ObjectId23)
9053
- ]).transform((val) => typeof val === "string" ? new ObjectId23(val) : val).optional(),
9901
+ z.instanceof(ObjectId25)
9902
+ ]).transform((val) => typeof val === "string" ? new ObjectId25(val) : val).optional(),
9054
9903
  count: z.number().int().min(0).default(0),
9055
9904
  type: z.string(),
9056
9905
  createdAt: z.date().optional().default(() => /* @__PURE__ */ new Date()),
@@ -9063,7 +9912,7 @@ function useCounterModel(db) {
9063
9912
  try {
9064
9913
  return TCounter.parse(value);
9065
9914
  } catch (error) {
9066
- throw new BadRequestError46(error.issues[0].message);
9915
+ throw new BadRequestError50(error.issues[0].message);
9067
9916
  }
9068
9917
  }
9069
9918
  function validateCounter(data) {
@@ -9077,23 +9926,23 @@ function useCounterModel(db) {
9077
9926
  }
9078
9927
 
9079
9928
  // src/resources/counter/counter.repository.ts
9080
- import { useAtlas as useAtlas23, useCache as useCache17, makeCacheKey as makeCacheKey16, logger as logger25 } from "@goweekdays/utils";
9929
+ import { useAtlas as useAtlas24, useCache as useCache18, makeCacheKey as makeCacheKey17, logger as logger27 } from "@goweekdays/utils";
9081
9930
  function useCounterRepo() {
9082
- const db = useAtlas23.getDb();
9931
+ const db = useAtlas24.getDb();
9083
9932
  if (!db) {
9084
9933
  throw new Error("Unable to connect to server.");
9085
9934
  }
9086
9935
  const namespace_collection = "counters";
9087
9936
  const { collection, createCounter } = useCounterModel(db);
9088
- const { getCache, setCache, delNamespace } = useCache17(namespace_collection);
9937
+ const { getCache, setCache, delNamespace } = useCache18(namespace_collection);
9089
9938
  function delCachedData() {
9090
9939
  delNamespace().then(() => {
9091
- logger25.log({
9940
+ logger27.log({
9092
9941
  level: "info",
9093
9942
  message: `Cache namespace cleared for ${namespace_collection}`
9094
9943
  });
9095
9944
  }).catch((err) => {
9096
- logger25.log({
9945
+ logger27.log({
9097
9946
  level: "error",
9098
9947
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
9099
9948
  });
@@ -9137,11 +9986,11 @@ function useCounterRepo() {
9137
9986
  }
9138
9987
  }
9139
9988
  async function getByType(type) {
9140
- const cacheKey = makeCacheKey16(namespace_collection, { type });
9989
+ const cacheKey = makeCacheKey17(namespace_collection, { type });
9141
9990
  try {
9142
9991
  const cached = await getCache(cacheKey);
9143
9992
  if (cached) {
9144
- logger25.log({
9993
+ logger27.log({
9145
9994
  level: "info",
9146
9995
  message: `Cache hit for getByType counter: ${cacheKey}`
9147
9996
  });
@@ -9150,12 +9999,12 @@ function useCounterRepo() {
9150
9999
  const data = await collection.findOne({ type });
9151
10000
  if (data) {
9152
10001
  setCache(cacheKey, data, 300).then(() => {
9153
- logger25.log({
10002
+ logger27.log({
9154
10003
  level: "info",
9155
10004
  message: `Cache set for counter by type: ${cacheKey}`
9156
10005
  });
9157
10006
  }).catch((err) => {
9158
- logger25.log({
10007
+ logger27.log({
9159
10008
  level: "error",
9160
10009
  message: `Failed to set cache for counter by type: ${err.message}`
9161
10010
  });
@@ -9175,7 +10024,7 @@ function useCounterRepo() {
9175
10024
  }
9176
10025
 
9177
10026
  // src/resources/file/file.service.ts
9178
- import { logger as logger26, useS3 as useS32, useAtlas as useAtlas24 } from "@goweekdays/utils";
10027
+ import { logger as logger28, useS3 as useS32, useAtlas as useAtlas25 } from "@goweekdays/utils";
9179
10028
  import cron from "node-cron";
9180
10029
  import * as fs from "fs";
9181
10030
  function useFileService() {
@@ -9193,7 +10042,7 @@ function useFileService() {
9193
10042
  forcePathStyle: true
9194
10043
  });
9195
10044
  async function createFile(value) {
9196
- const session = useAtlas24.getClient()?.startSession();
10045
+ const session = useAtlas25.getClient()?.startSession();
9197
10046
  session?.startTransaction();
9198
10047
  const file = {
9199
10048
  name: value.originalname,
@@ -9227,7 +10076,7 @@ function useFileService() {
9227
10076
  }
9228
10077
  }
9229
10078
  async function deleteFile(id) {
9230
- const session = useAtlas24.getClient()?.startSession();
10079
+ const session = useAtlas25.getClient()?.startSession();
9231
10080
  session?.startTransaction();
9232
10081
  try {
9233
10082
  await deleteFileById(id, session);
@@ -9248,12 +10097,12 @@ function useFileService() {
9248
10097
  const file = files[index];
9249
10098
  try {
9250
10099
  await deleteFile(file._id.toString());
9251
- await logger26.log({
10100
+ await logger28.log({
9252
10101
  level: "info",
9253
10102
  message: "Successfully deleted draft files."
9254
10103
  });
9255
10104
  } catch (error) {
9256
- logger26.log({
10105
+ logger28.log({
9257
10106
  level: "info",
9258
10107
  message: "Successfully deleted draft files."
9259
10108
  });
@@ -9271,11 +10120,11 @@ function useFileService() {
9271
10120
 
9272
10121
  // src/resources/file/file.controller.ts
9273
10122
  import {
9274
- AppError as AppError20,
9275
- BadRequestError as BadRequestError47,
9276
- InternalServerError as InternalServerError24
10123
+ AppError as AppError22,
10124
+ BadRequestError as BadRequestError51,
10125
+ InternalServerError as InternalServerError26
9277
10126
  } from "@goweekdays/utils";
9278
- import Joi34 from "joi";
10127
+ import Joi40 from "joi";
9279
10128
  function useFileController() {
9280
10129
  const { createFile, deleteFile: _deleteFile } = useFileService();
9281
10130
  async function upload(req, res, next) {
@@ -9288,29 +10137,29 @@ function useFileController() {
9288
10137
  res.json({ message: "Successfully uploaded file", id });
9289
10138
  return;
9290
10139
  } catch (error) {
9291
- if (error instanceof AppError20) {
10140
+ if (error instanceof AppError22) {
9292
10141
  next(error);
9293
10142
  } else {
9294
- next(new InternalServerError24(error));
10143
+ next(new InternalServerError26(error));
9295
10144
  }
9296
10145
  }
9297
10146
  }
9298
10147
  async function deleteFile(req, res, next) {
9299
10148
  const id = req.params.id;
9300
- const validation = Joi34.string().required();
10149
+ const validation = Joi40.string().required();
9301
10150
  const { error } = validation.validate(id);
9302
10151
  if (error) {
9303
- next(new BadRequestError47(error.message));
10152
+ next(new BadRequestError51(error.message));
9304
10153
  }
9305
10154
  try {
9306
10155
  const message = await _deleteFile(id);
9307
10156
  res.json({ message });
9308
10157
  return;
9309
10158
  } catch (error2) {
9310
- if (error2 instanceof AppError20) {
10159
+ if (error2 instanceof AppError22) {
9311
10160
  next(error2);
9312
10161
  } else {
9313
- next(new InternalServerError24(error2));
10162
+ next(new InternalServerError26(error2));
9314
10163
  }
9315
10164
  }
9316
10165
  }
@@ -9321,35 +10170,35 @@ function useFileController() {
9321
10170
  }
9322
10171
 
9323
10172
  // src/resources/promo/promo.model.ts
9324
- import Joi35 from "joi";
9325
- var schemaPromo = Joi35.object({
9326
- code: Joi35.string().min(3).max(50).required(),
9327
- description: Joi35.string().max(255).optional().allow("", null),
9328
- type: Joi35.string().valid("flat", "fixed", "tiered").required(),
9329
- flatRate: Joi35.number().positive().when("type", {
10173
+ import Joi41 from "joi";
10174
+ var schemaPromo = Joi41.object({
10175
+ code: Joi41.string().min(3).max(50).required(),
10176
+ description: Joi41.string().max(255).optional().allow("", null),
10177
+ type: Joi41.string().valid("flat", "fixed", "tiered").required(),
10178
+ flatRate: Joi41.number().positive().when("type", {
9330
10179
  is: "flat",
9331
- then: Joi35.required(),
9332
- otherwise: Joi35.forbidden()
10180
+ then: Joi41.required(),
10181
+ otherwise: Joi41.forbidden()
9333
10182
  }).optional().allow(null, 0),
9334
- fixedRate: Joi35.number().positive().when("type", {
10183
+ fixedRate: Joi41.number().positive().when("type", {
9335
10184
  is: "fixed",
9336
- then: Joi35.required(),
9337
- otherwise: Joi35.forbidden()
10185
+ then: Joi41.required(),
10186
+ otherwise: Joi41.forbidden()
9338
10187
  }).optional().allow(null, 0),
9339
- tiers: Joi35.array().items(
9340
- Joi35.object({
9341
- minSeats: Joi35.number().integer().min(1).required(),
9342
- maxSeats: Joi35.number().integer().min(Joi35.ref("minSeats")).required(),
9343
- rate: Joi35.number().positive().required()
10188
+ tiers: Joi41.array().items(
10189
+ Joi41.object({
10190
+ minSeats: Joi41.number().integer().min(1).required(),
10191
+ maxSeats: Joi41.number().integer().min(Joi41.ref("minSeats")).required(),
10192
+ rate: Joi41.number().positive().required()
9344
10193
  })
9345
10194
  ).when("type", {
9346
10195
  is: "tiered",
9347
- then: Joi35.required(),
9348
- otherwise: Joi35.forbidden()
10196
+ then: Joi41.required(),
10197
+ otherwise: Joi41.forbidden()
9349
10198
  }),
9350
- currency: Joi35.string().length(3).required(),
9351
- startDate: Joi35.date().required(),
9352
- endDate: Joi35.date().greater(Joi35.ref("startDate")).optional().allow(null, "")
10199
+ currency: Joi41.string().length(3).required(),
10200
+ startDate: Joi41.date().required(),
10201
+ endDate: Joi41.date().greater(Joi41.ref("startDate")).optional().allow(null, "")
9353
10202
  });
9354
10203
  function modelPromo(data) {
9355
10204
  const { error } = schemaPromo.validate(data);
@@ -9378,33 +10227,33 @@ function modelPromo(data) {
9378
10227
 
9379
10228
  // src/resources/promo/promo.repository.ts
9380
10229
  import {
9381
- AppError as AppError21,
9382
- BadRequestError as BadRequestError48,
9383
- InternalServerError as InternalServerError25,
9384
- logger as logger27,
9385
- makeCacheKey as makeCacheKey17,
9386
- paginate as paginate14,
9387
- useAtlas as useAtlas25,
9388
- useCache as useCache18
10230
+ AppError as AppError23,
10231
+ BadRequestError as BadRequestError52,
10232
+ InternalServerError as InternalServerError27,
10233
+ logger as logger29,
10234
+ makeCacheKey as makeCacheKey18,
10235
+ paginate as paginate15,
10236
+ useAtlas as useAtlas26,
10237
+ useCache as useCache19
9389
10238
  } from "@goweekdays/utils";
9390
- import Joi36 from "joi";
9391
- import { ObjectId as ObjectId24 } from "mongodb";
10239
+ import Joi42 from "joi";
10240
+ import { ObjectId as ObjectId26 } from "mongodb";
9392
10241
  function usePromoRepo() {
9393
- const db = useAtlas25.getDb();
10242
+ const db = useAtlas26.getDb();
9394
10243
  if (!db) {
9395
- throw new InternalServerError25("Unable to connect to server.");
10244
+ throw new InternalServerError27("Unable to connect to server.");
9396
10245
  }
9397
10246
  const namespace_collection = "users";
9398
10247
  const collection = db.collection(namespace_collection);
9399
- const { getCache, setCache, delNamespace } = useCache18(namespace_collection);
10248
+ const { getCache, setCache, delNamespace } = useCache19(namespace_collection);
9400
10249
  function delCachedData() {
9401
10250
  delNamespace().then(() => {
9402
- logger27.log({
10251
+ logger29.log({
9403
10252
  level: "info",
9404
10253
  message: `Cache namespace cleared for ${namespace_collection}`
9405
10254
  });
9406
10255
  }).catch((err) => {
9407
- logger27.log({
10256
+ logger29.log({
9408
10257
  level: "error",
9409
10258
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
9410
10259
  });
@@ -9436,7 +10285,7 @@ function usePromoRepo() {
9436
10285
  delCachedData();
9437
10286
  return "Successfully added promo.";
9438
10287
  } catch (error) {
9439
- throw new InternalServerError25("Failed to add promo.");
10288
+ throw new InternalServerError27("Failed to add promo.");
9440
10289
  }
9441
10290
  }
9442
10291
  async function getAll({
@@ -9457,7 +10306,7 @@ function usePromoRepo() {
9457
10306
  if (search) {
9458
10307
  query.$text = { $search: search };
9459
10308
  }
9460
- const cacheKey = makeCacheKey17(namespace_collection, cacheKeyOptions);
10309
+ const cacheKey = makeCacheKey18(namespace_collection, cacheKeyOptions);
9461
10310
  try {
9462
10311
  const cachedData = await getCache(cacheKey);
9463
10312
  if (cachedData) {
@@ -9469,30 +10318,30 @@ function usePromoRepo() {
9469
10318
  { $limit: limit }
9470
10319
  ]).toArray();
9471
10320
  const length = await collection.countDocuments(query);
9472
- const data = paginate14(items, page, limit, length);
10321
+ const data = paginate15(items, page, limit, length);
9473
10322
  setCache(cacheKey, data).then(() => {
9474
- logger27.log({
10323
+ logger29.log({
9475
10324
  level: "info",
9476
10325
  message: `Cache set for getAll promo: ${cacheKey}`
9477
10326
  });
9478
10327
  }).catch((err) => {
9479
- logger27.log({
10328
+ logger29.log({
9480
10329
  level: "error",
9481
10330
  message: `Failed to set cache for getAll promo: ${err.message}`
9482
10331
  });
9483
10332
  });
9484
10333
  return data;
9485
10334
  } catch (error) {
9486
- throw new InternalServerError25("Failed to get promos.");
10335
+ throw new InternalServerError27("Failed to get promos.");
9487
10336
  }
9488
10337
  }
9489
10338
  async function getByCode(code) {
9490
- const { error } = Joi36.string().min(3).max(50).required().validate(code);
10339
+ const { error } = Joi42.string().min(3).max(50).required().validate(code);
9491
10340
  if (error) {
9492
10341
  throw new Error(`Invalid promo code: ${error.message}`);
9493
10342
  }
9494
10343
  try {
9495
- const cacheKey = makeCacheKey17(namespace_collection, {
10344
+ const cacheKey = makeCacheKey18(namespace_collection, {
9496
10345
  code,
9497
10346
  tag: "getByCode"
9498
10347
  });
@@ -9505,33 +10354,33 @@ function usePromoRepo() {
9505
10354
  status: { $ne: "deleted" }
9506
10355
  });
9507
10356
  setCache(cacheKey, data).then(() => {
9508
- logger27.log({
10357
+ logger29.log({
9509
10358
  level: "info",
9510
10359
  message: `Cache set for getByCode promo: ${cacheKey}`
9511
10360
  });
9512
10361
  }).catch((err) => {
9513
- logger27.log({
10362
+ logger29.log({
9514
10363
  level: "error",
9515
10364
  message: `Failed to set cache for getByCode promo: ${err.message}`
9516
10365
  });
9517
10366
  });
9518
10367
  return data;
9519
10368
  } catch (error2) {
9520
- throw new InternalServerError25("Failed to get promo.");
10369
+ throw new InternalServerError27("Failed to get promo.");
9521
10370
  }
9522
10371
  }
9523
10372
  async function getById(_id) {
9524
- const { error } = Joi36.string().hex().length(24).required().validate(_id);
10373
+ const { error } = Joi42.string().hex().length(24).required().validate(_id);
9525
10374
  if (error) {
9526
10375
  throw new Error(`Invalid promo ID: ${error.message}`);
9527
10376
  }
9528
10377
  try {
9529
- _id = new ObjectId24(_id);
10378
+ _id = new ObjectId26(_id);
9530
10379
  } catch (error2) {
9531
- throw new BadRequestError48("Invalid promo ID.");
10380
+ throw new BadRequestError52("Invalid promo ID.");
9532
10381
  }
9533
10382
  try {
9534
- const cacheKey = makeCacheKey17(namespace_collection, {
10383
+ const cacheKey = makeCacheKey18(namespace_collection, {
9535
10384
  _id: String(_id),
9536
10385
  tag: "getById"
9537
10386
  });
@@ -9544,30 +10393,30 @@ function usePromoRepo() {
9544
10393
  status: { $ne: "deleted" }
9545
10394
  });
9546
10395
  setCache(cacheKey, data).then(() => {
9547
- logger27.log({
10396
+ logger29.log({
9548
10397
  level: "info",
9549
10398
  message: `Cache set for getById promo: ${cacheKey}`
9550
10399
  });
9551
10400
  }).catch((err) => {
9552
- logger27.log({
10401
+ logger29.log({
9553
10402
  level: "error",
9554
10403
  message: `Failed to set cache for getById promo: ${err.message}`
9555
10404
  });
9556
10405
  });
9557
10406
  return data;
9558
10407
  } catch (error2) {
9559
- throw new InternalServerError25("Failed to get promo.");
10408
+ throw new InternalServerError27("Failed to get promo.");
9560
10409
  }
9561
10410
  }
9562
10411
  async function deleteById(_id) {
9563
- const { error } = Joi36.string().hex().length(24).required().validate(_id);
10412
+ const { error } = Joi42.string().hex().length(24).required().validate(_id);
9564
10413
  if (error) {
9565
10414
  throw new Error(`Invalid promo ID: ${error.message}`);
9566
10415
  }
9567
10416
  try {
9568
- _id = new ObjectId24(_id);
10417
+ _id = new ObjectId26(_id);
9569
10418
  } catch (error2) {
9570
- throw new BadRequestError48("Invalid promo ID.");
10419
+ throw new BadRequestError52("Invalid promo ID.");
9571
10420
  }
9572
10421
  try {
9573
10422
  const result = await collection.updateOne(
@@ -9575,15 +10424,15 @@ function usePromoRepo() {
9575
10424
  { $set: { status: "deleted" } }
9576
10425
  );
9577
10426
  if (result.modifiedCount === 0) {
9578
- throw new InternalServerError25("Failed to delete promo.");
10427
+ throw new InternalServerError27("Failed to delete promo.");
9579
10428
  }
9580
10429
  delCachedData();
9581
10430
  return "Successfully deleted promo.";
9582
10431
  } catch (error2) {
9583
- if (error2 instanceof AppError21) {
10432
+ if (error2 instanceof AppError23) {
9584
10433
  throw error2;
9585
10434
  }
9586
- throw new InternalServerError25("Failed to delete promo.");
10435
+ throw new InternalServerError27("Failed to delete promo.");
9587
10436
  }
9588
10437
  }
9589
10438
  return {
@@ -9597,7 +10446,7 @@ function usePromoRepo() {
9597
10446
  }
9598
10447
 
9599
10448
  // src/resources/utils/github.service.ts
9600
- import { AppError as AppError22, BadRequestError as BadRequestError49 } from "@goweekdays/utils";
10449
+ import { AppError as AppError24, BadRequestError as BadRequestError53 } from "@goweekdays/utils";
9601
10450
  import { Octokit } from "@octokit/rest";
9602
10451
  import _sodium from "libsodium-wrappers";
9603
10452
  function useGitHubService() {
@@ -9611,23 +10460,23 @@ function useGitHubService() {
9611
10460
  try {
9612
10461
  const { data: repoData } = await octokit.repos.get({ owner, repo });
9613
10462
  if (!repoData.permissions?.admin) {
9614
- throw new BadRequestError49(
10463
+ throw new BadRequestError53(
9615
10464
  "You do not have admin access to this repository."
9616
10465
  );
9617
10466
  }
9618
10467
  } catch (error) {
9619
10468
  if (error.status === 404) {
9620
- throw new BadRequestError49(
10469
+ throw new BadRequestError53(
9621
10470
  "Repository not found or you don't have access to it."
9622
10471
  );
9623
10472
  } else if (error.status === 401) {
9624
- throw new BadRequestError49(
10473
+ throw new BadRequestError53(
9625
10474
  "Invalid GitHub token or insufficient permissions."
9626
10475
  );
9627
10476
  } else if (error.message.includes("admin access")) {
9628
10477
  throw error;
9629
10478
  } else {
9630
- throw new BadRequestError49(
10479
+ throw new BadRequestError53(
9631
10480
  `Failed to check repository permissions: ${error.message}`
9632
10481
  );
9633
10482
  }
@@ -9676,7 +10525,7 @@ function useGitHubService() {
9676
10525
  key_id: publicKeyRes.key_id
9677
10526
  });
9678
10527
  } catch (encryptionError) {
9679
- throw new BadRequestError49(
10528
+ throw new BadRequestError53(
9680
10529
  `Failed to encrypt secret '${key}': ${encryptionError.message}`
9681
10530
  );
9682
10531
  }
@@ -9706,22 +10555,22 @@ function useGitHubService() {
9706
10555
  }
9707
10556
  return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
9708
10557
  } catch (error) {
9709
- if (error instanceof AppError22)
10558
+ if (error instanceof AppError24)
9710
10559
  throw error;
9711
10560
  if (error.status === 422) {
9712
- throw new BadRequestError49(
10561
+ throw new BadRequestError53(
9713
10562
  `GitHub API validation error: ${error.message}`
9714
10563
  );
9715
10564
  } else if (error.status === 404) {
9716
- throw new BadRequestError49("Environment or repository not found.");
10565
+ throw new BadRequestError53("Environment or repository not found.");
9717
10566
  } else if (error.status === 403) {
9718
- throw new BadRequestError49(
10567
+ throw new BadRequestError53(
9719
10568
  "Forbidden: Insufficient permissions or rate limit exceeded."
9720
10569
  );
9721
10570
  } else if (error.message.includes("admin access") || error.message.includes("permissions")) {
9722
10571
  throw error;
9723
10572
  } else {
9724
- throw new BadRequestError49(
10573
+ throw new BadRequestError53(
9725
10574
  `Failed to set GitHub variables: ${error.message}`
9726
10575
  );
9727
10576
  }
@@ -9733,12 +10582,12 @@ function useGitHubService() {
9733
10582
  }
9734
10583
 
9735
10584
  // src/resources/utils/util.controller.ts
9736
- import Joi37 from "joi";
10585
+ import Joi43 from "joi";
9737
10586
  import {
9738
- AppError as AppError23,
9739
- BadRequestError as BadRequestError50,
9740
- InternalServerError as InternalServerError26,
9741
- logger as logger28
10587
+ AppError as AppError25,
10588
+ BadRequestError as BadRequestError54,
10589
+ InternalServerError as InternalServerError28,
10590
+ logger as logger30
9742
10591
  } from "@goweekdays/utils";
9743
10592
  function useUtilController() {
9744
10593
  async function healthCheck(req, res, next) {
@@ -9755,32 +10604,32 @@ function useUtilController() {
9755
10604
  }
9756
10605
  });
9757
10606
  } catch (error) {
9758
- logger28.error("Health check failed", { error: error.message });
9759
- next(new InternalServerError26("Health check failed"));
10607
+ logger30.error("Health check failed", { error: error.message });
10608
+ next(new InternalServerError28("Health check failed"));
9760
10609
  }
9761
10610
  }
9762
10611
  async function setGitHubVariables(req, res, next) {
9763
10612
  try {
9764
10613
  const { githubToken, repoUrl, environment, type, keyValues } = req.body;
9765
- const validation = Joi37.object({
9766
- githubToken: Joi37.string().required().messages({
10614
+ const validation = Joi43.object({
10615
+ githubToken: Joi43.string().required().messages({
9767
10616
  "string.empty": "GitHub token is required",
9768
10617
  "any.required": "GitHub token is required"
9769
10618
  }),
9770
- repoUrl: Joi37.string().uri().required().messages({
10619
+ repoUrl: Joi43.string().uri().required().messages({
9771
10620
  "string.empty": "Repository URL is required",
9772
10621
  "string.uri": "Repository URL must be a valid URL",
9773
10622
  "any.required": "Repository URL is required"
9774
10623
  }),
9775
- environment: Joi37.string().required().messages({
10624
+ environment: Joi43.string().required().messages({
9776
10625
  "string.empty": "Environment name is required",
9777
10626
  "any.required": "Environment name is required"
9778
10627
  }),
9779
- type: Joi37.string().valid("env", "secret").required().messages({
10628
+ type: Joi43.string().valid("env", "secret").required().messages({
9780
10629
  "any.only": 'Type must be either "env" or "secret"',
9781
10630
  "any.required": "Type is required"
9782
10631
  }),
9783
- keyValues: Joi37.string().required().messages({
10632
+ keyValues: Joi43.string().required().messages({
9784
10633
  "string.empty": "Key-value pairs are required",
9785
10634
  "any.required": "Key-value pairs are required"
9786
10635
  })
@@ -9793,13 +10642,13 @@ function useUtilController() {
9793
10642
  keyValues
9794
10643
  });
9795
10644
  if (error) {
9796
- next(new BadRequestError50(error.message));
10645
+ next(new BadRequestError54(error.message));
9797
10646
  return;
9798
10647
  }
9799
10648
  const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
9800
10649
  if (!repoUrlPattern.test(repoUrl)) {
9801
10650
  next(
9802
- new BadRequestError50(
10651
+ new BadRequestError54(
9803
10652
  "Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
9804
10653
  )
9805
10654
  );
@@ -9811,7 +10660,7 @@ function useUtilController() {
9811
10660
  );
9812
10661
  if (invalidLines.length > 0) {
9813
10662
  next(
9814
- new BadRequestError50(
10663
+ new BadRequestError54(
9815
10664
  "Invalid key-value format. Each pair should be in format: KEY=value. Pairs should be separated by semicolons."
9816
10665
  )
9817
10666
  );
@@ -9825,7 +10674,7 @@ function useUtilController() {
9825
10674
  type,
9826
10675
  keyValues
9827
10676
  });
9828
- logger28.info(`GitHub variables set successfully`, {
10677
+ logger30.info(`GitHub variables set successfully`, {
9829
10678
  repoUrl,
9830
10679
  environment,
9831
10680
  type,
@@ -9836,319 +10685,311 @@ function useUtilController() {
9836
10685
  message: result,
9837
10686
  data: {
9838
10687
  repoUrl,
9839
- environment,
9840
- type,
9841
- variablesSet: lines.length
9842
- }
9843
- });
9844
- } catch (error) {
9845
- logger28.error("Failed to set GitHub variables", {
9846
- error: error.message,
9847
- stack: error.stack
9848
- });
9849
- if (error instanceof AppError23) {
9850
- next(error);
9851
- } else {
9852
- next(
9853
- new InternalServerError26(
9854
- `Failed to set GitHub variables: ${error.message}`
9855
- )
9856
- );
9857
- }
9858
- }
9859
- }
9860
- const { verifySignature } = usePaypalService();
9861
- async function paypalWebhook(req, res, next) {
9862
- try {
9863
- const headers = req.headers;
9864
- const event = req.body;
9865
- const data = JSON.parse(event);
9866
- console.log(`headers`, headers);
9867
- console.log(`parsed json`, JSON.stringify(data, null, 2));
9868
- console.log(`raw event: ${event}`);
9869
- const isSignatureValid = await verifySignature(
9870
- event,
9871
- headers,
9872
- PAYPAL_WEBHOOK_ID
9873
- );
9874
- if (isSignatureValid) {
9875
- console.log("Signature is valid.");
9876
- console.log(`Received event`, JSON.stringify(data, null, 2));
9877
- } else {
9878
- console.log(
9879
- `Signature is not valid for ${data?.id} ${headers?.["correlation-id"]}`
9880
- );
9881
- }
9882
- res.sendStatus(200);
9883
- } catch (error) {
9884
- logger28.log({
9885
- level: "error",
9886
- message: `${error}`
9887
- });
9888
- }
9889
- }
9890
- return {
9891
- healthCheck,
9892
- setGitHubVariables,
9893
- paypalWebhook
9894
- };
9895
- }
9896
-
9897
- // src/resources/utils/transaction.schema.ts
9898
- import Joi38 from "joi";
9899
- var transactionSchema = Joi38.object({
9900
- _id: Joi38.string().hex().optional().allow("", null),
9901
- payment: Joi38.string().required(),
9902
- user: Joi38.string().hex().optional().allow("", null),
9903
- org: Joi38.string().hex().optional().allow("", null),
9904
- type: Joi38.string().required(),
9905
- amount: Joi38.number().positive().min(0).required(),
9906
- currency: Joi38.string().required(),
9907
- description: Joi38.string().optional().allow("", null),
9908
- metadata: Joi38.object({
9909
- subscriptionId: Joi38.string().hex().optional().allow("", null),
9910
- cycle: Joi38.number().optional().allow("", null),
9911
- seats: Joi38.number().optional().allow("", null),
9912
- promoCode: Joi38.string().optional().allow("", null)
9913
- }).optional().allow("", null),
9914
- status: Joi38.string().optional().allow("", null),
9915
- createdAt: Joi38.string().optional().allow("", null),
9916
- updatedAt: Joi38.string().optional().allow("", null),
9917
- deletedAt: Joi38.string().optional().allow("", null)
9918
- });
9919
-
9920
- // src/resources/verification/verification.controller.ts
9921
- import {
9922
- AppError as AppError24,
9923
- BadRequestError as BadRequestError51,
9924
- InternalServerError as InternalServerError27
9925
- } from "@goweekdays/utils";
9926
- import Joi39 from "joi";
9927
- function useVerificationController() {
9928
- const {
9929
- createUserInvite: _createUserInvite,
9930
- createForgetPassword: _createForgetPassword,
9931
- cancelUserInvitation: _cancelUserInvitation,
9932
- verify: _verify,
9933
- inviteMember: _inviteMember,
9934
- signUp: _signUp,
9935
- cancelInviteMember: _cancelInviteMember,
9936
- forgetPassword: _forgetPassword
9937
- } = useVerificationService();
9938
- const { getVerifications: _getVerifications } = useVerificationRepo();
9939
- async function createUserInvite(req, res, next) {
9940
- const validation = Joi39.object({
9941
- email: Joi39.string().email().required(),
9942
- app: Joi39.string().required(),
9943
- role: Joi39.string().hex().required(),
9944
- roleName: Joi39.string().required(),
9945
- org: Joi39.string().hex().optional().optional().allow("", null),
9946
- orgName: Joi39.string().optional().optional().allow("", null)
9947
- });
9948
- const { error } = validation.validate(req.body);
9949
- if (error) {
9950
- next(new BadRequestError51(error.message));
9951
- return;
9952
- }
9953
- const email = req.body.email ?? "";
9954
- const app = req.body.app ?? "";
9955
- const role = req.body.role ?? "";
9956
- const roleName = req.body.roleName ?? "";
9957
- const org = req.body.org ?? "";
9958
- const orgName = req.body.orgName ?? "";
9959
- try {
9960
- await _createUserInvite({
9961
- email,
9962
- metadata: {
9963
- app,
9964
- role,
9965
- roleName,
9966
- org,
9967
- orgName
10688
+ environment,
10689
+ type,
10690
+ variablesSet: lines.length
9968
10691
  }
9969
10692
  });
9970
- res.json({ message: "Successfully invited user." });
9971
- return;
9972
- } catch (error2) {
9973
- next(error2);
9974
- }
9975
- }
9976
- async function createForgetPassword(req, res, next) {
9977
- const email = req.body.email || "";
9978
- const validation = Joi39.string().email().required();
9979
- const { error } = validation.validate(email);
9980
- if (error) {
9981
- next(new BadRequestError51(error.message));
9982
- return;
9983
- }
9984
- try {
9985
- await _createForgetPassword(email);
9986
- res.json({
9987
- message: "Check your email to verify it before resetting your password."
10693
+ } catch (error) {
10694
+ logger30.error("Failed to set GitHub variables", {
10695
+ error: error.message,
10696
+ stack: error.stack
9988
10697
  });
9989
- return;
9990
- } catch (error2) {
9991
- if (error2 instanceof AppError24) {
9992
- next(error2);
10698
+ if (error instanceof AppError25) {
10699
+ next(error);
9993
10700
  } else {
9994
- next(new InternalServerError27("An unexpected error occurred"));
10701
+ next(
10702
+ new InternalServerError28(
10703
+ `Failed to set GitHub variables: ${error.message}`
10704
+ )
10705
+ );
9995
10706
  }
9996
10707
  }
9997
10708
  }
9998
- async function getVerifications(req, res, next) {
9999
- const validation = Joi39.object({
10000
- status: Joi39.string().required(),
10001
- search: Joi39.string().optional().allow("", null),
10002
- page: Joi39.number().required(),
10003
- type: Joi39.string().optional().allow("", null),
10004
- email: Joi39.string().optional().allow("", null),
10005
- app: Joi39.string().optional().allow("", null),
10006
- org: Joi39.string().optional().allow("", null)
10007
- });
10008
- const { error } = validation.validate(req.query);
10009
- if (error) {
10010
- next(new BadRequestError51(error.message));
10011
- return;
10012
- }
10013
- const status = req.query.status ?? "";
10014
- const search = req.query.search ?? "";
10015
- const page = Number(req.query.page) ?? 1;
10016
- let type = req.query.type ?? "";
10017
- const email = req.query.email ?? "";
10018
- const app = req.query.app ?? "";
10019
- const org = req.query.org ?? "";
10020
- const hasMultipleTypes = type.includes(",");
10021
- let splitType = [];
10022
- if (hasMultipleTypes) {
10023
- splitType = type.split(",");
10024
- }
10709
+ const { verifySignature, captureOrder } = usePaypalService();
10710
+ const { addWithVerification } = useOrgService();
10711
+ async function paypalWebhook(req, res, next) {
10025
10712
  try {
10026
- const items = await _getVerifications({
10027
- status,
10028
- search,
10029
- page,
10030
- type: hasMultipleTypes ? splitType : type,
10031
- email,
10032
- app,
10033
- org
10034
- });
10035
- res.json(items);
10713
+ const isSignatureValid = await verifySignature(
10714
+ req.body,
10715
+ req.headers,
10716
+ PAYPAL_WEBHOOK_ID
10717
+ );
10718
+ if (isSignatureValid) {
10719
+ const payload = JSON.parse(req.body);
10720
+ const eventType = payload.event_type;
10721
+ const resource = payload.resource;
10722
+ switch (eventType) {
10723
+ case "CHECKOUT.ORDER.APPROVED": {
10724
+ const orderId = resource.id;
10725
+ await captureOrder(orderId);
10726
+ break;
10727
+ }
10728
+ case "PAYMENT.CAPTURE.COMPLETED": {
10729
+ const customId = resource?.custom_id || resource?.purchase_units?.[0]?.custom_id;
10730
+ if (!customId) {
10731
+ throw new Error("Missing PayPal customId");
10732
+ }
10733
+ await addWithVerification(customId);
10734
+ break;
10735
+ }
10736
+ default:
10737
+ break;
10738
+ }
10739
+ } else {
10740
+ next(new BadRequestError54("Invalid PayPal webhook signature."));
10741
+ return;
10742
+ }
10743
+ res.sendStatus(200);
10036
10744
  return;
10037
- } catch (error2) {
10038
- next(error2);
10745
+ } catch (error) {
10746
+ logger30.log({
10747
+ level: "error",
10748
+ message: `${error}`
10749
+ });
10750
+ next(new InternalServerError28(`PayPal webhook error: ${error.message}`));
10039
10751
  }
10040
10752
  }
10041
- async function verify(req, res, next) {
10042
- const id = req.params.id || "";
10043
- const validation = Joi39.string().hex().required();
10044
- const { error } = validation.validate(id);
10045
- if (error) {
10046
- next(new BadRequestError51(error.message));
10047
- return;
10048
- }
10753
+ return {
10754
+ healthCheck,
10755
+ setGitHubVariables,
10756
+ paypalWebhook
10757
+ };
10758
+ }
10759
+
10760
+ // src/resources/utils/transaction.schema.ts
10761
+ import Joi44 from "joi";
10762
+ var transactionSchema = Joi44.object({
10763
+ _id: Joi44.string().hex().optional().allow("", null),
10764
+ payment: Joi44.string().required(),
10765
+ user: Joi44.string().hex().optional().allow("", null),
10766
+ org: Joi44.string().hex().optional().allow("", null),
10767
+ type: Joi44.string().required(),
10768
+ amount: Joi44.number().positive().min(0).required(),
10769
+ currency: Joi44.string().required(),
10770
+ description: Joi44.string().optional().allow("", null),
10771
+ metadata: Joi44.object({
10772
+ subscriptionId: Joi44.string().hex().optional().allow("", null),
10773
+ cycle: Joi44.number().optional().allow("", null),
10774
+ seats: Joi44.number().optional().allow("", null),
10775
+ promoCode: Joi44.string().optional().allow("", null)
10776
+ }).optional().allow("", null),
10777
+ status: Joi44.string().optional().allow("", null),
10778
+ createdAt: Joi44.string().optional().allow("", null),
10779
+ updatedAt: Joi44.string().optional().allow("", null),
10780
+ deletedAt: Joi44.string().optional().allow("", null)
10781
+ });
10782
+
10783
+ // src/resources/job-post/job.post.model.ts
10784
+ import { BadRequestError as BadRequestError55 } from "@goweekdays/utils";
10785
+ import Joi45 from "joi";
10786
+ import { ObjectId as ObjectId27 } from "mongodb";
10787
+ var schemaJobPost = Joi45.object({
10788
+ _id: Joi45.string().hex().optional(),
10789
+ org: Joi45.string().hex().optional(),
10790
+ title: Joi45.string().trim().required(),
10791
+ setup: Joi45.string().trim().required(),
10792
+ location: Joi45.string().trim().required(),
10793
+ type: Joi45.string().trim().required(),
10794
+ description: Joi45.string().trim().required(),
10795
+ status: Joi45.string().trim().required(),
10796
+ createdAt: Joi45.date().optional(),
10797
+ updatedAt: Joi45.date().optional(),
10798
+ deletedAt: Joi45.date().optional()
10799
+ });
10800
+ function modelJobPost(value) {
10801
+ const { error } = schemaJobPost.validate(value);
10802
+ if (error) {
10803
+ throw new BadRequestError55(`Invalid job post: ${error.message}`);
10804
+ }
10805
+ if (!value._id) {
10049
10806
  try {
10050
- const message = await _verify(id);
10051
- res.json(message);
10052
- return;
10807
+ value._id = new ObjectId27();
10053
10808
  } catch (error2) {
10054
- next(error2);
10809
+ throw new BadRequestError55("Invalid job post ID.");
10055
10810
  }
10056
10811
  }
10057
- async function cancelUserInvitation(req, res, next) {
10058
- const otpId = req.params.id || "";
10059
- const validation = Joi39.string().hex().required();
10060
- const { error } = validation.validate(otpId);
10061
- if (error) {
10062
- next(new BadRequestError51(error.message));
10063
- return;
10812
+ try {
10813
+ value.org = new ObjectId27(value.org);
10814
+ } catch (error2) {
10815
+ throw new BadRequestError55("Invalid Org ID");
10816
+ }
10817
+ return {
10818
+ _id: value._id,
10819
+ org: value.org,
10820
+ title: value.title,
10821
+ setup: value.setup,
10822
+ location: value.location,
10823
+ type: value.type,
10824
+ description: value.description,
10825
+ status: value.status ?? "active",
10826
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
10827
+ updatedAt: value.updatedAt,
10828
+ deletedAt: value.deletedAt
10829
+ };
10830
+ }
10831
+
10832
+ // src/resources/job-post/job.post.controller.ts
10833
+ import { BadRequestError as BadRequestError58, logger as logger32 } from "@goweekdays/utils";
10834
+
10835
+ // src/resources/job-post/job.post.repository.ts
10836
+ import { BadRequestError as BadRequestError56, useAtlas as useAtlas27, useCache as useCache20, logger as logger31, InternalServerError as InternalServerError29 } from "@goweekdays/utils";
10837
+ import { ObjectId as ObjectId28 } from "mongodb";
10838
+ function useJobPostRepo() {
10839
+ const db = useAtlas27.getDb();
10840
+ if (!db) {
10841
+ throw new BadRequestError56("Unable to connect to server.");
10842
+ }
10843
+ const namespace_collection = "job.posts";
10844
+ const collection = db.collection(namespace_collection);
10845
+ const { delNamespace } = useCache20(namespace_collection);
10846
+ function delCachedData() {
10847
+ delNamespace().then(() => {
10848
+ logger31.log({
10849
+ level: "info",
10850
+ message: `Cache namespace cleared for ${namespace_collection}`
10851
+ });
10852
+ }).catch((err) => {
10853
+ logger31.log({
10854
+ level: "error",
10855
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
10856
+ });
10857
+ });
10858
+ }
10859
+ async function createIndexes() {
10860
+ try {
10861
+ await collection.createIndexes([
10862
+ { key: { title: 1 } },
10863
+ { key: { setup: 1 } },
10864
+ { key: { location: 1 } },
10865
+ { key: { type: 1 } },
10866
+ {
10867
+ key: {
10868
+ title: "text",
10869
+ setup: "text",
10870
+ location: "text",
10871
+ type: "text"
10872
+ },
10873
+ name: "jobpost_text_search"
10874
+ }
10875
+ ]);
10876
+ return "Successfully created job post indexes.";
10877
+ } catch (error) {
10878
+ throw new BadRequestError56("Failed to create job post indexes.");
10064
10879
  }
10880
+ }
10881
+ async function add(value, session) {
10065
10882
  try {
10066
- await _cancelUserInvitation(otpId);
10067
- return res.json({
10068
- message: "User invite has been cancelled."
10883
+ value = modelJobPost(value);
10884
+ const res = await collection.insertOne(value, { session });
10885
+ delCachedData();
10886
+ return res.insertedId;
10887
+ } catch (error) {
10888
+ logger31.log({
10889
+ level: "error",
10890
+ message: error.message
10069
10891
  });
10070
- } catch (error2) {
10071
- throw error2;
10892
+ throw new BadRequestError56(`Failed to create job post: ${error.message}`);
10072
10893
  }
10073
10894
  }
10074
- async function signUp(req, res, next) {
10075
- const validation = Joi39.string().email().required();
10076
- const { error } = validation.validate(req.body.email);
10077
- if (error) {
10078
- next(new BadRequestError51(error.message));
10079
- return;
10895
+ async function deleteById(_id, session) {
10896
+ try {
10897
+ _id = new ObjectId28(_id);
10898
+ } catch (error) {
10899
+ throw new BadRequestError56("Invalid ID.");
10080
10900
  }
10081
- const email = req.body.email ?? "";
10082
10901
  try {
10083
- await _signUp({ email });
10084
- res.json({ message: "Successfully signed up user." });
10085
- return;
10086
- } catch (error2) {
10087
- next(error2);
10902
+ await collection.updateOne(
10903
+ { _id },
10904
+ {
10905
+ $set: {
10906
+ status: "deleted",
10907
+ updatedAt: /* @__PURE__ */ new Date(),
10908
+ deletedAt: /* @__PURE__ */ new Date()
10909
+ }
10910
+ },
10911
+ { session }
10912
+ );
10913
+ delCachedData();
10914
+ return "Successfully deleted job post.";
10915
+ } catch (error) {
10916
+ throw new InternalServerError29("Failed to delete job post.");
10088
10917
  }
10089
10918
  }
10090
- async function inviteMember(req, res, next) {
10091
- const { error } = schemaInviteMember.validate(req.body);
10919
+ return {
10920
+ createIndexes,
10921
+ add,
10922
+ deleteById
10923
+ };
10924
+ }
10925
+
10926
+ // src/resources/job-post/job.post.service.ts
10927
+ import {
10928
+ AppError as AppError26,
10929
+ BadRequestError as BadRequestError57,
10930
+ InternalServerError as InternalServerError30
10931
+ } from "@goweekdays/utils";
10932
+ import Joi46 from "joi";
10933
+ function useJobPostService() {
10934
+ const { deleteById: _deleteById } = useJobPostRepo();
10935
+ async function deleteById(id) {
10936
+ const { error } = Joi46.string().hex().required().validate(id);
10092
10937
  if (error) {
10093
- next(new BadRequestError51(error.message));
10094
- return;
10938
+ throw new BadRequestError57(error.message);
10095
10939
  }
10096
10940
  try {
10097
- await _inviteMember(req.body);
10098
- res.json({ message: "Successfully invited member." });
10099
- return;
10941
+ await _deleteById(id);
10942
+ return "Successfully deleted job post.";
10100
10943
  } catch (error2) {
10101
- next(error2);
10944
+ if (error2 instanceof AppError26) {
10945
+ throw error2;
10946
+ } else {
10947
+ throw new InternalServerError30("Failed to delete job post.");
10948
+ }
10102
10949
  }
10103
10950
  }
10104
- async function cancelInviteMember(req, res, next) {
10105
- const id = req.params.id || "";
10106
- const validation = Joi39.string().hex().required();
10107
- const { error } = validation.validate(id);
10951
+ return {
10952
+ deleteById
10953
+ };
10954
+ }
10955
+
10956
+ // src/resources/job-post/job.post.controller.ts
10957
+ function useJobPostController() {
10958
+ const { add: _add } = useJobPostRepo();
10959
+ const { deleteById: _deleteById } = useJobPostService();
10960
+ async function add(req, res, next) {
10961
+ const value = req.body;
10962
+ const { error } = schemaJobPost.validate(value);
10108
10963
  if (error) {
10109
- next(new BadRequestError51(error.message));
10964
+ next(new BadRequestError58(error.message));
10965
+ logger32.info(`Controller: ${error.message}`);
10110
10966
  return;
10111
10967
  }
10112
10968
  try {
10113
- const message = await _cancelInviteMember(id);
10114
- res.json({ message });
10969
+ const result = await _add(value);
10970
+ res.json({ message: "Successfully created job post.", data: { result } });
10115
10971
  return;
10116
10972
  } catch (error2) {
10117
10973
  next(error2);
10118
10974
  }
10119
10975
  }
10120
- async function forgetPassword(req, res, next) {
10121
- const email = req.body.email ?? "";
10122
- const validation = Joi39.string().email().required();
10123
- const { error } = validation.validate(email);
10124
- if (error) {
10125
- next(new BadRequestError51(error.message));
10976
+ async function deleteById(req, res, next) {
10977
+ const id = req.params.id;
10978
+ if (!id) {
10979
+ next(new BadRequestError58("Job Post ID is required."));
10126
10980
  return;
10127
10981
  }
10128
10982
  try {
10129
- const message = await _forgetPassword(email);
10130
- res.json({
10131
- message
10132
- });
10983
+ const message = await _deleteById(id);
10984
+ res.json(message);
10133
10985
  return;
10134
- } catch (error2) {
10135
- if (error2 instanceof AppError24) {
10136
- next(error2);
10137
- } else {
10138
- next(new InternalServerError27("An unexpected error occurred"));
10139
- }
10986
+ } catch (error) {
10987
+ next(error);
10140
10988
  }
10141
10989
  }
10142
10990
  return {
10143
- getVerifications,
10144
- createUserInvite,
10145
- createForgetPassword,
10146
- verify,
10147
- cancelUserInvitation,
10148
- inviteMember,
10149
- signUp,
10150
- cancelInviteMember,
10151
- forgetPassword
10991
+ add,
10992
+ deleteById
10152
10993
  };
10153
10994
  }
10154
10995
  export {
@@ -10194,7 +11035,11 @@ export {
10194
11035
  XENDIT_SECRET_KEY,
10195
11036
  currencies,
10196
11037
  isDev,
11038
+ ledgerBillStatuses,
11039
+ ledgerBillTypes,
10197
11040
  modelApp,
11041
+ modelJobPost,
11042
+ modelLedgerBill,
10198
11043
  modelMember,
10199
11044
  modelOrg,
10200
11045
  modelPermission,
@@ -10211,6 +11056,9 @@ export {
10211
11056
  schemaBuilding,
10212
11057
  schemaBuildingUnit,
10213
11058
  schemaInviteMember,
11059
+ schemaJobPost,
11060
+ schemaLedgerBill,
11061
+ schemaLedgerBillingSummary,
10214
11062
  schemaMember,
10215
11063
  schemaMemberRole,
10216
11064
  schemaMemberStatus,
@@ -10250,6 +11098,11 @@ export {
10250
11098
  useFileRepo,
10251
11099
  useFileService,
10252
11100
  useGitHubService,
11101
+ useJobPostController,
11102
+ useJobPostRepo,
11103
+ useJobPostService,
11104
+ useLedgerBillingController,
11105
+ useLedgerBillingRepo,
10253
11106
  useMemberController,
10254
11107
  useMemberRepo,
10255
11108
  useOrgController,