@goweekdays/core 2.6.1 → 2.7.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,331 +6489,1005 @@ 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", "completed", "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
+ function modelLedgerBill(value) {
6765
+ const { error } = schemaLedgerBill.validate(value);
6766
+ if (error) {
6767
+ throw new Error(`Ledger bill model validation error: ${error.message}`);
6768
+ }
6769
+ try {
6770
+ value.org = new ObjectId20(value.org);
6771
+ } catch (error2) {
6772
+ throw new BadRequestError35("Invalid org ID.");
6773
+ }
6774
+ return {
6775
+ _id: value._id,
6776
+ org: value.org,
6777
+ type: value.type,
6778
+ description: value.description,
6779
+ amount: value.amount,
6780
+ currency: value.currency,
6781
+ status: value.status,
6782
+ billingFrom: value.billingFrom ?? "",
6783
+ billingTo: value.billingTo ?? "",
6784
+ paidAt: value.paidAt ?? "",
6785
+ dueDate: value.dueDate ?? "",
6786
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date()
6787
+ };
6788
+ }
6789
+
6790
+ // src/resources/ledger/ledger.billing.repository.ts
6791
+ import {
6792
+ AppError as AppError15,
6793
+ BadRequestError as BadRequestError36,
6794
+ InternalServerError as InternalServerError19,
6795
+ logger as logger19,
6796
+ makeCacheKey as makeCacheKey13,
6797
+ paginate as paginate12,
6798
+ useAtlas as useAtlas16,
6799
+ useCache as useCache14
6800
+ } from "@goweekdays/utils";
6801
+ import { ObjectId as ObjectId21 } from "mongodb";
6802
+ import Joi30 from "joi";
6803
+ function useLedgerBillingRepo() {
6804
+ const db = useAtlas16.getDb();
6805
+ if (!db) {
6806
+ throw new Error("Unable to connect to server.");
6807
+ }
6808
+ const namespace_collection = "ledger.billings";
6809
+ const collection = db.collection(namespace_collection);
6810
+ const { getCache, setCache, delNamespace } = useCache14(namespace_collection);
6811
+ function delCachedData() {
6812
+ delNamespace().then(() => {
6813
+ logger19.log({
6814
+ level: "info",
6815
+ message: `Cache namespace cleared for ${namespace_collection}`
6816
+ });
6817
+ }).catch((err) => {
6818
+ logger19.log({
6819
+ level: "error",
6820
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
6821
+ });
6822
+ });
6823
+ }
6824
+ async function createIndexes() {
6756
6825
  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
- );
6826
+ await collection.createIndexes([
6827
+ { key: { org: 1 } },
6828
+ { key: { status: 1 } },
6829
+ { key: { description: "text" }, name: "text_index" }
6830
+ ]);
6831
+ return "Successfully created ledger billing indexes.";
6832
+ } catch (error) {
6833
+ throw new BadRequestError36("Failed to create ledger billing indexes.");
6834
+ }
6835
+ }
6836
+ async function add(value, session) {
6837
+ try {
6838
+ value = modelLedgerBill(value);
6839
+ const result = await collection.insertOne(value, { session });
6840
+ delCachedData();
6841
+ return result.insertedId;
6842
+ } catch (error) {
6843
+ if (error instanceof AppError15) {
6844
+ throw error;
6763
6845
  }
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
6771
- },
6846
+ throw new BadRequestError36(
6847
+ `Failed to add ledger billing: ${error.message}`
6848
+ );
6849
+ }
6850
+ }
6851
+ async function getAll({
6852
+ org = "",
6853
+ search = "",
6854
+ page = 1,
6855
+ limit = 10,
6856
+ status = ""
6857
+ } = {}) {
6858
+ page = page > 0 ? page - 1 : 0;
6859
+ const query = { status: { $ne: "deleted" } };
6860
+ const cacheKeyOptions = {
6861
+ search,
6862
+ page,
6863
+ limit,
6864
+ tag: "getAll"
6865
+ };
6866
+ try {
6867
+ query.org = new ObjectId21(org);
6868
+ cacheKeyOptions.org = org;
6869
+ } catch (error) {
6870
+ throw new BadRequestError36("Invalid organization ID.");
6871
+ }
6872
+ if (status) {
6873
+ query.status = status;
6874
+ cacheKeyOptions.status = status;
6875
+ }
6876
+ if (search) {
6877
+ query.$text = { $search: search };
6878
+ }
6879
+ const cacheKey = makeCacheKey13(namespace_collection, cacheKeyOptions);
6880
+ logger19.log({
6881
+ level: "info",
6882
+ message: `Cache key for getAll ledger billings: ${cacheKey}`
6883
+ });
6884
+ try {
6885
+ const cached = await getCache(cacheKey);
6886
+ if (cached) {
6887
+ logger19.log({
6888
+ level: "info",
6889
+ message: `Cache hit for getAll ledger billings: ${cacheKey}`
6890
+ });
6891
+ return cached;
6892
+ }
6893
+ const items = await collection.aggregate([
6894
+ { $match: query },
6895
+ { $skip: page * limit },
6896
+ { $limit: limit }
6897
+ ]).toArray();
6898
+ const length = await collection.countDocuments(query);
6899
+ const data = paginate12(items, page, limit, length);
6900
+ setCache(cacheKey, data, 600).then(() => {
6901
+ logger19.log({
6902
+ level: "info",
6903
+ message: `Cache set for getAll ledger billings: ${cacheKey}`
6904
+ });
6905
+ }).catch((err) => {
6906
+ logger19.log({
6907
+ level: "error",
6908
+ message: `Failed to set cache for getAll ledger billings: ${err.message}`
6909
+ });
6910
+ });
6911
+ return data;
6912
+ } catch (error) {
6913
+ logger19.log({ level: "error", message: `${error}` });
6914
+ throw error;
6915
+ }
6916
+ }
6917
+ async function getById(_id) {
6918
+ const { error } = Joi30.string().hex().length(24).required().validate(_id);
6919
+ if (error) {
6920
+ throw new Error(`Invalid ledger billing ID: ${error.message}`);
6921
+ }
6922
+ try {
6923
+ _id = new ObjectId21(_id);
6924
+ } catch (error2) {
6925
+ throw new BadRequestError36("Invalid ledger billing ID.");
6926
+ }
6927
+ try {
6928
+ const cacheKey = makeCacheKey13(namespace_collection, {
6929
+ _id: String(_id),
6930
+ tag: "getById"
6931
+ });
6932
+ const cachedData = await getCache(cacheKey);
6933
+ if (cachedData) {
6934
+ return cachedData;
6935
+ }
6936
+ const data = await collection.findOne({
6937
+ _id,
6938
+ status: { $ne: "deleted" }
6939
+ });
6940
+ setCache(cacheKey, data).then(() => {
6941
+ logger19.log({
6942
+ level: "info",
6943
+ message: `Cache set for getById ledger billing: ${cacheKey}`
6944
+ });
6945
+ }).catch((err) => {
6946
+ logger19.log({
6947
+ level: "error",
6948
+ message: `Failed to set cache for getById ledger billing: ${err.message}`
6949
+ });
6950
+ });
6951
+ return data;
6952
+ } catch (error2) {
6953
+ throw new InternalServerError19("Failed to get ledger billing.");
6954
+ }
6955
+ }
6956
+ return {
6957
+ delCachedData,
6958
+ createIndexes,
6959
+ add,
6960
+ getAll,
6961
+ getById
6962
+ };
6963
+ }
6964
+
6965
+ // src/resources/ledger/ledger.billing.controller.ts
6966
+ import Joi31 from "joi";
6967
+ import { BadRequestError as BadRequestError37 } from "@goweekdays/utils";
6968
+ function useLedgerBillingController() {
6969
+ const { getAll: _getAll, getById: _getById } = useLedgerBillingRepo();
6970
+ async function getAll(req, res, next) {
6971
+ const query = req.query;
6972
+ const validation = Joi31.object({
6973
+ org: Joi31.string().hex().optional().allow("", null),
6974
+ page: Joi31.number().min(1).optional().allow("", null),
6975
+ limit: Joi31.number().min(1).optional().allow("", null),
6976
+ search: Joi31.string().optional().allow("", null),
6977
+ status: Joi31.string().optional().allow("", null)
6978
+ });
6979
+ const { error } = validation.validate(query);
6980
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
6981
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
6982
+ const search = req.query.search ?? "";
6983
+ const org = req.query.org ?? "";
6984
+ const status = req.query.status ?? "";
6985
+ const isPageNumber = isFinite(page);
6986
+ if (!isPageNumber) {
6987
+ next(new BadRequestError37("Invalid page number."));
6988
+ return;
6989
+ }
6990
+ const isLimitNumber = isFinite(limit);
6991
+ if (!isLimitNumber) {
6992
+ next(new BadRequestError37("Invalid limit number."));
6993
+ return;
6994
+ }
6995
+ if (error) {
6996
+ next(new BadRequestError37(error.message));
6997
+ return;
6998
+ }
6999
+ try {
7000
+ const orgs = await _getAll({ org, page, limit, search, status });
7001
+ res.json(orgs);
7002
+ return;
7003
+ } catch (error2) {
7004
+ next(error2);
7005
+ }
7006
+ }
7007
+ async function getById(req, res, next) {
7008
+ const id = req.params.id;
7009
+ const validation = Joi31.object({
7010
+ id: Joi31.string().hex().required()
7011
+ });
7012
+ const { error } = validation.validate({ id });
7013
+ if (error) {
7014
+ next(new BadRequestError37(error.message));
7015
+ return;
7016
+ }
7017
+ try {
7018
+ const org = await _getById(id);
7019
+ res.json(org);
7020
+ return;
7021
+ } catch (error2) {
7022
+ next(error2);
7023
+ }
7024
+ }
7025
+ return {
7026
+ getAll,
7027
+ getById
7028
+ };
7029
+ }
7030
+
7031
+ // src/resources/organization/organization.service.ts
7032
+ function useOrgService() {
7033
+ const { add: addOrg } = useOrgRepo();
7034
+ const { addRole } = useRoleRepo();
7035
+ const { getAll: getAllPermission } = usePermissionRepo();
7036
+ const { add: addMember, updateRoleById: _updateRoleById } = useMemberRepo();
7037
+ const { getUserById } = useUserRepo();
7038
+ const { getDefault } = usePlanRepo();
7039
+ const { add: addSubscription } = useSubscriptionRepo();
7040
+ const { add: addSubscriptionTransaction } = useSubscriptionTransactionRepo();
7041
+ const { addOrder: addPaypalOrder } = usePaypalService();
7042
+ async function add(value) {
7043
+ const { error } = schemaOrgAdd.validate(value);
7044
+ if (error) {
7045
+ throw new BadRequestError38(error.message);
7046
+ }
7047
+ const session = useAtlas17.getClient()?.startSession();
7048
+ if (!session) {
7049
+ throw new BadRequestError38("Unable to start database session.");
7050
+ }
7051
+ try {
7052
+ session?.startTransaction();
7053
+ const org = await addOrg(
7054
+ {
7055
+ email: value.email,
7056
+ name: value.name,
7057
+ contact: value.contact,
7058
+ createdBy: value.createdBy
7059
+ },
7060
+ session
7061
+ );
7062
+ const plan = await getDefault();
7063
+ if (!plan) {
7064
+ throw new BadRequestError38(
7065
+ "Failed to create organization, plan not found."
7066
+ );
7067
+ }
7068
+ const currentDate = /* @__PURE__ */ new Date();
7069
+ const nextBillingDate = new Date(currentDate);
7070
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
7071
+ const amount = plan.price * value.seats;
7072
+ const subscriptionId = await addSubscription(
7073
+ {
7074
+ amount,
7075
+ org: String(org),
7076
+ seats: value.seats,
7077
+ paidSeats: value.seats,
7078
+ currency: plan.currency,
7079
+ billingCycle: plan.billingCycle,
7080
+ nextBillingDate
7081
+ },
7082
+ session
7083
+ );
7084
+ const createdBy = String(value.createdBy);
7085
+ const user = await getUserById(createdBy);
7086
+ if (!user) {
7087
+ throw new BadRequestError38("User is required to create org member.");
7088
+ }
7089
+ await addSubscriptionTransaction(
7090
+ {
7091
+ subscription: subscriptionId,
7092
+ type: "initiate",
7093
+ amount,
7094
+ currency: plan.currency,
7095
+ description: "Initial subscription transaction",
7096
+ createdBy: value.createdBy,
7097
+ createdByName: `${user.firstName} ${user.lastName}`
7098
+ },
7099
+ session
7100
+ );
7101
+ const allPermissions = await getAllPermission({
7102
+ app: "org",
7103
+ limit: 100
7104
+ });
7105
+ let permissions = [];
7106
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
7107
+ permissions = allPermissions.items.map((perm) => perm.key);
7108
+ }
7109
+ if (permissions.length === 0) {
7110
+ throw new Error("No permissions found for the organization type.");
7111
+ }
7112
+ const roleData = {
7113
+ org: String(org),
7114
+ name: "Owner",
7115
+ description: "Owner of the organization",
7116
+ permissions,
7117
+ createdBy,
7118
+ app: "org"
7119
+ };
7120
+ const role = await addRole(roleData, session);
7121
+ if (!role) {
7122
+ throw new BadRequestError38("Role is required to create org member.");
7123
+ }
7124
+ await addMember(
7125
+ {
7126
+ role: String(role),
7127
+ roleName: roleData.name,
7128
+ org: String(org),
7129
+ orgName: value.name,
7130
+ name: `${user.firstName} ${user.lastName}`,
7131
+ user: createdBy,
7132
+ app: "org"
7133
+ },
7134
+ session
7135
+ );
7136
+ const order = await addPaypalOrder({
7137
+ amount,
7138
+ currency: plan.currency,
7139
+ customId: subscriptionId,
7140
+ returnUrl: `${APP_ORG}/organizations/success`,
7141
+ cancelUrl: `${APP_ORG}/organizations/cancel`,
7142
+ action: "pay"
7143
+ });
7144
+ await session?.commitTransaction();
7145
+ const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
7146
+ (link) => link.rel === "approve"
7147
+ );
7148
+ return {
7149
+ org: String(org),
7150
+ paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
7151
+ };
7152
+ } catch (error2) {
7153
+ await session?.abortTransaction();
7154
+ throw error2;
7155
+ } finally {
7156
+ await session?.endSession();
7157
+ }
7158
+ }
7159
+ const { getById, updateStatusById: updateVerificationStatus } = useVerificationRepo();
7160
+ const { add: addLedgerBilling } = useLedgerBillingRepo();
7161
+ async function addWithVerification(id) {
7162
+ const { error } = Joi32.string().hex().required().validate(id);
7163
+ if (error) {
7164
+ throw new BadRequestError38(error.message);
7165
+ }
7166
+ const session = useAtlas17.getClient()?.startSession();
7167
+ if (!session) {
7168
+ throw new BadRequestError38("Unable to start database session.");
7169
+ }
7170
+ try {
7171
+ session?.startTransaction();
7172
+ const verification = await getById(id);
7173
+ await updateVerificationStatus(id, "complete", session);
7174
+ if (!verification) {
7175
+ throw new BadRequestError38("Verification not found.");
7176
+ }
7177
+ if (!verification.metadata?.orgName) {
7178
+ throw new BadRequestError38("Organization name is required.");
7179
+ }
7180
+ if (!verification.metadata?.seats) {
7181
+ throw new BadRequestError38("Number of seats is required.");
7182
+ }
7183
+ if (!verification.metadata?.createdBy) {
7184
+ throw new BadRequestError38("CreatedBy is required.");
7185
+ }
7186
+ if (!verification.metadata?.contact) {
7187
+ throw new BadRequestError38("Contact is required.");
7188
+ }
7189
+ const org = await addOrg(
7190
+ {
7191
+ email: verification.email,
7192
+ name: verification.metadata.orgName,
7193
+ contact: verification.metadata.contact,
7194
+ createdBy: verification.metadata.createdBy
7195
+ },
7196
+ session
7197
+ );
7198
+ const plan = await getDefault();
7199
+ if (!plan) {
7200
+ throw new BadRequestError38(
7201
+ "Failed to create organization, plan not found."
7202
+ );
7203
+ }
7204
+ const currentDate = /* @__PURE__ */ new Date();
7205
+ const nextBillingDate = new Date(currentDate);
7206
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
7207
+ const amount = plan.price * verification.metadata.seats;
7208
+ const subscriptionId = await addSubscription(
7209
+ {
7210
+ amount,
7211
+ org: String(org),
7212
+ seats: verification.metadata.seats,
7213
+ paidSeats: verification.metadata.seats,
7214
+ currency: plan.currency,
7215
+ billingCycle: plan.billingCycle,
7216
+ nextBillingDate
7217
+ },
7218
+ session
7219
+ );
7220
+ const createdBy = String(verification.metadata.createdBy);
7221
+ const user = await getUserById(createdBy);
7222
+ if (!user) {
7223
+ throw new BadRequestError38("User is required to create org member.");
7224
+ }
7225
+ await addSubscriptionTransaction(
7226
+ {
7227
+ subscription: subscriptionId,
7228
+ type: "initiate",
7229
+ amount,
7230
+ currency: plan.currency,
7231
+ description: "Initial subscription transaction",
7232
+ createdBy,
7233
+ createdByName: `${user.firstName} ${user.lastName}`
7234
+ },
7235
+ session
7236
+ );
7237
+ await addLedgerBilling(
7238
+ {
7239
+ org: String(org),
7240
+ amount: verification.metadata?.amount ?? 0,
7241
+ description: "Setup payment during organization creation",
7242
+ currency: plan.currency,
7243
+ type: "setup-fee",
7244
+ status: "completed"
7245
+ },
7246
+ session
7247
+ );
7248
+ const allPermissions = await getAllPermission({
7249
+ app: "org",
7250
+ limit: 100
7251
+ });
7252
+ let permissions = [];
7253
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
7254
+ permissions = allPermissions.items.map((perm) => perm.key);
7255
+ }
7256
+ if (permissions.length === 0) {
7257
+ throw new Error("No permissions found for the organization type.");
7258
+ }
7259
+ const roleData = {
7260
+ org: String(org),
7261
+ name: "Owner",
7262
+ description: "Owner of the organization",
7263
+ permissions,
7264
+ createdBy,
7265
+ app: "org"
7266
+ };
7267
+ const role = await addRole(roleData, session);
7268
+ if (!role) {
7269
+ throw new BadRequestError38("Role is required to create org member.");
7270
+ }
7271
+ await addMember(
7272
+ {
7273
+ role: String(role),
7274
+ roleName: roleData.name,
7275
+ org: String(org),
7276
+ orgName: verification.metadata.orgName,
7277
+ name: `${user.firstName} ${user.lastName}`,
7278
+ user: createdBy,
7279
+ app: "org"
7280
+ },
7281
+ session
7282
+ );
7283
+ await session?.commitTransaction();
7284
+ return "Successfully created organization with verification.";
7285
+ } catch (error2) {
7286
+ await session?.abortTransaction();
7287
+ throw error2;
7288
+ } finally {
7289
+ await session?.endSession();
7290
+ }
7291
+ }
7292
+ return {
7293
+ add,
7294
+ addWithVerification
7295
+ };
7296
+ }
7297
+
7298
+ // src/resources/organization/organization.controller.ts
7299
+ import { BadRequestError as BadRequestError39 } from "@goweekdays/utils";
7300
+ import Joi33 from "joi";
7301
+ function useOrgController() {
7302
+ const { add: _add } = useOrgService();
7303
+ const { getOrgsByMembership } = useMemberRepo();
7304
+ const {
7305
+ getByName: _getByName,
7306
+ getAll: getAllOrg,
7307
+ getById: _getById,
7308
+ updateById: _updateById
7309
+ } = useOrgRepo();
7310
+ async function add(req, res, next) {
7311
+ const value = req.body;
7312
+ const { error } = schemaOrgAdd.validate(value);
7313
+ if (error) {
7314
+ next(new BadRequestError39(error.message));
7315
+ return;
7316
+ }
7317
+ try {
7318
+ const data = await _add(value);
7319
+ res.json({
7320
+ message: "Organization created successfully.",
7321
+ data
7322
+ });
7323
+ return;
7324
+ } catch (error2) {
7325
+ next(error2);
7326
+ }
7327
+ }
7328
+ async function getOrgsByUserId(req, res, next) {
7329
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
7330
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
7331
+ const search = req.query.search ?? "";
7332
+ const user = req.params.user ?? "";
7333
+ const isPageNumber = isFinite(page);
7334
+ if (!isPageNumber) {
7335
+ next(new BadRequestError39("Invalid page number."));
7336
+ return;
7337
+ }
7338
+ const isLimitNumber = isFinite(limit);
7339
+ if (!isLimitNumber) {
7340
+ next(new BadRequestError39("Invalid limit number."));
7341
+ return;
7342
+ }
7343
+ const validation = Joi33.object({
7344
+ user: Joi33.string().hex().required(),
7345
+ page: Joi33.number().min(1).optional().allow("", null),
7346
+ limit: Joi33.number().min(1).optional().allow("", null),
7347
+ search: Joi33.string().optional().allow("", null)
7348
+ });
7349
+ const { error } = validation.validate({ user, page, limit, search });
7350
+ if (error) {
7351
+ next(new BadRequestError39(error.message));
7352
+ return;
7353
+ }
7354
+ try {
7355
+ const orgs = await getOrgsByMembership({ user, page, limit, search });
7356
+ res.json(orgs);
7357
+ return;
7358
+ } catch (error2) {
7359
+ next(error2);
7360
+ }
7361
+ }
7362
+ async function getAll(req, res, next) {
7363
+ const query = req.query;
7364
+ const validation = Joi33.object({
7365
+ page: Joi33.number().min(1).optional().allow("", null),
7366
+ limit: Joi33.number().min(1).optional().allow("", null),
7367
+ search: Joi33.string().optional().allow("", null),
7368
+ status: Joi33.string().valid("active", "suspended", "inactive", "deleted").optional()
7369
+ });
7370
+ const { error } = validation.validate(query);
7371
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
7372
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
7373
+ const search = req.query.search ?? "";
7374
+ const status = req.query.status ?? "active";
7375
+ const isPageNumber = isFinite(page);
7376
+ if (!isPageNumber) {
7377
+ next(new BadRequestError39("Invalid page number."));
7378
+ return;
7379
+ }
7380
+ const isLimitNumber = isFinite(limit);
7381
+ if (!isLimitNumber) {
7382
+ next(new BadRequestError39("Invalid limit number."));
7383
+ return;
7384
+ }
7385
+ if (error) {
7386
+ next(new BadRequestError39(error.message));
7387
+ return;
7388
+ }
7389
+ try {
7390
+ const orgs = await getAllOrg({ page, limit, search, status });
7391
+ res.json(orgs);
7392
+ return;
7393
+ } catch (error2) {
7394
+ next(error2);
7395
+ }
7396
+ }
7397
+ async function getByName(req, res, next) {
7398
+ const name = req.params.name;
7399
+ const validation = Joi33.object({
7400
+ name: Joi33.string().required()
7401
+ });
7402
+ const { error } = validation.validate({ name });
7403
+ if (error) {
7404
+ next(new BadRequestError39(error.message));
7405
+ return;
7406
+ }
7407
+ try {
7408
+ const org = await _getByName(name);
7409
+ res.json(org);
7410
+ return;
7411
+ } catch (error2) {
7412
+ next(error2);
7413
+ }
7414
+ }
7415
+ async function getById(req, res, next) {
7416
+ const id = req.params.id;
7417
+ const validation = Joi33.object({
7418
+ id: Joi33.string().hex().required()
7419
+ });
7420
+ const { error } = validation.validate({ id });
7421
+ if (error) {
7422
+ next(new BadRequestError39(error.message));
7423
+ return;
7424
+ }
7425
+ try {
7426
+ const org = await _getById(id);
7427
+ res.json(org);
7428
+ return;
7429
+ } catch (error2) {
7430
+ next(error2);
7431
+ }
7432
+ }
7433
+ async function updateById(req, res, next) {
7434
+ const _id = req.params.id ?? "";
7435
+ const payload = req.body;
7436
+ const { error } = schemaOrgUpdate.validate({ _id, ...payload });
7437
+ if (error) {
7438
+ next(new BadRequestError39(error.message));
7439
+ return;
7440
+ }
7441
+ try {
7442
+ const message = await _updateById(_id, payload);
7443
+ res.json({ message });
7444
+ return;
7445
+ } catch (error2) {
7446
+ next(error2);
7447
+ }
7448
+ }
7449
+ return {
7450
+ add,
7451
+ getOrgsByUserId,
7452
+ getByName,
7453
+ getAll,
7454
+ getById,
7455
+ updateById
7456
+ };
7457
+ }
7458
+
7459
+ // src/resources/user/user.service.ts
7460
+ function useUserService() {
7461
+ const {
7462
+ add: addUser,
7463
+ getUserByEmail,
7464
+ getUserById: _getById,
7465
+ updateName: _updateName,
7466
+ updateBirthday: _updateBirthday,
7467
+ updateUserFieldById: _updateUserFieldById
7468
+ } = useUserRepo();
7469
+ const { addRole, getById: getRoleById } = useRoleRepo();
7470
+ const { add: addMember } = useMemberRepo();
7471
+ const { getAll: getAllPermission } = usePermissionRepo();
7472
+ const { getById: getOrgById } = useOrgRepo();
7473
+ async function createDefaultUser() {
7474
+ const session = useAtlas18.getClient()?.startSession();
7475
+ try {
7476
+ session?.startTransaction();
7477
+ const _user = await getUserByEmail(DEFAULT_USER_EMAIL);
7478
+ if (_user) {
7479
+ throw new BadRequestError40(
7480
+ `User already exists: ${DEFAULT_USER_EMAIL}.`
7481
+ );
7482
+ }
7483
+ const hashedPassword = await hashPassword(DEFAULT_USER_PASSWORD);
7484
+ const userId = await addUser(
7485
+ {
7486
+ email: DEFAULT_USER_EMAIL,
7487
+ password: hashedPassword,
7488
+ firstName: DEFAULT_USER_FIRST_NAME,
7489
+ lastName: DEFAULT_USER_LAST_NAME
7490
+ },
6772
7491
  session
6773
7492
  );
6774
7493
  const permissions = await getAllPermission({ app: "admin", limit: 200 });
@@ -6807,7 +7526,7 @@ function useUserService() {
6807
7526
  try {
6808
7527
  const _user = await getUserByEmail(value.email);
6809
7528
  if (_user) {
6810
- throw new BadRequestError36(`User already exists: ${value.email}.`);
7529
+ throw new BadRequestError40(`User already exists: ${value.email}.`);
6811
7530
  }
6812
7531
  const hashedPassword = await hashPassword(value.password);
6813
7532
  const insertedId = await addUser({
@@ -6819,10 +7538,10 @@ function useUserService() {
6819
7538
  });
6820
7539
  return insertedId;
6821
7540
  } catch (error) {
6822
- if (error instanceof AppError14) {
7541
+ if (error instanceof AppError16) {
6823
7542
  throw error;
6824
7543
  } else {
6825
- throw new InternalServerError18(`Error creating user: ${error}`);
7544
+ throw new InternalServerError20(`Error creating user: ${error}`);
6826
7545
  }
6827
7546
  }
6828
7547
  }
@@ -6833,22 +7552,22 @@ function useUserService() {
6833
7552
  lastName = "",
6834
7553
  password = ""
6835
7554
  } = {}) {
6836
- const session = useAtlas17.getClient()?.startSession();
7555
+ const session = useAtlas18.getClient()?.startSession();
6837
7556
  session?.startTransaction();
6838
7557
  try {
6839
7558
  const invitation = await _getVerificationById(id);
6840
7559
  if (!invitation || !invitation.metadata?.app || !invitation.metadata?.role) {
6841
- throw new BadRequestError36("Invalid invitation.");
7560
+ throw new BadRequestError40("Invalid invitation.");
6842
7561
  }
6843
7562
  if (invitation.status === "complete") {
6844
- throw new BadRequestError36("Invitation already used.");
7563
+ throw new BadRequestError40("Invitation already used.");
6845
7564
  }
6846
7565
  if (!invitation.expireAt) {
6847
- throw new BadRequestError36("Expiration date is required.");
7566
+ throw new BadRequestError40("Expiration date is required.");
6848
7567
  }
6849
7568
  const expired = new Date(invitation.expireAt) < /* @__PURE__ */ new Date();
6850
7569
  if (invitation.status === "expired" || expired) {
6851
- throw new BadRequestError36("Invitation expired.");
7570
+ throw new BadRequestError40("Invitation expired.");
6852
7571
  }
6853
7572
  const email = invitation.email;
6854
7573
  const user = await getUserByEmail(invitation.email);
@@ -6899,10 +7618,10 @@ function useUserService() {
6899
7618
  return userId;
6900
7619
  } catch (error) {
6901
7620
  await session?.abortTransaction();
6902
- if (error instanceof AppError14) {
7621
+ if (error instanceof AppError16) {
6903
7622
  throw error;
6904
7623
  } else {
6905
- throw new InternalServerError18("Failed to create user by invite.");
7624
+ throw new InternalServerError20("Failed to create user by invite.");
6906
7625
  }
6907
7626
  } finally {
6908
7627
  session?.endSession();
@@ -6914,29 +7633,29 @@ function useUserService() {
6914
7633
  lastName = "",
6915
7634
  password = ""
6916
7635
  } = {}) {
6917
- const session = useAtlas17.getClient()?.startSession();
7636
+ const session = useAtlas18.getClient()?.startSession();
6918
7637
  session?.startTransaction();
6919
7638
  try {
6920
7639
  const signUp = await _getVerificationById(id);
6921
7640
  if (!signUp) {
6922
- throw new BadRequestError36("Invalid sign up link.");
7641
+ throw new BadRequestError40("Invalid sign up link.");
6923
7642
  }
6924
7643
  if (signUp.status === "complete") {
6925
- throw new BadRequestError36(
7644
+ throw new BadRequestError40(
6926
7645
  "You have already an account created using this link."
6927
7646
  );
6928
7647
  }
6929
7648
  if (!signUp.expireAt) {
6930
- throw new BadRequestError36("Expiration date is required.");
7649
+ throw new BadRequestError40("Expiration date is required.");
6931
7650
  }
6932
7651
  const expired = new Date(signUp.expireAt) < /* @__PURE__ */ new Date();
6933
7652
  if (signUp.status === "expired" || expired) {
6934
- throw new BadRequestError36("Sign up link expired.");
7653
+ throw new BadRequestError40("Sign up link expired.");
6935
7654
  }
6936
7655
  const email = signUp.email;
6937
7656
  const _user = await getUserByEmail(signUp.email);
6938
7657
  if (_user) {
6939
- throw new BadRequestError36(`User already exists: ${email}.`);
7658
+ throw new BadRequestError40(`User already exists: ${email}.`);
6940
7659
  }
6941
7660
  const hashedPassword = await hashPassword(password);
6942
7661
  const userId = await addUser(
@@ -6962,17 +7681,17 @@ function useUserService() {
6962
7681
  const { updateStatusById: updateVerificationStatusById } = useVerificationRepo();
6963
7682
  async function resetPassword(value) {
6964
7683
  if (value.newPassword !== value.confirmPassword) {
6965
- throw new BadRequestError36("Passwords do not match.");
7684
+ throw new BadRequestError40("Passwords do not match.");
6966
7685
  }
6967
7686
  let hashedPassword = "";
6968
7687
  try {
6969
7688
  hashedPassword = await hashPassword(value.newPassword);
6970
7689
  } catch (error) {
6971
- throw new InternalServerError18(`Error hashing password: ${error}`);
7690
+ throw new InternalServerError20(`Error hashing password: ${error}`);
6972
7691
  }
6973
- const session = useAtlas17.getClient()?.startSession();
7692
+ const session = useAtlas18.getClient()?.startSession();
6974
7693
  if (!session) {
6975
- throw new InternalServerError18("Failed to start database session.");
7694
+ throw new InternalServerError20("Failed to start database session.");
6976
7695
  }
6977
7696
  try {
6978
7697
  session.startTransaction();
@@ -6988,7 +7707,7 @@ function useUserService() {
6988
7707
  throw new NotFoundError2("User ID is invalid.");
6989
7708
  }
6990
7709
  if (otpDoc.status === "used") {
6991
- throw new BadRequestError36("This link has already been invalidated.");
7710
+ throw new BadRequestError40("This link has already been invalidated.");
6992
7711
  }
6993
7712
  await updateVerificationStatusById(value.id, "used", session);
6994
7713
  await _updateUserFieldById(
@@ -6999,31 +7718,31 @@ function useUserService() {
6999
7718
  return "Successfully reset password.";
7000
7719
  } catch (error) {
7001
7720
  await session.abortTransaction();
7002
- if (error instanceof AppError14) {
7721
+ if (error instanceof AppError16) {
7003
7722
  throw error;
7004
7723
  }
7005
- throw new InternalServerError18("Failed to reset password.");
7724
+ throw new InternalServerError20("Failed to reset password.");
7006
7725
  }
7007
7726
  }
7008
7727
  const { updateName: updateMemberName } = useMemberRepo();
7009
7728
  async function updateName(_id, firstName, lastName) {
7010
7729
  if (!_id) {
7011
- throw new BadRequestError36("Invalid user ID");
7730
+ throw new BadRequestError40("Invalid user ID");
7012
7731
  }
7013
7732
  if (!firstName) {
7014
- throw new BadRequestError36("Invalid firstName");
7733
+ throw new BadRequestError40("Invalid firstName");
7015
7734
  }
7016
7735
  if (!lastName) {
7017
- throw new BadRequestError36("Invalid lastName");
7736
+ throw new BadRequestError40("Invalid lastName");
7018
7737
  }
7019
- const session = useAtlas17.getClient()?.startSession();
7738
+ const session = useAtlas18.getClient()?.startSession();
7020
7739
  session?.startTransaction();
7021
- const cacheKey = makeCacheKey13("users", { user: _id });
7740
+ const cacheKey = makeCacheKey14("users", { user: _id });
7022
7741
  try {
7023
- useCache14().delCache(cacheKey).then(() => {
7024
- logger18.info(`Cache cleared for user: ${_id}`);
7742
+ useCache15().delCache(cacheKey).then(() => {
7743
+ logger20.info(`Cache cleared for user: ${_id}`);
7025
7744
  }).catch((error) => {
7026
- logger18.error(`Failed to clear cache for user: ${_id}`, error);
7745
+ logger20.error(`Failed to clear cache for user: ${_id}`, error);
7027
7746
  });
7028
7747
  await _updateName({ _id, firstName, lastName }, session);
7029
7748
  await updateMemberName(
@@ -7041,16 +7760,16 @@ function useUserService() {
7041
7760
  }
7042
7761
  async function updateBirthday(_id, month, day, year) {
7043
7762
  if (!_id) {
7044
- throw new BadRequestError36("Invalid user ID");
7763
+ throw new BadRequestError40("Invalid user ID");
7045
7764
  }
7046
7765
  if (!month) {
7047
- throw new BadRequestError36("Invalid birth month.");
7766
+ throw new BadRequestError40("Invalid birth month.");
7048
7767
  }
7049
7768
  if (!day) {
7050
- throw new BadRequestError36("Invalid birthday.");
7769
+ throw new BadRequestError40("Invalid birthday.");
7051
7770
  }
7052
7771
  if (!year) {
7053
- throw new BadRequestError36("Invalid birth year.");
7772
+ throw new BadRequestError40("Invalid birth year.");
7054
7773
  }
7055
7774
  try {
7056
7775
  await _updateBirthday({ _id, month, day, year });
@@ -7075,7 +7794,7 @@ function useUserService() {
7075
7794
  bucket: SPACES_BUCKET
7076
7795
  });
7077
7796
  async function updateUserProfile({ file, user, previousProfile } = {}) {
7078
- const session = useAtlas17.getClient()?.startSession();
7797
+ const session = useAtlas18.getClient()?.startSession();
7079
7798
  session?.startTransaction();
7080
7799
  const _file = {
7081
7800
  name: file.originalname,
@@ -7120,11 +7839,11 @@ function useUserService() {
7120
7839
 
7121
7840
  // src/resources/user/user.controller.ts
7122
7841
  import {
7123
- AppError as AppError15,
7124
- BadRequestError as BadRequestError37,
7125
- InternalServerError as InternalServerError19
7842
+ AppError as AppError17,
7843
+ BadRequestError as BadRequestError41,
7844
+ InternalServerError as InternalServerError21
7126
7845
  } from "@goweekdays/utils";
7127
- import Joi28 from "joi";
7846
+ import Joi34 from "joi";
7128
7847
  function useUserController() {
7129
7848
  const {
7130
7849
  updateName: _updateName,
@@ -7140,14 +7859,14 @@ function useUserController() {
7140
7859
  const status = req.query.status ?? "";
7141
7860
  const search = req.query.search ?? "";
7142
7861
  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()
7862
+ const validation = Joi34.object({
7863
+ status: Joi34.string().required(),
7864
+ search: Joi34.string().optional().allow("", null),
7865
+ page: Joi34.number().required()
7147
7866
  });
7148
7867
  const { error } = validation.validate({ status, search, page });
7149
7868
  if (error) {
7150
- next(new BadRequestError37(error.message));
7869
+ next(new BadRequestError41(error.message));
7151
7870
  return;
7152
7871
  }
7153
7872
  try {
@@ -7160,14 +7879,14 @@ function useUserController() {
7160
7879
  }
7161
7880
  async function getUserById(req, res, next) {
7162
7881
  const id = req.params.id || "";
7163
- const validation = Joi28.string().hex().validate(id);
7882
+ const validation = Joi34.string().hex().validate(id);
7164
7883
  if (validation.error) {
7165
- throw new BadRequestError37("Invalid id.");
7884
+ throw new BadRequestError41("Invalid id.");
7166
7885
  }
7167
7886
  try {
7168
7887
  const user = await _getUserById(id);
7169
7888
  if (!user) {
7170
- throw new BadRequestError37("User not found.");
7889
+ throw new BadRequestError41("User not found.");
7171
7890
  }
7172
7891
  res.json(user);
7173
7892
  } catch (error) {
@@ -7178,13 +7897,13 @@ function useUserController() {
7178
7897
  const id = req.headers.user ?? "";
7179
7898
  const firstName = req.body.firstName ?? "";
7180
7899
  const lastName = req.body.lastName ?? "";
7181
- const validation = Joi28.object({
7182
- firstName: Joi28.string().required(),
7183
- lastName: Joi28.string().required()
7900
+ const validation = Joi34.object({
7901
+ firstName: Joi34.string().required(),
7902
+ lastName: Joi34.string().required()
7184
7903
  });
7185
7904
  const { error } = validation.validate({ firstName, lastName });
7186
7905
  if (error) {
7187
- next(new BadRequestError37(error.message));
7906
+ next(new BadRequestError41(error.message));
7188
7907
  return;
7189
7908
  }
7190
7909
  try {
@@ -7200,14 +7919,14 @@ function useUserController() {
7200
7919
  const month = req.body.month ?? "";
7201
7920
  const day = req.body.day ?? 0;
7202
7921
  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()
7922
+ const validation = Joi34.object({
7923
+ month: Joi34.string().required(),
7924
+ day: Joi34.number().integer().min(1).max(31).required(),
7925
+ year: Joi34.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
7207
7926
  });
7208
7927
  const { error } = validation.validate({ month, day, year });
7209
7928
  if (error) {
7210
- next(new BadRequestError37(error.message));
7929
+ next(new BadRequestError41(error.message));
7211
7930
  return;
7212
7931
  }
7213
7932
  try {
@@ -7221,18 +7940,18 @@ function useUserController() {
7221
7940
  async function updateUserFieldById(req, res, next) {
7222
7941
  const _id = req.params.id;
7223
7942
  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", {
7943
+ const validation = Joi34.object({
7944
+ _id: Joi34.string().hex().required(),
7945
+ field: Joi34.string().valid("gender", "email", "contact", "profile").required(),
7946
+ value: Joi34.alternatives().conditional("field", {
7228
7947
  is: "email",
7229
- then: Joi28.string().email().required(),
7230
- otherwise: Joi28.string().required()
7948
+ then: Joi34.string().email().required(),
7949
+ otherwise: Joi34.string().required()
7231
7950
  })
7232
7951
  });
7233
7952
  const { error } = validation.validate({ _id, field, value });
7234
7953
  if (error) {
7235
- next(new BadRequestError37(error.message));
7954
+ next(new BadRequestError41(error.message));
7236
7955
  return;
7237
7956
  }
7238
7957
  try {
@@ -7248,12 +7967,12 @@ function useUserController() {
7248
7967
  return;
7249
7968
  }
7250
7969
  const previousProfile = req.body.previousProfile ?? "";
7251
- const validation = Joi28.object({
7252
- previousProfile: Joi28.string().hex().optional().allow("", null)
7970
+ const validation = Joi34.object({
7971
+ previousProfile: Joi34.string().hex().optional().allow("", null)
7253
7972
  });
7254
7973
  const { error } = validation.validate({ previousProfile });
7255
7974
  if (error) {
7256
- next(new BadRequestError37(error.message));
7975
+ next(new BadRequestError41(error.message));
7257
7976
  return;
7258
7977
  }
7259
7978
  const user = req.headers["user"] ?? "";
@@ -7266,10 +7985,10 @@ function useUserController() {
7266
7985
  res.json({ message: "Successfully updated profile picture." });
7267
7986
  return;
7268
7987
  } catch (error2) {
7269
- if (error2 instanceof AppError15) {
7988
+ if (error2 instanceof AppError17) {
7270
7989
  next(error2);
7271
7990
  } else {
7272
- next(new InternalServerError19(error2));
7991
+ next(new InternalServerError21(error2));
7273
7992
  }
7274
7993
  }
7275
7994
  }
@@ -7279,12 +7998,12 @@ function useUserController() {
7279
7998
  const password = req.body.password ?? "";
7280
7999
  const id = req.params.id ?? "";
7281
8000
  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()
8001
+ const validation = Joi34.object({
8002
+ firstName: Joi34.string().required(),
8003
+ lastName: Joi34.string().required(),
8004
+ password: Joi34.string().required(),
8005
+ id: Joi34.string().hex().required(),
8006
+ type: Joi34.string().required()
7288
8007
  });
7289
8008
  const { error } = validation.validate({
7290
8009
  firstName,
@@ -7294,7 +8013,7 @@ function useUserController() {
7294
8013
  type
7295
8014
  });
7296
8015
  if (error) {
7297
- next(new BadRequestError37(error.message));
8016
+ next(new BadRequestError41(error.message));
7298
8017
  return;
7299
8018
  }
7300
8019
  try {
@@ -7317,14 +8036,14 @@ function useUserController() {
7317
8036
  }
7318
8037
  async function resetPassword(req, res, next) {
7319
8038
  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()
8039
+ const validation = Joi34.object({
8040
+ id: Joi34.string().hex().required(),
8041
+ newPassword: Joi34.string().min(8).required(),
8042
+ confirmPassword: Joi34.string().min(8).required()
7324
8043
  });
7325
8044
  const { error } = validation.validate(payload);
7326
8045
  if (error) {
7327
- next(new BadRequestError37(error.message));
8046
+ next(new BadRequestError41(error.message));
7328
8047
  return;
7329
8048
  }
7330
8049
  try {
@@ -7349,7 +8068,7 @@ function useUserController() {
7349
8068
  }
7350
8069
 
7351
8070
  // src/resources/verification/verification.service.ts
7352
- import Joi29 from "joi";
8071
+ import Joi35 from "joi";
7353
8072
  function useVerificationService() {
7354
8073
  const MailerConfig = {
7355
8074
  host: MAILER_TRANSPORT_HOST,
@@ -7384,7 +8103,7 @@ function useVerificationService() {
7384
8103
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
7385
8104
  };
7386
8105
  if (!metadata.app) {
7387
- throw new BadRequestError38("App metadata is required.");
8106
+ throw new BadRequestError42("App metadata is required.");
7388
8107
  }
7389
8108
  try {
7390
8109
  const user = await getUserByEmail(email);
@@ -7407,7 +8126,7 @@ function useVerificationService() {
7407
8126
  html: emailContent2,
7408
8127
  from: "GoWeekdays"
7409
8128
  }).catch((error) => {
7410
- logger19.log({
8129
+ logger21.log({
7411
8130
  level: "error",
7412
8131
  message: `Error sending user invite email: ${error}`
7413
8132
  });
@@ -7429,7 +8148,7 @@ function useVerificationService() {
7429
8148
  html: emailContent,
7430
8149
  from: "GoWeekdays"
7431
8150
  }).catch((error) => {
7432
- logger19.log({
8151
+ logger21.log({
7433
8152
  level: "error",
7434
8153
  message: `Error sending user invite email: ${error}`
7435
8154
  });
@@ -7464,14 +8183,14 @@ function useVerificationService() {
7464
8183
  from: "GoWeekdays",
7465
8184
  html: emailContent
7466
8185
  }).catch((error) => {
7467
- logger19.log({
8186
+ logger21.log({
7468
8187
  level: "error",
7469
8188
  message: `Error sending forget password email: ${error}`
7470
8189
  });
7471
8190
  });
7472
8191
  return "Successfully created a link to reset password. Please check your email.";
7473
8192
  } catch (error) {
7474
- throw new InternalServerError20("Failed to create forget password link.");
8193
+ throw new InternalServerError22("Failed to create forget password link.");
7475
8194
  }
7476
8195
  }
7477
8196
  async function getById(id) {
@@ -7510,34 +8229,34 @@ function useVerificationService() {
7510
8229
  }
7511
8230
  function errorByType(type, status) {
7512
8231
  if (type === "user-invite" && status === "expired") {
7513
- throw new BadRequestError38(
8232
+ throw new BadRequestError42(
7514
8233
  "Invitation has already expired, please contact admin to resend the invitation."
7515
8234
  );
7516
8235
  }
7517
8236
  if (type === "user-sign-up" && status === "expired") {
7518
- throw new BadRequestError38(
8237
+ throw new BadRequestError42(
7519
8238
  "Sign up verification has expired, please sign up again to get a new verification link."
7520
8239
  );
7521
8240
  }
7522
8241
  if (type === "user-invite" && status === "complete") {
7523
- throw new BadRequestError38(
8242
+ throw new BadRequestError42(
7524
8243
  "User already registered, please login to continue."
7525
8244
  );
7526
8245
  }
7527
8246
  if (type === "forget-password" && status === "complete") {
7528
- throw new BadRequestError38(
8247
+ throw new BadRequestError42(
7529
8248
  "Forget password verification has already been used, please request a new one."
7530
8249
  );
7531
8250
  }
7532
8251
  if (type === "forget-password" && status === "expired") {
7533
- throw new BadRequestError38(
8252
+ throw new BadRequestError42(
7534
8253
  "Forget password verification has expired, please request a new one."
7535
8254
  );
7536
8255
  }
7537
- throw new BadRequestError38("Invalid verification.");
8256
+ throw new BadRequestError42("Invalid verification.");
7538
8257
  }
7539
8258
  async function verify(id) {
7540
- const session = useAtlas18.getClient()?.startSession();
8259
+ const session = useAtlas19.getClient()?.startSession();
7541
8260
  session?.startTransaction();
7542
8261
  try {
7543
8262
  const _id = await _getById(id);
@@ -7548,10 +8267,10 @@ function useVerificationService() {
7548
8267
  errorByType(_id.type, "expired");
7549
8268
  }
7550
8269
  if (_id.status === "complete") {
7551
- throw new BadRequestError38("Verification already completed.");
8270
+ throw new BadRequestError42("Verification already completed.");
7552
8271
  }
7553
8272
  if (!_id.expireAt) {
7554
- throw new BadRequestError38("Expiration date is required.");
8273
+ throw new BadRequestError42("Expiration date is required.");
7555
8274
  }
7556
8275
  const expiration = new Date(_id.expireAt).getTime();
7557
8276
  const now = (/* @__PURE__ */ new Date()).getTime();
@@ -7567,12 +8286,12 @@ function useVerificationService() {
7567
8286
  throw new NotFoundError3("User not found for member invite.");
7568
8287
  }
7569
8288
  if (!_id.metadata?.app) {
7570
- throw new BadRequestError38(
8289
+ throw new BadRequestError42(
7571
8290
  "App metadata is required for member invite."
7572
8291
  );
7573
8292
  }
7574
8293
  if (!_id.metadata?.role || !_id.metadata?.roleName) {
7575
- throw new BadRequestError38(
8294
+ throw new BadRequestError42(
7576
8295
  "Role metadata is required for member invite."
7577
8296
  );
7578
8297
  }
@@ -7594,7 +8313,7 @@ function useVerificationService() {
7594
8313
  return _id;
7595
8314
  } catch (error) {
7596
8315
  await session?.abortTransaction();
7597
- logger19.log({
8316
+ logger21.log({
7598
8317
  level: "info",
7599
8318
  message: `Error verifying user invitation: ${error}`
7600
8319
  });
@@ -7607,7 +8326,7 @@ function useVerificationService() {
7607
8326
  try {
7608
8327
  await updateStatusById(id, "cancelled");
7609
8328
  } catch (error) {
7610
- throw new InternalServerError20(
8329
+ throw new InternalServerError22(
7611
8330
  `Error cancelling user invitation: ${error}`
7612
8331
  );
7613
8332
  }
@@ -7627,7 +8346,7 @@ function useVerificationService() {
7627
8346
  try {
7628
8347
  const user = await getUserByEmail(email);
7629
8348
  if (user) {
7630
- throw new BadRequestError38(
8349
+ throw new BadRequestError42(
7631
8350
  `Email ${email} is already registered, please login to continue.`
7632
8351
  );
7633
8352
  }
@@ -7654,7 +8373,7 @@ function useVerificationService() {
7654
8373
  html: emailContent,
7655
8374
  from: "GoWeekdays"
7656
8375
  }).catch((error) => {
7657
- logger19.log({
8376
+ logger21.log({
7658
8377
  level: "error",
7659
8378
  message: `Error sending user invite email: ${error}`
7660
8379
  });
@@ -7667,7 +8386,7 @@ function useVerificationService() {
7667
8386
  async function inviteMember(value) {
7668
8387
  const { error } = schemaInviteMember.validate(value);
7669
8388
  if (error) {
7670
- throw new BadRequestError38(error.message);
8389
+ throw new BadRequestError42(error.message);
7671
8390
  }
7672
8391
  const role = await getRoleById(value.role);
7673
8392
  if (!role) {
@@ -7712,7 +8431,7 @@ function useVerificationService() {
7712
8431
  html: emailContent2,
7713
8432
  from: "GoWeekdays"
7714
8433
  }).catch((error2) => {
7715
- logger19.log({
8434
+ logger21.log({
7716
8435
  level: "error",
7717
8436
  message: `Error sending user invite email: ${error2}`
7718
8437
  });
@@ -7734,24 +8453,24 @@ function useVerificationService() {
7734
8453
  html: emailContent,
7735
8454
  from: "GoWeekdays"
7736
8455
  }).catch((error2) => {
7737
- logger19.log({
8456
+ logger21.log({
7738
8457
  level: "error",
7739
8458
  message: `Error sending user invite email: ${error2}`
7740
8459
  });
7741
8460
  });
7742
8461
  return verificationId;
7743
8462
  } catch (error2) {
7744
- if (error2 instanceof AppError16) {
8463
+ if (error2 instanceof AppError18) {
7745
8464
  throw error2;
7746
8465
  } else {
7747
- throw new InternalServerError20("Failed to invite member.");
8466
+ throw new InternalServerError22("Failed to invite member.");
7748
8467
  }
7749
8468
  }
7750
8469
  }
7751
8470
  async function cancelInviteMember(id) {
7752
- const { error } = Joi29.string().hex().required().validate(id);
8471
+ const { error } = Joi35.string().hex().required().validate(id);
7753
8472
  if (error) {
7754
- throw new BadRequestError38("Invalid verification ID.");
8473
+ throw new BadRequestError42("Invalid verification ID.");
7755
8474
  }
7756
8475
  try {
7757
8476
  const invite = await _getById(id);
@@ -7759,25 +8478,25 @@ function useVerificationService() {
7759
8478
  throw new NotFoundError3("Invitation not found.");
7760
8479
  }
7761
8480
  if (invite.status === "cancelled") {
7762
- throw new BadRequestError38("Invitation already cancelled.");
8481
+ throw new BadRequestError42("Invitation already cancelled.");
7763
8482
  }
7764
8483
  if (invite.status === "complete") {
7765
- throw new BadRequestError38("Cannot cancel a completed invitation.");
8484
+ throw new BadRequestError42("Cannot cancel a completed invitation.");
7766
8485
  }
7767
8486
  await _updateStatusById(id, "cancelled");
7768
8487
  return "Successfully cancelled the invitation.";
7769
8488
  } catch (error2) {
7770
- if (error2 instanceof AppError16) {
8489
+ if (error2 instanceof AppError18) {
7771
8490
  throw error2;
7772
8491
  } else {
7773
- throw new InternalServerError20("Failed to cancel the invitation.");
8492
+ throw new InternalServerError22("Failed to cancel the invitation.");
7774
8493
  }
7775
8494
  }
7776
8495
  }
7777
8496
  async function forgetPassword(email) {
7778
- const { error } = Joi29.string().email().required().validate(email);
8497
+ const { error } = Joi35.string().email().required().validate(email);
7779
8498
  if (error) {
7780
- throw new BadRequestError38("Invalid email address.");
8499
+ throw new BadRequestError42("Invalid email address.");
7781
8500
  }
7782
8501
  try {
7783
8502
  const member = await getUserByEmail(email);
@@ -7806,20 +8525,76 @@ function useVerificationService() {
7806
8525
  from: "GoWeekdays",
7807
8526
  html: emailContent
7808
8527
  }).catch((error2) => {
7809
- logger19.log({
8528
+ logger21.log({
7810
8529
  level: "error",
7811
8530
  message: `Error sending forget password email: ${error2}`
7812
8531
  });
7813
8532
  });
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
- );
8533
+ return "Successfully created a link to reset password. Please check your email.";
8534
+ } catch (error2) {
8535
+ if (error2 instanceof AppError18) {
8536
+ throw error2;
8537
+ } else {
8538
+ throw new InternalServerError22(
8539
+ "Failed to process forget password request."
8540
+ );
8541
+ }
8542
+ }
8543
+ }
8544
+ const { addOrder: addPaypalOrder } = usePaypalService();
8545
+ const { getByEmail: getOrgByEmail, getByName: getOrgByName } = useOrgRepo();
8546
+ async function orgSetupFee(value) {
8547
+ const session = useAtlas19.getClient()?.startSession();
8548
+ if (!session) {
8549
+ throw new BadRequestError42("Unable to start database session.");
8550
+ }
8551
+ try {
8552
+ session.startTransaction();
8553
+ const orgExistingByName = await getOrgByName(value.name);
8554
+ if (orgExistingByName) {
8555
+ throw new BadRequestError42(`Name ${value.name} is already taken.`);
8556
+ }
8557
+ const orgExistingByEmail = await getOrgByEmail(value.email);
8558
+ if (orgExistingByEmail) {
8559
+ throw new BadRequestError42(`Email ${value.email} is already taken.`);
8560
+ }
8561
+ const amount = 100;
8562
+ const verificationId = await add(
8563
+ {
8564
+ type: "org-setup-fee",
8565
+ email: value.email,
8566
+ metadata: {
8567
+ seats: value.seats,
8568
+ contact: value.contact,
8569
+ orgName: value.name,
8570
+ createdBy: value.createdBy,
8571
+ amount
8572
+ }
8573
+ },
8574
+ session
8575
+ );
8576
+ const order = await addPaypalOrder({
8577
+ amount,
8578
+ currency: "PHP",
8579
+ customId: String(verificationId),
8580
+ returnUrl: `${APP_ORG}/organizations/success`,
8581
+ cancelUrl: `${APP_ORG}/organizations/cancel`,
8582
+ action: "pay"
8583
+ });
8584
+ await session?.commitTransaction();
8585
+ const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
8586
+ (link) => link.rel === "approve"
8587
+ );
8588
+ return {
8589
+ paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
8590
+ };
8591
+ } catch (error) {
8592
+ if (error instanceof AppError18) {
8593
+ throw error;
7822
8594
  }
8595
+ throw new InternalServerError22(
8596
+ "Failed to process organization setup fee."
8597
+ );
7823
8598
  }
7824
8599
  }
7825
8600
  return {
@@ -7833,7 +8608,8 @@ function useVerificationService() {
7833
8608
  signUp,
7834
8609
  inviteMember,
7835
8610
  cancelInviteMember,
7836
- forgetPassword
8611
+ forgetPassword,
8612
+ orgSetupFee
7837
8613
  };
7838
8614
  }
7839
8615
 
@@ -7843,13 +8619,13 @@ function useAuthController() {
7843
8619
  async function login(req, res, next) {
7844
8620
  const email = req.body.email;
7845
8621
  const password = req.body.password;
7846
- const validation = Joi30.object({
7847
- email: Joi30.string().email().required(),
7848
- password: Joi30.string().required()
8622
+ const validation = Joi36.object({
8623
+ email: Joi36.string().email().required(),
8624
+ password: Joi36.string().required()
7849
8625
  });
7850
8626
  const { error } = validation.validate({ email, password });
7851
8627
  if (error) {
7852
- next(new BadRequestError39(error.message));
8628
+ next(new BadRequestError43(error.message));
7853
8629
  return;
7854
8630
  }
7855
8631
  try {
@@ -7865,14 +8641,14 @@ function useAuthController() {
7865
8641
  res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json({ message: "Login successful" });
7866
8642
  return;
7867
8643
  } catch (error2) {
7868
- logger20.log({
8644
+ logger22.log({
7869
8645
  level: "error",
7870
8646
  message: `Error during login: ${error2.message}`
7871
8647
  });
7872
- if (error2 instanceof AppError17) {
8648
+ if (error2 instanceof AppError19) {
7873
8649
  next(error2);
7874
8650
  } else {
7875
- next(new InternalServerError21("An unexpected error occurred"));
8651
+ next(new InternalServerError23("An unexpected error occurred"));
7876
8652
  }
7877
8653
  return;
7878
8654
  }
@@ -7880,17 +8656,17 @@ function useAuthController() {
7880
8656
  async function logout(req, res, next) {
7881
8657
  const sid = req.headers["authorization"] ?? "";
7882
8658
  if (!sid) {
7883
- next(new BadRequestError39("Session ID is required"));
8659
+ next(new BadRequestError43("Session ID is required"));
7884
8660
  return;
7885
8661
  }
7886
8662
  try {
7887
8663
  await useAuthService().logout(sid);
7888
8664
  res.json({ message: "Logged out successfully" });
7889
8665
  } catch (error) {
7890
- if (error instanceof AppError17) {
8666
+ if (error instanceof AppError19) {
7891
8667
  next(error);
7892
8668
  } else {
7893
- next(new InternalServerError21("An unexpected error occurred"));
8669
+ next(new InternalServerError23("An unexpected error occurred"));
7894
8670
  }
7895
8671
  }
7896
8672
  }
@@ -7901,64 +8677,64 @@ function useAuthController() {
7901
8677
  }
7902
8678
 
7903
8679
  // 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)
8680
+ import { BadRequestError as BadRequestError44, logger as logger23 } from "@goweekdays/utils";
8681
+ import Joi37 from "joi";
8682
+ import { ObjectId as ObjectId22 } from "mongodb";
8683
+ var schemaBuilding = Joi37.object({
8684
+ _id: Joi37.string().hex().optional(),
8685
+ school: Joi37.string().hex().required(),
8686
+ serial: Joi37.string().optional().allow("", null),
8687
+ name: Joi37.string().required(),
8688
+ levels: Joi37.number().integer().min(1).required(),
8689
+ createdAt: Joi37.date().optional().allow("", null),
8690
+ updatedAt: Joi37.date().optional().allow("", null),
8691
+ deletedAt: Joi37.date().optional().allow("", null),
8692
+ status: Joi37.string().optional().allow("", null)
7917
8693
  });
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)
8694
+ var schemaBuildingUnit = Joi37.object({
8695
+ _id: Joi37.string().hex().optional(),
8696
+ school: Joi37.string().hex().required(),
8697
+ name: Joi37.string().optional().allow("", null),
8698
+ building: Joi37.string().hex().required(),
8699
+ buildingName: Joi37.string().optional().allow("", null),
8700
+ level: Joi37.number().integer().min(1).required(),
8701
+ category: Joi37.string().required(),
8702
+ type: Joi37.string().required(),
8703
+ seating_capacity: Joi37.number().integer().min(0).required(),
8704
+ standing_capacity: Joi37.number().integer().min(0).required(),
8705
+ description: Joi37.string().optional().allow("", null),
8706
+ unit_of_measurement: Joi37.string().valid("sqm").required(),
8707
+ area: Joi37.number().positive().required(),
8708
+ status: Joi37.string().optional().allow("", null)
7933
8709
  });
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)
8710
+ var schemaUpdateOptions = Joi37.object({
8711
+ name: Joi37.string().optional().allow("", null),
8712
+ building: Joi37.string().hex().optional().allow("", null),
8713
+ buildingName: Joi37.string().optional().allow("", null),
8714
+ level: Joi37.number().integer().min(1).optional().allow("", null),
8715
+ category: Joi37.string().optional().allow("", null),
8716
+ type: Joi37.string().optional().allow("", null),
8717
+ seating_capacity: Joi37.number().integer().min(0).optional().allow("", null),
8718
+ standing_capacity: Joi37.number().integer().min(0).optional().allow("", null),
8719
+ area: Joi37.number().positive().optional().allow("", null)
7944
8720
  });
7945
8721
  function MBuilding(value) {
7946
8722
  const { error } = schemaBuilding.validate(value);
7947
8723
  if (error) {
7948
- logger21.info(`Building Model: ${error.message}`);
7949
- throw new BadRequestError40(error.message);
8724
+ logger23.info(`Building Model: ${error.message}`);
8725
+ throw new BadRequestError44(error.message);
7950
8726
  }
7951
8727
  if (value._id && typeof value._id === "string") {
7952
8728
  try {
7953
- value._id = new ObjectId20(value._id);
8729
+ value._id = new ObjectId22(value._id);
7954
8730
  } catch (error2) {
7955
- throw new BadRequestError40("Invalid _id format");
8731
+ throw new BadRequestError44("Invalid _id format");
7956
8732
  }
7957
8733
  }
7958
8734
  try {
7959
- value.school = new ObjectId20(value.school);
8735
+ value.school = new ObjectId22(value.school);
7960
8736
  } catch (error2) {
7961
- throw new BadRequestError40("Invalid school format");
8737
+ throw new BadRequestError44("Invalid school format");
7962
8738
  }
7963
8739
  return {
7964
8740
  _id: value._id ?? void 0,
@@ -7975,25 +8751,25 @@ function MBuilding(value) {
7975
8751
  function MBuildingUnit(value) {
7976
8752
  const { error } = schemaBuildingUnit.validate(value);
7977
8753
  if (error) {
7978
- logger21.info(`Building Unit Model: ${error.message}`);
7979
- throw new BadRequestError40(error.message);
8754
+ logger23.info(`Building Unit Model: ${error.message}`);
8755
+ throw new BadRequestError44(error.message);
7980
8756
  }
7981
8757
  if (value._id && typeof value._id === "string") {
7982
8758
  try {
7983
- value._id = new ObjectId20(value._id);
8759
+ value._id = new ObjectId22(value._id);
7984
8760
  } catch (error2) {
7985
- throw new BadRequestError40("Invalid ID");
8761
+ throw new BadRequestError44("Invalid ID");
7986
8762
  }
7987
8763
  }
7988
8764
  try {
7989
- value.school = new ObjectId20(value.school);
8765
+ value.school = new ObjectId22(value.school);
7990
8766
  } catch (error2) {
7991
- throw new BadRequestError40("Invalid school ID");
8767
+ throw new BadRequestError44("Invalid school ID");
7992
8768
  }
7993
8769
  try {
7994
- value.building = new ObjectId20(value.building);
8770
+ value.building = new ObjectId22(value.building);
7995
8771
  } catch (error2) {
7996
- throw new BadRequestError40("Invalid building ID");
8772
+ throw new BadRequestError44("Invalid building ID");
7997
8773
  }
7998
8774
  return {
7999
8775
  _id: value._id ?? void 0,
@@ -8018,24 +8794,24 @@ function MBuildingUnit(value) {
8018
8794
 
8019
8795
  // src/resources/building/building.repository.ts
8020
8796
  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
8797
+ AppError as AppError20,
8798
+ BadRequestError as BadRequestError45,
8799
+ InternalServerError as InternalServerError24,
8800
+ logger as logger24,
8801
+ makeCacheKey as makeCacheKey15,
8802
+ paginate as paginate13,
8803
+ useAtlas as useAtlas20,
8804
+ useCache as useCache16
8029
8805
  } from "@goweekdays/utils";
8030
- import { ObjectId as ObjectId21 } from "mongodb";
8806
+ import { ObjectId as ObjectId23 } from "mongodb";
8031
8807
  function useBuildingRepo() {
8032
- const db = useAtlas19.getDb();
8808
+ const db = useAtlas20.getDb();
8033
8809
  if (!db) {
8034
8810
  throw new Error("Unable to connect to server.");
8035
8811
  }
8036
8812
  const namespace_collection = "school.buildings";
8037
8813
  const collection = db.collection(namespace_collection);
8038
- const { getCache, setCache, delNamespace } = useCache15(namespace_collection);
8814
+ const { getCache, setCache, delNamespace } = useCache16(namespace_collection);
8039
8815
  async function createIndexes() {
8040
8816
  try {
8041
8817
  await collection.createIndexes([
@@ -8054,16 +8830,16 @@ function useBuildingRepo() {
8054
8830
  delCachedData();
8055
8831
  return res.insertedId;
8056
8832
  } catch (error) {
8057
- logger22.log({
8833
+ logger24.log({
8058
8834
  level: "error",
8059
8835
  message: error.message
8060
8836
  });
8061
- if (error instanceof AppError18) {
8837
+ if (error instanceof AppError20) {
8062
8838
  throw error;
8063
8839
  } else {
8064
8840
  const isDuplicated = error.message.includes("duplicate");
8065
8841
  if (isDuplicated) {
8066
- throw new BadRequestError41("Building already exists.");
8842
+ throw new BadRequestError45("Building already exists.");
8067
8843
  }
8068
8844
  throw new Error("Failed to create building.");
8069
8845
  }
@@ -8071,9 +8847,9 @@ function useBuildingRepo() {
8071
8847
  }
8072
8848
  async function updateById(_id, value, session) {
8073
8849
  try {
8074
- _id = new ObjectId21(_id);
8850
+ _id = new ObjectId23(_id);
8075
8851
  } catch (error) {
8076
- throw new BadRequestError41("Invalid ID.");
8852
+ throw new BadRequestError45("Invalid ID.");
8077
8853
  }
8078
8854
  try {
8079
8855
  const res = await collection.updateOne(
@@ -8084,11 +8860,11 @@ function useBuildingRepo() {
8084
8860
  delCachedData();
8085
8861
  return res;
8086
8862
  } catch (error) {
8087
- logger22.log({
8863
+ logger24.log({
8088
8864
  level: "error",
8089
8865
  message: error.message
8090
8866
  });
8091
- if (error instanceof AppError18) {
8867
+ if (error instanceof AppError20) {
8092
8868
  throw error;
8093
8869
  } else {
8094
8870
  throw new Error("Failed to update building.");
@@ -8113,9 +8889,9 @@ function useBuildingRepo() {
8113
8889
  }
8114
8890
  if (school) {
8115
8891
  try {
8116
- query.school = new ObjectId21(school);
8892
+ query.school = new ObjectId23(school);
8117
8893
  } catch (error) {
8118
- throw new BadRequestError41("Invalid school ID.");
8894
+ throw new BadRequestError45("Invalid school ID.");
8119
8895
  }
8120
8896
  }
8121
8897
  const cacheParams = {
@@ -8129,15 +8905,15 @@ function useBuildingRepo() {
8129
8905
  cacheParams.school = school;
8130
8906
  if (status !== "active")
8131
8907
  cacheParams.status = status;
8132
- const cacheKey = makeCacheKey14(namespace_collection, cacheParams);
8133
- logger22.log({
8908
+ const cacheKey = makeCacheKey15(namespace_collection, cacheParams);
8909
+ logger24.log({
8134
8910
  level: "info",
8135
8911
  message: `Cache key for getAll buildings: ${cacheKey}`
8136
8912
  });
8137
8913
  try {
8138
8914
  const cached = await getCache(cacheKey);
8139
8915
  if (cached) {
8140
- logger22.log({
8916
+ logger24.log({
8141
8917
  level: "info",
8142
8918
  message: `Cache hit for getAll buildings: ${cacheKey}`
8143
8919
  });
@@ -8150,35 +8926,35 @@ function useBuildingRepo() {
8150
8926
  { $limit: limit }
8151
8927
  ]).toArray();
8152
8928
  const length = await collection.countDocuments(query);
8153
- const data = paginate12(items, page, limit, length);
8929
+ const data = paginate13(items, page, limit, length);
8154
8930
  setCache(cacheKey, data, 600).then(() => {
8155
- logger22.log({
8931
+ logger24.log({
8156
8932
  level: "info",
8157
8933
  message: `Cache set for getAll buildings: ${cacheKey}`
8158
8934
  });
8159
8935
  }).catch((err) => {
8160
- logger22.log({
8936
+ logger24.log({
8161
8937
  level: "error",
8162
8938
  message: `Failed to set cache for getAll buildings: ${err.message}`
8163
8939
  });
8164
8940
  });
8165
8941
  return data;
8166
8942
  } catch (error) {
8167
- logger22.log({ level: "error", message: `${error}` });
8943
+ logger24.log({ level: "error", message: `${error}` });
8168
8944
  throw error;
8169
8945
  }
8170
8946
  }
8171
8947
  async function getById(_id) {
8172
8948
  try {
8173
- _id = new ObjectId21(_id);
8949
+ _id = new ObjectId23(_id);
8174
8950
  } catch (error) {
8175
- throw new BadRequestError41("Invalid ID.");
8951
+ throw new BadRequestError45("Invalid ID.");
8176
8952
  }
8177
- const cacheKey = makeCacheKey14(namespace_collection, { _id: String(_id) });
8953
+ const cacheKey = makeCacheKey15(namespace_collection, { _id: String(_id) });
8178
8954
  try {
8179
8955
  const cached = await getCache(cacheKey);
8180
8956
  if (cached) {
8181
- logger22.log({
8957
+ logger24.log({
8182
8958
  level: "info",
8183
8959
  message: `Cache hit for getById building: ${cacheKey}`
8184
8960
  });
@@ -8188,30 +8964,30 @@ function useBuildingRepo() {
8188
8964
  _id
8189
8965
  });
8190
8966
  setCache(cacheKey, result, 300).then(() => {
8191
- logger22.log({
8967
+ logger24.log({
8192
8968
  level: "info",
8193
8969
  message: `Cache set for building by id: ${cacheKey}`
8194
8970
  });
8195
8971
  }).catch((err) => {
8196
- logger22.log({
8972
+ logger24.log({
8197
8973
  level: "error",
8198
8974
  message: `Failed to set cache for building by id: ${err.message}`
8199
8975
  });
8200
8976
  });
8201
8977
  return result;
8202
8978
  } catch (error) {
8203
- if (error instanceof AppError18) {
8979
+ if (error instanceof AppError20) {
8204
8980
  throw error;
8205
8981
  } else {
8206
- throw new InternalServerError22("Failed to get building.");
8982
+ throw new InternalServerError24("Failed to get building.");
8207
8983
  }
8208
8984
  }
8209
8985
  }
8210
8986
  async function deleteById(_id, session) {
8211
8987
  try {
8212
- _id = new ObjectId21(_id);
8988
+ _id = new ObjectId23(_id);
8213
8989
  } catch (error) {
8214
- throw new BadRequestError41("Invalid ID.");
8990
+ throw new BadRequestError45("Invalid ID.");
8215
8991
  }
8216
8992
  try {
8217
8993
  const res = await collection.updateOne(
@@ -8221,25 +8997,25 @@ function useBuildingRepo() {
8221
8997
  delCachedData();
8222
8998
  return res;
8223
8999
  } catch (error) {
8224
- logger22.log({
9000
+ logger24.log({
8225
9001
  level: "error",
8226
9002
  message: error.message
8227
9003
  });
8228
- if (error instanceof AppError18) {
9004
+ if (error instanceof AppError20) {
8229
9005
  throw error;
8230
9006
  } else {
8231
- throw new InternalServerError22("Failed to delete building.");
9007
+ throw new InternalServerError24("Failed to delete building.");
8232
9008
  }
8233
9009
  }
8234
9010
  }
8235
9011
  function delCachedData() {
8236
9012
  delNamespace().then(() => {
8237
- logger22.log({
9013
+ logger24.log({
8238
9014
  level: "info",
8239
9015
  message: `Cache namespace cleared for ${namespace_collection}`
8240
9016
  });
8241
9017
  }).catch((err) => {
8242
- logger22.log({
9018
+ logger24.log({
8243
9019
  level: "error",
8244
9020
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
8245
9021
  });
@@ -8256,28 +9032,28 @@ function useBuildingRepo() {
8256
9032
  }
8257
9033
 
8258
9034
  // src/resources/building/building.service.ts
8259
- import { BadRequestError as BadRequestError43, NotFoundError as NotFoundError4, useAtlas as useAtlas21 } from "@goweekdays/utils";
9035
+ import { BadRequestError as BadRequestError47, NotFoundError as NotFoundError4, useAtlas as useAtlas22 } from "@goweekdays/utils";
8260
9036
 
8261
9037
  // src/resources/building/building-unit.repository.ts
8262
9038
  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
9039
+ AppError as AppError21,
9040
+ BadRequestError as BadRequestError46,
9041
+ InternalServerError as InternalServerError25,
9042
+ logger as logger25,
9043
+ makeCacheKey as makeCacheKey16,
9044
+ paginate as paginate14,
9045
+ useAtlas as useAtlas21,
9046
+ useCache as useCache17
8271
9047
  } from "@goweekdays/utils";
8272
- import { ObjectId as ObjectId22 } from "mongodb";
9048
+ import { ObjectId as ObjectId24 } from "mongodb";
8273
9049
  function useBuildingUnitRepo() {
8274
- const db = useAtlas20.getDb();
9050
+ const db = useAtlas21.getDb();
8275
9051
  if (!db) {
8276
9052
  throw new Error("Unable to connect to server.");
8277
9053
  }
8278
9054
  const namespace_collection = "school.building-units";
8279
9055
  const collection = db.collection(namespace_collection);
8280
- const { getCache, setCache, delNamespace } = useCache16(namespace_collection);
9056
+ const { getCache, setCache, delNamespace } = useCache17(namespace_collection);
8281
9057
  async function createIndexes() {
8282
9058
  try {
8283
9059
  await collection.createIndexes([
@@ -8305,12 +9081,12 @@ function useBuildingUnitRepo() {
8305
9081
  }
8306
9082
  function delCachedData() {
8307
9083
  delNamespace().then(() => {
8308
- logger23.log({
9084
+ logger25.log({
8309
9085
  level: "info",
8310
9086
  message: `Cache namespace cleared for ${namespace_collection}`
8311
9087
  });
8312
9088
  }).catch((err) => {
8313
- logger23.log({
9089
+ logger25.log({
8314
9090
  level: "error",
8315
9091
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
8316
9092
  });
@@ -8323,11 +9099,11 @@ function useBuildingUnitRepo() {
8323
9099
  delCachedData();
8324
9100
  return res.insertedId;
8325
9101
  } catch (error) {
8326
- logger23.log({
9102
+ logger25.log({
8327
9103
  level: "error",
8328
9104
  message: error.message
8329
9105
  });
8330
- if (error instanceof AppError19) {
9106
+ if (error instanceof AppError21) {
8331
9107
  throw error;
8332
9108
  } else {
8333
9109
  throw new Error("Failed to create building unit.");
@@ -8337,12 +9113,12 @@ function useBuildingUnitRepo() {
8337
9113
  async function updateById(_id, value, session) {
8338
9114
  const { error } = schemaUpdateOptions.validate(value);
8339
9115
  if (error) {
8340
- throw new BadRequestError42(error.message);
9116
+ throw new BadRequestError46(error.message);
8341
9117
  }
8342
9118
  try {
8343
- _id = new ObjectId22(_id);
9119
+ _id = new ObjectId24(_id);
8344
9120
  } catch (error2) {
8345
- throw new BadRequestError42("Invalid ID.");
9121
+ throw new BadRequestError46("Invalid ID.");
8346
9122
  }
8347
9123
  try {
8348
9124
  const res = await collection.updateOne(
@@ -8353,11 +9129,11 @@ function useBuildingUnitRepo() {
8353
9129
  delCachedData();
8354
9130
  return res;
8355
9131
  } catch (error2) {
8356
- logger23.log({
9132
+ logger25.log({
8357
9133
  level: "error",
8358
9134
  message: error2.message
8359
9135
  });
8360
- if (error2 instanceof AppError19) {
9136
+ if (error2 instanceof AppError21) {
8361
9137
  throw error2;
8362
9138
  } else {
8363
9139
  throw new Error("Failed to create building unit.");
@@ -8367,12 +9143,12 @@ function useBuildingUnitRepo() {
8367
9143
  async function updateByBuildingId(building, value, session) {
8368
9144
  const { error } = schemaUpdateOptions.validate(value);
8369
9145
  if (error) {
8370
- throw new BadRequestError42(error.message);
9146
+ throw new BadRequestError46(error.message);
8371
9147
  }
8372
9148
  try {
8373
- building = new ObjectId22(building);
9149
+ building = new ObjectId24(building);
8374
9150
  } catch (error2) {
8375
- throw new BadRequestError42("Invalid building ID.");
9151
+ throw new BadRequestError46("Invalid building ID.");
8376
9152
  }
8377
9153
  try {
8378
9154
  const res = await collection.updateMany(
@@ -8383,11 +9159,11 @@ function useBuildingUnitRepo() {
8383
9159
  delCachedData();
8384
9160
  return res;
8385
9161
  } catch (error2) {
8386
- logger23.log({
9162
+ logger25.log({
8387
9163
  level: "error",
8388
9164
  message: error2.message
8389
9165
  });
8390
- if (error2 instanceof AppError19) {
9166
+ if (error2 instanceof AppError21) {
8391
9167
  throw error2;
8392
9168
  } else {
8393
9169
  throw new Error("Failed to update building unit.");
@@ -8414,16 +9190,16 @@ function useBuildingUnitRepo() {
8414
9190
  }
8415
9191
  if (school) {
8416
9192
  try {
8417
- query.school = new ObjectId22(school);
9193
+ query.school = new ObjectId24(school);
8418
9194
  } catch (error) {
8419
- throw new BadRequestError42("Invalid school ID.");
9195
+ throw new BadRequestError46("Invalid school ID.");
8420
9196
  }
8421
9197
  }
8422
9198
  if (building) {
8423
9199
  try {
8424
- query.building = new ObjectId22(building);
9200
+ query.building = new ObjectId24(building);
8425
9201
  } catch (error) {
8426
- throw new BadRequestError42("Invalid building ID.");
9202
+ throw new BadRequestError46("Invalid building ID.");
8427
9203
  }
8428
9204
  }
8429
9205
  const cacheParams = {
@@ -8439,15 +9215,15 @@ function useBuildingUnitRepo() {
8439
9215
  cacheParams.building = building;
8440
9216
  if (status !== "active")
8441
9217
  cacheParams.status = status;
8442
- const cacheKey = makeCacheKey15(namespace_collection, cacheParams);
8443
- logger23.log({
9218
+ const cacheKey = makeCacheKey16(namespace_collection, cacheParams);
9219
+ logger25.log({
8444
9220
  level: "info",
8445
9221
  message: `Cache key for getAll building units: ${cacheKey}`
8446
9222
  });
8447
9223
  try {
8448
9224
  const cached = await getCache(cacheKey);
8449
9225
  if (cached) {
8450
- logger23.log({
9226
+ logger25.log({
8451
9227
  level: "info",
8452
9228
  message: `Cache hit for getAll building units: ${cacheKey}`
8453
9229
  });
@@ -8460,35 +9236,35 @@ function useBuildingUnitRepo() {
8460
9236
  { $limit: limit }
8461
9237
  ]).toArray();
8462
9238
  const length = await collection.countDocuments(query);
8463
- const data = paginate13(items, page, limit, length);
9239
+ const data = paginate14(items, page, limit, length);
8464
9240
  setCache(cacheKey, data, 600).then(() => {
8465
- logger23.log({
9241
+ logger25.log({
8466
9242
  level: "info",
8467
9243
  message: `Cache set for getAll building units: ${cacheKey}`
8468
9244
  });
8469
9245
  }).catch((err) => {
8470
- logger23.log({
9246
+ logger25.log({
8471
9247
  level: "error",
8472
9248
  message: `Failed to set cache for getAll building units: ${err.message}`
8473
9249
  });
8474
9250
  });
8475
9251
  return data;
8476
9252
  } catch (error) {
8477
- logger23.log({ level: "error", message: `${error}` });
9253
+ logger25.log({ level: "error", message: `${error}` });
8478
9254
  throw error;
8479
9255
  }
8480
9256
  }
8481
9257
  async function getById(_id) {
8482
9258
  try {
8483
- _id = new ObjectId22(_id);
9259
+ _id = new ObjectId24(_id);
8484
9260
  } catch (error) {
8485
- throw new BadRequestError42("Invalid ID.");
9261
+ throw new BadRequestError46("Invalid ID.");
8486
9262
  }
8487
- const cacheKey = makeCacheKey15(namespace_collection, { _id: String(_id) });
9263
+ const cacheKey = makeCacheKey16(namespace_collection, { _id: String(_id) });
8488
9264
  try {
8489
9265
  const cached = await getCache(cacheKey);
8490
9266
  if (cached) {
8491
- logger23.log({
9267
+ logger25.log({
8492
9268
  level: "info",
8493
9269
  message: `Cache hit for getById building unit: ${cacheKey}`
8494
9270
  });
@@ -8499,42 +9275,42 @@ function useBuildingUnitRepo() {
8499
9275
  deletedAt: { $in: ["", null] }
8500
9276
  });
8501
9277
  if (!result) {
8502
- throw new BadRequestError42("Building unit not found.");
9278
+ throw new BadRequestError46("Building unit not found.");
8503
9279
  }
8504
9280
  setCache(cacheKey, result, 300).then(() => {
8505
- logger23.log({
9281
+ logger25.log({
8506
9282
  level: "info",
8507
9283
  message: `Cache set for building unit by id: ${cacheKey}`
8508
9284
  });
8509
9285
  }).catch((err) => {
8510
- logger23.log({
9286
+ logger25.log({
8511
9287
  level: "error",
8512
9288
  message: `Failed to set cache for building unit by id: ${err.message}`
8513
9289
  });
8514
9290
  });
8515
9291
  return result;
8516
9292
  } catch (error) {
8517
- if (error instanceof AppError19) {
9293
+ if (error instanceof AppError21) {
8518
9294
  throw error;
8519
9295
  } else {
8520
- throw new InternalServerError23("Failed to get building unit.");
9296
+ throw new InternalServerError25("Failed to get building unit.");
8521
9297
  }
8522
9298
  }
8523
9299
  }
8524
9300
  async function getByBuildingLevel(building, level) {
8525
9301
  try {
8526
- building = new ObjectId22(building);
9302
+ building = new ObjectId24(building);
8527
9303
  } catch (error) {
8528
- throw new BadRequestError42("Invalid building ID.");
9304
+ throw new BadRequestError46("Invalid building ID.");
8529
9305
  }
8530
- const cacheKey = makeCacheKey15(namespace_collection, {
9306
+ const cacheKey = makeCacheKey16(namespace_collection, {
8531
9307
  building: String(building),
8532
9308
  level
8533
9309
  });
8534
9310
  try {
8535
9311
  const cached = await getCache(cacheKey);
8536
9312
  if (cached) {
8537
- logger23.log({
9313
+ logger25.log({
8538
9314
  level: "info",
8539
9315
  message: `Cache hit for getById building unit: ${cacheKey}`
8540
9316
  });
@@ -8546,38 +9322,38 @@ function useBuildingUnitRepo() {
8546
9322
  status: "active"
8547
9323
  });
8548
9324
  setCache(cacheKey, result, 300).then(() => {
8549
- logger23.log({
9325
+ logger25.log({
8550
9326
  level: "info",
8551
9327
  message: `Cache set for building unit by id: ${cacheKey}`
8552
9328
  });
8553
9329
  }).catch((err) => {
8554
- logger23.log({
9330
+ logger25.log({
8555
9331
  level: "error",
8556
9332
  message: `Failed to set cache for building unit by id: ${err.message}`
8557
9333
  });
8558
9334
  });
8559
9335
  return result;
8560
9336
  } catch (error) {
8561
- if (error instanceof AppError19) {
9337
+ if (error instanceof AppError21) {
8562
9338
  throw error;
8563
9339
  } else {
8564
- throw new InternalServerError23("Failed to get building unit.");
9340
+ throw new InternalServerError25("Failed to get building unit.");
8565
9341
  }
8566
9342
  }
8567
9343
  }
8568
9344
  async function getByBuilding(building) {
8569
9345
  try {
8570
- building = new ObjectId22(building);
9346
+ building = new ObjectId24(building);
8571
9347
  } catch (error) {
8572
- throw new BadRequestError42("Invalid building ID.");
9348
+ throw new BadRequestError46("Invalid building ID.");
8573
9349
  }
8574
- const cacheKey = makeCacheKey15(namespace_collection, {
9350
+ const cacheKey = makeCacheKey16(namespace_collection, {
8575
9351
  building: String(building)
8576
9352
  });
8577
9353
  try {
8578
9354
  const cached = await getCache(cacheKey);
8579
9355
  if (cached) {
8580
- logger23.log({
9356
+ logger25.log({
8581
9357
  level: "info",
8582
9358
  message: `Cache hit for getById building unit: ${cacheKey}`
8583
9359
  });
@@ -8588,30 +9364,30 @@ function useBuildingUnitRepo() {
8588
9364
  status: "active"
8589
9365
  });
8590
9366
  setCache(cacheKey, result, 300).then(() => {
8591
- logger23.log({
9367
+ logger25.log({
8592
9368
  level: "info",
8593
9369
  message: `Cache set for building unit by id: ${cacheKey}`
8594
9370
  });
8595
9371
  }).catch((err) => {
8596
- logger23.log({
9372
+ logger25.log({
8597
9373
  level: "error",
8598
9374
  message: `Failed to set cache for building unit by id: ${err.message}`
8599
9375
  });
8600
9376
  });
8601
9377
  return result;
8602
9378
  } catch (error) {
8603
- if (error instanceof AppError19) {
9379
+ if (error instanceof AppError21) {
8604
9380
  throw error;
8605
9381
  } else {
8606
- throw new InternalServerError23("Failed to get building unit.");
9382
+ throw new InternalServerError25("Failed to get building unit.");
8607
9383
  }
8608
9384
  }
8609
9385
  }
8610
9386
  async function deleteById(_id, session) {
8611
9387
  try {
8612
- _id = new ObjectId22(_id);
9388
+ _id = new ObjectId24(_id);
8613
9389
  } catch (error) {
8614
- throw new BadRequestError42("Invalid ID.");
9390
+ throw new BadRequestError46("Invalid ID.");
8615
9391
  }
8616
9392
  try {
8617
9393
  const res = await collection.updateOne(
@@ -8622,11 +9398,11 @@ function useBuildingUnitRepo() {
8622
9398
  delCachedData();
8623
9399
  return "Room/Facility deleted successfully.";
8624
9400
  } catch (error) {
8625
- logger23.log({
9401
+ logger25.log({
8626
9402
  level: "error",
8627
9403
  message: error.message
8628
9404
  });
8629
- if (error instanceof AppError19) {
9405
+ if (error instanceof AppError21) {
8630
9406
  throw error;
8631
9407
  } else {
8632
9408
  throw new Error("Failed to deleted room/facility.");
@@ -8656,7 +9432,7 @@ function useBuildingService() {
8656
9432
  const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
8657
9433
  async function updateById(id, data) {
8658
9434
  data.levels = Number(data.levels);
8659
- const session = useAtlas21.getClient()?.startSession();
9435
+ const session = useAtlas22.getClient()?.startSession();
8660
9436
  try {
8661
9437
  const building = await _getById(id);
8662
9438
  if (!building) {
@@ -8665,7 +9441,7 @@ function useBuildingService() {
8665
9441
  if (data.levels < building.levels) {
8666
9442
  const unit = await getByBuildingLevel(id, building.levels);
8667
9443
  if (unit) {
8668
- throw new BadRequestError43(
9444
+ throw new BadRequestError47(
8669
9445
  "Cannot reduce floors, there are existing building units at higher floors."
8670
9446
  );
8671
9447
  }
@@ -8687,7 +9463,7 @@ function useBuildingService() {
8687
9463
  async function deleteById(id) {
8688
9464
  const building = await getByBuilding(id);
8689
9465
  if (building) {
8690
- throw new BadRequestError43(
9466
+ throw new BadRequestError47(
8691
9467
  "Cannot delete building with existing room/facility. Please delete room/facility first."
8692
9468
  );
8693
9469
  }
@@ -8705,24 +9481,24 @@ function useBuildingService() {
8705
9481
  }
8706
9482
 
8707
9483
  // src/resources/building/building.controller.ts
8708
- import { BadRequestError as BadRequestError44, logger as logger24 } from "@goweekdays/utils";
8709
- import Joi32 from "joi";
9484
+ import { BadRequestError as BadRequestError48, logger as logger26 } from "@goweekdays/utils";
9485
+ import Joi38 from "joi";
8710
9486
  function useBuildingController() {
8711
9487
  const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
8712
9488
  const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
8713
9489
  async function createBuilding(req, res, next) {
8714
9490
  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)
9491
+ const validation = Joi38.object({
9492
+ name: Joi38.string().required(),
9493
+ school: Joi38.string().hex().required(),
9494
+ levels: Joi38.number().integer().min(1).required(),
9495
+ serial: Joi38.string().optional().allow("", null),
9496
+ status: Joi38.string().optional().allow("", null)
8721
9497
  });
8722
9498
  const { error } = validation.validate(value);
8723
9499
  if (error) {
8724
- next(new BadRequestError44(error.message));
8725
- logger24.info(`Controller: ${error.message}`);
9500
+ next(new BadRequestError48(error.message));
9501
+ logger26.info(`Controller: ${error.message}`);
8726
9502
  return;
8727
9503
  }
8728
9504
  try {
@@ -8736,18 +9512,18 @@ function useBuildingController() {
8736
9512
  async function updateById(req, res, next) {
8737
9513
  const value = req.body;
8738
9514
  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()
9515
+ const validation = Joi38.object({
9516
+ id: Joi38.string().hex().required(),
9517
+ value: Joi38.object({
9518
+ name: Joi38.string().required(),
9519
+ serial: Joi38.string().optional().allow("", null),
9520
+ levels: Joi38.number().integer().min(1).required()
8745
9521
  })
8746
9522
  });
8747
9523
  const { error } = validation.validate({ id, value });
8748
9524
  if (error) {
8749
- next(new BadRequestError44(error.message));
8750
- logger24.info(`Controller: ${error.message}`);
9525
+ next(new BadRequestError48(error.message));
9526
+ logger26.info(`Controller: ${error.message}`);
8751
9527
  return;
8752
9528
  }
8753
9529
  try {
@@ -8760,16 +9536,16 @@ function useBuildingController() {
8760
9536
  }
8761
9537
  async function getAll(req, res, next) {
8762
9538
  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)
9539
+ const validation = Joi38.object({
9540
+ page: Joi38.number().min(1).optional().allow("", null),
9541
+ limit: Joi38.number().min(1).optional().allow("", null),
9542
+ search: Joi38.string().optional().allow("", null),
9543
+ school: Joi38.string().hex().optional().allow("", null),
9544
+ status: Joi38.string().optional().allow("", null)
8769
9545
  });
8770
9546
  const { error } = validation.validate(query);
8771
9547
  if (error) {
8772
- next(new BadRequestError44(error.message));
9548
+ next(new BadRequestError48(error.message));
8773
9549
  return;
8774
9550
  }
8775
9551
  const page = parseInt(req.query.page) ?? 1;
@@ -8803,12 +9579,12 @@ function useBuildingController() {
8803
9579
  }
8804
9580
  async function getById(req, res, next) {
8805
9581
  const id = req.params.id;
8806
- const validation = Joi32.object({
8807
- id: Joi32.string().hex().required()
9582
+ const validation = Joi38.object({
9583
+ id: Joi38.string().hex().required()
8808
9584
  });
8809
9585
  const { error } = validation.validate({ id });
8810
9586
  if (error) {
8811
- next(new BadRequestError44(error.message));
9587
+ next(new BadRequestError48(error.message));
8812
9588
  return;
8813
9589
  }
8814
9590
  try {
@@ -8824,12 +9600,12 @@ function useBuildingController() {
8824
9600
  }
8825
9601
  async function deleteById(req, res, next) {
8826
9602
  const id = req.params.id;
8827
- const validation = Joi32.object({
8828
- id: Joi32.string().hex().required()
9603
+ const validation = Joi38.object({
9604
+ id: Joi38.string().hex().required()
8829
9605
  });
8830
9606
  const { error } = validation.validate({ id });
8831
9607
  if (error) {
8832
- next(new BadRequestError44(error.message));
9608
+ next(new BadRequestError48(error.message));
8833
9609
  return;
8834
9610
  }
8835
9611
  try {
@@ -8850,11 +9626,11 @@ function useBuildingController() {
8850
9626
  }
8851
9627
 
8852
9628
  // src/resources/building/building-unit.service.ts
8853
- import { useAtlas as useAtlas22 } from "@goweekdays/utils";
9629
+ import { useAtlas as useAtlas23 } from "@goweekdays/utils";
8854
9630
  function useBuildingUnitService() {
8855
9631
  const { add: _add } = useBuildingUnitRepo();
8856
9632
  async function add(value) {
8857
- const session = useAtlas22.getClient()?.startSession();
9633
+ const session = useAtlas23.getClient()?.startSession();
8858
9634
  if (!session) {
8859
9635
  throw new Error("Unable to start session for building unit service.");
8860
9636
  }
@@ -8881,8 +9657,8 @@ function useBuildingUnitService() {
8881
9657
  }
8882
9658
 
8883
9659
  // src/resources/building/building-unit.controller.ts
8884
- import { BadRequestError as BadRequestError45 } from "@goweekdays/utils";
8885
- import Joi33 from "joi";
9660
+ import { BadRequestError as BadRequestError49 } from "@goweekdays/utils";
9661
+ import Joi39 from "joi";
8886
9662
  function useBuildingUnitController() {
8887
9663
  const {
8888
9664
  getAll: _getAll,
@@ -8893,27 +9669,27 @@ function useBuildingUnitController() {
8893
9669
  const { add: _add } = useBuildingUnitService();
8894
9670
  async function add(req, res, next) {
8895
9671
  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)
9672
+ const validation = Joi39.object({
9673
+ building: Joi39.object({
9674
+ school: Joi39.string().hex().required(),
9675
+ name: Joi39.string().optional().allow("", null),
9676
+ building: Joi39.string().hex().required(),
9677
+ buildingName: Joi39.string().optional().allow("", null),
9678
+ level: Joi39.number().integer().min(1).required(),
9679
+ category: Joi39.string().required(),
9680
+ type: Joi39.string().required(),
9681
+ seating_capacity: Joi39.number().integer().min(0).required(),
9682
+ standing_capacity: Joi39.number().integer().min(0).required(),
9683
+ description: Joi39.string().optional().allow("", null),
9684
+ unit_of_measurement: Joi39.string().valid("sqm").required(),
9685
+ area: Joi39.number().positive().required(),
9686
+ status: Joi39.string().optional().allow("", null)
8911
9687
  }),
8912
- qty: Joi33.number().integer().min(1).max(20).optional().default(1)
9688
+ qty: Joi39.number().integer().min(1).max(20).optional().default(1)
8913
9689
  });
8914
9690
  const { error } = validation.validate(data);
8915
9691
  if (error) {
8916
- next(new BadRequestError45(error.message));
9692
+ next(new BadRequestError49(error.message));
8917
9693
  return;
8918
9694
  }
8919
9695
  try {
@@ -8929,13 +9705,13 @@ function useBuildingUnitController() {
8929
9705
  async function updateById(req, res, next) {
8930
9706
  const data = req.body;
8931
9707
  const id = req.params.id ?? "";
8932
- const validation = Joi33.object({
8933
- id: Joi33.string().hex().required(),
9708
+ const validation = Joi39.object({
9709
+ id: Joi39.string().hex().required(),
8934
9710
  value: schemaUpdateOptions
8935
9711
  });
8936
9712
  const { error } = validation.validate({ id, value: data });
8937
9713
  if (error) {
8938
- next(new BadRequestError45(error.message));
9714
+ next(new BadRequestError49(error.message));
8939
9715
  return;
8940
9716
  }
8941
9717
  try {
@@ -8950,17 +9726,17 @@ function useBuildingUnitController() {
8950
9726
  }
8951
9727
  async function getAll(req, res, next) {
8952
9728
  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)
9729
+ const validation = Joi39.object({
9730
+ page: Joi39.number().min(1).optional().allow("", null),
9731
+ limit: Joi39.number().min(1).optional().allow("", null),
9732
+ search: Joi39.string().optional().allow("", null),
9733
+ school: Joi39.string().hex().optional().allow("", null),
9734
+ building: Joi39.string().hex().optional().allow("", null),
9735
+ status: Joi39.string().optional().allow("", null)
8960
9736
  });
8961
9737
  const { error } = validation.validate(query);
8962
9738
  if (error) {
8963
- next(new BadRequestError45(error.message));
9739
+ next(new BadRequestError49(error.message));
8964
9740
  return;
8965
9741
  }
8966
9742
  const page = parseInt(req.query.page) ?? 1;
@@ -8996,12 +9772,12 @@ function useBuildingUnitController() {
8996
9772
  }
8997
9773
  async function getById(req, res, next) {
8998
9774
  const id = req.params.id;
8999
- const validation = Joi33.object({
9000
- id: Joi33.string().hex().required()
9775
+ const validation = Joi39.object({
9776
+ id: Joi39.string().hex().required()
9001
9777
  });
9002
9778
  const { error } = validation.validate({ id });
9003
9779
  if (error) {
9004
- next(new BadRequestError45(error.message));
9780
+ next(new BadRequestError49(error.message));
9005
9781
  return;
9006
9782
  }
9007
9783
  try {
@@ -9017,12 +9793,12 @@ function useBuildingUnitController() {
9017
9793
  }
9018
9794
  async function deleteById(req, res, next) {
9019
9795
  const id = req.params.id;
9020
- const validation = Joi33.object({
9021
- id: Joi33.string().hex().required()
9796
+ const validation = Joi39.object({
9797
+ id: Joi39.string().hex().required()
9022
9798
  });
9023
9799
  const { error } = validation.validate({ id });
9024
9800
  if (error) {
9025
- next(new BadRequestError45(error.message));
9801
+ next(new BadRequestError49(error.message));
9026
9802
  return;
9027
9803
  }
9028
9804
  try {
@@ -9043,14 +9819,14 @@ function useBuildingUnitController() {
9043
9819
  }
9044
9820
 
9045
9821
  // src/resources/counter/counter.model.ts
9046
- import { BadRequestError as BadRequestError46 } from "@goweekdays/utils";
9047
- import { ObjectId as ObjectId23 } from "mongodb";
9822
+ import { BadRequestError as BadRequestError50 } from "@goweekdays/utils";
9823
+ import { ObjectId as ObjectId25 } from "mongodb";
9048
9824
  import { z } from "zod";
9049
9825
  var TCounter = z.object({
9050
9826
  _id: z.union([
9051
9827
  z.string().length(24, "Invalid ObjectId hex string"),
9052
- z.instanceof(ObjectId23)
9053
- ]).transform((val) => typeof val === "string" ? new ObjectId23(val) : val).optional(),
9828
+ z.instanceof(ObjectId25)
9829
+ ]).transform((val) => typeof val === "string" ? new ObjectId25(val) : val).optional(),
9054
9830
  count: z.number().int().min(0).default(0),
9055
9831
  type: z.string(),
9056
9832
  createdAt: z.date().optional().default(() => /* @__PURE__ */ new Date()),
@@ -9063,7 +9839,7 @@ function useCounterModel(db) {
9063
9839
  try {
9064
9840
  return TCounter.parse(value);
9065
9841
  } catch (error) {
9066
- throw new BadRequestError46(error.issues[0].message);
9842
+ throw new BadRequestError50(error.issues[0].message);
9067
9843
  }
9068
9844
  }
9069
9845
  function validateCounter(data) {
@@ -9077,23 +9853,23 @@ function useCounterModel(db) {
9077
9853
  }
9078
9854
 
9079
9855
  // src/resources/counter/counter.repository.ts
9080
- import { useAtlas as useAtlas23, useCache as useCache17, makeCacheKey as makeCacheKey16, logger as logger25 } from "@goweekdays/utils";
9856
+ import { useAtlas as useAtlas24, useCache as useCache18, makeCacheKey as makeCacheKey17, logger as logger27 } from "@goweekdays/utils";
9081
9857
  function useCounterRepo() {
9082
- const db = useAtlas23.getDb();
9858
+ const db = useAtlas24.getDb();
9083
9859
  if (!db) {
9084
9860
  throw new Error("Unable to connect to server.");
9085
9861
  }
9086
9862
  const namespace_collection = "counters";
9087
9863
  const { collection, createCounter } = useCounterModel(db);
9088
- const { getCache, setCache, delNamespace } = useCache17(namespace_collection);
9864
+ const { getCache, setCache, delNamespace } = useCache18(namespace_collection);
9089
9865
  function delCachedData() {
9090
9866
  delNamespace().then(() => {
9091
- logger25.log({
9867
+ logger27.log({
9092
9868
  level: "info",
9093
9869
  message: `Cache namespace cleared for ${namespace_collection}`
9094
9870
  });
9095
9871
  }).catch((err) => {
9096
- logger25.log({
9872
+ logger27.log({
9097
9873
  level: "error",
9098
9874
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
9099
9875
  });
@@ -9137,11 +9913,11 @@ function useCounterRepo() {
9137
9913
  }
9138
9914
  }
9139
9915
  async function getByType(type) {
9140
- const cacheKey = makeCacheKey16(namespace_collection, { type });
9916
+ const cacheKey = makeCacheKey17(namespace_collection, { type });
9141
9917
  try {
9142
9918
  const cached = await getCache(cacheKey);
9143
9919
  if (cached) {
9144
- logger25.log({
9920
+ logger27.log({
9145
9921
  level: "info",
9146
9922
  message: `Cache hit for getByType counter: ${cacheKey}`
9147
9923
  });
@@ -9150,12 +9926,12 @@ function useCounterRepo() {
9150
9926
  const data = await collection.findOne({ type });
9151
9927
  if (data) {
9152
9928
  setCache(cacheKey, data, 300).then(() => {
9153
- logger25.log({
9929
+ logger27.log({
9154
9930
  level: "info",
9155
9931
  message: `Cache set for counter by type: ${cacheKey}`
9156
9932
  });
9157
9933
  }).catch((err) => {
9158
- logger25.log({
9934
+ logger27.log({
9159
9935
  level: "error",
9160
9936
  message: `Failed to set cache for counter by type: ${err.message}`
9161
9937
  });
@@ -9175,7 +9951,7 @@ function useCounterRepo() {
9175
9951
  }
9176
9952
 
9177
9953
  // src/resources/file/file.service.ts
9178
- import { logger as logger26, useS3 as useS32, useAtlas as useAtlas24 } from "@goweekdays/utils";
9954
+ import { logger as logger28, useS3 as useS32, useAtlas as useAtlas25 } from "@goweekdays/utils";
9179
9955
  import cron from "node-cron";
9180
9956
  import * as fs from "fs";
9181
9957
  function useFileService() {
@@ -9193,7 +9969,7 @@ function useFileService() {
9193
9969
  forcePathStyle: true
9194
9970
  });
9195
9971
  async function createFile(value) {
9196
- const session = useAtlas24.getClient()?.startSession();
9972
+ const session = useAtlas25.getClient()?.startSession();
9197
9973
  session?.startTransaction();
9198
9974
  const file = {
9199
9975
  name: value.originalname,
@@ -9227,7 +10003,7 @@ function useFileService() {
9227
10003
  }
9228
10004
  }
9229
10005
  async function deleteFile(id) {
9230
- const session = useAtlas24.getClient()?.startSession();
10006
+ const session = useAtlas25.getClient()?.startSession();
9231
10007
  session?.startTransaction();
9232
10008
  try {
9233
10009
  await deleteFileById(id, session);
@@ -9248,12 +10024,12 @@ function useFileService() {
9248
10024
  const file = files[index];
9249
10025
  try {
9250
10026
  await deleteFile(file._id.toString());
9251
- await logger26.log({
10027
+ await logger28.log({
9252
10028
  level: "info",
9253
10029
  message: "Successfully deleted draft files."
9254
10030
  });
9255
10031
  } catch (error) {
9256
- logger26.log({
10032
+ logger28.log({
9257
10033
  level: "info",
9258
10034
  message: "Successfully deleted draft files."
9259
10035
  });
@@ -9271,11 +10047,11 @@ function useFileService() {
9271
10047
 
9272
10048
  // src/resources/file/file.controller.ts
9273
10049
  import {
9274
- AppError as AppError20,
9275
- BadRequestError as BadRequestError47,
9276
- InternalServerError as InternalServerError24
10050
+ AppError as AppError22,
10051
+ BadRequestError as BadRequestError51,
10052
+ InternalServerError as InternalServerError26
9277
10053
  } from "@goweekdays/utils";
9278
- import Joi34 from "joi";
10054
+ import Joi40 from "joi";
9279
10055
  function useFileController() {
9280
10056
  const { createFile, deleteFile: _deleteFile } = useFileService();
9281
10057
  async function upload(req, res, next) {
@@ -9288,29 +10064,29 @@ function useFileController() {
9288
10064
  res.json({ message: "Successfully uploaded file", id });
9289
10065
  return;
9290
10066
  } catch (error) {
9291
- if (error instanceof AppError20) {
10067
+ if (error instanceof AppError22) {
9292
10068
  next(error);
9293
10069
  } else {
9294
- next(new InternalServerError24(error));
10070
+ next(new InternalServerError26(error));
9295
10071
  }
9296
10072
  }
9297
10073
  }
9298
10074
  async function deleteFile(req, res, next) {
9299
10075
  const id = req.params.id;
9300
- const validation = Joi34.string().required();
10076
+ const validation = Joi40.string().required();
9301
10077
  const { error } = validation.validate(id);
9302
10078
  if (error) {
9303
- next(new BadRequestError47(error.message));
10079
+ next(new BadRequestError51(error.message));
9304
10080
  }
9305
10081
  try {
9306
10082
  const message = await _deleteFile(id);
9307
10083
  res.json({ message });
9308
10084
  return;
9309
10085
  } catch (error2) {
9310
- if (error2 instanceof AppError20) {
10086
+ if (error2 instanceof AppError22) {
9311
10087
  next(error2);
9312
10088
  } else {
9313
- next(new InternalServerError24(error2));
10089
+ next(new InternalServerError26(error2));
9314
10090
  }
9315
10091
  }
9316
10092
  }
@@ -9321,35 +10097,35 @@ function useFileController() {
9321
10097
  }
9322
10098
 
9323
10099
  // 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", {
10100
+ import Joi41 from "joi";
10101
+ var schemaPromo = Joi41.object({
10102
+ code: Joi41.string().min(3).max(50).required(),
10103
+ description: Joi41.string().max(255).optional().allow("", null),
10104
+ type: Joi41.string().valid("flat", "fixed", "tiered").required(),
10105
+ flatRate: Joi41.number().positive().when("type", {
9330
10106
  is: "flat",
9331
- then: Joi35.required(),
9332
- otherwise: Joi35.forbidden()
10107
+ then: Joi41.required(),
10108
+ otherwise: Joi41.forbidden()
9333
10109
  }).optional().allow(null, 0),
9334
- fixedRate: Joi35.number().positive().when("type", {
10110
+ fixedRate: Joi41.number().positive().when("type", {
9335
10111
  is: "fixed",
9336
- then: Joi35.required(),
9337
- otherwise: Joi35.forbidden()
10112
+ then: Joi41.required(),
10113
+ otherwise: Joi41.forbidden()
9338
10114
  }).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()
10115
+ tiers: Joi41.array().items(
10116
+ Joi41.object({
10117
+ minSeats: Joi41.number().integer().min(1).required(),
10118
+ maxSeats: Joi41.number().integer().min(Joi41.ref("minSeats")).required(),
10119
+ rate: Joi41.number().positive().required()
9344
10120
  })
9345
10121
  ).when("type", {
9346
10122
  is: "tiered",
9347
- then: Joi35.required(),
9348
- otherwise: Joi35.forbidden()
10123
+ then: Joi41.required(),
10124
+ otherwise: Joi41.forbidden()
9349
10125
  }),
9350
- currency: Joi35.string().length(3).required(),
9351
- startDate: Joi35.date().required(),
9352
- endDate: Joi35.date().greater(Joi35.ref("startDate")).optional().allow(null, "")
10126
+ currency: Joi41.string().length(3).required(),
10127
+ startDate: Joi41.date().required(),
10128
+ endDate: Joi41.date().greater(Joi41.ref("startDate")).optional().allow(null, "")
9353
10129
  });
9354
10130
  function modelPromo(data) {
9355
10131
  const { error } = schemaPromo.validate(data);
@@ -9378,33 +10154,33 @@ function modelPromo(data) {
9378
10154
 
9379
10155
  // src/resources/promo/promo.repository.ts
9380
10156
  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
10157
+ AppError as AppError23,
10158
+ BadRequestError as BadRequestError52,
10159
+ InternalServerError as InternalServerError27,
10160
+ logger as logger29,
10161
+ makeCacheKey as makeCacheKey18,
10162
+ paginate as paginate15,
10163
+ useAtlas as useAtlas26,
10164
+ useCache as useCache19
9389
10165
  } from "@goweekdays/utils";
9390
- import Joi36 from "joi";
9391
- import { ObjectId as ObjectId24 } from "mongodb";
10166
+ import Joi42 from "joi";
10167
+ import { ObjectId as ObjectId26 } from "mongodb";
9392
10168
  function usePromoRepo() {
9393
- const db = useAtlas25.getDb();
10169
+ const db = useAtlas26.getDb();
9394
10170
  if (!db) {
9395
- throw new InternalServerError25("Unable to connect to server.");
10171
+ throw new InternalServerError27("Unable to connect to server.");
9396
10172
  }
9397
10173
  const namespace_collection = "users";
9398
10174
  const collection = db.collection(namespace_collection);
9399
- const { getCache, setCache, delNamespace } = useCache18(namespace_collection);
10175
+ const { getCache, setCache, delNamespace } = useCache19(namespace_collection);
9400
10176
  function delCachedData() {
9401
10177
  delNamespace().then(() => {
9402
- logger27.log({
10178
+ logger29.log({
9403
10179
  level: "info",
9404
10180
  message: `Cache namespace cleared for ${namespace_collection}`
9405
10181
  });
9406
10182
  }).catch((err) => {
9407
- logger27.log({
10183
+ logger29.log({
9408
10184
  level: "error",
9409
10185
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
9410
10186
  });
@@ -9436,7 +10212,7 @@ function usePromoRepo() {
9436
10212
  delCachedData();
9437
10213
  return "Successfully added promo.";
9438
10214
  } catch (error) {
9439
- throw new InternalServerError25("Failed to add promo.");
10215
+ throw new InternalServerError27("Failed to add promo.");
9440
10216
  }
9441
10217
  }
9442
10218
  async function getAll({
@@ -9457,7 +10233,7 @@ function usePromoRepo() {
9457
10233
  if (search) {
9458
10234
  query.$text = { $search: search };
9459
10235
  }
9460
- const cacheKey = makeCacheKey17(namespace_collection, cacheKeyOptions);
10236
+ const cacheKey = makeCacheKey18(namespace_collection, cacheKeyOptions);
9461
10237
  try {
9462
10238
  const cachedData = await getCache(cacheKey);
9463
10239
  if (cachedData) {
@@ -9469,30 +10245,30 @@ function usePromoRepo() {
9469
10245
  { $limit: limit }
9470
10246
  ]).toArray();
9471
10247
  const length = await collection.countDocuments(query);
9472
- const data = paginate14(items, page, limit, length);
10248
+ const data = paginate15(items, page, limit, length);
9473
10249
  setCache(cacheKey, data).then(() => {
9474
- logger27.log({
10250
+ logger29.log({
9475
10251
  level: "info",
9476
10252
  message: `Cache set for getAll promo: ${cacheKey}`
9477
10253
  });
9478
10254
  }).catch((err) => {
9479
- logger27.log({
10255
+ logger29.log({
9480
10256
  level: "error",
9481
10257
  message: `Failed to set cache for getAll promo: ${err.message}`
9482
10258
  });
9483
10259
  });
9484
10260
  return data;
9485
10261
  } catch (error) {
9486
- throw new InternalServerError25("Failed to get promos.");
10262
+ throw new InternalServerError27("Failed to get promos.");
9487
10263
  }
9488
10264
  }
9489
10265
  async function getByCode(code) {
9490
- const { error } = Joi36.string().min(3).max(50).required().validate(code);
10266
+ const { error } = Joi42.string().min(3).max(50).required().validate(code);
9491
10267
  if (error) {
9492
10268
  throw new Error(`Invalid promo code: ${error.message}`);
9493
10269
  }
9494
10270
  try {
9495
- const cacheKey = makeCacheKey17(namespace_collection, {
10271
+ const cacheKey = makeCacheKey18(namespace_collection, {
9496
10272
  code,
9497
10273
  tag: "getByCode"
9498
10274
  });
@@ -9505,33 +10281,33 @@ function usePromoRepo() {
9505
10281
  status: { $ne: "deleted" }
9506
10282
  });
9507
10283
  setCache(cacheKey, data).then(() => {
9508
- logger27.log({
10284
+ logger29.log({
9509
10285
  level: "info",
9510
10286
  message: `Cache set for getByCode promo: ${cacheKey}`
9511
10287
  });
9512
10288
  }).catch((err) => {
9513
- logger27.log({
10289
+ logger29.log({
9514
10290
  level: "error",
9515
10291
  message: `Failed to set cache for getByCode promo: ${err.message}`
9516
10292
  });
9517
10293
  });
9518
10294
  return data;
9519
10295
  } catch (error2) {
9520
- throw new InternalServerError25("Failed to get promo.");
10296
+ throw new InternalServerError27("Failed to get promo.");
9521
10297
  }
9522
10298
  }
9523
10299
  async function getById(_id) {
9524
- const { error } = Joi36.string().hex().length(24).required().validate(_id);
10300
+ const { error } = Joi42.string().hex().length(24).required().validate(_id);
9525
10301
  if (error) {
9526
10302
  throw new Error(`Invalid promo ID: ${error.message}`);
9527
10303
  }
9528
10304
  try {
9529
- _id = new ObjectId24(_id);
10305
+ _id = new ObjectId26(_id);
9530
10306
  } catch (error2) {
9531
- throw new BadRequestError48("Invalid promo ID.");
10307
+ throw new BadRequestError52("Invalid promo ID.");
9532
10308
  }
9533
10309
  try {
9534
- const cacheKey = makeCacheKey17(namespace_collection, {
10310
+ const cacheKey = makeCacheKey18(namespace_collection, {
9535
10311
  _id: String(_id),
9536
10312
  tag: "getById"
9537
10313
  });
@@ -9544,30 +10320,30 @@ function usePromoRepo() {
9544
10320
  status: { $ne: "deleted" }
9545
10321
  });
9546
10322
  setCache(cacheKey, data).then(() => {
9547
- logger27.log({
10323
+ logger29.log({
9548
10324
  level: "info",
9549
10325
  message: `Cache set for getById promo: ${cacheKey}`
9550
10326
  });
9551
10327
  }).catch((err) => {
9552
- logger27.log({
10328
+ logger29.log({
9553
10329
  level: "error",
9554
10330
  message: `Failed to set cache for getById promo: ${err.message}`
9555
10331
  });
9556
10332
  });
9557
10333
  return data;
9558
10334
  } catch (error2) {
9559
- throw new InternalServerError25("Failed to get promo.");
10335
+ throw new InternalServerError27("Failed to get promo.");
9560
10336
  }
9561
10337
  }
9562
10338
  async function deleteById(_id) {
9563
- const { error } = Joi36.string().hex().length(24).required().validate(_id);
10339
+ const { error } = Joi42.string().hex().length(24).required().validate(_id);
9564
10340
  if (error) {
9565
10341
  throw new Error(`Invalid promo ID: ${error.message}`);
9566
10342
  }
9567
10343
  try {
9568
- _id = new ObjectId24(_id);
10344
+ _id = new ObjectId26(_id);
9569
10345
  } catch (error2) {
9570
- throw new BadRequestError48("Invalid promo ID.");
10346
+ throw new BadRequestError52("Invalid promo ID.");
9571
10347
  }
9572
10348
  try {
9573
10349
  const result = await collection.updateOne(
@@ -9575,15 +10351,15 @@ function usePromoRepo() {
9575
10351
  { $set: { status: "deleted" } }
9576
10352
  );
9577
10353
  if (result.modifiedCount === 0) {
9578
- throw new InternalServerError25("Failed to delete promo.");
10354
+ throw new InternalServerError27("Failed to delete promo.");
9579
10355
  }
9580
10356
  delCachedData();
9581
10357
  return "Successfully deleted promo.";
9582
10358
  } catch (error2) {
9583
- if (error2 instanceof AppError21) {
10359
+ if (error2 instanceof AppError23) {
9584
10360
  throw error2;
9585
10361
  }
9586
- throw new InternalServerError25("Failed to delete promo.");
10362
+ throw new InternalServerError27("Failed to delete promo.");
9587
10363
  }
9588
10364
  }
9589
10365
  return {
@@ -9597,7 +10373,7 @@ function usePromoRepo() {
9597
10373
  }
9598
10374
 
9599
10375
  // src/resources/utils/github.service.ts
9600
- import { AppError as AppError22, BadRequestError as BadRequestError49 } from "@goweekdays/utils";
10376
+ import { AppError as AppError24, BadRequestError as BadRequestError53 } from "@goweekdays/utils";
9601
10377
  import { Octokit } from "@octokit/rest";
9602
10378
  import _sodium from "libsodium-wrappers";
9603
10379
  function useGitHubService() {
@@ -9611,23 +10387,23 @@ function useGitHubService() {
9611
10387
  try {
9612
10388
  const { data: repoData } = await octokit.repos.get({ owner, repo });
9613
10389
  if (!repoData.permissions?.admin) {
9614
- throw new BadRequestError49(
10390
+ throw new BadRequestError53(
9615
10391
  "You do not have admin access to this repository."
9616
10392
  );
9617
10393
  }
9618
10394
  } catch (error) {
9619
10395
  if (error.status === 404) {
9620
- throw new BadRequestError49(
10396
+ throw new BadRequestError53(
9621
10397
  "Repository not found or you don't have access to it."
9622
10398
  );
9623
10399
  } else if (error.status === 401) {
9624
- throw new BadRequestError49(
10400
+ throw new BadRequestError53(
9625
10401
  "Invalid GitHub token or insufficient permissions."
9626
10402
  );
9627
10403
  } else if (error.message.includes("admin access")) {
9628
10404
  throw error;
9629
10405
  } else {
9630
- throw new BadRequestError49(
10406
+ throw new BadRequestError53(
9631
10407
  `Failed to check repository permissions: ${error.message}`
9632
10408
  );
9633
10409
  }
@@ -9676,7 +10452,7 @@ function useGitHubService() {
9676
10452
  key_id: publicKeyRes.key_id
9677
10453
  });
9678
10454
  } catch (encryptionError) {
9679
- throw new BadRequestError49(
10455
+ throw new BadRequestError53(
9680
10456
  `Failed to encrypt secret '${key}': ${encryptionError.message}`
9681
10457
  );
9682
10458
  }
@@ -9706,22 +10482,22 @@ function useGitHubService() {
9706
10482
  }
9707
10483
  return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
9708
10484
  } catch (error) {
9709
- if (error instanceof AppError22)
10485
+ if (error instanceof AppError24)
9710
10486
  throw error;
9711
10487
  if (error.status === 422) {
9712
- throw new BadRequestError49(
10488
+ throw new BadRequestError53(
9713
10489
  `GitHub API validation error: ${error.message}`
9714
10490
  );
9715
10491
  } else if (error.status === 404) {
9716
- throw new BadRequestError49("Environment or repository not found.");
10492
+ throw new BadRequestError53("Environment or repository not found.");
9717
10493
  } else if (error.status === 403) {
9718
- throw new BadRequestError49(
10494
+ throw new BadRequestError53(
9719
10495
  "Forbidden: Insufficient permissions or rate limit exceeded."
9720
10496
  );
9721
10497
  } else if (error.message.includes("admin access") || error.message.includes("permissions")) {
9722
10498
  throw error;
9723
10499
  } else {
9724
- throw new BadRequestError49(
10500
+ throw new BadRequestError53(
9725
10501
  `Failed to set GitHub variables: ${error.message}`
9726
10502
  );
9727
10503
  }
@@ -9733,12 +10509,12 @@ function useGitHubService() {
9733
10509
  }
9734
10510
 
9735
10511
  // src/resources/utils/util.controller.ts
9736
- import Joi37 from "joi";
10512
+ import Joi43 from "joi";
9737
10513
  import {
9738
- AppError as AppError23,
9739
- BadRequestError as BadRequestError50,
9740
- InternalServerError as InternalServerError26,
9741
- logger as logger28
10514
+ AppError as AppError25,
10515
+ BadRequestError as BadRequestError54,
10516
+ InternalServerError as InternalServerError28,
10517
+ logger as logger30
9742
10518
  } from "@goweekdays/utils";
9743
10519
  function useUtilController() {
9744
10520
  async function healthCheck(req, res, next) {
@@ -9755,32 +10531,32 @@ function useUtilController() {
9755
10531
  }
9756
10532
  });
9757
10533
  } catch (error) {
9758
- logger28.error("Health check failed", { error: error.message });
9759
- next(new InternalServerError26("Health check failed"));
10534
+ logger30.error("Health check failed", { error: error.message });
10535
+ next(new InternalServerError28("Health check failed"));
9760
10536
  }
9761
10537
  }
9762
10538
  async function setGitHubVariables(req, res, next) {
9763
10539
  try {
9764
10540
  const { githubToken, repoUrl, environment, type, keyValues } = req.body;
9765
- const validation = Joi37.object({
9766
- githubToken: Joi37.string().required().messages({
10541
+ const validation = Joi43.object({
10542
+ githubToken: Joi43.string().required().messages({
9767
10543
  "string.empty": "GitHub token is required",
9768
10544
  "any.required": "GitHub token is required"
9769
10545
  }),
9770
- repoUrl: Joi37.string().uri().required().messages({
10546
+ repoUrl: Joi43.string().uri().required().messages({
9771
10547
  "string.empty": "Repository URL is required",
9772
10548
  "string.uri": "Repository URL must be a valid URL",
9773
10549
  "any.required": "Repository URL is required"
9774
10550
  }),
9775
- environment: Joi37.string().required().messages({
10551
+ environment: Joi43.string().required().messages({
9776
10552
  "string.empty": "Environment name is required",
9777
10553
  "any.required": "Environment name is required"
9778
10554
  }),
9779
- type: Joi37.string().valid("env", "secret").required().messages({
10555
+ type: Joi43.string().valid("env", "secret").required().messages({
9780
10556
  "any.only": 'Type must be either "env" or "secret"',
9781
10557
  "any.required": "Type is required"
9782
10558
  }),
9783
- keyValues: Joi37.string().required().messages({
10559
+ keyValues: Joi43.string().required().messages({
9784
10560
  "string.empty": "Key-value pairs are required",
9785
10561
  "any.required": "Key-value pairs are required"
9786
10562
  })
@@ -9793,13 +10569,13 @@ function useUtilController() {
9793
10569
  keyValues
9794
10570
  });
9795
10571
  if (error) {
9796
- next(new BadRequestError50(error.message));
10572
+ next(new BadRequestError54(error.message));
9797
10573
  return;
9798
10574
  }
9799
10575
  const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
9800
10576
  if (!repoUrlPattern.test(repoUrl)) {
9801
10577
  next(
9802
- new BadRequestError50(
10578
+ new BadRequestError54(
9803
10579
  "Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
9804
10580
  )
9805
10581
  );
@@ -9811,7 +10587,7 @@ function useUtilController() {
9811
10587
  );
9812
10588
  if (invalidLines.length > 0) {
9813
10589
  next(
9814
- new BadRequestError50(
10590
+ new BadRequestError54(
9815
10591
  "Invalid key-value format. Each pair should be in format: KEY=value. Pairs should be separated by semicolons."
9816
10592
  )
9817
10593
  );
@@ -9825,7 +10601,7 @@ function useUtilController() {
9825
10601
  type,
9826
10602
  keyValues
9827
10603
  });
9828
- logger28.info(`GitHub variables set successfully`, {
10604
+ logger30.info(`GitHub variables set successfully`, {
9829
10605
  repoUrl,
9830
10606
  environment,
9831
10607
  type,
@@ -9836,319 +10612,311 @@ function useUtilController() {
9836
10612
  message: result,
9837
10613
  data: {
9838
10614
  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
10615
+ environment,
10616
+ type,
10617
+ variablesSet: lines.length
9968
10618
  }
9969
10619
  });
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."
10620
+ } catch (error) {
10621
+ logger30.error("Failed to set GitHub variables", {
10622
+ error: error.message,
10623
+ stack: error.stack
9988
10624
  });
9989
- return;
9990
- } catch (error2) {
9991
- if (error2 instanceof AppError24) {
9992
- next(error2);
10625
+ if (error instanceof AppError25) {
10626
+ next(error);
9993
10627
  } else {
9994
- next(new InternalServerError27("An unexpected error occurred"));
10628
+ next(
10629
+ new InternalServerError28(
10630
+ `Failed to set GitHub variables: ${error.message}`
10631
+ )
10632
+ );
9995
10633
  }
9996
10634
  }
9997
10635
  }
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
- }
10636
+ const { verifySignature, captureOrder } = usePaypalService();
10637
+ const { addWithVerification } = useOrgService();
10638
+ async function paypalWebhook(req, res, next) {
10025
10639
  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);
10640
+ const isSignatureValid = await verifySignature(
10641
+ req.body,
10642
+ req.headers,
10643
+ PAYPAL_WEBHOOK_ID
10644
+ );
10645
+ if (isSignatureValid) {
10646
+ const payload = JSON.parse(req.body);
10647
+ const eventType = payload.event_type;
10648
+ const resource = payload.resource;
10649
+ switch (eventType) {
10650
+ case "CHECKOUT.ORDER.APPROVED": {
10651
+ const orderId = resource.id;
10652
+ await captureOrder(orderId);
10653
+ break;
10654
+ }
10655
+ case "PAYMENT.CAPTURE.COMPLETED": {
10656
+ const customId = resource?.custom_id || resource?.purchase_units?.[0]?.custom_id;
10657
+ if (!customId) {
10658
+ throw new Error("Missing PayPal customId");
10659
+ }
10660
+ await addWithVerification(customId);
10661
+ break;
10662
+ }
10663
+ default:
10664
+ break;
10665
+ }
10666
+ } else {
10667
+ next(new BadRequestError54("Invalid PayPal webhook signature."));
10668
+ return;
10669
+ }
10670
+ res.sendStatus(200);
10036
10671
  return;
10037
- } catch (error2) {
10038
- next(error2);
10672
+ } catch (error) {
10673
+ logger30.log({
10674
+ level: "error",
10675
+ message: `${error}`
10676
+ });
10677
+ next(new InternalServerError28(`PayPal webhook error: ${error.message}`));
10039
10678
  }
10040
10679
  }
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
- }
10680
+ return {
10681
+ healthCheck,
10682
+ setGitHubVariables,
10683
+ paypalWebhook
10684
+ };
10685
+ }
10686
+
10687
+ // src/resources/utils/transaction.schema.ts
10688
+ import Joi44 from "joi";
10689
+ var transactionSchema = Joi44.object({
10690
+ _id: Joi44.string().hex().optional().allow("", null),
10691
+ payment: Joi44.string().required(),
10692
+ user: Joi44.string().hex().optional().allow("", null),
10693
+ org: Joi44.string().hex().optional().allow("", null),
10694
+ type: Joi44.string().required(),
10695
+ amount: Joi44.number().positive().min(0).required(),
10696
+ currency: Joi44.string().required(),
10697
+ description: Joi44.string().optional().allow("", null),
10698
+ metadata: Joi44.object({
10699
+ subscriptionId: Joi44.string().hex().optional().allow("", null),
10700
+ cycle: Joi44.number().optional().allow("", null),
10701
+ seats: Joi44.number().optional().allow("", null),
10702
+ promoCode: Joi44.string().optional().allow("", null)
10703
+ }).optional().allow("", null),
10704
+ status: Joi44.string().optional().allow("", null),
10705
+ createdAt: Joi44.string().optional().allow("", null),
10706
+ updatedAt: Joi44.string().optional().allow("", null),
10707
+ deletedAt: Joi44.string().optional().allow("", null)
10708
+ });
10709
+
10710
+ // src/resources/job-post/job.post.model.ts
10711
+ import { BadRequestError as BadRequestError55 } from "@goweekdays/utils";
10712
+ import Joi45 from "joi";
10713
+ import { ObjectId as ObjectId27 } from "mongodb";
10714
+ var schemaJobPost = Joi45.object({
10715
+ _id: Joi45.string().hex().optional(),
10716
+ org: Joi45.string().hex().optional(),
10717
+ title: Joi45.string().trim().required(),
10718
+ setup: Joi45.string().trim().required(),
10719
+ location: Joi45.string().trim().required(),
10720
+ type: Joi45.string().trim().required(),
10721
+ description: Joi45.string().trim().required(),
10722
+ status: Joi45.string().trim().required(),
10723
+ createdAt: Joi45.date().optional(),
10724
+ updatedAt: Joi45.date().optional(),
10725
+ deletedAt: Joi45.date().optional()
10726
+ });
10727
+ function modelJobPost(value) {
10728
+ const { error } = schemaJobPost.validate(value);
10729
+ if (error) {
10730
+ throw new BadRequestError55(`Invalid job post: ${error.message}`);
10731
+ }
10732
+ if (!value._id) {
10049
10733
  try {
10050
- const message = await _verify(id);
10051
- res.json(message);
10052
- return;
10734
+ value._id = new ObjectId27();
10053
10735
  } catch (error2) {
10054
- next(error2);
10736
+ throw new BadRequestError55("Invalid job post ID.");
10055
10737
  }
10056
10738
  }
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;
10739
+ try {
10740
+ value.org = new ObjectId27(value.org);
10741
+ } catch (error2) {
10742
+ throw new BadRequestError55("Invalid Org ID");
10743
+ }
10744
+ return {
10745
+ _id: value._id,
10746
+ org: value.org,
10747
+ title: value.title,
10748
+ setup: value.setup,
10749
+ location: value.location,
10750
+ type: value.type,
10751
+ description: value.description,
10752
+ status: value.status ?? "active",
10753
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
10754
+ updatedAt: value.updatedAt,
10755
+ deletedAt: value.deletedAt
10756
+ };
10757
+ }
10758
+
10759
+ // src/resources/job-post/job.post.controller.ts
10760
+ import { BadRequestError as BadRequestError58, logger as logger32 } from "@goweekdays/utils";
10761
+
10762
+ // src/resources/job-post/job.post.repository.ts
10763
+ import { BadRequestError as BadRequestError56, useAtlas as useAtlas27, useCache as useCache20, logger as logger31, InternalServerError as InternalServerError29 } from "@goweekdays/utils";
10764
+ import { ObjectId as ObjectId28 } from "mongodb";
10765
+ function useJobPostRepo() {
10766
+ const db = useAtlas27.getDb();
10767
+ if (!db) {
10768
+ throw new BadRequestError56("Unable to connect to server.");
10769
+ }
10770
+ const namespace_collection = "job.posts";
10771
+ const collection = db.collection(namespace_collection);
10772
+ const { delNamespace } = useCache20(namespace_collection);
10773
+ function delCachedData() {
10774
+ delNamespace().then(() => {
10775
+ logger31.log({
10776
+ level: "info",
10777
+ message: `Cache namespace cleared for ${namespace_collection}`
10778
+ });
10779
+ }).catch((err) => {
10780
+ logger31.log({
10781
+ level: "error",
10782
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
10783
+ });
10784
+ });
10785
+ }
10786
+ async function createIndexes() {
10787
+ try {
10788
+ await collection.createIndexes([
10789
+ { key: { title: 1 } },
10790
+ { key: { setup: 1 } },
10791
+ { key: { location: 1 } },
10792
+ { key: { type: 1 } },
10793
+ {
10794
+ key: {
10795
+ title: "text",
10796
+ setup: "text",
10797
+ location: "text",
10798
+ type: "text"
10799
+ },
10800
+ name: "jobpost_text_search"
10801
+ }
10802
+ ]);
10803
+ return "Successfully created job post indexes.";
10804
+ } catch (error) {
10805
+ throw new BadRequestError56("Failed to create job post indexes.");
10064
10806
  }
10807
+ }
10808
+ async function add(value, session) {
10065
10809
  try {
10066
- await _cancelUserInvitation(otpId);
10067
- return res.json({
10068
- message: "User invite has been cancelled."
10810
+ value = modelJobPost(value);
10811
+ const res = await collection.insertOne(value, { session });
10812
+ delCachedData();
10813
+ return res.insertedId;
10814
+ } catch (error) {
10815
+ logger31.log({
10816
+ level: "error",
10817
+ message: error.message
10069
10818
  });
10070
- } catch (error2) {
10071
- throw error2;
10819
+ throw new BadRequestError56(`Failed to create job post: ${error.message}`);
10072
10820
  }
10073
10821
  }
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;
10822
+ async function deleteById(_id, session) {
10823
+ try {
10824
+ _id = new ObjectId28(_id);
10825
+ } catch (error) {
10826
+ throw new BadRequestError56("Invalid ID.");
10080
10827
  }
10081
- const email = req.body.email ?? "";
10082
10828
  try {
10083
- await _signUp({ email });
10084
- res.json({ message: "Successfully signed up user." });
10085
- return;
10086
- } catch (error2) {
10087
- next(error2);
10829
+ await collection.updateOne(
10830
+ { _id },
10831
+ {
10832
+ $set: {
10833
+ status: "deleted",
10834
+ updatedAt: /* @__PURE__ */ new Date(),
10835
+ deletedAt: /* @__PURE__ */ new Date()
10836
+ }
10837
+ },
10838
+ { session }
10839
+ );
10840
+ delCachedData();
10841
+ return "Successfully deleted job post.";
10842
+ } catch (error) {
10843
+ throw new InternalServerError29("Failed to delete job post.");
10088
10844
  }
10089
10845
  }
10090
- async function inviteMember(req, res, next) {
10091
- const { error } = schemaInviteMember.validate(req.body);
10846
+ return {
10847
+ createIndexes,
10848
+ add,
10849
+ deleteById
10850
+ };
10851
+ }
10852
+
10853
+ // src/resources/job-post/job.post.service.ts
10854
+ import {
10855
+ AppError as AppError26,
10856
+ BadRequestError as BadRequestError57,
10857
+ InternalServerError as InternalServerError30
10858
+ } from "@goweekdays/utils";
10859
+ import Joi46 from "joi";
10860
+ function useJobPostService() {
10861
+ const { deleteById: _deleteById } = useJobPostRepo();
10862
+ async function deleteById(id) {
10863
+ const { error } = Joi46.string().hex().required().validate(id);
10092
10864
  if (error) {
10093
- next(new BadRequestError51(error.message));
10094
- return;
10865
+ throw new BadRequestError57(error.message);
10095
10866
  }
10096
10867
  try {
10097
- await _inviteMember(req.body);
10098
- res.json({ message: "Successfully invited member." });
10099
- return;
10868
+ await _deleteById(id);
10869
+ return "Successfully deleted job post.";
10100
10870
  } catch (error2) {
10101
- next(error2);
10871
+ if (error2 instanceof AppError26) {
10872
+ throw error2;
10873
+ } else {
10874
+ throw new InternalServerError30("Failed to delete job post.");
10875
+ }
10102
10876
  }
10103
10877
  }
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);
10878
+ return {
10879
+ deleteById
10880
+ };
10881
+ }
10882
+
10883
+ // src/resources/job-post/job.post.controller.ts
10884
+ function useJobPostController() {
10885
+ const { add: _add } = useJobPostRepo();
10886
+ const { deleteById: _deleteById } = useJobPostService();
10887
+ async function add(req, res, next) {
10888
+ const value = req.body;
10889
+ const { error } = schemaJobPost.validate(value);
10108
10890
  if (error) {
10109
- next(new BadRequestError51(error.message));
10891
+ next(new BadRequestError58(error.message));
10892
+ logger32.info(`Controller: ${error.message}`);
10110
10893
  return;
10111
10894
  }
10112
10895
  try {
10113
- const message = await _cancelInviteMember(id);
10114
- res.json({ message });
10896
+ const result = await _add(value);
10897
+ res.json({ message: "Successfully created job post.", data: { result } });
10115
10898
  return;
10116
10899
  } catch (error2) {
10117
10900
  next(error2);
10118
10901
  }
10119
10902
  }
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));
10903
+ async function deleteById(req, res, next) {
10904
+ const id = req.params.id;
10905
+ if (!id) {
10906
+ next(new BadRequestError58("Job Post ID is required."));
10126
10907
  return;
10127
10908
  }
10128
10909
  try {
10129
- const message = await _forgetPassword(email);
10130
- res.json({
10131
- message
10132
- });
10910
+ const message = await _deleteById(id);
10911
+ res.json(message);
10133
10912
  return;
10134
- } catch (error2) {
10135
- if (error2 instanceof AppError24) {
10136
- next(error2);
10137
- } else {
10138
- next(new InternalServerError27("An unexpected error occurred"));
10139
- }
10913
+ } catch (error) {
10914
+ next(error);
10140
10915
  }
10141
10916
  }
10142
10917
  return {
10143
- getVerifications,
10144
- createUserInvite,
10145
- createForgetPassword,
10146
- verify,
10147
- cancelUserInvitation,
10148
- inviteMember,
10149
- signUp,
10150
- cancelInviteMember,
10151
- forgetPassword
10918
+ add,
10919
+ deleteById
10152
10920
  };
10153
10921
  }
10154
10922
  export {
@@ -10194,7 +10962,11 @@ export {
10194
10962
  XENDIT_SECRET_KEY,
10195
10963
  currencies,
10196
10964
  isDev,
10965
+ ledgerBillStatuses,
10966
+ ledgerBillTypes,
10197
10967
  modelApp,
10968
+ modelJobPost,
10969
+ modelLedgerBill,
10198
10970
  modelMember,
10199
10971
  modelOrg,
10200
10972
  modelPermission,
@@ -10211,6 +10983,8 @@ export {
10211
10983
  schemaBuilding,
10212
10984
  schemaBuildingUnit,
10213
10985
  schemaInviteMember,
10986
+ schemaJobPost,
10987
+ schemaLedgerBill,
10214
10988
  schemaMember,
10215
10989
  schemaMemberRole,
10216
10990
  schemaMemberStatus,
@@ -10250,6 +11024,11 @@ export {
10250
11024
  useFileRepo,
10251
11025
  useFileService,
10252
11026
  useGitHubService,
11027
+ useJobPostController,
11028
+ useJobPostRepo,
11029
+ useJobPostService,
11030
+ useLedgerBillingController,
11031
+ useLedgerBillingRepo,
10253
11032
  useMemberController,
10254
11033
  useMemberRepo,
10255
11034
  useOrgController,