@goweekdays/core 2.6.1 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -72,7 +72,11 @@ __export(src_exports, {
72
72
  XENDIT_SECRET_KEY: () => XENDIT_SECRET_KEY,
73
73
  currencies: () => currencies,
74
74
  isDev: () => isDev,
75
+ ledgerBillStatuses: () => ledgerBillStatuses,
76
+ ledgerBillTypes: () => ledgerBillTypes,
75
77
  modelApp: () => modelApp,
78
+ modelJobPost: () => modelJobPost,
79
+ modelLedgerBill: () => modelLedgerBill,
76
80
  modelMember: () => modelMember,
77
81
  modelOrg: () => modelOrg,
78
82
  modelPermission: () => modelPermission,
@@ -89,6 +93,9 @@ __export(src_exports, {
89
93
  schemaBuilding: () => schemaBuilding,
90
94
  schemaBuildingUnit: () => schemaBuildingUnit,
91
95
  schemaInviteMember: () => schemaInviteMember,
96
+ schemaJobPost: () => schemaJobPost,
97
+ schemaLedgerBill: () => schemaLedgerBill,
98
+ schemaLedgerBillingSummary: () => schemaLedgerBillingSummary,
92
99
  schemaMember: () => schemaMember,
93
100
  schemaMemberRole: () => schemaMemberRole,
94
101
  schemaMemberStatus: () => schemaMemberStatus,
@@ -128,6 +135,11 @@ __export(src_exports, {
128
135
  useFileRepo: () => useFileRepo,
129
136
  useFileService: () => useFileService,
130
137
  useGitHubService: () => useGitHubService,
138
+ useJobPostController: () => useJobPostController,
139
+ useJobPostRepo: () => useJobPostRepo,
140
+ useJobPostService: () => useJobPostService,
141
+ useLedgerBillingController: () => useLedgerBillingController,
142
+ useLedgerBillingRepo: () => useLedgerBillingRepo,
131
143
  useMemberController: () => useMemberController,
132
144
  useMemberRepo: () => useMemberRepo,
133
145
  useOrgController: () => useOrgController,
@@ -638,11 +650,11 @@ function useAuthService() {
638
650
  }
639
651
 
640
652
  // src/resources/auth/auth.controller.ts
641
- var import_joi30 = __toESM(require("joi"));
642
- var import_utils41 = require("@goweekdays/utils");
653
+ var import_joi36 = __toESM(require("joi"));
654
+ var import_utils46 = require("@goweekdays/utils");
643
655
 
644
656
  // src/resources/verification/verification.service.ts
645
- var import_utils40 = require("@goweekdays/utils");
657
+ var import_utils45 = require("@goweekdays/utils");
646
658
 
647
659
  // src/resources/verification/verification.model.ts
648
660
  var import_utils3 = require("@goweekdays/utils");
@@ -664,7 +676,11 @@ var schemaVerification = import_joi2.default.object({
664
676
  roleName: import_joi2.default.string().optional().allow("", null),
665
677
  referralCode: import_joi2.default.string().optional().allow("", null),
666
678
  org: import_joi2.default.string().hex().optional().allow("", null),
667
- orgName: import_joi2.default.string().optional().allow("", null)
679
+ orgName: import_joi2.default.string().optional().allow("", null),
680
+ contact: import_joi2.default.string().optional().allow("", null),
681
+ seats: import_joi2.default.number().optional().allow("", null),
682
+ createdBy: import_joi2.default.string().optional().allow("", null),
683
+ amount: import_joi2.default.number().optional().allow("", null)
668
684
  }).optional(),
669
685
  expireAt: import_joi2.default.date().optional().allow("", null)
670
686
  });
@@ -1037,7 +1053,7 @@ var DOMAIN = process.env.DOMAIN || "localhost";
1037
1053
  var APP_ORG = process.env.APP_ORG || "http://localhost/organizations/create";
1038
1054
 
1039
1055
  // src/resources/user/user.service.ts
1040
- var import_utils38 = require("@goweekdays/utils");
1056
+ var import_utils43 = require("@goweekdays/utils");
1041
1057
 
1042
1058
  // src/resources/file/file.repository.ts
1043
1059
  var import_utils5 = require("@goweekdays/utils");
@@ -1635,9 +1651,6 @@ function useMemberRepo() {
1635
1651
  {
1636
1652
  $match: query
1637
1653
  },
1638
- {
1639
- $sort: { _id: -1 }
1640
- },
1641
1654
  {
1642
1655
  $limit: limit
1643
1656
  },
@@ -4425,6 +4438,7 @@ function modelOrg(value) {
4425
4438
  // src/resources/organization/organization.repository.ts
4426
4439
  var import_utils22 = require("@goweekdays/utils");
4427
4440
  var import_mongodb14 = require("mongodb");
4441
+ var import_joi16 = __toESM(require("joi"));
4428
4442
  function useOrgRepo() {
4429
4443
  const db = import_utils22.useAtlas.getDb();
4430
4444
  if (!db) {
@@ -4600,10 +4614,9 @@ function useOrgRepo() {
4600
4614
  });
4601
4615
  return cached;
4602
4616
  }
4603
- const result = await collection.findOne({ name });
4604
- if (!result) {
4605
- throw new import_utils22.BadRequestError("Organization not found.");
4606
- }
4617
+ const result = await collection.findOne({
4618
+ name: { $regex: name, $options: "i" }
4619
+ });
4607
4620
  setCache(cacheKey, result, 300).then(() => {
4608
4621
  import_utils22.logger.log({
4609
4622
  level: "info",
@@ -4624,6 +4637,42 @@ function useOrgRepo() {
4624
4637
  }
4625
4638
  }
4626
4639
  }
4640
+ async function getByEmail(email) {
4641
+ const { error } = import_joi16.default.string().email().required().validate(email);
4642
+ if (error) {
4643
+ throw new import_utils22.BadRequestError(error.message);
4644
+ }
4645
+ const cacheKey = (0, import_utils22.makeCacheKey)(namespace_collection, { email });
4646
+ try {
4647
+ const cached = await getCache(cacheKey);
4648
+ if (cached) {
4649
+ import_utils22.logger.log({
4650
+ level: "info",
4651
+ message: `Cache hit for getByEmail organization: ${cacheKey}`
4652
+ });
4653
+ return cached;
4654
+ }
4655
+ const result = await collection.findOne({ email });
4656
+ setCache(cacheKey, result, 300).then(() => {
4657
+ import_utils22.logger.log({
4658
+ level: "info",
4659
+ message: `Cache set for organization by email: ${cacheKey}`
4660
+ });
4661
+ }).catch((err) => {
4662
+ import_utils22.logger.log({
4663
+ level: "error",
4664
+ message: `Failed to set cache for organization by email: ${err.message}`
4665
+ });
4666
+ });
4667
+ return result;
4668
+ } catch (error2) {
4669
+ if (error2 instanceof import_utils22.AppError) {
4670
+ throw error2;
4671
+ } else {
4672
+ throw new import_utils22.InternalServerError("Failed to get organization.");
4673
+ }
4674
+ }
4675
+ }
4627
4676
  async function updateFieldById({ _id, field, value } = {}, session) {
4628
4677
  const allowedFields = ["name", "description"];
4629
4678
  if (!allowedFields.includes(field)) {
@@ -4698,15 +4747,16 @@ function useOrgRepo() {
4698
4747
  updateFieldById,
4699
4748
  deleteById,
4700
4749
  getByName,
4750
+ getByEmail,
4701
4751
  updateById
4702
4752
  };
4703
4753
  }
4704
4754
 
4705
4755
  // src/resources/organization/organization.service.ts
4706
- var import_utils36 = require("@goweekdays/utils");
4756
+ var import_utils41 = require("@goweekdays/utils");
4707
4757
 
4708
4758
  // src/resources/member/member.controller.ts
4709
- var import_joi18 = __toESM(require("joi"));
4759
+ var import_joi19 = __toESM(require("joi"));
4710
4760
  var import_utils26 = require("@goweekdays/utils");
4711
4761
 
4712
4762
  // src/resources/member/member.service.ts
@@ -4738,7 +4788,7 @@ function useRoleService() {
4738
4788
  }
4739
4789
 
4740
4790
  // src/resources/role/role.controller.ts
4741
- var import_joi16 = __toESM(require("joi"));
4791
+ var import_joi17 = __toESM(require("joi"));
4742
4792
  var import_utils24 = require("@goweekdays/utils");
4743
4793
  function useRoleController() {
4744
4794
  const {
@@ -4771,12 +4821,12 @@ function useRoleController() {
4771
4821
  const limit = parseInt(req.query.limit ?? "10");
4772
4822
  const app = req.query.app ?? "";
4773
4823
  const org = req.query.org ?? "";
4774
- const validation = import_joi16.default.object({
4775
- search: import_joi16.default.string().optional().allow("", null),
4776
- page: import_joi16.default.number().required(),
4777
- limit: import_joi16.default.number().required(),
4778
- app: import_joi16.default.string().optional().allow("", null),
4779
- org: import_joi16.default.string().hex().optional().allow("", null)
4824
+ const validation = import_joi17.default.object({
4825
+ search: import_joi17.default.string().optional().allow("", null),
4826
+ page: import_joi17.default.number().required(),
4827
+ limit: import_joi17.default.number().required(),
4828
+ app: import_joi17.default.string().optional().allow("", null),
4829
+ org: import_joi17.default.string().hex().optional().allow("", null)
4780
4830
  });
4781
4831
  const { error } = validation.validate({ search, page, limit, app, org });
4782
4832
  if (error) {
@@ -4793,8 +4843,8 @@ function useRoleController() {
4793
4843
  }
4794
4844
  async function getRoleByUserId(req, res, next) {
4795
4845
  const userId = req.params.userId;
4796
- const validation = import_joi16.default.object({
4797
- userId: import_joi16.default.string().required()
4846
+ const validation = import_joi17.default.object({
4847
+ userId: import_joi17.default.string().required()
4798
4848
  });
4799
4849
  const { error } = validation.validate({ userId });
4800
4850
  if (error) {
@@ -4811,8 +4861,8 @@ function useRoleController() {
4811
4861
  }
4812
4862
  async function getRoleById(req, res, next) {
4813
4863
  const _id = req.params.id;
4814
- const validation = import_joi16.default.object({
4815
- _id: import_joi16.default.string().hex().required()
4864
+ const validation = import_joi17.default.object({
4865
+ _id: import_joi17.default.string().hex().required()
4816
4866
  });
4817
4867
  const { error } = validation.validate({ _id });
4818
4868
  if (error) {
@@ -4831,10 +4881,10 @@ function useRoleController() {
4831
4881
  const _id = req.params.id;
4832
4882
  const name = req.body.name ?? "";
4833
4883
  const permissions = req.body.permissions ?? [];
4834
- const validation = import_joi16.default.object({
4835
- _id: import_joi16.default.string().required(),
4836
- name: import_joi16.default.string().required(),
4837
- permissions: import_joi16.default.array().items(import_joi16.default.string()).required()
4884
+ const validation = import_joi17.default.object({
4885
+ _id: import_joi17.default.string().required(),
4886
+ name: import_joi17.default.string().required(),
4887
+ permissions: import_joi17.default.array().items(import_joi17.default.string()).required()
4838
4888
  });
4839
4889
  const { error } = validation.validate({ _id, name, permissions });
4840
4890
  if (error) {
@@ -4852,9 +4902,9 @@ function useRoleController() {
4852
4902
  async function updatePermissionsById(req, res, next) {
4853
4903
  const _id = req.params.id;
4854
4904
  const permissions = req.body.permissions ?? [];
4855
- const validation = import_joi16.default.object({
4856
- _id: import_joi16.default.string().required(),
4857
- permissions: import_joi16.default.array().items(import_joi16.default.string()).required()
4905
+ const validation = import_joi17.default.object({
4906
+ _id: import_joi17.default.string().required(),
4907
+ permissions: import_joi17.default.array().items(import_joi17.default.string()).required()
4858
4908
  });
4859
4909
  const { error } = validation.validate({ _id, permissions });
4860
4910
  if (error) {
@@ -4871,8 +4921,8 @@ function useRoleController() {
4871
4921
  }
4872
4922
  async function deleteRole(req, res, next) {
4873
4923
  const _id = req.params.id;
4874
- const validation = import_joi16.default.object({
4875
- _id: import_joi16.default.string().required()
4924
+ const validation = import_joi17.default.object({
4925
+ _id: import_joi17.default.string().required()
4876
4926
  });
4877
4927
  const { error } = validation.validate({ _id });
4878
4928
  if (error) {
@@ -4899,7 +4949,7 @@ function useRoleController() {
4899
4949
  }
4900
4950
 
4901
4951
  // src/resources/member/member.service.ts
4902
- var import_joi17 = __toESM(require("joi"));
4952
+ var import_joi18 = __toESM(require("joi"));
4903
4953
  function useMemberService() {
4904
4954
  const { getById: getRoleById } = useRoleRepo();
4905
4955
  const {
@@ -4952,7 +5002,7 @@ function useMemberService() {
4952
5002
  }
4953
5003
  }
4954
5004
  async function deleteById(id) {
4955
- const { error } = import_joi17.default.string().hex().required().validate(id);
5005
+ const { error } = import_joi18.default.string().hex().required().validate(id);
4956
5006
  if (error) {
4957
5007
  throw new import_utils25.BadRequestError(error.message);
4958
5008
  }
@@ -4995,8 +5045,8 @@ function useMemberController() {
4995
5045
  } = useMemberService();
4996
5046
  async function getByUserId(req, res, next) {
4997
5047
  const userId = req.params.id;
4998
- const validation = import_joi18.default.object({
4999
- id: import_joi18.default.string().hex().required()
5048
+ const validation = import_joi19.default.object({
5049
+ id: import_joi19.default.string().hex().required()
5000
5050
  });
5001
5051
  const { error } = validation.validate({ id: userId });
5002
5052
  if (error) {
@@ -5015,10 +5065,10 @@ function useMemberController() {
5015
5065
  }
5016
5066
  }
5017
5067
  async function getByUserType(req, res, next) {
5018
- const validation = import_joi18.default.object({
5019
- org: import_joi18.default.string().hex().optional().allow("", null),
5020
- user: import_joi18.default.string().hex().required(),
5021
- app: import_joi18.default.string().required()
5068
+ const validation = import_joi19.default.object({
5069
+ org: import_joi19.default.string().hex().optional().allow("", null),
5070
+ user: import_joi19.default.string().hex().required(),
5071
+ app: import_joi19.default.string().required()
5022
5072
  });
5023
5073
  const { error } = validation.validate({ ...req.params, ...req.query });
5024
5074
  if (error) {
@@ -5040,10 +5090,10 @@ function useMemberController() {
5040
5090
  }
5041
5091
  }
5042
5092
  async function getByApp(req, res, next) {
5043
- const validation = import_joi18.default.object({
5044
- org: import_joi18.default.string().hex().optional().allow("", null),
5045
- user: import_joi18.default.string().hex().required(),
5046
- app: import_joi18.default.string().required()
5093
+ const validation = import_joi19.default.object({
5094
+ org: import_joi19.default.string().hex().optional().allow("", null),
5095
+ user: import_joi19.default.string().hex().required(),
5096
+ app: import_joi19.default.string().required()
5047
5097
  });
5048
5098
  const app = req.params.app ?? "";
5049
5099
  const org = req.query.org;
@@ -5072,14 +5122,14 @@ function useMemberController() {
5072
5122
  const org = req.query.org ?? "";
5073
5123
  const app = req.params.app ?? "";
5074
5124
  const status = req.query.status ?? "active";
5075
- const validation = import_joi18.default.object({
5076
- limit: import_joi18.default.number().min(10).max(50).required(),
5077
- search: import_joi18.default.string().optional().allow("", null),
5078
- page: import_joi18.default.number().required(),
5079
- user: import_joi18.default.string().hex().optional().allow("", null),
5080
- org: import_joi18.default.string().hex().optional().allow("", null),
5081
- app: import_joi18.default.string().required(),
5082
- status: import_joi18.default.string().required()
5125
+ const validation = import_joi19.default.object({
5126
+ limit: import_joi19.default.number().min(10).max(50).required(),
5127
+ search: import_joi19.default.string().optional().allow("", null),
5128
+ page: import_joi19.default.number().required(),
5129
+ user: import_joi19.default.string().hex().optional().allow("", null),
5130
+ org: import_joi19.default.string().hex().optional().allow("", null),
5131
+ app: import_joi19.default.string().required(),
5132
+ status: import_joi19.default.string().required()
5083
5133
  });
5084
5134
  const { error } = validation.validate({
5085
5135
  search,
@@ -5116,12 +5166,12 @@ function useMemberController() {
5116
5166
  const page = Number(req.query.page) ?? 1;
5117
5167
  const user = req.params.user ?? "";
5118
5168
  const app = req.params.app ?? "";
5119
- const validation = import_joi18.default.object({
5120
- limit: import_joi18.default.number().min(10).max(50).allow(null, ""),
5121
- search: import_joi18.default.string().optional().allow("", null),
5122
- page: import_joi18.default.number().optional().allow(null, ""),
5123
- app: import_joi18.default.string().required(),
5124
- user: import_joi18.default.string().hex().required()
5169
+ const validation = import_joi19.default.object({
5170
+ limit: import_joi19.default.number().min(10).max(200).allow(null, ""),
5171
+ search: import_joi19.default.string().optional().allow("", null),
5172
+ page: import_joi19.default.number().optional().allow(null, ""),
5173
+ app: import_joi19.default.string().required(),
5174
+ user: import_joi19.default.string().hex().required()
5125
5175
  });
5126
5176
  const { error } = validation.validate({
5127
5177
  search,
@@ -5153,11 +5203,11 @@ function useMemberController() {
5153
5203
  const search = req.query.search ?? "";
5154
5204
  const page = Number(req.query.page) ?? 1;
5155
5205
  const user = req.query.user ?? "";
5156
- const validation = import_joi18.default.object({
5157
- limit: import_joi18.default.number().min(10).max(50).required(),
5158
- search: import_joi18.default.string().optional().allow("", null),
5159
- page: import_joi18.default.number().required(),
5160
- user: import_joi18.default.string().hex().optional().allow("", null)
5206
+ const validation = import_joi19.default.object({
5207
+ limit: import_joi19.default.number().min(10).max(50).required(),
5208
+ search: import_joi19.default.string().optional().allow("", null),
5209
+ page: import_joi19.default.number().required(),
5210
+ user: import_joi19.default.string().hex().optional().allow("", null)
5161
5211
  });
5162
5212
  const { error } = validation.validate({
5163
5213
  search,
@@ -5182,9 +5232,9 @@ function useMemberController() {
5182
5232
  }
5183
5233
  }
5184
5234
  async function updateStatusByUserId(req, res, next) {
5185
- const validation = import_joi18.default.object({
5186
- id: import_joi18.default.string().hex().required(),
5187
- status: import_joi18.default.string().valid("active", "suspended", "deleted").required()
5235
+ const validation = import_joi19.default.object({
5236
+ id: import_joi19.default.string().hex().required(),
5237
+ status: import_joi19.default.string().valid("active", "suspended", "deleted").required()
5188
5238
  });
5189
5239
  const { error } = validation.validate(req.params);
5190
5240
  if (error) {
@@ -5233,7 +5283,7 @@ function useMemberController() {
5233
5283
  async function deleteById(req, res, next) {
5234
5284
  const payload = req.body;
5235
5285
  const _id = req.params.id ?? "";
5236
- const { error } = import_joi18.default.string().hex().required().validate(_id);
5286
+ const { error } = import_joi19.default.string().hex().required().validate(_id);
5237
5287
  if (error) {
5238
5288
  next(new import_utils26.BadRequestError(error.message));
5239
5289
  return;
@@ -5261,30 +5311,30 @@ function useMemberController() {
5261
5311
 
5262
5312
  // src/resources/subscription/subscription.model.ts
5263
5313
  var import_utils27 = require("@goweekdays/utils");
5264
- var import_joi19 = __toESM(require("joi"));
5314
+ var import_joi20 = __toESM(require("joi"));
5265
5315
  var import_mongodb15 = require("mongodb");
5266
5316
  var schema2 = {
5267
- seats: import_joi19.default.number().integer().min(1).required(),
5268
- paidSeats: import_joi19.default.number().integer().min(0).required(),
5269
- amount: import_joi19.default.number().positive().required(),
5270
- promoCode: import_joi19.default.string().optional().allow("", null),
5271
- nextBillingDate: import_joi19.default.date().optional().allow("", null)
5317
+ seats: import_joi20.default.number().integer().min(1).required(),
5318
+ paidSeats: import_joi20.default.number().integer().min(0).required(),
5319
+ amount: import_joi20.default.number().positive().required(),
5320
+ promoCode: import_joi20.default.string().optional().allow("", null),
5321
+ nextBillingDate: import_joi20.default.date().optional().allow("", null)
5272
5322
  };
5273
- var schemaSubscription = import_joi19.default.object({
5323
+ var schemaSubscription = import_joi20.default.object({
5274
5324
  ...schema2,
5275
- org: import_joi19.default.string().hex().length(24).required(),
5276
- currency: import_joi19.default.string().length(3).required(),
5277
- billingCycle: import_joi19.default.string().valid("monthly", "yearly").required()
5325
+ org: import_joi20.default.string().hex().length(24).required(),
5326
+ currency: import_joi20.default.string().length(3).required(),
5327
+ billingCycle: import_joi20.default.string().valid("monthly", "yearly").required()
5278
5328
  });
5279
- var schemaSubscriptionUpdate = import_joi19.default.object({
5329
+ var schemaSubscriptionUpdate = import_joi20.default.object({
5280
5330
  ...schema2,
5281
- status: import_joi19.default.string().optional().allow("", null)
5331
+ status: import_joi20.default.string().optional().allow("", null)
5282
5332
  });
5283
- var schemaSubscriptionSeats = import_joi19.default.object({
5284
- id: import_joi19.default.string().hex().length(24).required(),
5285
- seats: import_joi19.default.number().integer().min(1).required(),
5286
- amount: import_joi19.default.number().positive().optional().allow(null, 0),
5287
- user: import_joi19.default.string().hex().length(24).required()
5333
+ var schemaSubscriptionSeats = import_joi20.default.object({
5334
+ id: import_joi20.default.string().hex().length(24).required(),
5335
+ seats: import_joi20.default.number().integer().min(1).required(),
5336
+ amount: import_joi20.default.number().positive().optional().allow(null, 0),
5337
+ user: import_joi20.default.string().hex().length(24).required()
5288
5338
  });
5289
5339
  function modelSubscription(data) {
5290
5340
  const { error } = schemaSubscription.validate(data);
@@ -5321,7 +5371,7 @@ function modelSubscription(data) {
5321
5371
 
5322
5372
  // src/resources/subscription/subscription.repository.ts
5323
5373
  var import_utils28 = require("@goweekdays/utils");
5324
- var import_joi20 = __toESM(require("joi"));
5374
+ var import_joi21 = __toESM(require("joi"));
5325
5375
  var import_mongodb16 = require("mongodb");
5326
5376
  function useSubscriptionRepo() {
5327
5377
  const db = import_utils28.useAtlas.getDb();
@@ -5431,7 +5481,7 @@ function useSubscriptionRepo() {
5431
5481
  }
5432
5482
  }
5433
5483
  async function getByOrg(org) {
5434
- const { error } = import_joi20.default.string().hex().length(24).required().validate(org);
5484
+ const { error } = import_joi21.default.string().hex().length(24).required().validate(org);
5435
5485
  if (error) {
5436
5486
  throw new Error(`Invalid org ID: ${error.message}`);
5437
5487
  }
@@ -5470,7 +5520,7 @@ function useSubscriptionRepo() {
5470
5520
  }
5471
5521
  }
5472
5522
  async function getById(_id) {
5473
- const { error } = import_joi20.default.string().hex().length(24).required().validate(_id);
5523
+ const { error } = import_joi21.default.string().hex().length(24).required().validate(_id);
5474
5524
  if (error) {
5475
5525
  throw new Error(`Invalid subscription ID: ${error.message}`);
5476
5526
  }
@@ -5509,7 +5559,7 @@ function useSubscriptionRepo() {
5509
5559
  }
5510
5560
  }
5511
5561
  async function deleteById(_id) {
5512
- const { error } = import_joi20.default.string().hex().length(24).required().validate(_id);
5562
+ const { error } = import_joi21.default.string().hex().length(24).required().validate(_id);
5513
5563
  if (error) {
5514
5564
  throw new Error(`Invalid subscription ID: ${error.message}`);
5515
5565
  }
@@ -5536,7 +5586,7 @@ function useSubscriptionRepo() {
5536
5586
  }
5537
5587
  }
5538
5588
  async function updateById(_id, options, session) {
5539
- const { error: errorId } = import_joi20.default.string().hex().length(24).required().validate(_id);
5589
+ const { error: errorId } = import_joi21.default.string().hex().length(24).required().validate(_id);
5540
5590
  if (errorId) {
5541
5591
  throw new Error(`Invalid subscription ID: ${errorId.message}`);
5542
5592
  }
@@ -5581,7 +5631,7 @@ function useSubscriptionRepo() {
5581
5631
  }
5582
5632
 
5583
5633
  // src/resources/subscription/subscription.controller.ts
5584
- var import_joi22 = __toESM(require("joi"));
5634
+ var import_joi23 = __toESM(require("joi"));
5585
5635
  var import_utils32 = require("@goweekdays/utils");
5586
5636
 
5587
5637
  // src/resources/subscription/subscription.service.ts
@@ -5592,16 +5642,16 @@ var import_utils30 = require("@goweekdays/utils");
5592
5642
 
5593
5643
  // src/resources/subscription/subscription.transaction.model.ts
5594
5644
  var import_utils29 = require("@goweekdays/utils");
5595
- var import_joi21 = __toESM(require("joi"));
5645
+ var import_joi22 = __toESM(require("joi"));
5596
5646
  var import_mongodb17 = require("mongodb");
5597
- var schemaSubscriptionTransaction = import_joi21.default.object({
5598
- subscription: import_joi21.default.string().hex().length(24).required(),
5599
- amount: import_joi21.default.number().positive().required(),
5600
- currency: import_joi21.default.string().length(3).required(),
5601
- type: import_joi21.default.string().valid("initiate", "add-seat", "remove-seat", "renewal").required(),
5602
- description: import_joi21.default.string().max(255).optional().allow("", null),
5603
- createdBy: import_joi21.default.string().hex().length(24).required(),
5604
- createdByName: import_joi21.default.string().optional().allow("", null)
5647
+ var schemaSubscriptionTransaction = import_joi22.default.object({
5648
+ subscription: import_joi22.default.string().hex().length(24).required(),
5649
+ amount: import_joi22.default.number().positive().required(),
5650
+ currency: import_joi22.default.string().length(3).required(),
5651
+ type: import_joi22.default.string().valid("initiate", "add-seat", "remove-seat", "renewal").required(),
5652
+ description: import_joi22.default.string().max(255).optional().allow("", null),
5653
+ createdBy: import_joi22.default.string().hex().length(24).required(),
5654
+ createdByName: import_joi22.default.string().optional().allow("", null)
5605
5655
  });
5606
5656
  function modelSubscriptionTransaction(data) {
5607
5657
  const { error } = schemaSubscriptionTransaction.validate(data);
@@ -5857,10 +5907,10 @@ function useSubscriptionController() {
5857
5907
  } = useSubscriptionRepo();
5858
5908
  const { updateSeats: _updateSeats } = useSubscriptionService();
5859
5909
  async function getAll(req, res, next) {
5860
- const validation = import_joi22.default.object({
5861
- page: import_joi22.default.number().min(1).max(100).optional().allow(null, "").default(1),
5862
- limit: import_joi22.default.number().min(1).max(100).optional().allow(null, "").default(10),
5863
- status: import_joi22.default.string().valid("active", "suspended").optional().default("active")
5910
+ const validation = import_joi23.default.object({
5911
+ page: import_joi23.default.number().min(1).max(100).optional().allow(null, "").default(1),
5912
+ limit: import_joi23.default.number().min(1).max(100).optional().allow(null, "").default(10),
5913
+ status: import_joi23.default.string().valid("active", "suspended").optional().default("active")
5864
5914
  });
5865
5915
  const query = req.query;
5866
5916
  const { error, value } = validation.validate(query);
@@ -5878,8 +5928,8 @@ function useSubscriptionController() {
5878
5928
  }
5879
5929
  async function getById(req, res, next) {
5880
5930
  const id = req.params.id ?? "";
5881
- const validation = import_joi22.default.object({
5882
- id: import_joi22.default.string().hex().length(24).required()
5931
+ const validation = import_joi23.default.object({
5932
+ id: import_joi23.default.string().hex().length(24).required()
5883
5933
  });
5884
5934
  const { error, value } = validation.validate({ id });
5885
5935
  if (error) {
@@ -5896,8 +5946,8 @@ function useSubscriptionController() {
5896
5946
  }
5897
5947
  async function getByOrg(req, res, next) {
5898
5948
  const org = req.params.org ?? "";
5899
- const validation = import_joi22.default.object({
5900
- org: import_joi22.default.string().hex().length(24).required()
5949
+ const validation = import_joi23.default.object({
5950
+ org: import_joi23.default.string().hex().length(24).required()
5901
5951
  });
5902
5952
  const { error, value } = validation.validate({ org });
5903
5953
  if (error) {
@@ -5940,15 +5990,15 @@ function useSubscriptionController() {
5940
5990
  }
5941
5991
 
5942
5992
  // src/resources/subscription/subscription.transaction.controller.ts
5943
- var import_joi23 = __toESM(require("joi"));
5993
+ var import_joi24 = __toESM(require("joi"));
5944
5994
  var import_utils33 = require("@goweekdays/utils");
5945
5995
  function useSubscriptionTransactionController() {
5946
5996
  const { getAll: _getAll } = useSubscriptionTransactionRepo();
5947
5997
  async function getAll(req, res, next) {
5948
- const validation = import_joi23.default.object({
5949
- id: import_joi23.default.string().hex().length(24).required(),
5950
- page: import_joi23.default.number().min(1).max(100).optional().allow(null, "").default(1),
5951
- limit: import_joi23.default.number().min(1).max(100).optional().allow(null, "").default(10)
5998
+ const validation = import_joi24.default.object({
5999
+ id: import_joi24.default.string().hex().length(24).required(),
6000
+ page: import_joi24.default.number().min(1).max(100).optional().allow(null, "").default(1),
6001
+ limit: import_joi24.default.number().min(1).max(100).optional().allow(null, "").default(10)
5952
6002
  });
5953
6003
  const query = req.query;
5954
6004
  const id = req.params.id ?? "";
@@ -5971,16 +6021,16 @@ function useSubscriptionTransactionController() {
5971
6021
  }
5972
6022
 
5973
6023
  // src/resources/plan/plan.model.ts
5974
- var import_joi24 = __toESM(require("joi"));
6024
+ var import_joi25 = __toESM(require("joi"));
5975
6025
  var currencies = ["USD", "PHP"];
5976
- var schemaPlan = import_joi24.default.object({
5977
- name: import_joi24.default.string().min(3).max(100).required(),
5978
- description: import_joi24.default.string().max(255).optional().allow("", null),
5979
- features: import_joi24.default.array().items(import_joi24.default.string().max(100)).optional(),
5980
- price: import_joi24.default.number().positive().required(),
5981
- currency: import_joi24.default.string().length(3).allow(...currencies).required(),
5982
- default: import_joi24.default.boolean().optional().allow(null, ""),
5983
- billingCycle: import_joi24.default.string().valid("monthly", "yearly").required()
6026
+ var schemaPlan = import_joi25.default.object({
6027
+ name: import_joi25.default.string().min(3).max(100).required(),
6028
+ description: import_joi25.default.string().max(255).optional().allow("", null),
6029
+ features: import_joi25.default.array().items(import_joi25.default.string().max(100)).optional(),
6030
+ price: import_joi25.default.number().positive().required(),
6031
+ currency: import_joi25.default.string().length(3).allow(...currencies).required(),
6032
+ default: import_joi25.default.boolean().optional().allow(null, ""),
6033
+ billingCycle: import_joi25.default.string().valid("monthly", "yearly").required()
5984
6034
  });
5985
6035
  function modelPlan(data) {
5986
6036
  const { error } = schemaPlan.validate(data);
@@ -6004,7 +6054,7 @@ function modelPlan(data) {
6004
6054
 
6005
6055
  // src/resources/plan/plan.repository.ts
6006
6056
  var import_utils34 = require("@goweekdays/utils");
6007
- var import_joi25 = __toESM(require("joi"));
6057
+ var import_joi26 = __toESM(require("joi"));
6008
6058
  var import_mongodb19 = require("mongodb");
6009
6059
  function usePlanRepo() {
6010
6060
  const db = import_utils34.useAtlas.getDb();
@@ -6124,7 +6174,7 @@ function usePlanRepo() {
6124
6174
  }
6125
6175
  }
6126
6176
  async function getById(_id) {
6127
- const { error } = import_joi25.default.string().hex().length(24).required().validate(_id);
6177
+ const { error } = import_joi26.default.string().hex().length(24).required().validate(_id);
6128
6178
  if (error) {
6129
6179
  throw new Error(`Invalid plan ID: ${error.message}`);
6130
6180
  }
@@ -6193,7 +6243,7 @@ function usePlanRepo() {
6193
6243
  }
6194
6244
  }
6195
6245
  async function deleteById(_id) {
6196
- const { error } = import_joi25.default.string().hex().length(24).required().validate(_id);
6246
+ const { error } = import_joi26.default.string().hex().length(24).required().validate(_id);
6197
6247
  if (error) {
6198
6248
  throw new Error(`Invalid plan ID: ${error.message}`);
6199
6249
  }
@@ -6252,7 +6302,7 @@ function usePlanService() {
6252
6302
  }
6253
6303
 
6254
6304
  // src/resources/plan/plan.controller.ts
6255
- var import_joi26 = __toESM(require("joi"));
6305
+ var import_joi27 = __toESM(require("joi"));
6256
6306
  var import_utils35 = require("@goweekdays/utils");
6257
6307
  function usePlanController() {
6258
6308
  const {
@@ -6264,13 +6314,13 @@ function usePlanController() {
6264
6314
  } = usePlanRepo();
6265
6315
  async function add(req, res, next) {
6266
6316
  const value = req.body;
6267
- const validation = import_joi26.default.object({
6268
- name: import_joi26.default.string().min(3).max(100).required(),
6269
- description: import_joi26.default.string().max(255).optional().allow("", null),
6270
- features: import_joi26.default.array().items(import_joi26.default.string().max(100)).optional(),
6271
- price: import_joi26.default.number().positive().required(),
6272
- currency: import_joi26.default.string().length(3).required(),
6273
- billingCycle: import_joi26.default.string().valid("monthly", "yearly").required()
6317
+ const validation = import_joi27.default.object({
6318
+ name: import_joi27.default.string().min(3).max(100).required(),
6319
+ description: import_joi27.default.string().max(255).optional().allow("", null),
6320
+ features: import_joi27.default.array().items(import_joi27.default.string().max(100)).optional(),
6321
+ price: import_joi27.default.number().positive().required(),
6322
+ currency: import_joi27.default.string().length(3).required(),
6323
+ billingCycle: import_joi27.default.string().valid("monthly", "yearly").required()
6274
6324
  });
6275
6325
  const { error } = validation.validate(value);
6276
6326
  if (error) {
@@ -6290,11 +6340,11 @@ function usePlanController() {
6290
6340
  const search = req.query.search ?? "";
6291
6341
  const page = Number(req.query.page) ?? 1;
6292
6342
  const limit = Number(req.query.limit) ?? 10;
6293
- const validation = import_joi26.default.object({
6294
- status: import_joi26.default.string().required(),
6295
- search: import_joi26.default.string().optional().allow("", null),
6296
- page: import_joi26.default.number().required(),
6297
- limit: import_joi26.default.number().required()
6343
+ const validation = import_joi27.default.object({
6344
+ status: import_joi27.default.string().required(),
6345
+ search: import_joi27.default.string().optional().allow("", null),
6346
+ page: import_joi27.default.number().required(),
6347
+ limit: import_joi27.default.number().required()
6298
6348
  });
6299
6349
  const { error } = validation.validate({ status, search, page, limit });
6300
6350
  if (error) {
@@ -6311,7 +6361,7 @@ function usePlanController() {
6311
6361
  }
6312
6362
  async function getById(req, res, next) {
6313
6363
  const id = req.params.id;
6314
- const validation = import_joi26.default.string().hex().length(24).required();
6364
+ const validation = import_joi27.default.string().hex().length(24).required();
6315
6365
  const { error } = validation.validate(id);
6316
6366
  if (error) {
6317
6367
  next(new import_utils35.BadRequestError(error.message));
@@ -6327,7 +6377,7 @@ function usePlanController() {
6327
6377
  }
6328
6378
  async function deleteById(req, res, next) {
6329
6379
  const id = req.params.id;
6330
- const validation = import_joi26.default.string().hex().length(24).required();
6380
+ const validation = import_joi27.default.string().hex().length(24).required();
6331
6381
  const { error } = validation.validate(id);
6332
6382
  if (error) {
6333
6383
  next(new import_utils35.BadRequestError(error.message));
@@ -6363,6 +6413,7 @@ function usePlanController() {
6363
6413
  var import_paypal_server_sdk = require("@paypal/paypal-server-sdk");
6364
6414
  var import_crypto3 = __toESM(require("crypto"));
6365
6415
  var import_buffer_crc32 = __toESM(require("buffer-crc32"));
6416
+ var import_utils36 = require("@goweekdays/utils");
6366
6417
  var certCache = /* @__PURE__ */ new Map();
6367
6418
  function usePaypalService() {
6368
6419
  const paypalClient = new import_paypal_server_sdk.Client({
@@ -6426,11 +6477,14 @@ function usePaypalService() {
6426
6477
  const certUrl = headers["paypal-cert-url"];
6427
6478
  const transmissionSig = headers["paypal-transmission-sig"];
6428
6479
  if (!transmissionId || !timeStamp || !certUrl || !transmissionSig) {
6480
+ import_utils36.logger.log({
6481
+ level: "error",
6482
+ message: "Missing required PayPal webhook headers"
6483
+ });
6429
6484
  return false;
6430
6485
  }
6431
- const eventBuffer = Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(rawBody);
6432
- const crcValue = parseInt("0x" + (0, import_buffer_crc32.default)(eventBuffer).toString("hex"));
6433
- const message = `${transmissionId}|${timeStamp}|${webhookId}|${crcValue}`;
6486
+ const crc = parseInt("0x" + (0, import_buffer_crc32.default)(rawBody).toString("hex"));
6487
+ const message = `${transmissionId}|${timeStamp}|${webhookId}|${crc}`;
6434
6488
  try {
6435
6489
  const certPem = await downloadAndCacheCert(certUrl);
6436
6490
  const signatureBuffer = Buffer.from(transmissionSig, "base64");
@@ -6438,7 +6492,10 @@ function usePaypalService() {
6438
6492
  verifier.update(message);
6439
6493
  return verifier.verify(certPem, signatureBuffer);
6440
6494
  } catch (error) {
6441
- console.error("PayPal webhook verification error:", error);
6495
+ import_utils36.logger.log({
6496
+ level: "error",
6497
+ message: `PayPal webhook verification error: ${error}`
6498
+ });
6442
6499
  throw new Error("Failed to verify PayPal webhook signature.");
6443
6500
  }
6444
6501
  }
@@ -6450,192 +6507,926 @@ function usePaypalService() {
6450
6507
  }
6451
6508
 
6452
6509
  // src/resources/organization/organization.service.ts
6453
- function useOrgService() {
6454
- const { add: addOrg } = useOrgRepo();
6455
- const { addRole } = useRoleRepo();
6456
- const { getAll: getAllPermission } = usePermissionRepo();
6457
- const { add: addMember, updateRoleById: _updateRoleById } = useMemberRepo();
6458
- const { getUserById } = useUserRepo();
6459
- const { getDefault } = usePlanRepo();
6460
- const { add: addSubscription } = useSubscriptionRepo();
6461
- const { add: addSubscriptionTransaction } = useSubscriptionTransactionRepo();
6462
- const { addOrder: addPaypalOrder } = usePaypalService();
6463
- async function add(value) {
6464
- const { error } = schemaOrgAdd.validate(value);
6465
- if (error) {
6466
- throw new import_utils36.BadRequestError(error.message);
6467
- }
6468
- const session = import_utils36.useAtlas.getClient()?.startSession();
6469
- if (!session) {
6470
- throw new import_utils36.BadRequestError("Unable to start database session.");
6471
- }
6472
- try {
6473
- session?.startTransaction();
6474
- const org = await addOrg(
6475
- {
6476
- email: value.email,
6477
- name: value.name,
6478
- contact: value.contact,
6479
- createdBy: value.createdBy
6480
- },
6481
- session
6482
- );
6483
- const plan = await getDefault();
6484
- if (!plan) {
6485
- throw new import_utils36.BadRequestError(
6486
- "Failed to create organization, plan not found."
6487
- );
6488
- }
6489
- const currentDate = /* @__PURE__ */ new Date();
6490
- const nextBillingDate = new Date(currentDate);
6491
- nextBillingDate.setMonth(currentDate.getMonth() + 1);
6492
- const amount = plan.price * value.seats;
6493
- const subscriptionId = await addSubscription(
6494
- {
6495
- amount,
6496
- org: String(org),
6497
- seats: value.seats,
6498
- paidSeats: value.seats,
6499
- currency: plan.currency,
6500
- billingCycle: plan.billingCycle,
6501
- nextBillingDate
6502
- },
6503
- session
6504
- );
6505
- const createdBy = String(value.createdBy);
6506
- const user = await getUserById(createdBy);
6507
- if (!user) {
6508
- throw new import_utils36.BadRequestError("User is required to create org member.");
6509
- }
6510
- await addSubscriptionTransaction(
6511
- {
6512
- subscription: subscriptionId,
6513
- type: "initiate",
6514
- amount,
6515
- currency: plan.currency,
6516
- description: "Initial subscription transaction",
6517
- createdBy: value.createdBy,
6518
- createdByName: `${user.firstName} ${user.lastName}`
6519
- },
6520
- session
6521
- );
6522
- const allPermissions = await getAllPermission({
6523
- app: "org",
6524
- limit: 100
6525
- });
6526
- let permissions = [];
6527
- if (allPermissions && allPermissions.items && allPermissions.items.length) {
6528
- permissions = allPermissions.items.map((perm) => perm.key);
6529
- }
6530
- if (permissions.length === 0) {
6531
- throw new Error("No permissions found for the organization type.");
6532
- }
6533
- const roleData = {
6534
- org: String(org),
6535
- name: "Owner",
6536
- description: "Owner of the organization",
6537
- permissions,
6538
- createdBy,
6539
- app: "org"
6540
- };
6541
- const role = await addRole(roleData, session);
6542
- if (!role) {
6543
- throw new import_utils36.BadRequestError("Role is required to create org member.");
6544
- }
6545
- await addMember(
6546
- {
6547
- role: String(role),
6548
- roleName: roleData.name,
6549
- org: String(org),
6550
- orgName: value.name,
6551
- name: `${user.firstName} ${user.lastName}`,
6552
- user: createdBy,
6553
- app: "org"
6554
- },
6555
- session
6556
- );
6557
- const order = await addPaypalOrder({
6558
- amount,
6559
- currency: plan.currency,
6560
- customId: subscriptionId,
6561
- returnUrl: `${APP_ORG}/organizations/success`,
6562
- cancelUrl: `${APP_ORG}/organizations/cancel`,
6563
- action: "pay"
6564
- });
6565
- await session?.commitTransaction();
6566
- const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
6567
- (link) => link.rel === "approve"
6568
- );
6569
- return {
6570
- org: String(org),
6571
- paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
6572
- };
6573
- } catch (error2) {
6574
- await session?.abortTransaction();
6575
- throw error2;
6576
- } finally {
6577
- await session?.endSession();
6578
- }
6579
- }
6580
- return {
6581
- add
6582
- };
6583
- }
6510
+ var import_joi32 = __toESM(require("joi"));
6584
6511
 
6585
- // src/resources/organization/organization.controller.ts
6512
+ // src/resources/verification/verification.controller.ts
6586
6513
  var import_utils37 = require("@goweekdays/utils");
6587
- var import_joi27 = __toESM(require("joi"));
6588
- function useOrgController() {
6589
- const { add: _add } = useOrgService();
6590
- const { getOrgsByMembership } = useMemberRepo();
6514
+ var import_joi28 = __toESM(require("joi"));
6515
+ function useVerificationController() {
6591
6516
  const {
6592
- getByName: _getByName,
6593
- getAll: getAllOrg,
6594
- getById: _getById,
6595
- updateById: _updateById
6596
- } = useOrgRepo();
6597
- async function add(req, res, next) {
6598
- const value = req.body;
6599
- const { error } = schemaOrgAdd.validate(value);
6517
+ createUserInvite: _createUserInvite,
6518
+ createForgetPassword: _createForgetPassword,
6519
+ cancelUserInvitation: _cancelUserInvitation,
6520
+ verify: _verify,
6521
+ inviteMember: _inviteMember,
6522
+ signUp: _signUp,
6523
+ cancelInviteMember: _cancelInviteMember,
6524
+ forgetPassword: _forgetPassword,
6525
+ orgSetupFee: _orgSetupFee
6526
+ } = useVerificationService();
6527
+ const { getVerifications: _getVerifications } = useVerificationRepo();
6528
+ async function createUserInvite(req, res, next) {
6529
+ const validation = import_joi28.default.object({
6530
+ email: import_joi28.default.string().email().required(),
6531
+ app: import_joi28.default.string().required(),
6532
+ role: import_joi28.default.string().hex().required(),
6533
+ roleName: import_joi28.default.string().required(),
6534
+ org: import_joi28.default.string().hex().optional().optional().allow("", null),
6535
+ orgName: import_joi28.default.string().optional().optional().allow("", null)
6536
+ });
6537
+ const { error } = validation.validate(req.body);
6600
6538
  if (error) {
6601
6539
  next(new import_utils37.BadRequestError(error.message));
6602
6540
  return;
6603
6541
  }
6542
+ const email = req.body.email ?? "";
6543
+ const app = req.body.app ?? "";
6544
+ const role = req.body.role ?? "";
6545
+ const roleName = req.body.roleName ?? "";
6546
+ const org = req.body.org ?? "";
6547
+ const orgName = req.body.orgName ?? "";
6604
6548
  try {
6605
- const data = await _add(value);
6606
- res.json({
6607
- message: "Organization created successfully.",
6608
- data
6609
- });
6610
- return;
6611
- } catch (error2) {
6612
- next(error2);
6613
- }
6614
- }
6615
- async function getOrgsByUserId(req, res, next) {
6549
+ await _createUserInvite({
6550
+ email,
6551
+ metadata: {
6552
+ app,
6553
+ role,
6554
+ roleName,
6555
+ org,
6556
+ orgName
6557
+ }
6558
+ });
6559
+ res.json({ message: "Successfully invited user." });
6560
+ return;
6561
+ } catch (error2) {
6562
+ next(error2);
6563
+ }
6564
+ }
6565
+ async function createForgetPassword(req, res, next) {
6566
+ const email = req.body.email || "";
6567
+ const validation = import_joi28.default.string().email().required();
6568
+ const { error } = validation.validate(email);
6569
+ if (error) {
6570
+ next(new import_utils37.BadRequestError(error.message));
6571
+ return;
6572
+ }
6573
+ try {
6574
+ await _createForgetPassword(email);
6575
+ res.json({
6576
+ message: "Check your email to verify it before resetting your password."
6577
+ });
6578
+ return;
6579
+ } catch (error2) {
6580
+ if (error2 instanceof import_utils37.AppError) {
6581
+ next(error2);
6582
+ } else {
6583
+ next(new import_utils37.InternalServerError("An unexpected error occurred"));
6584
+ }
6585
+ }
6586
+ }
6587
+ async function getVerifications(req, res, next) {
6588
+ const validation = import_joi28.default.object({
6589
+ status: import_joi28.default.string().required(),
6590
+ search: import_joi28.default.string().optional().allow("", null),
6591
+ page: import_joi28.default.number().required(),
6592
+ type: import_joi28.default.string().optional().allow("", null),
6593
+ email: import_joi28.default.string().optional().allow("", null),
6594
+ app: import_joi28.default.string().optional().allow("", null),
6595
+ org: import_joi28.default.string().optional().allow("", null)
6596
+ });
6597
+ const { error } = validation.validate(req.query);
6598
+ if (error) {
6599
+ next(new import_utils37.BadRequestError(error.message));
6600
+ return;
6601
+ }
6602
+ const status = req.query.status ?? "";
6603
+ const search = req.query.search ?? "";
6604
+ const page = Number(req.query.page) ?? 1;
6605
+ let type = req.query.type ?? "";
6606
+ const email = req.query.email ?? "";
6607
+ const app = req.query.app ?? "";
6608
+ const org = req.query.org ?? "";
6609
+ const hasMultipleTypes = type.includes(",");
6610
+ let splitType = [];
6611
+ if (hasMultipleTypes) {
6612
+ splitType = type.split(",");
6613
+ }
6614
+ try {
6615
+ const items = await _getVerifications({
6616
+ status,
6617
+ search,
6618
+ page,
6619
+ type: hasMultipleTypes ? splitType : type,
6620
+ email,
6621
+ app,
6622
+ org
6623
+ });
6624
+ res.json(items);
6625
+ return;
6626
+ } catch (error2) {
6627
+ next(error2);
6628
+ }
6629
+ }
6630
+ async function verify(req, res, next) {
6631
+ const id = req.params.id || "";
6632
+ const validation = import_joi28.default.string().hex().required();
6633
+ const { error } = validation.validate(id);
6634
+ if (error) {
6635
+ next(new import_utils37.BadRequestError(error.message));
6636
+ return;
6637
+ }
6638
+ try {
6639
+ const message = await _verify(id);
6640
+ res.json(message);
6641
+ return;
6642
+ } catch (error2) {
6643
+ next(error2);
6644
+ }
6645
+ }
6646
+ async function cancelUserInvitation(req, res, next) {
6647
+ const otpId = req.params.id || "";
6648
+ const validation = import_joi28.default.string().hex().required();
6649
+ const { error } = validation.validate(otpId);
6650
+ if (error) {
6651
+ next(new import_utils37.BadRequestError(error.message));
6652
+ return;
6653
+ }
6654
+ try {
6655
+ await _cancelUserInvitation(otpId);
6656
+ return res.json({
6657
+ message: "User invite has been cancelled."
6658
+ });
6659
+ } catch (error2) {
6660
+ throw error2;
6661
+ }
6662
+ }
6663
+ async function signUp(req, res, next) {
6664
+ const validation = import_joi28.default.string().email().required();
6665
+ const { error } = validation.validate(req.body.email);
6666
+ if (error) {
6667
+ next(new import_utils37.BadRequestError(error.message));
6668
+ return;
6669
+ }
6670
+ const email = req.body.email ?? "";
6671
+ try {
6672
+ await _signUp({ email });
6673
+ res.json({ message: "Successfully signed up user." });
6674
+ return;
6675
+ } catch (error2) {
6676
+ next(error2);
6677
+ }
6678
+ }
6679
+ async function inviteMember(req, res, next) {
6680
+ const { error } = schemaInviteMember.validate(req.body);
6681
+ if (error) {
6682
+ next(new import_utils37.BadRequestError(error.message));
6683
+ return;
6684
+ }
6685
+ try {
6686
+ await _inviteMember(req.body);
6687
+ res.json({ message: "Successfully invited member." });
6688
+ return;
6689
+ } catch (error2) {
6690
+ next(error2);
6691
+ }
6692
+ }
6693
+ async function cancelInviteMember(req, res, next) {
6694
+ const id = req.params.id || "";
6695
+ const validation = import_joi28.default.string().hex().required();
6696
+ const { error } = validation.validate(id);
6697
+ if (error) {
6698
+ next(new import_utils37.BadRequestError(error.message));
6699
+ return;
6700
+ }
6701
+ try {
6702
+ const message = await _cancelInviteMember(id);
6703
+ res.json({ message });
6704
+ return;
6705
+ } catch (error2) {
6706
+ next(error2);
6707
+ }
6708
+ }
6709
+ async function forgetPassword(req, res, next) {
6710
+ const email = req.body.email ?? "";
6711
+ const validation = import_joi28.default.string().email().required();
6712
+ const { error } = validation.validate(email);
6713
+ if (error) {
6714
+ next(new import_utils37.BadRequestError(error.message));
6715
+ return;
6716
+ }
6717
+ try {
6718
+ const message = await _forgetPassword(email);
6719
+ res.json({
6720
+ message
6721
+ });
6722
+ return;
6723
+ } catch (error2) {
6724
+ if (error2 instanceof import_utils37.AppError) {
6725
+ next(error2);
6726
+ } else {
6727
+ next(new import_utils37.InternalServerError("An unexpected error occurred"));
6728
+ }
6729
+ }
6730
+ }
6731
+ async function orgSetupFee(req, res, next) {
6732
+ const value = req.body;
6733
+ const { error } = schemaOrgAdd.validate(value);
6734
+ if (error) {
6735
+ next(new import_utils37.BadRequestError(error.message));
6736
+ return;
6737
+ }
6738
+ try {
6739
+ const data = await _orgSetupFee(value);
6740
+ res.json(data);
6741
+ return;
6742
+ } catch (error2) {
6743
+ next(error2);
6744
+ }
6745
+ }
6746
+ return {
6747
+ getVerifications,
6748
+ createUserInvite,
6749
+ createForgetPassword,
6750
+ verify,
6751
+ cancelUserInvitation,
6752
+ inviteMember,
6753
+ signUp,
6754
+ cancelInviteMember,
6755
+ forgetPassword,
6756
+ orgSetupFee
6757
+ };
6758
+ }
6759
+
6760
+ // src/resources/ledger/ledger.billing.model.ts
6761
+ var import_utils38 = require("@goweekdays/utils");
6762
+ var import_joi29 = __toESM(require("joi"));
6763
+ var import_mongodb20 = require("mongodb");
6764
+ var ledgerBillTypes = ["setup-fee", "subscription"];
6765
+ var ledgerBillStatuses = ["pending", "paid", "overdue"];
6766
+ var schemaLedgerBill = import_joi29.default.object({
6767
+ org: import_joi29.default.string().hex().length(24).required(),
6768
+ type: import_joi29.default.string().valid(...ledgerBillTypes).required(),
6769
+ description: import_joi29.default.string().max(255).required(),
6770
+ amount: import_joi29.default.number().positive().required(),
6771
+ currency: import_joi29.default.string().length(3).required(),
6772
+ status: import_joi29.default.string().valid(...ledgerBillStatuses).required(),
6773
+ billingFrom: import_joi29.default.date().optional().allow("", null),
6774
+ billingTo: import_joi29.default.date().optional().allow("", null),
6775
+ paidAt: import_joi29.default.date().optional().allow("", null),
6776
+ dueDate: import_joi29.default.date().optional().allow("", null)
6777
+ });
6778
+ var schemaLedgerBillingSummary = import_joi29.default.object({
6779
+ status: import_joi29.default.string().valid(...ledgerBillStatuses).required(),
6780
+ org: import_joi29.default.string().hex().length(24).required()
6781
+ });
6782
+ function modelLedgerBill(value) {
6783
+ const { error } = schemaLedgerBill.validate(value);
6784
+ if (error) {
6785
+ throw new Error(`Ledger bill model validation error: ${error.message}`);
6786
+ }
6787
+ try {
6788
+ value.org = new import_mongodb20.ObjectId(value.org);
6789
+ } catch (error2) {
6790
+ throw new import_utils38.BadRequestError("Invalid org ID.");
6791
+ }
6792
+ return {
6793
+ _id: value._id,
6794
+ org: value.org,
6795
+ type: value.type,
6796
+ description: value.description,
6797
+ amount: value.amount,
6798
+ currency: value.currency,
6799
+ status: value.status,
6800
+ billingFrom: value.billingFrom ?? "",
6801
+ billingTo: value.billingTo ?? "",
6802
+ paidAt: value.paidAt ?? "",
6803
+ dueDate: value.dueDate ?? "",
6804
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date()
6805
+ };
6806
+ }
6807
+
6808
+ // src/resources/ledger/ledger.billing.repository.ts
6809
+ var import_utils39 = require("@goweekdays/utils");
6810
+ var import_mongodb21 = require("mongodb");
6811
+ var import_joi30 = __toESM(require("joi"));
6812
+ function useLedgerBillingRepo() {
6813
+ const db = import_utils39.useAtlas.getDb();
6814
+ if (!db) {
6815
+ throw new Error("Unable to connect to server.");
6816
+ }
6817
+ const namespace_collection = "ledger.billings";
6818
+ const collection = db.collection(namespace_collection);
6819
+ const { getCache, setCache, delNamespace } = (0, import_utils39.useCache)(namespace_collection);
6820
+ function delCachedData() {
6821
+ delNamespace().then(() => {
6822
+ import_utils39.logger.log({
6823
+ level: "info",
6824
+ message: `Cache namespace cleared for ${namespace_collection}`
6825
+ });
6826
+ }).catch((err) => {
6827
+ import_utils39.logger.log({
6828
+ level: "error",
6829
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
6830
+ });
6831
+ });
6832
+ }
6833
+ async function createIndexes() {
6834
+ try {
6835
+ await collection.createIndexes([
6836
+ { key: { org: 1 } },
6837
+ { key: { status: 1 } },
6838
+ { key: { description: "text" }, name: "text_index" }
6839
+ ]);
6840
+ return "Successfully created ledger billing indexes.";
6841
+ } catch (error) {
6842
+ throw new import_utils39.BadRequestError("Failed to create ledger billing indexes.");
6843
+ }
6844
+ }
6845
+ async function add(value, session) {
6846
+ try {
6847
+ value = modelLedgerBill(value);
6848
+ const result = await collection.insertOne(value, { session });
6849
+ delCachedData();
6850
+ return result.insertedId;
6851
+ } catch (error) {
6852
+ if (error instanceof import_utils39.AppError) {
6853
+ throw error;
6854
+ }
6855
+ throw new import_utils39.BadRequestError(
6856
+ `Failed to add ledger billing: ${error.message}`
6857
+ );
6858
+ }
6859
+ }
6860
+ async function getAll({
6861
+ org = "",
6862
+ search = "",
6863
+ page = 1,
6864
+ limit = 10,
6865
+ status = ""
6866
+ } = {}) {
6867
+ page = page > 0 ? page - 1 : 0;
6868
+ const query = { status: { $ne: "deleted" } };
6869
+ const cacheKeyOptions = {
6870
+ search,
6871
+ page,
6872
+ limit,
6873
+ tag: "getAll"
6874
+ };
6875
+ try {
6876
+ query.org = new import_mongodb21.ObjectId(org);
6877
+ cacheKeyOptions.org = org;
6878
+ } catch (error) {
6879
+ throw new import_utils39.BadRequestError("Invalid organization ID.");
6880
+ }
6881
+ if (status) {
6882
+ query.status = status;
6883
+ cacheKeyOptions.status = status;
6884
+ }
6885
+ if (search) {
6886
+ query.$text = { $search: search };
6887
+ }
6888
+ const cacheKey = (0, import_utils39.makeCacheKey)(namespace_collection, cacheKeyOptions);
6889
+ import_utils39.logger.log({
6890
+ level: "info",
6891
+ message: `Cache key for getAll ledger billings: ${cacheKey}`
6892
+ });
6893
+ try {
6894
+ const cached = await getCache(cacheKey);
6895
+ if (cached) {
6896
+ import_utils39.logger.log({
6897
+ level: "info",
6898
+ message: `Cache hit for getAll ledger billings: ${cacheKey}`
6899
+ });
6900
+ return cached;
6901
+ }
6902
+ const items = await collection.aggregate([
6903
+ { $match: query },
6904
+ { $skip: page * limit },
6905
+ { $limit: limit }
6906
+ ]).toArray();
6907
+ const length = await collection.countDocuments(query);
6908
+ const data = (0, import_utils39.paginate)(items, page, limit, length);
6909
+ setCache(cacheKey, data, 600).then(() => {
6910
+ import_utils39.logger.log({
6911
+ level: "info",
6912
+ message: `Cache set for getAll ledger billings: ${cacheKey}`
6913
+ });
6914
+ }).catch((err) => {
6915
+ import_utils39.logger.log({
6916
+ level: "error",
6917
+ message: `Failed to set cache for getAll ledger billings: ${err.message}`
6918
+ });
6919
+ });
6920
+ return data;
6921
+ } catch (error) {
6922
+ import_utils39.logger.log({ level: "error", message: `${error}` });
6923
+ throw error;
6924
+ }
6925
+ }
6926
+ async function getById(_id) {
6927
+ const { error } = import_joi30.default.string().hex().length(24).required().validate(_id);
6928
+ if (error) {
6929
+ throw new Error(`Invalid ledger billing ID: ${error.message}`);
6930
+ }
6931
+ try {
6932
+ _id = new import_mongodb21.ObjectId(_id);
6933
+ } catch (error2) {
6934
+ throw new import_utils39.BadRequestError("Invalid ledger billing ID.");
6935
+ }
6936
+ try {
6937
+ const cacheKey = (0, import_utils39.makeCacheKey)(namespace_collection, {
6938
+ _id: String(_id),
6939
+ tag: "getById"
6940
+ });
6941
+ const cachedData = await getCache(cacheKey);
6942
+ if (cachedData) {
6943
+ return cachedData;
6944
+ }
6945
+ const data = await collection.findOne({
6946
+ _id,
6947
+ status: { $ne: "deleted" }
6948
+ });
6949
+ setCache(cacheKey, data).then(() => {
6950
+ import_utils39.logger.log({
6951
+ level: "info",
6952
+ message: `Cache set for getById ledger billing: ${cacheKey}`
6953
+ });
6954
+ }).catch((err) => {
6955
+ import_utils39.logger.log({
6956
+ level: "error",
6957
+ message: `Failed to set cache for getById ledger billing: ${err.message}`
6958
+ });
6959
+ });
6960
+ return data;
6961
+ } catch (error2) {
6962
+ throw new import_utils39.InternalServerError("Failed to get ledger billing.");
6963
+ }
6964
+ }
6965
+ async function getSummary(status, org) {
6966
+ const { error } = schemaLedgerBillingSummary.validate({ status, org });
6967
+ if (error) {
6968
+ throw new Error(`Invalid ledger billing ID: ${error.message}`);
6969
+ }
6970
+ try {
6971
+ org = new import_mongodb21.ObjectId(org);
6972
+ } catch (error2) {
6973
+ throw new import_utils39.BadRequestError("Invalid ledger billing org.");
6974
+ }
6975
+ try {
6976
+ const cacheKey = (0, import_utils39.makeCacheKey)(namespace_collection, {
6977
+ org: String(org),
6978
+ status,
6979
+ tag: "getSummaryByOrgStatus"
6980
+ });
6981
+ const cachedData = await getCache(cacheKey);
6982
+ if (cachedData) {
6983
+ return cachedData;
6984
+ }
6985
+ const data = await collection.aggregate([
6986
+ { $match: { org, status } },
6987
+ {
6988
+ $group: {
6989
+ _id: "$status",
6990
+ totalAmount: { $sum: "$amount" },
6991
+ count: { $sum: 1 }
6992
+ }
6993
+ }
6994
+ ]).toArray();
6995
+ setCache(cacheKey, data[0]).then(() => {
6996
+ import_utils39.logger.log({
6997
+ level: "info",
6998
+ message: `Cache set for ledger billing summary: ${cacheKey}`
6999
+ });
7000
+ }).catch((err) => {
7001
+ import_utils39.logger.log({
7002
+ level: "error",
7003
+ message: `Failed to set cache for ledger billing summary: ${err.message}`
7004
+ });
7005
+ });
7006
+ return data[0];
7007
+ } catch (error2) {
7008
+ throw new import_utils39.InternalServerError("Failed to get ledger billing summary.");
7009
+ }
7010
+ }
7011
+ return {
7012
+ delCachedData,
7013
+ createIndexes,
7014
+ add,
7015
+ getAll,
7016
+ getById,
7017
+ getSummary
7018
+ };
7019
+ }
7020
+
7021
+ // src/resources/ledger/ledger.billing.controller.ts
7022
+ var import_joi31 = __toESM(require("joi"));
7023
+ var import_utils40 = require("@goweekdays/utils");
7024
+ function useLedgerBillingController() {
7025
+ const {
7026
+ getAll: _getAll,
7027
+ getById: _getById,
7028
+ getSummary: _getSummary
7029
+ } = useLedgerBillingRepo();
7030
+ async function getAll(req, res, next) {
7031
+ const query = req.query;
7032
+ const validation = import_joi31.default.object({
7033
+ org: import_joi31.default.string().hex().optional().allow("", null),
7034
+ page: import_joi31.default.number().min(1).optional().allow("", null),
7035
+ limit: import_joi31.default.number().min(1).optional().allow("", null),
7036
+ search: import_joi31.default.string().optional().allow("", null),
7037
+ status: import_joi31.default.string().optional().allow("", null)
7038
+ });
7039
+ const { error } = validation.validate(query);
7040
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
7041
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
7042
+ const search = req.query.search ?? "";
7043
+ const org = req.query.org ?? "";
7044
+ const status = req.query.status ?? "";
7045
+ const isPageNumber = isFinite(page);
7046
+ if (!isPageNumber) {
7047
+ next(new import_utils40.BadRequestError("Invalid page number."));
7048
+ return;
7049
+ }
7050
+ const isLimitNumber = isFinite(limit);
7051
+ if (!isLimitNumber) {
7052
+ next(new import_utils40.BadRequestError("Invalid limit number."));
7053
+ return;
7054
+ }
7055
+ if (error) {
7056
+ next(new import_utils40.BadRequestError(error.message));
7057
+ return;
7058
+ }
7059
+ try {
7060
+ const orgs = await _getAll({ org, page, limit, search, status });
7061
+ res.json(orgs);
7062
+ return;
7063
+ } catch (error2) {
7064
+ next(error2);
7065
+ }
7066
+ }
7067
+ async function getById(req, res, next) {
7068
+ const id = req.params.id;
7069
+ const validation = import_joi31.default.object({
7070
+ id: import_joi31.default.string().hex().required()
7071
+ });
7072
+ const { error } = validation.validate({ id });
7073
+ if (error) {
7074
+ next(new import_utils40.BadRequestError(error.message));
7075
+ return;
7076
+ }
7077
+ try {
7078
+ const org = await _getById(id);
7079
+ res.json(org);
7080
+ return;
7081
+ } catch (error2) {
7082
+ next(error2);
7083
+ }
7084
+ }
7085
+ async function getSummary(req, res, next) {
7086
+ const params = req.params;
7087
+ const { error } = schemaLedgerBillingSummary.validate(params);
7088
+ const org = req.params.org ?? "";
7089
+ const status = req.params.status ?? "";
7090
+ if (error) {
7091
+ next(new import_utils40.BadRequestError(error.message));
7092
+ return;
7093
+ }
7094
+ try {
7095
+ const summary = await _getSummary(status, org);
7096
+ res.json(summary);
7097
+ return;
7098
+ } catch (error2) {
7099
+ next(error2);
7100
+ }
7101
+ }
7102
+ return {
7103
+ getAll,
7104
+ getById,
7105
+ getSummary
7106
+ };
7107
+ }
7108
+
7109
+ // src/resources/organization/organization.service.ts
7110
+ function useOrgService() {
7111
+ const { add: addOrg } = useOrgRepo();
7112
+ const { addRole } = useRoleRepo();
7113
+ const { getAll: getAllPermission } = usePermissionRepo();
7114
+ const { add: addMember, updateRoleById: _updateRoleById } = useMemberRepo();
7115
+ const { getUserById } = useUserRepo();
7116
+ const { getDefault } = usePlanRepo();
7117
+ const { add: addSubscription } = useSubscriptionRepo();
7118
+ const { add: addSubscriptionTransaction } = useSubscriptionTransactionRepo();
7119
+ const { addOrder: addPaypalOrder } = usePaypalService();
7120
+ async function add(value) {
7121
+ const { error } = schemaOrgAdd.validate(value);
7122
+ if (error) {
7123
+ throw new import_utils41.BadRequestError(error.message);
7124
+ }
7125
+ const session = import_utils41.useAtlas.getClient()?.startSession();
7126
+ if (!session) {
7127
+ throw new import_utils41.BadRequestError("Unable to start database session.");
7128
+ }
7129
+ try {
7130
+ session?.startTransaction();
7131
+ const org = await addOrg(
7132
+ {
7133
+ email: value.email,
7134
+ name: value.name,
7135
+ contact: value.contact,
7136
+ createdBy: value.createdBy
7137
+ },
7138
+ session
7139
+ );
7140
+ const plan = await getDefault();
7141
+ if (!plan) {
7142
+ throw new import_utils41.BadRequestError(
7143
+ "Failed to create organization, plan not found."
7144
+ );
7145
+ }
7146
+ const currentDate = /* @__PURE__ */ new Date();
7147
+ const nextBillingDate = new Date(currentDate);
7148
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
7149
+ const amount = plan.price * value.seats;
7150
+ const subscriptionId = await addSubscription(
7151
+ {
7152
+ amount,
7153
+ org: String(org),
7154
+ seats: value.seats,
7155
+ paidSeats: value.seats,
7156
+ currency: plan.currency,
7157
+ billingCycle: plan.billingCycle,
7158
+ nextBillingDate
7159
+ },
7160
+ session
7161
+ );
7162
+ const createdBy = String(value.createdBy);
7163
+ const user = await getUserById(createdBy);
7164
+ if (!user) {
7165
+ throw new import_utils41.BadRequestError("User is required to create org member.");
7166
+ }
7167
+ await addSubscriptionTransaction(
7168
+ {
7169
+ subscription: subscriptionId,
7170
+ type: "initiate",
7171
+ amount,
7172
+ currency: plan.currency,
7173
+ description: "Initial subscription transaction",
7174
+ createdBy: value.createdBy,
7175
+ createdByName: `${user.firstName} ${user.lastName}`
7176
+ },
7177
+ session
7178
+ );
7179
+ const allPermissions = await getAllPermission({
7180
+ app: "org",
7181
+ limit: 100
7182
+ });
7183
+ let permissions = [];
7184
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
7185
+ permissions = allPermissions.items.map((perm) => perm.key);
7186
+ }
7187
+ if (permissions.length === 0) {
7188
+ throw new Error("No permissions found for the organization type.");
7189
+ }
7190
+ const roleData = {
7191
+ org: String(org),
7192
+ name: "Owner",
7193
+ description: "Owner of the organization",
7194
+ permissions,
7195
+ createdBy,
7196
+ app: "org"
7197
+ };
7198
+ const role = await addRole(roleData, session);
7199
+ if (!role) {
7200
+ throw new import_utils41.BadRequestError("Role is required to create org member.");
7201
+ }
7202
+ await addMember(
7203
+ {
7204
+ role: String(role),
7205
+ roleName: roleData.name,
7206
+ org: String(org),
7207
+ orgName: value.name,
7208
+ name: `${user.firstName} ${user.lastName}`,
7209
+ user: createdBy,
7210
+ app: "org"
7211
+ },
7212
+ session
7213
+ );
7214
+ const order = await addPaypalOrder({
7215
+ amount,
7216
+ currency: plan.currency,
7217
+ customId: subscriptionId,
7218
+ returnUrl: `${APP_ORG}/organizations/success`,
7219
+ cancelUrl: `${APP_ORG}/organizations/cancel`,
7220
+ action: "pay"
7221
+ });
7222
+ await session?.commitTransaction();
7223
+ const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
7224
+ (link) => link.rel === "approve"
7225
+ );
7226
+ return {
7227
+ org: String(org),
7228
+ paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
7229
+ };
7230
+ } catch (error2) {
7231
+ await session?.abortTransaction();
7232
+ throw error2;
7233
+ } finally {
7234
+ await session?.endSession();
7235
+ }
7236
+ }
7237
+ const { getById, updateStatusById: updateVerificationStatus } = useVerificationRepo();
7238
+ const { add: addLedgerBilling } = useLedgerBillingRepo();
7239
+ async function addWithVerification(id) {
7240
+ const { error } = import_joi32.default.string().hex().required().validate(id);
7241
+ if (error) {
7242
+ throw new import_utils41.BadRequestError(error.message);
7243
+ }
7244
+ const session = import_utils41.useAtlas.getClient()?.startSession();
7245
+ if (!session) {
7246
+ throw new import_utils41.BadRequestError("Unable to start database session.");
7247
+ }
7248
+ try {
7249
+ session?.startTransaction();
7250
+ const verification = await getById(id);
7251
+ await updateVerificationStatus(id, "complete", session);
7252
+ if (!verification) {
7253
+ throw new import_utils41.BadRequestError("Verification not found.");
7254
+ }
7255
+ if (!verification.metadata?.orgName) {
7256
+ throw new import_utils41.BadRequestError("Organization name is required.");
7257
+ }
7258
+ if (!verification.metadata?.seats) {
7259
+ throw new import_utils41.BadRequestError("Number of seats is required.");
7260
+ }
7261
+ if (!verification.metadata?.createdBy) {
7262
+ throw new import_utils41.BadRequestError("CreatedBy is required.");
7263
+ }
7264
+ if (!verification.metadata?.contact) {
7265
+ throw new import_utils41.BadRequestError("Contact is required.");
7266
+ }
7267
+ const org = await addOrg(
7268
+ {
7269
+ email: verification.email,
7270
+ name: verification.metadata.orgName,
7271
+ contact: verification.metadata.contact,
7272
+ createdBy: verification.metadata.createdBy
7273
+ },
7274
+ session
7275
+ );
7276
+ const plan = await getDefault();
7277
+ if (!plan) {
7278
+ throw new import_utils41.BadRequestError(
7279
+ "Failed to create organization, plan not found."
7280
+ );
7281
+ }
7282
+ const currentDate = /* @__PURE__ */ new Date();
7283
+ const nextBillingDate = new Date(currentDate);
7284
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
7285
+ const amount = plan.price * verification.metadata.seats;
7286
+ const subscriptionId = await addSubscription(
7287
+ {
7288
+ amount,
7289
+ org: String(org),
7290
+ seats: verification.metadata.seats,
7291
+ paidSeats: verification.metadata.seats,
7292
+ currency: plan.currency,
7293
+ billingCycle: plan.billingCycle,
7294
+ nextBillingDate
7295
+ },
7296
+ session
7297
+ );
7298
+ const createdBy = String(verification.metadata.createdBy);
7299
+ const user = await getUserById(createdBy);
7300
+ if (!user) {
7301
+ throw new import_utils41.BadRequestError("User is required to create org member.");
7302
+ }
7303
+ await addSubscriptionTransaction(
7304
+ {
7305
+ subscription: subscriptionId,
7306
+ type: "initiate",
7307
+ amount,
7308
+ currency: plan.currency,
7309
+ description: "Initial subscription transaction",
7310
+ createdBy,
7311
+ createdByName: `${user.firstName} ${user.lastName}`
7312
+ },
7313
+ session
7314
+ );
7315
+ await addLedgerBilling(
7316
+ {
7317
+ org: String(org),
7318
+ amount: verification.metadata?.amount ?? 0,
7319
+ description: "Setup payment during organization creation",
7320
+ currency: plan.currency,
7321
+ type: "setup-fee",
7322
+ status: "paid"
7323
+ },
7324
+ session
7325
+ );
7326
+ const allPermissions = await getAllPermission({
7327
+ app: "org",
7328
+ limit: 100
7329
+ });
7330
+ let permissions = [];
7331
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
7332
+ permissions = allPermissions.items.map((perm) => perm.key);
7333
+ }
7334
+ if (permissions.length === 0) {
7335
+ throw new Error("No permissions found for the organization type.");
7336
+ }
7337
+ const roleData = {
7338
+ org: String(org),
7339
+ name: "Owner",
7340
+ description: "Owner of the organization",
7341
+ permissions,
7342
+ createdBy,
7343
+ app: "org"
7344
+ };
7345
+ const role = await addRole(roleData, session);
7346
+ if (!role) {
7347
+ throw new import_utils41.BadRequestError("Role is required to create org member.");
7348
+ }
7349
+ await addMember(
7350
+ {
7351
+ role: String(role),
7352
+ roleName: roleData.name,
7353
+ org: String(org),
7354
+ orgName: verification.metadata.orgName,
7355
+ name: `${user.firstName} ${user.lastName}`,
7356
+ user: createdBy,
7357
+ app: "org"
7358
+ },
7359
+ session
7360
+ );
7361
+ await session?.commitTransaction();
7362
+ return "Successfully created organization with verification.";
7363
+ } catch (error2) {
7364
+ await session?.abortTransaction();
7365
+ throw error2;
7366
+ } finally {
7367
+ await session?.endSession();
7368
+ }
7369
+ }
7370
+ return {
7371
+ add,
7372
+ addWithVerification
7373
+ };
7374
+ }
7375
+
7376
+ // src/resources/organization/organization.controller.ts
7377
+ var import_utils42 = require("@goweekdays/utils");
7378
+ var import_joi33 = __toESM(require("joi"));
7379
+ function useOrgController() {
7380
+ const { add: _add } = useOrgService();
7381
+ const { getOrgsByMembership } = useMemberRepo();
7382
+ const {
7383
+ getByName: _getByName,
7384
+ getAll: getAllOrg,
7385
+ getById: _getById,
7386
+ updateById: _updateById
7387
+ } = useOrgRepo();
7388
+ async function add(req, res, next) {
7389
+ const value = req.body;
7390
+ const { error } = schemaOrgAdd.validate(value);
7391
+ if (error) {
7392
+ next(new import_utils42.BadRequestError(error.message));
7393
+ return;
7394
+ }
7395
+ try {
7396
+ const data = await _add(value);
7397
+ res.json({
7398
+ message: "Organization created successfully.",
7399
+ data
7400
+ });
7401
+ return;
7402
+ } catch (error2) {
7403
+ next(error2);
7404
+ }
7405
+ }
7406
+ async function getOrgsByUserId(req, res, next) {
6616
7407
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
6617
7408
  const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
6618
7409
  const search = req.query.search ?? "";
6619
7410
  const user = req.params.user ?? "";
6620
7411
  const isPageNumber = isFinite(page);
6621
7412
  if (!isPageNumber) {
6622
- next(new import_utils37.BadRequestError("Invalid page number."));
7413
+ next(new import_utils42.BadRequestError("Invalid page number."));
6623
7414
  return;
6624
7415
  }
6625
7416
  const isLimitNumber = isFinite(limit);
6626
7417
  if (!isLimitNumber) {
6627
- next(new import_utils37.BadRequestError("Invalid limit number."));
7418
+ next(new import_utils42.BadRequestError("Invalid limit number."));
6628
7419
  return;
6629
7420
  }
6630
- const validation = import_joi27.default.object({
6631
- user: import_joi27.default.string().hex().required(),
6632
- page: import_joi27.default.number().min(1).optional().allow("", null),
6633
- limit: import_joi27.default.number().min(1).optional().allow("", null),
6634
- search: import_joi27.default.string().optional().allow("", null)
7421
+ const validation = import_joi33.default.object({
7422
+ user: import_joi33.default.string().hex().required(),
7423
+ page: import_joi33.default.number().min(1).optional().allow("", null),
7424
+ limit: import_joi33.default.number().min(1).optional().allow("", null),
7425
+ search: import_joi33.default.string().optional().allow("", null)
6635
7426
  });
6636
7427
  const { error } = validation.validate({ user, page, limit, search });
6637
7428
  if (error) {
6638
- next(new import_utils37.BadRequestError(error.message));
7429
+ next(new import_utils42.BadRequestError(error.message));
6639
7430
  return;
6640
7431
  }
6641
7432
  try {
@@ -6648,11 +7439,11 @@ function useOrgController() {
6648
7439
  }
6649
7440
  async function getAll(req, res, next) {
6650
7441
  const query = req.query;
6651
- const validation = import_joi27.default.object({
6652
- page: import_joi27.default.number().min(1).optional().allow("", null),
6653
- limit: import_joi27.default.number().min(1).optional().allow("", null),
6654
- search: import_joi27.default.string().optional().allow("", null),
6655
- status: import_joi27.default.string().valid("active", "suspended", "inactive", "deleted").optional()
7442
+ const validation = import_joi33.default.object({
7443
+ page: import_joi33.default.number().min(1).optional().allow("", null),
7444
+ limit: import_joi33.default.number().min(1).optional().allow("", null),
7445
+ search: import_joi33.default.string().optional().allow("", null),
7446
+ status: import_joi33.default.string().valid("active", "suspended", "inactive", "deleted").optional()
6656
7447
  });
6657
7448
  const { error } = validation.validate(query);
6658
7449
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -6661,16 +7452,16 @@ function useOrgController() {
6661
7452
  const status = req.query.status ?? "active";
6662
7453
  const isPageNumber = isFinite(page);
6663
7454
  if (!isPageNumber) {
6664
- next(new import_utils37.BadRequestError("Invalid page number."));
7455
+ next(new import_utils42.BadRequestError("Invalid page number."));
6665
7456
  return;
6666
7457
  }
6667
7458
  const isLimitNumber = isFinite(limit);
6668
7459
  if (!isLimitNumber) {
6669
- next(new import_utils37.BadRequestError("Invalid limit number."));
7460
+ next(new import_utils42.BadRequestError("Invalid limit number."));
6670
7461
  return;
6671
7462
  }
6672
7463
  if (error) {
6673
- next(new import_utils37.BadRequestError(error.message));
7464
+ next(new import_utils42.BadRequestError(error.message));
6674
7465
  return;
6675
7466
  }
6676
7467
  try {
@@ -6683,12 +7474,12 @@ function useOrgController() {
6683
7474
  }
6684
7475
  async function getByName(req, res, next) {
6685
7476
  const name = req.params.name;
6686
- const validation = import_joi27.default.object({
6687
- name: import_joi27.default.string().required()
7477
+ const validation = import_joi33.default.object({
7478
+ name: import_joi33.default.string().required()
6688
7479
  });
6689
7480
  const { error } = validation.validate({ name });
6690
7481
  if (error) {
6691
- next(new import_utils37.BadRequestError(error.message));
7482
+ next(new import_utils42.BadRequestError(error.message));
6692
7483
  return;
6693
7484
  }
6694
7485
  try {
@@ -6701,12 +7492,12 @@ function useOrgController() {
6701
7492
  }
6702
7493
  async function getById(req, res, next) {
6703
7494
  const id = req.params.id;
6704
- const validation = import_joi27.default.object({
6705
- id: import_joi27.default.string().hex().required()
7495
+ const validation = import_joi33.default.object({
7496
+ id: import_joi33.default.string().hex().required()
6706
7497
  });
6707
7498
  const { error } = validation.validate({ id });
6708
7499
  if (error) {
6709
- next(new import_utils37.BadRequestError(error.message));
7500
+ next(new import_utils42.BadRequestError(error.message));
6710
7501
  return;
6711
7502
  }
6712
7503
  try {
@@ -6722,7 +7513,7 @@ function useOrgController() {
6722
7513
  const payload = req.body;
6723
7514
  const { error } = schemaOrgUpdate.validate({ _id, ...payload });
6724
7515
  if (error) {
6725
- next(new import_utils37.BadRequestError(error.message));
7516
+ next(new import_utils42.BadRequestError(error.message));
6726
7517
  return;
6727
7518
  }
6728
7519
  try {
@@ -6758,16 +7549,16 @@ function useUserService() {
6758
7549
  const { getAll: getAllPermission } = usePermissionRepo();
6759
7550
  const { getById: getOrgById } = useOrgRepo();
6760
7551
  async function createDefaultUser() {
6761
- const session = import_utils38.useAtlas.getClient()?.startSession();
7552
+ const session = import_utils43.useAtlas.getClient()?.startSession();
6762
7553
  try {
6763
7554
  session?.startTransaction();
6764
7555
  const _user = await getUserByEmail(DEFAULT_USER_EMAIL);
6765
7556
  if (_user) {
6766
- throw new import_utils38.BadRequestError(
7557
+ throw new import_utils43.BadRequestError(
6767
7558
  `User already exists: ${DEFAULT_USER_EMAIL}.`
6768
7559
  );
6769
7560
  }
6770
- const hashedPassword = await (0, import_utils38.hashPassword)(DEFAULT_USER_PASSWORD);
7561
+ const hashedPassword = await (0, import_utils43.hashPassword)(DEFAULT_USER_PASSWORD);
6771
7562
  const userId = await addUser(
6772
7563
  {
6773
7564
  email: DEFAULT_USER_EMAIL,
@@ -6813,9 +7604,9 @@ function useUserService() {
6813
7604
  try {
6814
7605
  const _user = await getUserByEmail(value.email);
6815
7606
  if (_user) {
6816
- throw new import_utils38.BadRequestError(`User already exists: ${value.email}.`);
7607
+ throw new import_utils43.BadRequestError(`User already exists: ${value.email}.`);
6817
7608
  }
6818
- const hashedPassword = await (0, import_utils38.hashPassword)(value.password);
7609
+ const hashedPassword = await (0, import_utils43.hashPassword)(value.password);
6819
7610
  const insertedId = await addUser({
6820
7611
  email: value.email,
6821
7612
  password: hashedPassword,
@@ -6825,10 +7616,10 @@ function useUserService() {
6825
7616
  });
6826
7617
  return insertedId;
6827
7618
  } catch (error) {
6828
- if (error instanceof import_utils38.AppError) {
7619
+ if (error instanceof import_utils43.AppError) {
6829
7620
  throw error;
6830
7621
  } else {
6831
- throw new import_utils38.InternalServerError(`Error creating user: ${error}`);
7622
+ throw new import_utils43.InternalServerError(`Error creating user: ${error}`);
6832
7623
  }
6833
7624
  }
6834
7625
  }
@@ -6839,28 +7630,28 @@ function useUserService() {
6839
7630
  lastName = "",
6840
7631
  password = ""
6841
7632
  } = {}) {
6842
- const session = import_utils38.useAtlas.getClient()?.startSession();
7633
+ const session = import_utils43.useAtlas.getClient()?.startSession();
6843
7634
  session?.startTransaction();
6844
7635
  try {
6845
7636
  const invitation = await _getVerificationById(id);
6846
7637
  if (!invitation || !invitation.metadata?.app || !invitation.metadata?.role) {
6847
- throw new import_utils38.BadRequestError("Invalid invitation.");
7638
+ throw new import_utils43.BadRequestError("Invalid invitation.");
6848
7639
  }
6849
7640
  if (invitation.status === "complete") {
6850
- throw new import_utils38.BadRequestError("Invitation already used.");
7641
+ throw new import_utils43.BadRequestError("Invitation already used.");
6851
7642
  }
6852
7643
  if (!invitation.expireAt) {
6853
- throw new import_utils38.BadRequestError("Expiration date is required.");
7644
+ throw new import_utils43.BadRequestError("Expiration date is required.");
6854
7645
  }
6855
7646
  const expired = new Date(invitation.expireAt) < /* @__PURE__ */ new Date();
6856
7647
  if (invitation.status === "expired" || expired) {
6857
- throw new import_utils38.BadRequestError("Invitation expired.");
7648
+ throw new import_utils43.BadRequestError("Invitation expired.");
6858
7649
  }
6859
7650
  const email = invitation.email;
6860
7651
  const user = await getUserByEmail(invitation.email);
6861
7652
  let userId = user?._id ?? "";
6862
7653
  if (!user) {
6863
- const hashedPassword = await (0, import_utils38.hashPassword)(password);
7654
+ const hashedPassword = await (0, import_utils43.hashPassword)(password);
6864
7655
  userId = await addUser(
6865
7656
  {
6866
7657
  email,
@@ -6877,7 +7668,7 @@ function useUserService() {
6877
7668
  if (invitation.metadata?.org) {
6878
7669
  const org = await getOrgById(String(invitation.metadata.org));
6879
7670
  if (!org) {
6880
- throw new import_utils38.NotFoundError("Organization not found.");
7671
+ throw new import_utils43.NotFoundError("Organization not found.");
6881
7672
  }
6882
7673
  orgName = org.name;
6883
7674
  }
@@ -6885,7 +7676,7 @@ function useUserService() {
6885
7676
  if (invitation.metadata.role) {
6886
7677
  const role = await getRoleById(String(invitation.metadata.role));
6887
7678
  if (!role) {
6888
- throw new import_utils38.NotFoundError("Role not found.");
7679
+ throw new import_utils43.NotFoundError("Role not found.");
6889
7680
  }
6890
7681
  roleName = role.name;
6891
7682
  }
@@ -6905,10 +7696,10 @@ function useUserService() {
6905
7696
  return userId;
6906
7697
  } catch (error) {
6907
7698
  await session?.abortTransaction();
6908
- if (error instanceof import_utils38.AppError) {
7699
+ if (error instanceof import_utils43.AppError) {
6909
7700
  throw error;
6910
7701
  } else {
6911
- throw new import_utils38.InternalServerError("Failed to create user by invite.");
7702
+ throw new import_utils43.InternalServerError("Failed to create user by invite.");
6912
7703
  }
6913
7704
  } finally {
6914
7705
  session?.endSession();
@@ -6920,31 +7711,31 @@ function useUserService() {
6920
7711
  lastName = "",
6921
7712
  password = ""
6922
7713
  } = {}) {
6923
- const session = import_utils38.useAtlas.getClient()?.startSession();
7714
+ const session = import_utils43.useAtlas.getClient()?.startSession();
6924
7715
  session?.startTransaction();
6925
7716
  try {
6926
7717
  const signUp = await _getVerificationById(id);
6927
7718
  if (!signUp) {
6928
- throw new import_utils38.BadRequestError("Invalid sign up link.");
7719
+ throw new import_utils43.BadRequestError("Invalid sign up link.");
6929
7720
  }
6930
7721
  if (signUp.status === "complete") {
6931
- throw new import_utils38.BadRequestError(
7722
+ throw new import_utils43.BadRequestError(
6932
7723
  "You have already an account created using this link."
6933
7724
  );
6934
7725
  }
6935
7726
  if (!signUp.expireAt) {
6936
- throw new import_utils38.BadRequestError("Expiration date is required.");
7727
+ throw new import_utils43.BadRequestError("Expiration date is required.");
6937
7728
  }
6938
7729
  const expired = new Date(signUp.expireAt) < /* @__PURE__ */ new Date();
6939
7730
  if (signUp.status === "expired" || expired) {
6940
- throw new import_utils38.BadRequestError("Sign up link expired.");
7731
+ throw new import_utils43.BadRequestError("Sign up link expired.");
6941
7732
  }
6942
7733
  const email = signUp.email;
6943
7734
  const _user = await getUserByEmail(signUp.email);
6944
7735
  if (_user) {
6945
- throw new import_utils38.BadRequestError(`User already exists: ${email}.`);
7736
+ throw new import_utils43.BadRequestError(`User already exists: ${email}.`);
6946
7737
  }
6947
- const hashedPassword = await (0, import_utils38.hashPassword)(password);
7738
+ const hashedPassword = await (0, import_utils43.hashPassword)(password);
6948
7739
  const userId = await addUser(
6949
7740
  {
6950
7741
  email,
@@ -6968,33 +7759,33 @@ function useUserService() {
6968
7759
  const { updateStatusById: updateVerificationStatusById } = useVerificationRepo();
6969
7760
  async function resetPassword(value) {
6970
7761
  if (value.newPassword !== value.confirmPassword) {
6971
- throw new import_utils38.BadRequestError("Passwords do not match.");
7762
+ throw new import_utils43.BadRequestError("Passwords do not match.");
6972
7763
  }
6973
7764
  let hashedPassword = "";
6974
7765
  try {
6975
- hashedPassword = await (0, import_utils38.hashPassword)(value.newPassword);
7766
+ hashedPassword = await (0, import_utils43.hashPassword)(value.newPassword);
6976
7767
  } catch (error) {
6977
- throw new import_utils38.InternalServerError(`Error hashing password: ${error}`);
7768
+ throw new import_utils43.InternalServerError(`Error hashing password: ${error}`);
6978
7769
  }
6979
- const session = import_utils38.useAtlas.getClient()?.startSession();
7770
+ const session = import_utils43.useAtlas.getClient()?.startSession();
6980
7771
  if (!session) {
6981
- throw new import_utils38.InternalServerError("Failed to start database session.");
7772
+ throw new import_utils43.InternalServerError("Failed to start database session.");
6982
7773
  }
6983
7774
  try {
6984
7775
  session.startTransaction();
6985
7776
  const otpDoc = await getById(value.id);
6986
7777
  if (!otpDoc) {
6987
- throw new import_utils38.NotFoundError("You are using an invalid reset link.");
7778
+ throw new import_utils43.NotFoundError("You are using an invalid reset link.");
6988
7779
  }
6989
7780
  const user = await getUserByEmail(otpDoc.email);
6990
7781
  if (!user) {
6991
- throw new import_utils38.NotFoundError("User not found.");
7782
+ throw new import_utils43.NotFoundError("User not found.");
6992
7783
  }
6993
7784
  if (!user._id) {
6994
- throw new import_utils38.NotFoundError("User ID is invalid.");
7785
+ throw new import_utils43.NotFoundError("User ID is invalid.");
6995
7786
  }
6996
7787
  if (otpDoc.status === "used") {
6997
- throw new import_utils38.BadRequestError("This link has already been invalidated.");
7788
+ throw new import_utils43.BadRequestError("This link has already been invalidated.");
6998
7789
  }
6999
7790
  await updateVerificationStatusById(value.id, "used", session);
7000
7791
  await _updateUserFieldById(
@@ -7005,31 +7796,31 @@ function useUserService() {
7005
7796
  return "Successfully reset password.";
7006
7797
  } catch (error) {
7007
7798
  await session.abortTransaction();
7008
- if (error instanceof import_utils38.AppError) {
7799
+ if (error instanceof import_utils43.AppError) {
7009
7800
  throw error;
7010
7801
  }
7011
- throw new import_utils38.InternalServerError("Failed to reset password.");
7802
+ throw new import_utils43.InternalServerError("Failed to reset password.");
7012
7803
  }
7013
7804
  }
7014
7805
  const { updateName: updateMemberName } = useMemberRepo();
7015
7806
  async function updateName(_id, firstName, lastName) {
7016
7807
  if (!_id) {
7017
- throw new import_utils38.BadRequestError("Invalid user ID");
7808
+ throw new import_utils43.BadRequestError("Invalid user ID");
7018
7809
  }
7019
7810
  if (!firstName) {
7020
- throw new import_utils38.BadRequestError("Invalid firstName");
7811
+ throw new import_utils43.BadRequestError("Invalid firstName");
7021
7812
  }
7022
7813
  if (!lastName) {
7023
- throw new import_utils38.BadRequestError("Invalid lastName");
7814
+ throw new import_utils43.BadRequestError("Invalid lastName");
7024
7815
  }
7025
- const session = import_utils38.useAtlas.getClient()?.startSession();
7816
+ const session = import_utils43.useAtlas.getClient()?.startSession();
7026
7817
  session?.startTransaction();
7027
- const cacheKey = (0, import_utils38.makeCacheKey)("users", { user: _id });
7818
+ const cacheKey = (0, import_utils43.makeCacheKey)("users", { user: _id });
7028
7819
  try {
7029
- (0, import_utils38.useCache)().delCache(cacheKey).then(() => {
7030
- import_utils38.logger.info(`Cache cleared for user: ${_id}`);
7820
+ (0, import_utils43.useCache)().delCache(cacheKey).then(() => {
7821
+ import_utils43.logger.info(`Cache cleared for user: ${_id}`);
7031
7822
  }).catch((error) => {
7032
- import_utils38.logger.error(`Failed to clear cache for user: ${_id}`, error);
7823
+ import_utils43.logger.error(`Failed to clear cache for user: ${_id}`, error);
7033
7824
  });
7034
7825
  await _updateName({ _id, firstName, lastName }, session);
7035
7826
  await updateMemberName(
@@ -7047,16 +7838,16 @@ function useUserService() {
7047
7838
  }
7048
7839
  async function updateBirthday(_id, month, day, year) {
7049
7840
  if (!_id) {
7050
- throw new import_utils38.BadRequestError("Invalid user ID");
7841
+ throw new import_utils43.BadRequestError("Invalid user ID");
7051
7842
  }
7052
7843
  if (!month) {
7053
- throw new import_utils38.BadRequestError("Invalid birth month.");
7844
+ throw new import_utils43.BadRequestError("Invalid birth month.");
7054
7845
  }
7055
7846
  if (!day) {
7056
- throw new import_utils38.BadRequestError("Invalid birthday.");
7847
+ throw new import_utils43.BadRequestError("Invalid birthday.");
7057
7848
  }
7058
7849
  if (!year) {
7059
- throw new import_utils38.BadRequestError("Invalid birth year.");
7850
+ throw new import_utils43.BadRequestError("Invalid birth year.");
7060
7851
  }
7061
7852
  try {
7062
7853
  await _updateBirthday({ _id, month, day, year });
@@ -7073,7 +7864,7 @@ function useUserService() {
7073
7864
  }
7074
7865
  }
7075
7866
  const { createFile: _createFile, deleteFileById } = useFileRepo();
7076
- const s3 = new import_utils38.useS3({
7867
+ const s3 = new import_utils43.useS3({
7077
7868
  accessKeyId: SPACES_ACCESS_KEY,
7078
7869
  secretAccessKey: SPACES_SECRET_KEY,
7079
7870
  endpoint: SPACES_ENDPOINT,
@@ -7081,7 +7872,7 @@ function useUserService() {
7081
7872
  bucket: SPACES_BUCKET
7082
7873
  });
7083
7874
  async function updateUserProfile({ file, user, previousProfile } = {}) {
7084
- const session = import_utils38.useAtlas.getClient()?.startSession();
7875
+ const session = import_utils43.useAtlas.getClient()?.startSession();
7085
7876
  session?.startTransaction();
7086
7877
  const _file = {
7087
7878
  name: file.originalname,
@@ -7125,8 +7916,8 @@ function useUserService() {
7125
7916
  }
7126
7917
 
7127
7918
  // src/resources/user/user.controller.ts
7128
- var import_utils39 = require("@goweekdays/utils");
7129
- var import_joi28 = __toESM(require("joi"));
7919
+ var import_utils44 = require("@goweekdays/utils");
7920
+ var import_joi34 = __toESM(require("joi"));
7130
7921
  function useUserController() {
7131
7922
  const {
7132
7923
  updateName: _updateName,
@@ -7142,14 +7933,14 @@ function useUserController() {
7142
7933
  const status = req.query.status ?? "";
7143
7934
  const search = req.query.search ?? "";
7144
7935
  const page = Number(req.query.page) ?? 1;
7145
- const validation = import_joi28.default.object({
7146
- status: import_joi28.default.string().required(),
7147
- search: import_joi28.default.string().optional().allow("", null),
7148
- page: import_joi28.default.number().required()
7936
+ const validation = import_joi34.default.object({
7937
+ status: import_joi34.default.string().required(),
7938
+ search: import_joi34.default.string().optional().allow("", null),
7939
+ page: import_joi34.default.number().required()
7149
7940
  });
7150
7941
  const { error } = validation.validate({ status, search, page });
7151
7942
  if (error) {
7152
- next(new import_utils39.BadRequestError(error.message));
7943
+ next(new import_utils44.BadRequestError(error.message));
7153
7944
  return;
7154
7945
  }
7155
7946
  try {
@@ -7162,14 +7953,14 @@ function useUserController() {
7162
7953
  }
7163
7954
  async function getUserById(req, res, next) {
7164
7955
  const id = req.params.id || "";
7165
- const validation = import_joi28.default.string().hex().validate(id);
7956
+ const validation = import_joi34.default.string().hex().validate(id);
7166
7957
  if (validation.error) {
7167
- throw new import_utils39.BadRequestError("Invalid id.");
7958
+ throw new import_utils44.BadRequestError("Invalid id.");
7168
7959
  }
7169
7960
  try {
7170
7961
  const user = await _getUserById(id);
7171
7962
  if (!user) {
7172
- throw new import_utils39.BadRequestError("User not found.");
7963
+ throw new import_utils44.BadRequestError("User not found.");
7173
7964
  }
7174
7965
  res.json(user);
7175
7966
  } catch (error) {
@@ -7180,13 +7971,13 @@ function useUserController() {
7180
7971
  const id = req.headers.user ?? "";
7181
7972
  const firstName = req.body.firstName ?? "";
7182
7973
  const lastName = req.body.lastName ?? "";
7183
- const validation = import_joi28.default.object({
7184
- firstName: import_joi28.default.string().required(),
7185
- lastName: import_joi28.default.string().required()
7974
+ const validation = import_joi34.default.object({
7975
+ firstName: import_joi34.default.string().required(),
7976
+ lastName: import_joi34.default.string().required()
7186
7977
  });
7187
7978
  const { error } = validation.validate({ firstName, lastName });
7188
7979
  if (error) {
7189
- next(new import_utils39.BadRequestError(error.message));
7980
+ next(new import_utils44.BadRequestError(error.message));
7190
7981
  return;
7191
7982
  }
7192
7983
  try {
@@ -7202,14 +7993,14 @@ function useUserController() {
7202
7993
  const month = req.body.month ?? "";
7203
7994
  const day = req.body.day ?? 0;
7204
7995
  const year = req.body.year ?? 0;
7205
- const validation = import_joi28.default.object({
7206
- month: import_joi28.default.string().required(),
7207
- day: import_joi28.default.number().integer().min(1).max(31).required(),
7208
- year: import_joi28.default.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
7996
+ const validation = import_joi34.default.object({
7997
+ month: import_joi34.default.string().required(),
7998
+ day: import_joi34.default.number().integer().min(1).max(31).required(),
7999
+ year: import_joi34.default.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
7209
8000
  });
7210
8001
  const { error } = validation.validate({ month, day, year });
7211
8002
  if (error) {
7212
- next(new import_utils39.BadRequestError(error.message));
8003
+ next(new import_utils44.BadRequestError(error.message));
7213
8004
  return;
7214
8005
  }
7215
8006
  try {
@@ -7223,18 +8014,18 @@ function useUserController() {
7223
8014
  async function updateUserFieldById(req, res, next) {
7224
8015
  const _id = req.params.id;
7225
8016
  const { field, value } = req.body;
7226
- const validation = import_joi28.default.object({
7227
- _id: import_joi28.default.string().hex().required(),
7228
- field: import_joi28.default.string().valid("gender", "email", "contact", "profile").required(),
7229
- value: import_joi28.default.alternatives().conditional("field", {
8017
+ const validation = import_joi34.default.object({
8018
+ _id: import_joi34.default.string().hex().required(),
8019
+ field: import_joi34.default.string().valid("gender", "email", "contact", "profile").required(),
8020
+ value: import_joi34.default.alternatives().conditional("field", {
7230
8021
  is: "email",
7231
- then: import_joi28.default.string().email().required(),
7232
- otherwise: import_joi28.default.string().required()
8022
+ then: import_joi34.default.string().email().required(),
8023
+ otherwise: import_joi34.default.string().required()
7233
8024
  })
7234
8025
  });
7235
8026
  const { error } = validation.validate({ _id, field, value });
7236
8027
  if (error) {
7237
- next(new import_utils39.BadRequestError(error.message));
8028
+ next(new import_utils44.BadRequestError(error.message));
7238
8029
  return;
7239
8030
  }
7240
8031
  try {
@@ -7250,12 +8041,12 @@ function useUserController() {
7250
8041
  return;
7251
8042
  }
7252
8043
  const previousProfile = req.body.previousProfile ?? "";
7253
- const validation = import_joi28.default.object({
7254
- previousProfile: import_joi28.default.string().hex().optional().allow("", null)
8044
+ const validation = import_joi34.default.object({
8045
+ previousProfile: import_joi34.default.string().hex().optional().allow("", null)
7255
8046
  });
7256
8047
  const { error } = validation.validate({ previousProfile });
7257
8048
  if (error) {
7258
- next(new import_utils39.BadRequestError(error.message));
8049
+ next(new import_utils44.BadRequestError(error.message));
7259
8050
  return;
7260
8051
  }
7261
8052
  const user = req.headers["user"] ?? "";
@@ -7268,10 +8059,10 @@ function useUserController() {
7268
8059
  res.json({ message: "Successfully updated profile picture." });
7269
8060
  return;
7270
8061
  } catch (error2) {
7271
- if (error2 instanceof import_utils39.AppError) {
8062
+ if (error2 instanceof import_utils44.AppError) {
7272
8063
  next(error2);
7273
8064
  } else {
7274
- next(new import_utils39.InternalServerError(error2));
8065
+ next(new import_utils44.InternalServerError(error2));
7275
8066
  }
7276
8067
  }
7277
8068
  }
@@ -7281,12 +8072,12 @@ function useUserController() {
7281
8072
  const password = req.body.password ?? "";
7282
8073
  const id = req.params.id ?? "";
7283
8074
  const type = req.body.type ?? "";
7284
- const validation = import_joi28.default.object({
7285
- firstName: import_joi28.default.string().required(),
7286
- lastName: import_joi28.default.string().required(),
7287
- password: import_joi28.default.string().required(),
7288
- id: import_joi28.default.string().hex().required(),
7289
- type: import_joi28.default.string().required()
8075
+ const validation = import_joi34.default.object({
8076
+ firstName: import_joi34.default.string().required(),
8077
+ lastName: import_joi34.default.string().required(),
8078
+ password: import_joi34.default.string().required(),
8079
+ id: import_joi34.default.string().hex().required(),
8080
+ type: import_joi34.default.string().required()
7290
8081
  });
7291
8082
  const { error } = validation.validate({
7292
8083
  firstName,
@@ -7296,7 +8087,7 @@ function useUserController() {
7296
8087
  type
7297
8088
  });
7298
8089
  if (error) {
7299
- next(new import_utils39.BadRequestError(error.message));
8090
+ next(new import_utils44.BadRequestError(error.message));
7300
8091
  return;
7301
8092
  }
7302
8093
  try {
@@ -7319,14 +8110,14 @@ function useUserController() {
7319
8110
  }
7320
8111
  async function resetPassword(req, res, next) {
7321
8112
  const payload = req.body;
7322
- const validation = import_joi28.default.object({
7323
- id: import_joi28.default.string().hex().required(),
7324
- newPassword: import_joi28.default.string().min(8).required(),
7325
- confirmPassword: import_joi28.default.string().min(8).required()
8113
+ const validation = import_joi34.default.object({
8114
+ id: import_joi34.default.string().hex().required(),
8115
+ newPassword: import_joi34.default.string().min(8).required(),
8116
+ confirmPassword: import_joi34.default.string().min(8).required()
7326
8117
  });
7327
8118
  const { error } = validation.validate(payload);
7328
8119
  if (error) {
7329
- next(new import_utils39.BadRequestError(error.message));
8120
+ next(new import_utils44.BadRequestError(error.message));
7330
8121
  return;
7331
8122
  }
7332
8123
  try {
@@ -7351,7 +8142,7 @@ function useUserController() {
7351
8142
  }
7352
8143
 
7353
8144
  // src/resources/verification/verification.service.ts
7354
- var import_joi29 = __toESM(require("joi"));
8145
+ var import_joi35 = __toESM(require("joi"));
7355
8146
  function useVerificationService() {
7356
8147
  const MailerConfig = {
7357
8148
  host: MAILER_TRANSPORT_HOST,
@@ -7360,7 +8151,7 @@ function useVerificationService() {
7360
8151
  email: MAILER_EMAIL,
7361
8152
  password: MAILER_PASSWORD
7362
8153
  };
7363
- const mailer = new import_utils40.useMailer(MailerConfig);
8154
+ const mailer = new import_utils45.useMailer(MailerConfig);
7364
8155
  const {
7365
8156
  add,
7366
8157
  getById: _getById,
@@ -7386,7 +8177,7 @@ function useVerificationService() {
7386
8177
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
7387
8178
  };
7388
8179
  if (!metadata.app) {
7389
- throw new import_utils40.BadRequestError("App metadata is required.");
8180
+ throw new import_utils45.BadRequestError("App metadata is required.");
7390
8181
  }
7391
8182
  try {
7392
8183
  const user = await getUserByEmail(email);
@@ -7394,8 +8185,8 @@ function useVerificationService() {
7394
8185
  if (user) {
7395
8186
  value.type = "member-invite";
7396
8187
  const res2 = await add(value);
7397
- const filePath2 = (0, import_utils40.getDirectory)(dir, "./public/handlebars/member-invite");
7398
- const emailContent2 = (0, import_utils40.compileHandlebar)({
8188
+ const filePath2 = (0, import_utils45.getDirectory)(dir, "./public/handlebars/member-invite");
8189
+ const emailContent2 = (0, import_utils45.compileHandlebar)({
7399
8190
  context: {
7400
8191
  validity: VERIFICATION_USER_INVITE_DURATION,
7401
8192
  link: `${APP_MAIN}/verify/member-invite/${res2}`,
@@ -7409,7 +8200,7 @@ function useVerificationService() {
7409
8200
  html: emailContent2,
7410
8201
  from: "GoWeekdays"
7411
8202
  }).catch((error) => {
7412
- import_utils40.logger.log({
8203
+ import_utils45.logger.log({
7413
8204
  level: "error",
7414
8205
  message: `Error sending user invite email: ${error}`
7415
8206
  });
@@ -7417,8 +8208,8 @@ function useVerificationService() {
7417
8208
  return res2;
7418
8209
  }
7419
8210
  const res = await add(value);
7420
- const filePath = (0, import_utils40.getDirectory)(dir, "./public/handlebars/user-invite");
7421
- const emailContent = (0, import_utils40.compileHandlebar)({
8211
+ const filePath = (0, import_utils45.getDirectory)(dir, "./public/handlebars/user-invite");
8212
+ const emailContent = (0, import_utils45.compileHandlebar)({
7422
8213
  context: {
7423
8214
  validity: VERIFICATION_USER_INVITE_DURATION,
7424
8215
  link: `${APP_MAIN}/verify/invitation/${res}`
@@ -7431,7 +8222,7 @@ function useVerificationService() {
7431
8222
  html: emailContent,
7432
8223
  from: "GoWeekdays"
7433
8224
  }).catch((error) => {
7434
- import_utils40.logger.log({
8225
+ import_utils45.logger.log({
7435
8226
  level: "error",
7436
8227
  message: `Error sending user invite email: ${error}`
7437
8228
  });
@@ -7452,8 +8243,8 @@ function useVerificationService() {
7452
8243
  try {
7453
8244
  const res = await add(value);
7454
8245
  const dir = __dirname;
7455
- const filePath = (0, import_utils40.getDirectory)(dir, "./public/handlebars/forget-password");
7456
- const emailContent = (0, import_utils40.compileHandlebar)({
8246
+ const filePath = (0, import_utils45.getDirectory)(dir, "./public/handlebars/forget-password");
8247
+ const emailContent = (0, import_utils45.compileHandlebar)({
7457
8248
  context: {
7458
8249
  validity: VERIFICATION_FORGET_PASSWORD_DURATION,
7459
8250
  link: `${APP_MAIN}/reset-password/${res}`
@@ -7466,21 +8257,21 @@ function useVerificationService() {
7466
8257
  from: "GoWeekdays",
7467
8258
  html: emailContent
7468
8259
  }).catch((error) => {
7469
- import_utils40.logger.log({
8260
+ import_utils45.logger.log({
7470
8261
  level: "error",
7471
8262
  message: `Error sending forget password email: ${error}`
7472
8263
  });
7473
8264
  });
7474
8265
  return "Successfully created a link to reset password. Please check your email.";
7475
8266
  } catch (error) {
7476
- throw new import_utils40.InternalServerError("Failed to create forget password link.");
8267
+ throw new import_utils45.InternalServerError("Failed to create forget password link.");
7477
8268
  }
7478
8269
  }
7479
8270
  async function getById(id) {
7480
8271
  try {
7481
8272
  const _id = await _getById(id);
7482
8273
  if (!_id) {
7483
- throw new import_utils40.NotFoundError("Verification not found.");
8274
+ throw new import_utils45.NotFoundError("Verification not found.");
7484
8275
  }
7485
8276
  return _id;
7486
8277
  } catch (error) {
@@ -7512,48 +8303,48 @@ function useVerificationService() {
7512
8303
  }
7513
8304
  function errorByType(type, status) {
7514
8305
  if (type === "user-invite" && status === "expired") {
7515
- throw new import_utils40.BadRequestError(
8306
+ throw new import_utils45.BadRequestError(
7516
8307
  "Invitation has already expired, please contact admin to resend the invitation."
7517
8308
  );
7518
8309
  }
7519
8310
  if (type === "user-sign-up" && status === "expired") {
7520
- throw new import_utils40.BadRequestError(
8311
+ throw new import_utils45.BadRequestError(
7521
8312
  "Sign up verification has expired, please sign up again to get a new verification link."
7522
8313
  );
7523
8314
  }
7524
8315
  if (type === "user-invite" && status === "complete") {
7525
- throw new import_utils40.BadRequestError(
8316
+ throw new import_utils45.BadRequestError(
7526
8317
  "User already registered, please login to continue."
7527
8318
  );
7528
8319
  }
7529
8320
  if (type === "forget-password" && status === "complete") {
7530
- throw new import_utils40.BadRequestError(
8321
+ throw new import_utils45.BadRequestError(
7531
8322
  "Forget password verification has already been used, please request a new one."
7532
8323
  );
7533
8324
  }
7534
8325
  if (type === "forget-password" && status === "expired") {
7535
- throw new import_utils40.BadRequestError(
8326
+ throw new import_utils45.BadRequestError(
7536
8327
  "Forget password verification has expired, please request a new one."
7537
8328
  );
7538
8329
  }
7539
- throw new import_utils40.BadRequestError("Invalid verification.");
8330
+ throw new import_utils45.BadRequestError("Invalid verification.");
7540
8331
  }
7541
8332
  async function verify(id) {
7542
- const session = import_utils40.useAtlas.getClient()?.startSession();
8333
+ const session = import_utils45.useAtlas.getClient()?.startSession();
7543
8334
  session?.startTransaction();
7544
8335
  try {
7545
8336
  const _id = await _getById(id);
7546
8337
  if (!_id) {
7547
- throw new import_utils40.NotFoundError("Verification not found.");
8338
+ throw new import_utils45.NotFoundError("Verification not found.");
7548
8339
  }
7549
8340
  if (_id.status === "expired") {
7550
8341
  errorByType(_id.type, "expired");
7551
8342
  }
7552
8343
  if (_id.status === "complete") {
7553
- throw new import_utils40.BadRequestError("Verification already completed.");
8344
+ throw new import_utils45.BadRequestError("Verification already completed.");
7554
8345
  }
7555
8346
  if (!_id.expireAt) {
7556
- throw new import_utils40.BadRequestError("Expiration date is required.");
8347
+ throw new import_utils45.BadRequestError("Expiration date is required.");
7557
8348
  }
7558
8349
  const expiration = new Date(_id.expireAt).getTime();
7559
8350
  const now = (/* @__PURE__ */ new Date()).getTime();
@@ -7566,15 +8357,15 @@ function useVerificationService() {
7566
8357
  await _updateStatusById(id, "complete", session);
7567
8358
  const user = await getUserByEmail(_id.email);
7568
8359
  if (!user) {
7569
- throw new import_utils40.NotFoundError("User not found for member invite.");
8360
+ throw new import_utils45.NotFoundError("User not found for member invite.");
7570
8361
  }
7571
8362
  if (!_id.metadata?.app) {
7572
- throw new import_utils40.BadRequestError(
8363
+ throw new import_utils45.BadRequestError(
7573
8364
  "App metadata is required for member invite."
7574
8365
  );
7575
8366
  }
7576
8367
  if (!_id.metadata?.role || !_id.metadata?.roleName) {
7577
- throw new import_utils40.BadRequestError(
8368
+ throw new import_utils45.BadRequestError(
7578
8369
  "Role metadata is required for member invite."
7579
8370
  );
7580
8371
  }
@@ -7596,7 +8387,7 @@ function useVerificationService() {
7596
8387
  return _id;
7597
8388
  } catch (error) {
7598
8389
  await session?.abortTransaction();
7599
- import_utils40.logger.log({
8390
+ import_utils45.logger.log({
7600
8391
  level: "info",
7601
8392
  message: `Error verifying user invitation: ${error}`
7602
8393
  });
@@ -7609,7 +8400,7 @@ function useVerificationService() {
7609
8400
  try {
7610
8401
  await updateStatusById(id, "cancelled");
7611
8402
  } catch (error) {
7612
- throw new import_utils40.InternalServerError(
8403
+ throw new import_utils45.InternalServerError(
7613
8404
  `Error cancelling user invitation: ${error}`
7614
8405
  );
7615
8406
  }
@@ -7629,7 +8420,7 @@ function useVerificationService() {
7629
8420
  try {
7630
8421
  const user = await getUserByEmail(email);
7631
8422
  if (user) {
7632
- throw new import_utils40.BadRequestError(
8423
+ throw new import_utils45.BadRequestError(
7633
8424
  `Email ${email} is already registered, please login to continue.`
7634
8425
  );
7635
8426
  }
@@ -7642,8 +8433,8 @@ function useVerificationService() {
7642
8433
  };
7643
8434
  const res = await add(value);
7644
8435
  const dir = __dirname;
7645
- const filePath = (0, import_utils40.getDirectory)(dir, "./public/handlebars/sign-up");
7646
- const emailContent = (0, import_utils40.compileHandlebar)({
8436
+ const filePath = (0, import_utils45.getDirectory)(dir, "./public/handlebars/sign-up");
8437
+ const emailContent = (0, import_utils45.compileHandlebar)({
7647
8438
  context: {
7648
8439
  validity: "5 minutes",
7649
8440
  link: `${APP_MAIN}/sign-up/${res}`
@@ -7656,7 +8447,7 @@ function useVerificationService() {
7656
8447
  html: emailContent,
7657
8448
  from: "GoWeekdays"
7658
8449
  }).catch((error) => {
7659
- import_utils40.logger.log({
8450
+ import_utils45.logger.log({
7660
8451
  level: "error",
7661
8452
  message: `Error sending user invite email: ${error}`
7662
8453
  });
@@ -7669,17 +8460,17 @@ function useVerificationService() {
7669
8460
  async function inviteMember(value) {
7670
8461
  const { error } = schemaInviteMember.validate(value);
7671
8462
  if (error) {
7672
- throw new import_utils40.BadRequestError(error.message);
8463
+ throw new import_utils45.BadRequestError(error.message);
7673
8464
  }
7674
8465
  const role = await getRoleById(value.role);
7675
8466
  if (!role) {
7676
- throw new import_utils40.NotFoundError("Role not found.");
8467
+ throw new import_utils45.NotFoundError("Role not found.");
7677
8468
  }
7678
8469
  let org = null;
7679
8470
  if (value.org) {
7680
8471
  org = await getOrgById(String(value.org));
7681
8472
  if (!org) {
7682
- throw new import_utils40.NotFoundError("Organization not found.");
8473
+ throw new import_utils45.NotFoundError("Organization not found.");
7683
8474
  }
7684
8475
  }
7685
8476
  let verificationData = {
@@ -7699,8 +8490,8 @@ function useVerificationService() {
7699
8490
  if (user) {
7700
8491
  verificationData.type = "member-invite";
7701
8492
  const verificationId2 = await add(verificationData);
7702
- const filePath2 = (0, import_utils40.getDirectory)(dir, "./public/handlebars/member-invite");
7703
- const emailContent2 = (0, import_utils40.compileHandlebar)({
8493
+ const filePath2 = (0, import_utils45.getDirectory)(dir, "./public/handlebars/member-invite");
8494
+ const emailContent2 = (0, import_utils45.compileHandlebar)({
7704
8495
  context: {
7705
8496
  validity: VERIFICATION_USER_INVITE_DURATION,
7706
8497
  link: `${APP_MAIN}/verify/member-invite/${verificationId2}`,
@@ -7714,7 +8505,7 @@ function useVerificationService() {
7714
8505
  html: emailContent2,
7715
8506
  from: "GoWeekdays"
7716
8507
  }).catch((error2) => {
7717
- import_utils40.logger.log({
8508
+ import_utils45.logger.log({
7718
8509
  level: "error",
7719
8510
  message: `Error sending user invite email: ${error2}`
7720
8511
  });
@@ -7722,8 +8513,8 @@ function useVerificationService() {
7722
8513
  return verificationId2;
7723
8514
  }
7724
8515
  const verificationId = await add(verificationData);
7725
- const filePath = (0, import_utils40.getDirectory)(dir, "./public/handlebars/user-invite");
7726
- const emailContent = (0, import_utils40.compileHandlebar)({
8516
+ const filePath = (0, import_utils45.getDirectory)(dir, "./public/handlebars/user-invite");
8517
+ const emailContent = (0, import_utils45.compileHandlebar)({
7727
8518
  context: {
7728
8519
  validity: VERIFICATION_USER_INVITE_DURATION,
7729
8520
  link: `${APP_MAIN}/verify/invitation/${verificationId}`
@@ -7736,55 +8527,55 @@ function useVerificationService() {
7736
8527
  html: emailContent,
7737
8528
  from: "GoWeekdays"
7738
8529
  }).catch((error2) => {
7739
- import_utils40.logger.log({
8530
+ import_utils45.logger.log({
7740
8531
  level: "error",
7741
8532
  message: `Error sending user invite email: ${error2}`
7742
8533
  });
7743
8534
  });
7744
8535
  return verificationId;
7745
8536
  } catch (error2) {
7746
- if (error2 instanceof import_utils40.AppError) {
8537
+ if (error2 instanceof import_utils45.AppError) {
7747
8538
  throw error2;
7748
8539
  } else {
7749
- throw new import_utils40.InternalServerError("Failed to invite member.");
8540
+ throw new import_utils45.InternalServerError("Failed to invite member.");
7750
8541
  }
7751
8542
  }
7752
8543
  }
7753
8544
  async function cancelInviteMember(id) {
7754
- const { error } = import_joi29.default.string().hex().required().validate(id);
8545
+ const { error } = import_joi35.default.string().hex().required().validate(id);
7755
8546
  if (error) {
7756
- throw new import_utils40.BadRequestError("Invalid verification ID.");
8547
+ throw new import_utils45.BadRequestError("Invalid verification ID.");
7757
8548
  }
7758
8549
  try {
7759
8550
  const invite = await _getById(id);
7760
8551
  if (!invite) {
7761
- throw new import_utils40.NotFoundError("Invitation not found.");
8552
+ throw new import_utils45.NotFoundError("Invitation not found.");
7762
8553
  }
7763
8554
  if (invite.status === "cancelled") {
7764
- throw new import_utils40.BadRequestError("Invitation already cancelled.");
8555
+ throw new import_utils45.BadRequestError("Invitation already cancelled.");
7765
8556
  }
7766
8557
  if (invite.status === "complete") {
7767
- throw new import_utils40.BadRequestError("Cannot cancel a completed invitation.");
8558
+ throw new import_utils45.BadRequestError("Cannot cancel a completed invitation.");
7768
8559
  }
7769
8560
  await _updateStatusById(id, "cancelled");
7770
8561
  return "Successfully cancelled the invitation.";
7771
8562
  } catch (error2) {
7772
- if (error2 instanceof import_utils40.AppError) {
8563
+ if (error2 instanceof import_utils45.AppError) {
7773
8564
  throw error2;
7774
8565
  } else {
7775
- throw new import_utils40.InternalServerError("Failed to cancel the invitation.");
8566
+ throw new import_utils45.InternalServerError("Failed to cancel the invitation.");
7776
8567
  }
7777
8568
  }
7778
8569
  }
7779
8570
  async function forgetPassword(email) {
7780
- const { error } = import_joi29.default.string().email().required().validate(email);
8571
+ const { error } = import_joi35.default.string().email().required().validate(email);
7781
8572
  if (error) {
7782
- throw new import_utils40.BadRequestError("Invalid email address.");
8573
+ throw new import_utils45.BadRequestError("Invalid email address.");
7783
8574
  }
7784
8575
  try {
7785
8576
  const member = await getUserByEmail(email);
7786
8577
  if (!member) {
7787
- throw new import_utils40.NotFoundError("User not found.");
8578
+ throw new import_utils45.NotFoundError("User not found.");
7788
8579
  }
7789
8580
  const value = {
7790
8581
  type: "forget-password",
@@ -7794,8 +8585,8 @@ function useVerificationService() {
7794
8585
  };
7795
8586
  const res = await add(value);
7796
8587
  const dir = __dirname;
7797
- const filePath = (0, import_utils40.getDirectory)(dir, "./public/handlebars/forget-password");
7798
- const emailContent = (0, import_utils40.compileHandlebar)({
8588
+ const filePath = (0, import_utils45.getDirectory)(dir, "./public/handlebars/forget-password");
8589
+ const emailContent = (0, import_utils45.compileHandlebar)({
7799
8590
  context: {
7800
8591
  validity: VERIFICATION_FORGET_PASSWORD_DURATION,
7801
8592
  link: `${APP_MAIN}/reset-password/${res}`
@@ -7808,22 +8599,78 @@ function useVerificationService() {
7808
8599
  from: "GoWeekdays",
7809
8600
  html: emailContent
7810
8601
  }).catch((error2) => {
7811
- import_utils40.logger.log({
8602
+ import_utils45.logger.log({
7812
8603
  level: "error",
7813
8604
  message: `Error sending forget password email: ${error2}`
7814
8605
  });
7815
8606
  });
7816
8607
  return "Successfully created a link to reset password. Please check your email.";
7817
8608
  } catch (error2) {
7818
- if (error2 instanceof import_utils40.AppError) {
8609
+ if (error2 instanceof import_utils45.AppError) {
7819
8610
  throw error2;
7820
8611
  } else {
7821
- throw new import_utils40.InternalServerError(
8612
+ throw new import_utils45.InternalServerError(
7822
8613
  "Failed to process forget password request."
7823
8614
  );
7824
8615
  }
7825
8616
  }
7826
8617
  }
8618
+ const { addOrder: addPaypalOrder } = usePaypalService();
8619
+ const { getByEmail: getOrgByEmail, getByName: getOrgByName } = useOrgRepo();
8620
+ async function orgSetupFee(value) {
8621
+ const session = import_utils45.useAtlas.getClient()?.startSession();
8622
+ if (!session) {
8623
+ throw new import_utils45.BadRequestError("Unable to start database session.");
8624
+ }
8625
+ try {
8626
+ session.startTransaction();
8627
+ const orgExistingByName = await getOrgByName(value.name);
8628
+ if (orgExistingByName) {
8629
+ throw new import_utils45.BadRequestError(`Name ${value.name} is already taken.`);
8630
+ }
8631
+ const orgExistingByEmail = await getOrgByEmail(value.email);
8632
+ if (orgExistingByEmail) {
8633
+ throw new import_utils45.BadRequestError(`Email ${value.email} is already taken.`);
8634
+ }
8635
+ const amount = 100;
8636
+ const verificationId = await add(
8637
+ {
8638
+ type: "org-setup-fee",
8639
+ email: value.email,
8640
+ metadata: {
8641
+ seats: value.seats,
8642
+ contact: value.contact,
8643
+ orgName: value.name,
8644
+ createdBy: value.createdBy,
8645
+ amount
8646
+ }
8647
+ },
8648
+ session
8649
+ );
8650
+ const order = await addPaypalOrder({
8651
+ amount,
8652
+ currency: "PHP",
8653
+ customId: String(verificationId),
8654
+ returnUrl: `${APP_ORG}/organizations/success`,
8655
+ cancelUrl: `${APP_ORG}/organizations/cancel`,
8656
+ action: "pay"
8657
+ });
8658
+ await session?.commitTransaction();
8659
+ const paypalOrderLink = JSON.parse(order.body.toString()).links.find(
8660
+ (link) => link.rel === "approve"
8661
+ );
8662
+ return {
8663
+ paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
8664
+ };
8665
+ } catch (error) {
8666
+ if (error instanceof import_utils45.AppError) {
8667
+ throw error;
8668
+ }
8669
+ throw new import_utils45.InternalServerError(
8670
+ "Failed to process organization setup fee."
8671
+ );
8672
+ }
8673
+ }
7827
8674
  return {
7828
8675
  createForgetPassword,
7829
8676
  createUserInvite,
@@ -7835,7 +8682,8 @@ function useVerificationService() {
7835
8682
  signUp,
7836
8683
  inviteMember,
7837
8684
  cancelInviteMember,
7838
- forgetPassword
8685
+ forgetPassword,
8686
+ orgSetupFee
7839
8687
  };
7840
8688
  }
7841
8689
 
@@ -7845,13 +8693,13 @@ function useAuthController() {
7845
8693
  async function login(req, res, next) {
7846
8694
  const email = req.body.email;
7847
8695
  const password = req.body.password;
7848
- const validation = import_joi30.default.object({
7849
- email: import_joi30.default.string().email().required(),
7850
- password: import_joi30.default.string().required()
8696
+ const validation = import_joi36.default.object({
8697
+ email: import_joi36.default.string().email().required(),
8698
+ password: import_joi36.default.string().required()
7851
8699
  });
7852
8700
  const { error } = validation.validate({ email, password });
7853
8701
  if (error) {
7854
- next(new import_utils41.BadRequestError(error.message));
8702
+ next(new import_utils46.BadRequestError(error.message));
7855
8703
  return;
7856
8704
  }
7857
8705
  try {
@@ -7867,14 +8715,14 @@ function useAuthController() {
7867
8715
  res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json({ message: "Login successful" });
7868
8716
  return;
7869
8717
  } catch (error2) {
7870
- import_utils41.logger.log({
8718
+ import_utils46.logger.log({
7871
8719
  level: "error",
7872
8720
  message: `Error during login: ${error2.message}`
7873
8721
  });
7874
- if (error2 instanceof import_utils41.AppError) {
8722
+ if (error2 instanceof import_utils46.AppError) {
7875
8723
  next(error2);
7876
8724
  } else {
7877
- next(new import_utils41.InternalServerError("An unexpected error occurred"));
8725
+ next(new import_utils46.InternalServerError("An unexpected error occurred"));
7878
8726
  }
7879
8727
  return;
7880
8728
  }
@@ -7882,17 +8730,17 @@ function useAuthController() {
7882
8730
  async function logout(req, res, next) {
7883
8731
  const sid = req.headers["authorization"] ?? "";
7884
8732
  if (!sid) {
7885
- next(new import_utils41.BadRequestError("Session ID is required"));
8733
+ next(new import_utils46.BadRequestError("Session ID is required"));
7886
8734
  return;
7887
8735
  }
7888
8736
  try {
7889
8737
  await useAuthService().logout(sid);
7890
8738
  res.json({ message: "Logged out successfully" });
7891
8739
  } catch (error) {
7892
- if (error instanceof import_utils41.AppError) {
8740
+ if (error instanceof import_utils46.AppError) {
7893
8741
  next(error);
7894
8742
  } else {
7895
- next(new import_utils41.InternalServerError("An unexpected error occurred"));
8743
+ next(new import_utils46.InternalServerError("An unexpected error occurred"));
7896
8744
  }
7897
8745
  }
7898
8746
  }
@@ -7903,64 +8751,64 @@ function useAuthController() {
7903
8751
  }
7904
8752
 
7905
8753
  // src/resources/building/building.model.ts
7906
- var import_utils42 = require("@goweekdays/utils");
7907
- var import_joi31 = __toESM(require("joi"));
7908
- var import_mongodb20 = require("mongodb");
7909
- var schemaBuilding = import_joi31.default.object({
7910
- _id: import_joi31.default.string().hex().optional(),
7911
- school: import_joi31.default.string().hex().required(),
7912
- serial: import_joi31.default.string().optional().allow("", null),
7913
- name: import_joi31.default.string().required(),
7914
- levels: import_joi31.default.number().integer().min(1).required(),
7915
- createdAt: import_joi31.default.date().optional().allow("", null),
7916
- updatedAt: import_joi31.default.date().optional().allow("", null),
7917
- deletedAt: import_joi31.default.date().optional().allow("", null),
7918
- status: import_joi31.default.string().optional().allow("", null)
8754
+ var import_utils47 = require("@goweekdays/utils");
8755
+ var import_joi37 = __toESM(require("joi"));
8756
+ var import_mongodb22 = require("mongodb");
8757
+ var schemaBuilding = import_joi37.default.object({
8758
+ _id: import_joi37.default.string().hex().optional(),
8759
+ school: import_joi37.default.string().hex().required(),
8760
+ serial: import_joi37.default.string().optional().allow("", null),
8761
+ name: import_joi37.default.string().required(),
8762
+ levels: import_joi37.default.number().integer().min(1).required(),
8763
+ createdAt: import_joi37.default.date().optional().allow("", null),
8764
+ updatedAt: import_joi37.default.date().optional().allow("", null),
8765
+ deletedAt: import_joi37.default.date().optional().allow("", null),
8766
+ status: import_joi37.default.string().optional().allow("", null)
7919
8767
  });
7920
- var schemaBuildingUnit = import_joi31.default.object({
7921
- _id: import_joi31.default.string().hex().optional(),
7922
- school: import_joi31.default.string().hex().required(),
7923
- name: import_joi31.default.string().optional().allow("", null),
7924
- building: import_joi31.default.string().hex().required(),
7925
- buildingName: import_joi31.default.string().optional().allow("", null),
7926
- level: import_joi31.default.number().integer().min(1).required(),
7927
- category: import_joi31.default.string().required(),
7928
- type: import_joi31.default.string().required(),
7929
- seating_capacity: import_joi31.default.number().integer().min(0).required(),
7930
- standing_capacity: import_joi31.default.number().integer().min(0).required(),
7931
- description: import_joi31.default.string().optional().allow("", null),
7932
- unit_of_measurement: import_joi31.default.string().valid("sqm").required(),
7933
- area: import_joi31.default.number().positive().required(),
7934
- status: import_joi31.default.string().optional().allow("", null)
8768
+ var schemaBuildingUnit = import_joi37.default.object({
8769
+ _id: import_joi37.default.string().hex().optional(),
8770
+ school: import_joi37.default.string().hex().required(),
8771
+ name: import_joi37.default.string().optional().allow("", null),
8772
+ building: import_joi37.default.string().hex().required(),
8773
+ buildingName: import_joi37.default.string().optional().allow("", null),
8774
+ level: import_joi37.default.number().integer().min(1).required(),
8775
+ category: import_joi37.default.string().required(),
8776
+ type: import_joi37.default.string().required(),
8777
+ seating_capacity: import_joi37.default.number().integer().min(0).required(),
8778
+ standing_capacity: import_joi37.default.number().integer().min(0).required(),
8779
+ description: import_joi37.default.string().optional().allow("", null),
8780
+ unit_of_measurement: import_joi37.default.string().valid("sqm").required(),
8781
+ area: import_joi37.default.number().positive().required(),
8782
+ status: import_joi37.default.string().optional().allow("", null)
7935
8783
  });
7936
- var schemaUpdateOptions = import_joi31.default.object({
7937
- name: import_joi31.default.string().optional().allow("", null),
7938
- building: import_joi31.default.string().hex().optional().allow("", null),
7939
- buildingName: import_joi31.default.string().optional().allow("", null),
7940
- level: import_joi31.default.number().integer().min(1).optional().allow("", null),
7941
- category: import_joi31.default.string().optional().allow("", null),
7942
- type: import_joi31.default.string().optional().allow("", null),
7943
- seating_capacity: import_joi31.default.number().integer().min(0).optional().allow("", null),
7944
- standing_capacity: import_joi31.default.number().integer().min(0).optional().allow("", null),
7945
- area: import_joi31.default.number().positive().optional().allow("", null)
8784
+ var schemaUpdateOptions = import_joi37.default.object({
8785
+ name: import_joi37.default.string().optional().allow("", null),
8786
+ building: import_joi37.default.string().hex().optional().allow("", null),
8787
+ buildingName: import_joi37.default.string().optional().allow("", null),
8788
+ level: import_joi37.default.number().integer().min(1).optional().allow("", null),
8789
+ category: import_joi37.default.string().optional().allow("", null),
8790
+ type: import_joi37.default.string().optional().allow("", null),
8791
+ seating_capacity: import_joi37.default.number().integer().min(0).optional().allow("", null),
8792
+ standing_capacity: import_joi37.default.number().integer().min(0).optional().allow("", null),
8793
+ area: import_joi37.default.number().positive().optional().allow("", null)
7946
8794
  });
7947
8795
  function MBuilding(value) {
7948
8796
  const { error } = schemaBuilding.validate(value);
7949
8797
  if (error) {
7950
- import_utils42.logger.info(`Building Model: ${error.message}`);
7951
- throw new import_utils42.BadRequestError(error.message);
8798
+ import_utils47.logger.info(`Building Model: ${error.message}`);
8799
+ throw new import_utils47.BadRequestError(error.message);
7952
8800
  }
7953
8801
  if (value._id && typeof value._id === "string") {
7954
8802
  try {
7955
- value._id = new import_mongodb20.ObjectId(value._id);
8803
+ value._id = new import_mongodb22.ObjectId(value._id);
7956
8804
  } catch (error2) {
7957
- throw new import_utils42.BadRequestError("Invalid _id format");
8805
+ throw new import_utils47.BadRequestError("Invalid _id format");
7958
8806
  }
7959
8807
  }
7960
8808
  try {
7961
- value.school = new import_mongodb20.ObjectId(value.school);
8809
+ value.school = new import_mongodb22.ObjectId(value.school);
7962
8810
  } catch (error2) {
7963
- throw new import_utils42.BadRequestError("Invalid school format");
8811
+ throw new import_utils47.BadRequestError("Invalid school format");
7964
8812
  }
7965
8813
  return {
7966
8814
  _id: value._id ?? void 0,
@@ -7977,25 +8825,25 @@ function MBuilding(value) {
7977
8825
  function MBuildingUnit(value) {
7978
8826
  const { error } = schemaBuildingUnit.validate(value);
7979
8827
  if (error) {
7980
- import_utils42.logger.info(`Building Unit Model: ${error.message}`);
7981
- throw new import_utils42.BadRequestError(error.message);
8828
+ import_utils47.logger.info(`Building Unit Model: ${error.message}`);
8829
+ throw new import_utils47.BadRequestError(error.message);
7982
8830
  }
7983
8831
  if (value._id && typeof value._id === "string") {
7984
8832
  try {
7985
- value._id = new import_mongodb20.ObjectId(value._id);
8833
+ value._id = new import_mongodb22.ObjectId(value._id);
7986
8834
  } catch (error2) {
7987
- throw new import_utils42.BadRequestError("Invalid ID");
8835
+ throw new import_utils47.BadRequestError("Invalid ID");
7988
8836
  }
7989
8837
  }
7990
8838
  try {
7991
- value.school = new import_mongodb20.ObjectId(value.school);
8839
+ value.school = new import_mongodb22.ObjectId(value.school);
7992
8840
  } catch (error2) {
7993
- throw new import_utils42.BadRequestError("Invalid school ID");
8841
+ throw new import_utils47.BadRequestError("Invalid school ID");
7994
8842
  }
7995
8843
  try {
7996
- value.building = new import_mongodb20.ObjectId(value.building);
8844
+ value.building = new import_mongodb22.ObjectId(value.building);
7997
8845
  } catch (error2) {
7998
- throw new import_utils42.BadRequestError("Invalid building ID");
8846
+ throw new import_utils47.BadRequestError("Invalid building ID");
7999
8847
  }
8000
8848
  return {
8001
8849
  _id: value._id ?? void 0,
@@ -8019,16 +8867,16 @@ function MBuildingUnit(value) {
8019
8867
  }
8020
8868
 
8021
8869
  // src/resources/building/building.repository.ts
8022
- var import_utils43 = require("@goweekdays/utils");
8023
- var import_mongodb21 = require("mongodb");
8870
+ var import_utils48 = require("@goweekdays/utils");
8871
+ var import_mongodb23 = require("mongodb");
8024
8872
  function useBuildingRepo() {
8025
- const db = import_utils43.useAtlas.getDb();
8873
+ const db = import_utils48.useAtlas.getDb();
8026
8874
  if (!db) {
8027
8875
  throw new Error("Unable to connect to server.");
8028
8876
  }
8029
8877
  const namespace_collection = "school.buildings";
8030
8878
  const collection = db.collection(namespace_collection);
8031
- const { getCache, setCache, delNamespace } = (0, import_utils43.useCache)(namespace_collection);
8879
+ const { getCache, setCache, delNamespace } = (0, import_utils48.useCache)(namespace_collection);
8032
8880
  async function createIndexes() {
8033
8881
  try {
8034
8882
  await collection.createIndexes([
@@ -8047,16 +8895,16 @@ function useBuildingRepo() {
8047
8895
  delCachedData();
8048
8896
  return res.insertedId;
8049
8897
  } catch (error) {
8050
- import_utils43.logger.log({
8898
+ import_utils48.logger.log({
8051
8899
  level: "error",
8052
8900
  message: error.message
8053
8901
  });
8054
- if (error instanceof import_utils43.AppError) {
8902
+ if (error instanceof import_utils48.AppError) {
8055
8903
  throw error;
8056
8904
  } else {
8057
8905
  const isDuplicated = error.message.includes("duplicate");
8058
8906
  if (isDuplicated) {
8059
- throw new import_utils43.BadRequestError("Building already exists.");
8907
+ throw new import_utils48.BadRequestError("Building already exists.");
8060
8908
  }
8061
8909
  throw new Error("Failed to create building.");
8062
8910
  }
@@ -8064,9 +8912,9 @@ function useBuildingRepo() {
8064
8912
  }
8065
8913
  async function updateById(_id, value, session) {
8066
8914
  try {
8067
- _id = new import_mongodb21.ObjectId(_id);
8915
+ _id = new import_mongodb23.ObjectId(_id);
8068
8916
  } catch (error) {
8069
- throw new import_utils43.BadRequestError("Invalid ID.");
8917
+ throw new import_utils48.BadRequestError("Invalid ID.");
8070
8918
  }
8071
8919
  try {
8072
8920
  const res = await collection.updateOne(
@@ -8077,11 +8925,11 @@ function useBuildingRepo() {
8077
8925
  delCachedData();
8078
8926
  return res;
8079
8927
  } catch (error) {
8080
- import_utils43.logger.log({
8928
+ import_utils48.logger.log({
8081
8929
  level: "error",
8082
8930
  message: error.message
8083
8931
  });
8084
- if (error instanceof import_utils43.AppError) {
8932
+ if (error instanceof import_utils48.AppError) {
8085
8933
  throw error;
8086
8934
  } else {
8087
8935
  throw new Error("Failed to update building.");
@@ -8106,9 +8954,9 @@ function useBuildingRepo() {
8106
8954
  }
8107
8955
  if (school) {
8108
8956
  try {
8109
- query.school = new import_mongodb21.ObjectId(school);
8957
+ query.school = new import_mongodb23.ObjectId(school);
8110
8958
  } catch (error) {
8111
- throw new import_utils43.BadRequestError("Invalid school ID.");
8959
+ throw new import_utils48.BadRequestError("Invalid school ID.");
8112
8960
  }
8113
8961
  }
8114
8962
  const cacheParams = {
@@ -8122,15 +8970,15 @@ function useBuildingRepo() {
8122
8970
  cacheParams.school = school;
8123
8971
  if (status !== "active")
8124
8972
  cacheParams.status = status;
8125
- const cacheKey = (0, import_utils43.makeCacheKey)(namespace_collection, cacheParams);
8126
- import_utils43.logger.log({
8973
+ const cacheKey = (0, import_utils48.makeCacheKey)(namespace_collection, cacheParams);
8974
+ import_utils48.logger.log({
8127
8975
  level: "info",
8128
8976
  message: `Cache key for getAll buildings: ${cacheKey}`
8129
8977
  });
8130
8978
  try {
8131
8979
  const cached = await getCache(cacheKey);
8132
8980
  if (cached) {
8133
- import_utils43.logger.log({
8981
+ import_utils48.logger.log({
8134
8982
  level: "info",
8135
8983
  message: `Cache hit for getAll buildings: ${cacheKey}`
8136
8984
  });
@@ -8143,35 +8991,35 @@ function useBuildingRepo() {
8143
8991
  { $limit: limit }
8144
8992
  ]).toArray();
8145
8993
  const length = await collection.countDocuments(query);
8146
- const data = (0, import_utils43.paginate)(items, page, limit, length);
8994
+ const data = (0, import_utils48.paginate)(items, page, limit, length);
8147
8995
  setCache(cacheKey, data, 600).then(() => {
8148
- import_utils43.logger.log({
8996
+ import_utils48.logger.log({
8149
8997
  level: "info",
8150
8998
  message: `Cache set for getAll buildings: ${cacheKey}`
8151
8999
  });
8152
9000
  }).catch((err) => {
8153
- import_utils43.logger.log({
9001
+ import_utils48.logger.log({
8154
9002
  level: "error",
8155
9003
  message: `Failed to set cache for getAll buildings: ${err.message}`
8156
9004
  });
8157
9005
  });
8158
9006
  return data;
8159
9007
  } catch (error) {
8160
- import_utils43.logger.log({ level: "error", message: `${error}` });
9008
+ import_utils48.logger.log({ level: "error", message: `${error}` });
8161
9009
  throw error;
8162
9010
  }
8163
9011
  }
8164
9012
  async function getById(_id) {
8165
9013
  try {
8166
- _id = new import_mongodb21.ObjectId(_id);
9014
+ _id = new import_mongodb23.ObjectId(_id);
8167
9015
  } catch (error) {
8168
- throw new import_utils43.BadRequestError("Invalid ID.");
9016
+ throw new import_utils48.BadRequestError("Invalid ID.");
8169
9017
  }
8170
- const cacheKey = (0, import_utils43.makeCacheKey)(namespace_collection, { _id: String(_id) });
9018
+ const cacheKey = (0, import_utils48.makeCacheKey)(namespace_collection, { _id: String(_id) });
8171
9019
  try {
8172
9020
  const cached = await getCache(cacheKey);
8173
9021
  if (cached) {
8174
- import_utils43.logger.log({
9022
+ import_utils48.logger.log({
8175
9023
  level: "info",
8176
9024
  message: `Cache hit for getById building: ${cacheKey}`
8177
9025
  });
@@ -8181,30 +9029,30 @@ function useBuildingRepo() {
8181
9029
  _id
8182
9030
  });
8183
9031
  setCache(cacheKey, result, 300).then(() => {
8184
- import_utils43.logger.log({
9032
+ import_utils48.logger.log({
8185
9033
  level: "info",
8186
9034
  message: `Cache set for building by id: ${cacheKey}`
8187
9035
  });
8188
9036
  }).catch((err) => {
8189
- import_utils43.logger.log({
9037
+ import_utils48.logger.log({
8190
9038
  level: "error",
8191
9039
  message: `Failed to set cache for building by id: ${err.message}`
8192
9040
  });
8193
9041
  });
8194
9042
  return result;
8195
9043
  } catch (error) {
8196
- if (error instanceof import_utils43.AppError) {
9044
+ if (error instanceof import_utils48.AppError) {
8197
9045
  throw error;
8198
9046
  } else {
8199
- throw new import_utils43.InternalServerError("Failed to get building.");
9047
+ throw new import_utils48.InternalServerError("Failed to get building.");
8200
9048
  }
8201
9049
  }
8202
9050
  }
8203
9051
  async function deleteById(_id, session) {
8204
9052
  try {
8205
- _id = new import_mongodb21.ObjectId(_id);
9053
+ _id = new import_mongodb23.ObjectId(_id);
8206
9054
  } catch (error) {
8207
- throw new import_utils43.BadRequestError("Invalid ID.");
9055
+ throw new import_utils48.BadRequestError("Invalid ID.");
8208
9056
  }
8209
9057
  try {
8210
9058
  const res = await collection.updateOne(
@@ -8214,25 +9062,25 @@ function useBuildingRepo() {
8214
9062
  delCachedData();
8215
9063
  return res;
8216
9064
  } catch (error) {
8217
- import_utils43.logger.log({
9065
+ import_utils48.logger.log({
8218
9066
  level: "error",
8219
9067
  message: error.message
8220
9068
  });
8221
- if (error instanceof import_utils43.AppError) {
9069
+ if (error instanceof import_utils48.AppError) {
8222
9070
  throw error;
8223
9071
  } else {
8224
- throw new import_utils43.InternalServerError("Failed to delete building.");
9072
+ throw new import_utils48.InternalServerError("Failed to delete building.");
8225
9073
  }
8226
9074
  }
8227
9075
  }
8228
9076
  function delCachedData() {
8229
9077
  delNamespace().then(() => {
8230
- import_utils43.logger.log({
9078
+ import_utils48.logger.log({
8231
9079
  level: "info",
8232
9080
  message: `Cache namespace cleared for ${namespace_collection}`
8233
9081
  });
8234
9082
  }).catch((err) => {
8235
- import_utils43.logger.log({
9083
+ import_utils48.logger.log({
8236
9084
  level: "error",
8237
9085
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
8238
9086
  });
@@ -8249,19 +9097,19 @@ function useBuildingRepo() {
8249
9097
  }
8250
9098
 
8251
9099
  // src/resources/building/building.service.ts
8252
- var import_utils45 = require("@goweekdays/utils");
9100
+ var import_utils50 = require("@goweekdays/utils");
8253
9101
 
8254
9102
  // src/resources/building/building-unit.repository.ts
8255
- var import_utils44 = require("@goweekdays/utils");
8256
- var import_mongodb22 = require("mongodb");
9103
+ var import_utils49 = require("@goweekdays/utils");
9104
+ var import_mongodb24 = require("mongodb");
8257
9105
  function useBuildingUnitRepo() {
8258
- const db = import_utils44.useAtlas.getDb();
9106
+ const db = import_utils49.useAtlas.getDb();
8259
9107
  if (!db) {
8260
9108
  throw new Error("Unable to connect to server.");
8261
9109
  }
8262
9110
  const namespace_collection = "school.building-units";
8263
9111
  const collection = db.collection(namespace_collection);
8264
- const { getCache, setCache, delNamespace } = (0, import_utils44.useCache)(namespace_collection);
9112
+ const { getCache, setCache, delNamespace } = (0, import_utils49.useCache)(namespace_collection);
8265
9113
  async function createIndexes() {
8266
9114
  try {
8267
9115
  await collection.createIndexes([
@@ -8289,12 +9137,12 @@ function useBuildingUnitRepo() {
8289
9137
  }
8290
9138
  function delCachedData() {
8291
9139
  delNamespace().then(() => {
8292
- import_utils44.logger.log({
9140
+ import_utils49.logger.log({
8293
9141
  level: "info",
8294
9142
  message: `Cache namespace cleared for ${namespace_collection}`
8295
9143
  });
8296
9144
  }).catch((err) => {
8297
- import_utils44.logger.log({
9145
+ import_utils49.logger.log({
8298
9146
  level: "error",
8299
9147
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
8300
9148
  });
@@ -8307,11 +9155,11 @@ function useBuildingUnitRepo() {
8307
9155
  delCachedData();
8308
9156
  return res.insertedId;
8309
9157
  } catch (error) {
8310
- import_utils44.logger.log({
9158
+ import_utils49.logger.log({
8311
9159
  level: "error",
8312
9160
  message: error.message
8313
9161
  });
8314
- if (error instanceof import_utils44.AppError) {
9162
+ if (error instanceof import_utils49.AppError) {
8315
9163
  throw error;
8316
9164
  } else {
8317
9165
  throw new Error("Failed to create building unit.");
@@ -8321,12 +9169,12 @@ function useBuildingUnitRepo() {
8321
9169
  async function updateById(_id, value, session) {
8322
9170
  const { error } = schemaUpdateOptions.validate(value);
8323
9171
  if (error) {
8324
- throw new import_utils44.BadRequestError(error.message);
9172
+ throw new import_utils49.BadRequestError(error.message);
8325
9173
  }
8326
9174
  try {
8327
- _id = new import_mongodb22.ObjectId(_id);
9175
+ _id = new import_mongodb24.ObjectId(_id);
8328
9176
  } catch (error2) {
8329
- throw new import_utils44.BadRequestError("Invalid ID.");
9177
+ throw new import_utils49.BadRequestError("Invalid ID.");
8330
9178
  }
8331
9179
  try {
8332
9180
  const res = await collection.updateOne(
@@ -8337,11 +9185,11 @@ function useBuildingUnitRepo() {
8337
9185
  delCachedData();
8338
9186
  return res;
8339
9187
  } catch (error2) {
8340
- import_utils44.logger.log({
9188
+ import_utils49.logger.log({
8341
9189
  level: "error",
8342
9190
  message: error2.message
8343
9191
  });
8344
- if (error2 instanceof import_utils44.AppError) {
9192
+ if (error2 instanceof import_utils49.AppError) {
8345
9193
  throw error2;
8346
9194
  } else {
8347
9195
  throw new Error("Failed to create building unit.");
@@ -8351,12 +9199,12 @@ function useBuildingUnitRepo() {
8351
9199
  async function updateByBuildingId(building, value, session) {
8352
9200
  const { error } = schemaUpdateOptions.validate(value);
8353
9201
  if (error) {
8354
- throw new import_utils44.BadRequestError(error.message);
9202
+ throw new import_utils49.BadRequestError(error.message);
8355
9203
  }
8356
9204
  try {
8357
- building = new import_mongodb22.ObjectId(building);
9205
+ building = new import_mongodb24.ObjectId(building);
8358
9206
  } catch (error2) {
8359
- throw new import_utils44.BadRequestError("Invalid building ID.");
9207
+ throw new import_utils49.BadRequestError("Invalid building ID.");
8360
9208
  }
8361
9209
  try {
8362
9210
  const res = await collection.updateMany(
@@ -8367,11 +9215,11 @@ function useBuildingUnitRepo() {
8367
9215
  delCachedData();
8368
9216
  return res;
8369
9217
  } catch (error2) {
8370
- import_utils44.logger.log({
9218
+ import_utils49.logger.log({
8371
9219
  level: "error",
8372
9220
  message: error2.message
8373
9221
  });
8374
- if (error2 instanceof import_utils44.AppError) {
9222
+ if (error2 instanceof import_utils49.AppError) {
8375
9223
  throw error2;
8376
9224
  } else {
8377
9225
  throw new Error("Failed to update building unit.");
@@ -8398,16 +9246,16 @@ function useBuildingUnitRepo() {
8398
9246
  }
8399
9247
  if (school) {
8400
9248
  try {
8401
- query.school = new import_mongodb22.ObjectId(school);
9249
+ query.school = new import_mongodb24.ObjectId(school);
8402
9250
  } catch (error) {
8403
- throw new import_utils44.BadRequestError("Invalid school ID.");
9251
+ throw new import_utils49.BadRequestError("Invalid school ID.");
8404
9252
  }
8405
9253
  }
8406
9254
  if (building) {
8407
9255
  try {
8408
- query.building = new import_mongodb22.ObjectId(building);
9256
+ query.building = new import_mongodb24.ObjectId(building);
8409
9257
  } catch (error) {
8410
- throw new import_utils44.BadRequestError("Invalid building ID.");
9258
+ throw new import_utils49.BadRequestError("Invalid building ID.");
8411
9259
  }
8412
9260
  }
8413
9261
  const cacheParams = {
@@ -8423,15 +9271,15 @@ function useBuildingUnitRepo() {
8423
9271
  cacheParams.building = building;
8424
9272
  if (status !== "active")
8425
9273
  cacheParams.status = status;
8426
- const cacheKey = (0, import_utils44.makeCacheKey)(namespace_collection, cacheParams);
8427
- import_utils44.logger.log({
9274
+ const cacheKey = (0, import_utils49.makeCacheKey)(namespace_collection, cacheParams);
9275
+ import_utils49.logger.log({
8428
9276
  level: "info",
8429
9277
  message: `Cache key for getAll building units: ${cacheKey}`
8430
9278
  });
8431
9279
  try {
8432
9280
  const cached = await getCache(cacheKey);
8433
9281
  if (cached) {
8434
- import_utils44.logger.log({
9282
+ import_utils49.logger.log({
8435
9283
  level: "info",
8436
9284
  message: `Cache hit for getAll building units: ${cacheKey}`
8437
9285
  });
@@ -8444,35 +9292,35 @@ function useBuildingUnitRepo() {
8444
9292
  { $limit: limit }
8445
9293
  ]).toArray();
8446
9294
  const length = await collection.countDocuments(query);
8447
- const data = (0, import_utils44.paginate)(items, page, limit, length);
9295
+ const data = (0, import_utils49.paginate)(items, page, limit, length);
8448
9296
  setCache(cacheKey, data, 600).then(() => {
8449
- import_utils44.logger.log({
9297
+ import_utils49.logger.log({
8450
9298
  level: "info",
8451
9299
  message: `Cache set for getAll building units: ${cacheKey}`
8452
9300
  });
8453
9301
  }).catch((err) => {
8454
- import_utils44.logger.log({
9302
+ import_utils49.logger.log({
8455
9303
  level: "error",
8456
9304
  message: `Failed to set cache for getAll building units: ${err.message}`
8457
9305
  });
8458
9306
  });
8459
9307
  return data;
8460
9308
  } catch (error) {
8461
- import_utils44.logger.log({ level: "error", message: `${error}` });
9309
+ import_utils49.logger.log({ level: "error", message: `${error}` });
8462
9310
  throw error;
8463
9311
  }
8464
9312
  }
8465
9313
  async function getById(_id) {
8466
9314
  try {
8467
- _id = new import_mongodb22.ObjectId(_id);
9315
+ _id = new import_mongodb24.ObjectId(_id);
8468
9316
  } catch (error) {
8469
- throw new import_utils44.BadRequestError("Invalid ID.");
9317
+ throw new import_utils49.BadRequestError("Invalid ID.");
8470
9318
  }
8471
- const cacheKey = (0, import_utils44.makeCacheKey)(namespace_collection, { _id: String(_id) });
9319
+ const cacheKey = (0, import_utils49.makeCacheKey)(namespace_collection, { _id: String(_id) });
8472
9320
  try {
8473
9321
  const cached = await getCache(cacheKey);
8474
9322
  if (cached) {
8475
- import_utils44.logger.log({
9323
+ import_utils49.logger.log({
8476
9324
  level: "info",
8477
9325
  message: `Cache hit for getById building unit: ${cacheKey}`
8478
9326
  });
@@ -8483,42 +9331,42 @@ function useBuildingUnitRepo() {
8483
9331
  deletedAt: { $in: ["", null] }
8484
9332
  });
8485
9333
  if (!result) {
8486
- throw new import_utils44.BadRequestError("Building unit not found.");
9334
+ throw new import_utils49.BadRequestError("Building unit not found.");
8487
9335
  }
8488
9336
  setCache(cacheKey, result, 300).then(() => {
8489
- import_utils44.logger.log({
9337
+ import_utils49.logger.log({
8490
9338
  level: "info",
8491
9339
  message: `Cache set for building unit by id: ${cacheKey}`
8492
9340
  });
8493
9341
  }).catch((err) => {
8494
- import_utils44.logger.log({
9342
+ import_utils49.logger.log({
8495
9343
  level: "error",
8496
9344
  message: `Failed to set cache for building unit by id: ${err.message}`
8497
9345
  });
8498
9346
  });
8499
9347
  return result;
8500
9348
  } catch (error) {
8501
- if (error instanceof import_utils44.AppError) {
9349
+ if (error instanceof import_utils49.AppError) {
8502
9350
  throw error;
8503
9351
  } else {
8504
- throw new import_utils44.InternalServerError("Failed to get building unit.");
9352
+ throw new import_utils49.InternalServerError("Failed to get building unit.");
8505
9353
  }
8506
9354
  }
8507
9355
  }
8508
9356
  async function getByBuildingLevel(building, level) {
8509
9357
  try {
8510
- building = new import_mongodb22.ObjectId(building);
9358
+ building = new import_mongodb24.ObjectId(building);
8511
9359
  } catch (error) {
8512
- throw new import_utils44.BadRequestError("Invalid building ID.");
9360
+ throw new import_utils49.BadRequestError("Invalid building ID.");
8513
9361
  }
8514
- const cacheKey = (0, import_utils44.makeCacheKey)(namespace_collection, {
9362
+ const cacheKey = (0, import_utils49.makeCacheKey)(namespace_collection, {
8515
9363
  building: String(building),
8516
9364
  level
8517
9365
  });
8518
9366
  try {
8519
9367
  const cached = await getCache(cacheKey);
8520
9368
  if (cached) {
8521
- import_utils44.logger.log({
9369
+ import_utils49.logger.log({
8522
9370
  level: "info",
8523
9371
  message: `Cache hit for getById building unit: ${cacheKey}`
8524
9372
  });
@@ -8530,38 +9378,38 @@ function useBuildingUnitRepo() {
8530
9378
  status: "active"
8531
9379
  });
8532
9380
  setCache(cacheKey, result, 300).then(() => {
8533
- import_utils44.logger.log({
9381
+ import_utils49.logger.log({
8534
9382
  level: "info",
8535
9383
  message: `Cache set for building unit by id: ${cacheKey}`
8536
9384
  });
8537
9385
  }).catch((err) => {
8538
- import_utils44.logger.log({
9386
+ import_utils49.logger.log({
8539
9387
  level: "error",
8540
9388
  message: `Failed to set cache for building unit by id: ${err.message}`
8541
9389
  });
8542
9390
  });
8543
9391
  return result;
8544
9392
  } catch (error) {
8545
- if (error instanceof import_utils44.AppError) {
9393
+ if (error instanceof import_utils49.AppError) {
8546
9394
  throw error;
8547
9395
  } else {
8548
- throw new import_utils44.InternalServerError("Failed to get building unit.");
9396
+ throw new import_utils49.InternalServerError("Failed to get building unit.");
8549
9397
  }
8550
9398
  }
8551
9399
  }
8552
9400
  async function getByBuilding(building) {
8553
9401
  try {
8554
- building = new import_mongodb22.ObjectId(building);
9402
+ building = new import_mongodb24.ObjectId(building);
8555
9403
  } catch (error) {
8556
- throw new import_utils44.BadRequestError("Invalid building ID.");
9404
+ throw new import_utils49.BadRequestError("Invalid building ID.");
8557
9405
  }
8558
- const cacheKey = (0, import_utils44.makeCacheKey)(namespace_collection, {
9406
+ const cacheKey = (0, import_utils49.makeCacheKey)(namespace_collection, {
8559
9407
  building: String(building)
8560
9408
  });
8561
9409
  try {
8562
9410
  const cached = await getCache(cacheKey);
8563
9411
  if (cached) {
8564
- import_utils44.logger.log({
9412
+ import_utils49.logger.log({
8565
9413
  level: "info",
8566
9414
  message: `Cache hit for getById building unit: ${cacheKey}`
8567
9415
  });
@@ -8572,30 +9420,30 @@ function useBuildingUnitRepo() {
8572
9420
  status: "active"
8573
9421
  });
8574
9422
  setCache(cacheKey, result, 300).then(() => {
8575
- import_utils44.logger.log({
9423
+ import_utils49.logger.log({
8576
9424
  level: "info",
8577
9425
  message: `Cache set for building unit by id: ${cacheKey}`
8578
9426
  });
8579
9427
  }).catch((err) => {
8580
- import_utils44.logger.log({
9428
+ import_utils49.logger.log({
8581
9429
  level: "error",
8582
9430
  message: `Failed to set cache for building unit by id: ${err.message}`
8583
9431
  });
8584
9432
  });
8585
9433
  return result;
8586
9434
  } catch (error) {
8587
- if (error instanceof import_utils44.AppError) {
9435
+ if (error instanceof import_utils49.AppError) {
8588
9436
  throw error;
8589
9437
  } else {
8590
- throw new import_utils44.InternalServerError("Failed to get building unit.");
9438
+ throw new import_utils49.InternalServerError("Failed to get building unit.");
8591
9439
  }
8592
9440
  }
8593
9441
  }
8594
9442
  async function deleteById(_id, session) {
8595
9443
  try {
8596
- _id = new import_mongodb22.ObjectId(_id);
9444
+ _id = new import_mongodb24.ObjectId(_id);
8597
9445
  } catch (error) {
8598
- throw new import_utils44.BadRequestError("Invalid ID.");
9446
+ throw new import_utils49.BadRequestError("Invalid ID.");
8599
9447
  }
8600
9448
  try {
8601
9449
  const res = await collection.updateOne(
@@ -8606,11 +9454,11 @@ function useBuildingUnitRepo() {
8606
9454
  delCachedData();
8607
9455
  return "Room/Facility deleted successfully.";
8608
9456
  } catch (error) {
8609
- import_utils44.logger.log({
9457
+ import_utils49.logger.log({
8610
9458
  level: "error",
8611
9459
  message: error.message
8612
9460
  });
8613
- if (error instanceof import_utils44.AppError) {
9461
+ if (error instanceof import_utils49.AppError) {
8614
9462
  throw error;
8615
9463
  } else {
8616
9464
  throw new Error("Failed to deleted room/facility.");
@@ -8640,16 +9488,16 @@ function useBuildingService() {
8640
9488
  const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
8641
9489
  async function updateById(id, data) {
8642
9490
  data.levels = Number(data.levels);
8643
- const session = import_utils45.useAtlas.getClient()?.startSession();
9491
+ const session = import_utils50.useAtlas.getClient()?.startSession();
8644
9492
  try {
8645
9493
  const building = await _getById(id);
8646
9494
  if (!building) {
8647
- throw new import_utils45.NotFoundError("Building not found.");
9495
+ throw new import_utils50.NotFoundError("Building not found.");
8648
9496
  }
8649
9497
  if (data.levels < building.levels) {
8650
9498
  const unit = await getByBuildingLevel(id, building.levels);
8651
9499
  if (unit) {
8652
- throw new import_utils45.BadRequestError(
9500
+ throw new import_utils50.BadRequestError(
8653
9501
  "Cannot reduce floors, there are existing building units at higher floors."
8654
9502
  );
8655
9503
  }
@@ -8671,7 +9519,7 @@ function useBuildingService() {
8671
9519
  async function deleteById(id) {
8672
9520
  const building = await getByBuilding(id);
8673
9521
  if (building) {
8674
- throw new import_utils45.BadRequestError(
9522
+ throw new import_utils50.BadRequestError(
8675
9523
  "Cannot delete building with existing room/facility. Please delete room/facility first."
8676
9524
  );
8677
9525
  }
@@ -8689,24 +9537,24 @@ function useBuildingService() {
8689
9537
  }
8690
9538
 
8691
9539
  // src/resources/building/building.controller.ts
8692
- var import_utils46 = require("@goweekdays/utils");
8693
- var import_joi32 = __toESM(require("joi"));
9540
+ var import_utils51 = require("@goweekdays/utils");
9541
+ var import_joi38 = __toESM(require("joi"));
8694
9542
  function useBuildingController() {
8695
9543
  const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
8696
9544
  const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
8697
9545
  async function createBuilding(req, res, next) {
8698
9546
  const value = req.body;
8699
- const validation = import_joi32.default.object({
8700
- name: import_joi32.default.string().required(),
8701
- school: import_joi32.default.string().hex().required(),
8702
- levels: import_joi32.default.number().integer().min(1).required(),
8703
- serial: import_joi32.default.string().optional().allow("", null),
8704
- status: import_joi32.default.string().optional().allow("", null)
9547
+ const validation = import_joi38.default.object({
9548
+ name: import_joi38.default.string().required(),
9549
+ school: import_joi38.default.string().hex().required(),
9550
+ levels: import_joi38.default.number().integer().min(1).required(),
9551
+ serial: import_joi38.default.string().optional().allow("", null),
9552
+ status: import_joi38.default.string().optional().allow("", null)
8705
9553
  });
8706
9554
  const { error } = validation.validate(value);
8707
9555
  if (error) {
8708
- next(new import_utils46.BadRequestError(error.message));
8709
- import_utils46.logger.info(`Controller: ${error.message}`);
9556
+ next(new import_utils51.BadRequestError(error.message));
9557
+ import_utils51.logger.info(`Controller: ${error.message}`);
8710
9558
  return;
8711
9559
  }
8712
9560
  try {
@@ -8720,18 +9568,18 @@ function useBuildingController() {
8720
9568
  async function updateById(req, res, next) {
8721
9569
  const value = req.body;
8722
9570
  const id = req.params.id ?? "";
8723
- const validation = import_joi32.default.object({
8724
- id: import_joi32.default.string().hex().required(),
8725
- value: import_joi32.default.object({
8726
- name: import_joi32.default.string().required(),
8727
- serial: import_joi32.default.string().optional().allow("", null),
8728
- levels: import_joi32.default.number().integer().min(1).required()
9571
+ const validation = import_joi38.default.object({
9572
+ id: import_joi38.default.string().hex().required(),
9573
+ value: import_joi38.default.object({
9574
+ name: import_joi38.default.string().required(),
9575
+ serial: import_joi38.default.string().optional().allow("", null),
9576
+ levels: import_joi38.default.number().integer().min(1).required()
8729
9577
  })
8730
9578
  });
8731
9579
  const { error } = validation.validate({ id, value });
8732
9580
  if (error) {
8733
- next(new import_utils46.BadRequestError(error.message));
8734
- import_utils46.logger.info(`Controller: ${error.message}`);
9581
+ next(new import_utils51.BadRequestError(error.message));
9582
+ import_utils51.logger.info(`Controller: ${error.message}`);
8735
9583
  return;
8736
9584
  }
8737
9585
  try {
@@ -8744,16 +9592,16 @@ function useBuildingController() {
8744
9592
  }
8745
9593
  async function getAll(req, res, next) {
8746
9594
  const query = req.query;
8747
- const validation = import_joi32.default.object({
8748
- page: import_joi32.default.number().min(1).optional().allow("", null),
8749
- limit: import_joi32.default.number().min(1).optional().allow("", null),
8750
- search: import_joi32.default.string().optional().allow("", null),
8751
- school: import_joi32.default.string().hex().optional().allow("", null),
8752
- status: import_joi32.default.string().optional().allow("", null)
9595
+ const validation = import_joi38.default.object({
9596
+ page: import_joi38.default.number().min(1).optional().allow("", null),
9597
+ limit: import_joi38.default.number().min(1).optional().allow("", null),
9598
+ search: import_joi38.default.string().optional().allow("", null),
9599
+ school: import_joi38.default.string().hex().optional().allow("", null),
9600
+ status: import_joi38.default.string().optional().allow("", null)
8753
9601
  });
8754
9602
  const { error } = validation.validate(query);
8755
9603
  if (error) {
8756
- next(new import_utils46.BadRequestError(error.message));
9604
+ next(new import_utils51.BadRequestError(error.message));
8757
9605
  return;
8758
9606
  }
8759
9607
  const page = parseInt(req.query.page) ?? 1;
@@ -8787,12 +9635,12 @@ function useBuildingController() {
8787
9635
  }
8788
9636
  async function getById(req, res, next) {
8789
9637
  const id = req.params.id;
8790
- const validation = import_joi32.default.object({
8791
- id: import_joi32.default.string().hex().required()
9638
+ const validation = import_joi38.default.object({
9639
+ id: import_joi38.default.string().hex().required()
8792
9640
  });
8793
9641
  const { error } = validation.validate({ id });
8794
9642
  if (error) {
8795
- next(new import_utils46.BadRequestError(error.message));
9643
+ next(new import_utils51.BadRequestError(error.message));
8796
9644
  return;
8797
9645
  }
8798
9646
  try {
@@ -8808,12 +9656,12 @@ function useBuildingController() {
8808
9656
  }
8809
9657
  async function deleteById(req, res, next) {
8810
9658
  const id = req.params.id;
8811
- const validation = import_joi32.default.object({
8812
- id: import_joi32.default.string().hex().required()
9659
+ const validation = import_joi38.default.object({
9660
+ id: import_joi38.default.string().hex().required()
8813
9661
  });
8814
9662
  const { error } = validation.validate({ id });
8815
9663
  if (error) {
8816
- next(new import_utils46.BadRequestError(error.message));
9664
+ next(new import_utils51.BadRequestError(error.message));
8817
9665
  return;
8818
9666
  }
8819
9667
  try {
@@ -8834,11 +9682,11 @@ function useBuildingController() {
8834
9682
  }
8835
9683
 
8836
9684
  // src/resources/building/building-unit.service.ts
8837
- var import_utils47 = require("@goweekdays/utils");
9685
+ var import_utils52 = require("@goweekdays/utils");
8838
9686
  function useBuildingUnitService() {
8839
9687
  const { add: _add } = useBuildingUnitRepo();
8840
9688
  async function add(value) {
8841
- const session = import_utils47.useAtlas.getClient()?.startSession();
9689
+ const session = import_utils52.useAtlas.getClient()?.startSession();
8842
9690
  if (!session) {
8843
9691
  throw new Error("Unable to start session for building unit service.");
8844
9692
  }
@@ -8865,8 +9713,8 @@ function useBuildingUnitService() {
8865
9713
  }
8866
9714
 
8867
9715
  // src/resources/building/building-unit.controller.ts
8868
- var import_utils48 = require("@goweekdays/utils");
8869
- var import_joi33 = __toESM(require("joi"));
9716
+ var import_utils53 = require("@goweekdays/utils");
9717
+ var import_joi39 = __toESM(require("joi"));
8870
9718
  function useBuildingUnitController() {
8871
9719
  const {
8872
9720
  getAll: _getAll,
@@ -8877,27 +9725,27 @@ function useBuildingUnitController() {
8877
9725
  const { add: _add } = useBuildingUnitService();
8878
9726
  async function add(req, res, next) {
8879
9727
  const data = req.body;
8880
- const validation = import_joi33.default.object({
8881
- building: import_joi33.default.object({
8882
- school: import_joi33.default.string().hex().required(),
8883
- name: import_joi33.default.string().optional().allow("", null),
8884
- building: import_joi33.default.string().hex().required(),
8885
- buildingName: import_joi33.default.string().optional().allow("", null),
8886
- level: import_joi33.default.number().integer().min(1).required(),
8887
- category: import_joi33.default.string().required(),
8888
- type: import_joi33.default.string().required(),
8889
- seating_capacity: import_joi33.default.number().integer().min(0).required(),
8890
- standing_capacity: import_joi33.default.number().integer().min(0).required(),
8891
- description: import_joi33.default.string().optional().allow("", null),
8892
- unit_of_measurement: import_joi33.default.string().valid("sqm").required(),
8893
- area: import_joi33.default.number().positive().required(),
8894
- status: import_joi33.default.string().optional().allow("", null)
9728
+ const validation = import_joi39.default.object({
9729
+ building: import_joi39.default.object({
9730
+ school: import_joi39.default.string().hex().required(),
9731
+ name: import_joi39.default.string().optional().allow("", null),
9732
+ building: import_joi39.default.string().hex().required(),
9733
+ buildingName: import_joi39.default.string().optional().allow("", null),
9734
+ level: import_joi39.default.number().integer().min(1).required(),
9735
+ category: import_joi39.default.string().required(),
9736
+ type: import_joi39.default.string().required(),
9737
+ seating_capacity: import_joi39.default.number().integer().min(0).required(),
9738
+ standing_capacity: import_joi39.default.number().integer().min(0).required(),
9739
+ description: import_joi39.default.string().optional().allow("", null),
9740
+ unit_of_measurement: import_joi39.default.string().valid("sqm").required(),
9741
+ area: import_joi39.default.number().positive().required(),
9742
+ status: import_joi39.default.string().optional().allow("", null)
8895
9743
  }),
8896
- qty: import_joi33.default.number().integer().min(1).max(20).optional().default(1)
9744
+ qty: import_joi39.default.number().integer().min(1).max(20).optional().default(1)
8897
9745
  });
8898
9746
  const { error } = validation.validate(data);
8899
9747
  if (error) {
8900
- next(new import_utils48.BadRequestError(error.message));
9748
+ next(new import_utils53.BadRequestError(error.message));
8901
9749
  return;
8902
9750
  }
8903
9751
  try {
@@ -8913,13 +9761,13 @@ function useBuildingUnitController() {
8913
9761
  async function updateById(req, res, next) {
8914
9762
  const data = req.body;
8915
9763
  const id = req.params.id ?? "";
8916
- const validation = import_joi33.default.object({
8917
- id: import_joi33.default.string().hex().required(),
9764
+ const validation = import_joi39.default.object({
9765
+ id: import_joi39.default.string().hex().required(),
8918
9766
  value: schemaUpdateOptions
8919
9767
  });
8920
9768
  const { error } = validation.validate({ id, value: data });
8921
9769
  if (error) {
8922
- next(new import_utils48.BadRequestError(error.message));
9770
+ next(new import_utils53.BadRequestError(error.message));
8923
9771
  return;
8924
9772
  }
8925
9773
  try {
@@ -8934,17 +9782,17 @@ function useBuildingUnitController() {
8934
9782
  }
8935
9783
  async function getAll(req, res, next) {
8936
9784
  const query = req.query;
8937
- const validation = import_joi33.default.object({
8938
- page: import_joi33.default.number().min(1).optional().allow("", null),
8939
- limit: import_joi33.default.number().min(1).optional().allow("", null),
8940
- search: import_joi33.default.string().optional().allow("", null),
8941
- school: import_joi33.default.string().hex().optional().allow("", null),
8942
- building: import_joi33.default.string().hex().optional().allow("", null),
8943
- status: import_joi33.default.string().optional().allow("", null)
9785
+ const validation = import_joi39.default.object({
9786
+ page: import_joi39.default.number().min(1).optional().allow("", null),
9787
+ limit: import_joi39.default.number().min(1).optional().allow("", null),
9788
+ search: import_joi39.default.string().optional().allow("", null),
9789
+ school: import_joi39.default.string().hex().optional().allow("", null),
9790
+ building: import_joi39.default.string().hex().optional().allow("", null),
9791
+ status: import_joi39.default.string().optional().allow("", null)
8944
9792
  });
8945
9793
  const { error } = validation.validate(query);
8946
9794
  if (error) {
8947
- next(new import_utils48.BadRequestError(error.message));
9795
+ next(new import_utils53.BadRequestError(error.message));
8948
9796
  return;
8949
9797
  }
8950
9798
  const page = parseInt(req.query.page) ?? 1;
@@ -8980,12 +9828,12 @@ function useBuildingUnitController() {
8980
9828
  }
8981
9829
  async function getById(req, res, next) {
8982
9830
  const id = req.params.id;
8983
- const validation = import_joi33.default.object({
8984
- id: import_joi33.default.string().hex().required()
9831
+ const validation = import_joi39.default.object({
9832
+ id: import_joi39.default.string().hex().required()
8985
9833
  });
8986
9834
  const { error } = validation.validate({ id });
8987
9835
  if (error) {
8988
- next(new import_utils48.BadRequestError(error.message));
9836
+ next(new import_utils53.BadRequestError(error.message));
8989
9837
  return;
8990
9838
  }
8991
9839
  try {
@@ -9001,12 +9849,12 @@ function useBuildingUnitController() {
9001
9849
  }
9002
9850
  async function deleteById(req, res, next) {
9003
9851
  const id = req.params.id;
9004
- const validation = import_joi33.default.object({
9005
- id: import_joi33.default.string().hex().required()
9852
+ const validation = import_joi39.default.object({
9853
+ id: import_joi39.default.string().hex().required()
9006
9854
  });
9007
9855
  const { error } = validation.validate({ id });
9008
9856
  if (error) {
9009
- next(new import_utils48.BadRequestError(error.message));
9857
+ next(new import_utils53.BadRequestError(error.message));
9010
9858
  return;
9011
9859
  }
9012
9860
  try {
@@ -9027,14 +9875,14 @@ function useBuildingUnitController() {
9027
9875
  }
9028
9876
 
9029
9877
  // src/resources/counter/counter.model.ts
9030
- var import_utils49 = require("@goweekdays/utils");
9031
- var import_mongodb23 = require("mongodb");
9878
+ var import_utils54 = require("@goweekdays/utils");
9879
+ var import_mongodb25 = require("mongodb");
9032
9880
  var import_zod = require("zod");
9033
9881
  var TCounter = import_zod.z.object({
9034
9882
  _id: import_zod.z.union([
9035
9883
  import_zod.z.string().length(24, "Invalid ObjectId hex string"),
9036
- import_zod.z.instanceof(import_mongodb23.ObjectId)
9037
- ]).transform((val) => typeof val === "string" ? new import_mongodb23.ObjectId(val) : val).optional(),
9884
+ import_zod.z.instanceof(import_mongodb25.ObjectId)
9885
+ ]).transform((val) => typeof val === "string" ? new import_mongodb25.ObjectId(val) : val).optional(),
9038
9886
  count: import_zod.z.number().int().min(0).default(0),
9039
9887
  type: import_zod.z.string(),
9040
9888
  createdAt: import_zod.z.date().optional().default(() => /* @__PURE__ */ new Date()),
@@ -9047,7 +9895,7 @@ function useCounterModel(db) {
9047
9895
  try {
9048
9896
  return TCounter.parse(value);
9049
9897
  } catch (error) {
9050
- throw new import_utils49.BadRequestError(error.issues[0].message);
9898
+ throw new import_utils54.BadRequestError(error.issues[0].message);
9051
9899
  }
9052
9900
  }
9053
9901
  function validateCounter(data) {
@@ -9061,23 +9909,23 @@ function useCounterModel(db) {
9061
9909
  }
9062
9910
 
9063
9911
  // src/resources/counter/counter.repository.ts
9064
- var import_utils50 = require("@goweekdays/utils");
9912
+ var import_utils55 = require("@goweekdays/utils");
9065
9913
  function useCounterRepo() {
9066
- const db = import_utils50.useAtlas.getDb();
9914
+ const db = import_utils55.useAtlas.getDb();
9067
9915
  if (!db) {
9068
9916
  throw new Error("Unable to connect to server.");
9069
9917
  }
9070
9918
  const namespace_collection = "counters";
9071
9919
  const { collection, createCounter } = useCounterModel(db);
9072
- const { getCache, setCache, delNamespace } = (0, import_utils50.useCache)(namespace_collection);
9920
+ const { getCache, setCache, delNamespace } = (0, import_utils55.useCache)(namespace_collection);
9073
9921
  function delCachedData() {
9074
9922
  delNamespace().then(() => {
9075
- import_utils50.logger.log({
9923
+ import_utils55.logger.log({
9076
9924
  level: "info",
9077
9925
  message: `Cache namespace cleared for ${namespace_collection}`
9078
9926
  });
9079
9927
  }).catch((err) => {
9080
- import_utils50.logger.log({
9928
+ import_utils55.logger.log({
9081
9929
  level: "error",
9082
9930
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
9083
9931
  });
@@ -9121,11 +9969,11 @@ function useCounterRepo() {
9121
9969
  }
9122
9970
  }
9123
9971
  async function getByType(type) {
9124
- const cacheKey = (0, import_utils50.makeCacheKey)(namespace_collection, { type });
9972
+ const cacheKey = (0, import_utils55.makeCacheKey)(namespace_collection, { type });
9125
9973
  try {
9126
9974
  const cached = await getCache(cacheKey);
9127
9975
  if (cached) {
9128
- import_utils50.logger.log({
9976
+ import_utils55.logger.log({
9129
9977
  level: "info",
9130
9978
  message: `Cache hit for getByType counter: ${cacheKey}`
9131
9979
  });
@@ -9134,12 +9982,12 @@ function useCounterRepo() {
9134
9982
  const data = await collection.findOne({ type });
9135
9983
  if (data) {
9136
9984
  setCache(cacheKey, data, 300).then(() => {
9137
- import_utils50.logger.log({
9985
+ import_utils55.logger.log({
9138
9986
  level: "info",
9139
9987
  message: `Cache set for counter by type: ${cacheKey}`
9140
9988
  });
9141
9989
  }).catch((err) => {
9142
- import_utils50.logger.log({
9990
+ import_utils55.logger.log({
9143
9991
  level: "error",
9144
9992
  message: `Failed to set cache for counter by type: ${err.message}`
9145
9993
  });
@@ -9159,7 +10007,7 @@ function useCounterRepo() {
9159
10007
  }
9160
10008
 
9161
10009
  // src/resources/file/file.service.ts
9162
- var import_utils51 = require("@goweekdays/utils");
10010
+ var import_utils56 = require("@goweekdays/utils");
9163
10011
  var import_node_cron = __toESM(require("node-cron"));
9164
10012
  var fs = __toESM(require("fs"));
9165
10013
  function useFileService() {
@@ -9168,7 +10016,7 @@ function useFileService() {
9168
10016
  deleteFileById,
9169
10017
  getAllDraftedFiles
9170
10018
  } = useFileRepo();
9171
- const s3 = new import_utils51.useS3({
10019
+ const s3 = new import_utils56.useS3({
9172
10020
  accessKeyId: SPACES_ACCESS_KEY,
9173
10021
  secretAccessKey: SPACES_SECRET_KEY,
9174
10022
  endpoint: SPACES_ENDPOINT,
@@ -9177,7 +10025,7 @@ function useFileService() {
9177
10025
  forcePathStyle: true
9178
10026
  });
9179
10027
  async function createFile(value) {
9180
- const session = import_utils51.useAtlas.getClient()?.startSession();
10028
+ const session = import_utils56.useAtlas.getClient()?.startSession();
9181
10029
  session?.startTransaction();
9182
10030
  const file = {
9183
10031
  name: value.originalname,
@@ -9211,7 +10059,7 @@ function useFileService() {
9211
10059
  }
9212
10060
  }
9213
10061
  async function deleteFile(id) {
9214
- const session = import_utils51.useAtlas.getClient()?.startSession();
10062
+ const session = import_utils56.useAtlas.getClient()?.startSession();
9215
10063
  session?.startTransaction();
9216
10064
  try {
9217
10065
  await deleteFileById(id, session);
@@ -9232,12 +10080,12 @@ function useFileService() {
9232
10080
  const file = files[index];
9233
10081
  try {
9234
10082
  await deleteFile(file._id.toString());
9235
- await import_utils51.logger.log({
10083
+ await import_utils56.logger.log({
9236
10084
  level: "info",
9237
10085
  message: "Successfully deleted draft files."
9238
10086
  });
9239
10087
  } catch (error) {
9240
- import_utils51.logger.log({
10088
+ import_utils56.logger.log({
9241
10089
  level: "info",
9242
10090
  message: "Successfully deleted draft files."
9243
10091
  });
@@ -9254,8 +10102,8 @@ function useFileService() {
9254
10102
  }
9255
10103
 
9256
10104
  // src/resources/file/file.controller.ts
9257
- var import_utils52 = require("@goweekdays/utils");
9258
- var import_joi34 = __toESM(require("joi"));
10105
+ var import_utils57 = require("@goweekdays/utils");
10106
+ var import_joi40 = __toESM(require("joi"));
9259
10107
  function useFileController() {
9260
10108
  const { createFile, deleteFile: _deleteFile } = useFileService();
9261
10109
  async function upload(req, res, next) {
@@ -9268,29 +10116,29 @@ function useFileController() {
9268
10116
  res.json({ message: "Successfully uploaded file", id });
9269
10117
  return;
9270
10118
  } catch (error) {
9271
- if (error instanceof import_utils52.AppError) {
10119
+ if (error instanceof import_utils57.AppError) {
9272
10120
  next(error);
9273
10121
  } else {
9274
- next(new import_utils52.InternalServerError(error));
10122
+ next(new import_utils57.InternalServerError(error));
9275
10123
  }
9276
10124
  }
9277
10125
  }
9278
10126
  async function deleteFile(req, res, next) {
9279
10127
  const id = req.params.id;
9280
- const validation = import_joi34.default.string().required();
10128
+ const validation = import_joi40.default.string().required();
9281
10129
  const { error } = validation.validate(id);
9282
10130
  if (error) {
9283
- next(new import_utils52.BadRequestError(error.message));
10131
+ next(new import_utils57.BadRequestError(error.message));
9284
10132
  }
9285
10133
  try {
9286
10134
  const message = await _deleteFile(id);
9287
10135
  res.json({ message });
9288
10136
  return;
9289
10137
  } catch (error2) {
9290
- if (error2 instanceof import_utils52.AppError) {
10138
+ if (error2 instanceof import_utils57.AppError) {
9291
10139
  next(error2);
9292
10140
  } else {
9293
- next(new import_utils52.InternalServerError(error2));
10141
+ next(new import_utils57.InternalServerError(error2));
9294
10142
  }
9295
10143
  }
9296
10144
  }
@@ -9301,35 +10149,35 @@ function useFileController() {
9301
10149
  }
9302
10150
 
9303
10151
  // src/resources/promo/promo.model.ts
9304
- var import_joi35 = __toESM(require("joi"));
9305
- var schemaPromo = import_joi35.default.object({
9306
- code: import_joi35.default.string().min(3).max(50).required(),
9307
- description: import_joi35.default.string().max(255).optional().allow("", null),
9308
- type: import_joi35.default.string().valid("flat", "fixed", "tiered").required(),
9309
- flatRate: import_joi35.default.number().positive().when("type", {
10152
+ var import_joi41 = __toESM(require("joi"));
10153
+ var schemaPromo = import_joi41.default.object({
10154
+ code: import_joi41.default.string().min(3).max(50).required(),
10155
+ description: import_joi41.default.string().max(255).optional().allow("", null),
10156
+ type: import_joi41.default.string().valid("flat", "fixed", "tiered").required(),
10157
+ flatRate: import_joi41.default.number().positive().when("type", {
9310
10158
  is: "flat",
9311
- then: import_joi35.default.required(),
9312
- otherwise: import_joi35.default.forbidden()
10159
+ then: import_joi41.default.required(),
10160
+ otherwise: import_joi41.default.forbidden()
9313
10161
  }).optional().allow(null, 0),
9314
- fixedRate: import_joi35.default.number().positive().when("type", {
10162
+ fixedRate: import_joi41.default.number().positive().when("type", {
9315
10163
  is: "fixed",
9316
- then: import_joi35.default.required(),
9317
- otherwise: import_joi35.default.forbidden()
10164
+ then: import_joi41.default.required(),
10165
+ otherwise: import_joi41.default.forbidden()
9318
10166
  }).optional().allow(null, 0),
9319
- tiers: import_joi35.default.array().items(
9320
- import_joi35.default.object({
9321
- minSeats: import_joi35.default.number().integer().min(1).required(),
9322
- maxSeats: import_joi35.default.number().integer().min(import_joi35.default.ref("minSeats")).required(),
9323
- rate: import_joi35.default.number().positive().required()
10167
+ tiers: import_joi41.default.array().items(
10168
+ import_joi41.default.object({
10169
+ minSeats: import_joi41.default.number().integer().min(1).required(),
10170
+ maxSeats: import_joi41.default.number().integer().min(import_joi41.default.ref("minSeats")).required(),
10171
+ rate: import_joi41.default.number().positive().required()
9324
10172
  })
9325
10173
  ).when("type", {
9326
10174
  is: "tiered",
9327
- then: import_joi35.default.required(),
9328
- otherwise: import_joi35.default.forbidden()
10175
+ then: import_joi41.default.required(),
10176
+ otherwise: import_joi41.default.forbidden()
9329
10177
  }),
9330
- currency: import_joi35.default.string().length(3).required(),
9331
- startDate: import_joi35.default.date().required(),
9332
- endDate: import_joi35.default.date().greater(import_joi35.default.ref("startDate")).optional().allow(null, "")
10178
+ currency: import_joi41.default.string().length(3).required(),
10179
+ startDate: import_joi41.default.date().required(),
10180
+ endDate: import_joi41.default.date().greater(import_joi41.default.ref("startDate")).optional().allow(null, "")
9333
10181
  });
9334
10182
  function modelPromo(data) {
9335
10183
  const { error } = schemaPromo.validate(data);
@@ -9357,25 +10205,25 @@ function modelPromo(data) {
9357
10205
  }
9358
10206
 
9359
10207
  // src/resources/promo/promo.repository.ts
9360
- var import_utils53 = require("@goweekdays/utils");
9361
- var import_joi36 = __toESM(require("joi"));
9362
- var import_mongodb24 = require("mongodb");
10208
+ var import_utils58 = require("@goweekdays/utils");
10209
+ var import_joi42 = __toESM(require("joi"));
10210
+ var import_mongodb26 = require("mongodb");
9363
10211
  function usePromoRepo() {
9364
- const db = import_utils53.useAtlas.getDb();
10212
+ const db = import_utils58.useAtlas.getDb();
9365
10213
  if (!db) {
9366
- throw new import_utils53.InternalServerError("Unable to connect to server.");
10214
+ throw new import_utils58.InternalServerError("Unable to connect to server.");
9367
10215
  }
9368
10216
  const namespace_collection = "users";
9369
10217
  const collection = db.collection(namespace_collection);
9370
- const { getCache, setCache, delNamespace } = (0, import_utils53.useCache)(namespace_collection);
10218
+ const { getCache, setCache, delNamespace } = (0, import_utils58.useCache)(namespace_collection);
9371
10219
  function delCachedData() {
9372
10220
  delNamespace().then(() => {
9373
- import_utils53.logger.log({
10221
+ import_utils58.logger.log({
9374
10222
  level: "info",
9375
10223
  message: `Cache namespace cleared for ${namespace_collection}`
9376
10224
  });
9377
10225
  }).catch((err) => {
9378
- import_utils53.logger.log({
10226
+ import_utils58.logger.log({
9379
10227
  level: "error",
9380
10228
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
9381
10229
  });
@@ -9407,7 +10255,7 @@ function usePromoRepo() {
9407
10255
  delCachedData();
9408
10256
  return "Successfully added promo.";
9409
10257
  } catch (error) {
9410
- throw new import_utils53.InternalServerError("Failed to add promo.");
10258
+ throw new import_utils58.InternalServerError("Failed to add promo.");
9411
10259
  }
9412
10260
  }
9413
10261
  async function getAll({
@@ -9428,7 +10276,7 @@ function usePromoRepo() {
9428
10276
  if (search) {
9429
10277
  query.$text = { $search: search };
9430
10278
  }
9431
- const cacheKey = (0, import_utils53.makeCacheKey)(namespace_collection, cacheKeyOptions);
10279
+ const cacheKey = (0, import_utils58.makeCacheKey)(namespace_collection, cacheKeyOptions);
9432
10280
  try {
9433
10281
  const cachedData = await getCache(cacheKey);
9434
10282
  if (cachedData) {
@@ -9440,30 +10288,30 @@ function usePromoRepo() {
9440
10288
  { $limit: limit }
9441
10289
  ]).toArray();
9442
10290
  const length = await collection.countDocuments(query);
9443
- const data = (0, import_utils53.paginate)(items, page, limit, length);
10291
+ const data = (0, import_utils58.paginate)(items, page, limit, length);
9444
10292
  setCache(cacheKey, data).then(() => {
9445
- import_utils53.logger.log({
10293
+ import_utils58.logger.log({
9446
10294
  level: "info",
9447
10295
  message: `Cache set for getAll promo: ${cacheKey}`
9448
10296
  });
9449
10297
  }).catch((err) => {
9450
- import_utils53.logger.log({
10298
+ import_utils58.logger.log({
9451
10299
  level: "error",
9452
10300
  message: `Failed to set cache for getAll promo: ${err.message}`
9453
10301
  });
9454
10302
  });
9455
10303
  return data;
9456
10304
  } catch (error) {
9457
- throw new import_utils53.InternalServerError("Failed to get promos.");
10305
+ throw new import_utils58.InternalServerError("Failed to get promos.");
9458
10306
  }
9459
10307
  }
9460
10308
  async function getByCode(code) {
9461
- const { error } = import_joi36.default.string().min(3).max(50).required().validate(code);
10309
+ const { error } = import_joi42.default.string().min(3).max(50).required().validate(code);
9462
10310
  if (error) {
9463
10311
  throw new Error(`Invalid promo code: ${error.message}`);
9464
10312
  }
9465
10313
  try {
9466
- const cacheKey = (0, import_utils53.makeCacheKey)(namespace_collection, {
10314
+ const cacheKey = (0, import_utils58.makeCacheKey)(namespace_collection, {
9467
10315
  code,
9468
10316
  tag: "getByCode"
9469
10317
  });
@@ -9476,33 +10324,33 @@ function usePromoRepo() {
9476
10324
  status: { $ne: "deleted" }
9477
10325
  });
9478
10326
  setCache(cacheKey, data).then(() => {
9479
- import_utils53.logger.log({
10327
+ import_utils58.logger.log({
9480
10328
  level: "info",
9481
10329
  message: `Cache set for getByCode promo: ${cacheKey}`
9482
10330
  });
9483
10331
  }).catch((err) => {
9484
- import_utils53.logger.log({
10332
+ import_utils58.logger.log({
9485
10333
  level: "error",
9486
10334
  message: `Failed to set cache for getByCode promo: ${err.message}`
9487
10335
  });
9488
10336
  });
9489
10337
  return data;
9490
10338
  } catch (error2) {
9491
- throw new import_utils53.InternalServerError("Failed to get promo.");
10339
+ throw new import_utils58.InternalServerError("Failed to get promo.");
9492
10340
  }
9493
10341
  }
9494
10342
  async function getById(_id) {
9495
- const { error } = import_joi36.default.string().hex().length(24).required().validate(_id);
10343
+ const { error } = import_joi42.default.string().hex().length(24).required().validate(_id);
9496
10344
  if (error) {
9497
10345
  throw new Error(`Invalid promo ID: ${error.message}`);
9498
10346
  }
9499
10347
  try {
9500
- _id = new import_mongodb24.ObjectId(_id);
10348
+ _id = new import_mongodb26.ObjectId(_id);
9501
10349
  } catch (error2) {
9502
- throw new import_utils53.BadRequestError("Invalid promo ID.");
10350
+ throw new import_utils58.BadRequestError("Invalid promo ID.");
9503
10351
  }
9504
10352
  try {
9505
- const cacheKey = (0, import_utils53.makeCacheKey)(namespace_collection, {
10353
+ const cacheKey = (0, import_utils58.makeCacheKey)(namespace_collection, {
9506
10354
  _id: String(_id),
9507
10355
  tag: "getById"
9508
10356
  });
@@ -9515,30 +10363,30 @@ function usePromoRepo() {
9515
10363
  status: { $ne: "deleted" }
9516
10364
  });
9517
10365
  setCache(cacheKey, data).then(() => {
9518
- import_utils53.logger.log({
10366
+ import_utils58.logger.log({
9519
10367
  level: "info",
9520
10368
  message: `Cache set for getById promo: ${cacheKey}`
9521
10369
  });
9522
10370
  }).catch((err) => {
9523
- import_utils53.logger.log({
10371
+ import_utils58.logger.log({
9524
10372
  level: "error",
9525
10373
  message: `Failed to set cache for getById promo: ${err.message}`
9526
10374
  });
9527
10375
  });
9528
10376
  return data;
9529
10377
  } catch (error2) {
9530
- throw new import_utils53.InternalServerError("Failed to get promo.");
10378
+ throw new import_utils58.InternalServerError("Failed to get promo.");
9531
10379
  }
9532
10380
  }
9533
10381
  async function deleteById(_id) {
9534
- const { error } = import_joi36.default.string().hex().length(24).required().validate(_id);
10382
+ const { error } = import_joi42.default.string().hex().length(24).required().validate(_id);
9535
10383
  if (error) {
9536
10384
  throw new Error(`Invalid promo ID: ${error.message}`);
9537
10385
  }
9538
10386
  try {
9539
- _id = new import_mongodb24.ObjectId(_id);
10387
+ _id = new import_mongodb26.ObjectId(_id);
9540
10388
  } catch (error2) {
9541
- throw new import_utils53.BadRequestError("Invalid promo ID.");
10389
+ throw new import_utils58.BadRequestError("Invalid promo ID.");
9542
10390
  }
9543
10391
  try {
9544
10392
  const result = await collection.updateOne(
@@ -9546,15 +10394,15 @@ function usePromoRepo() {
9546
10394
  { $set: { status: "deleted" } }
9547
10395
  );
9548
10396
  if (result.modifiedCount === 0) {
9549
- throw new import_utils53.InternalServerError("Failed to delete promo.");
10397
+ throw new import_utils58.InternalServerError("Failed to delete promo.");
9550
10398
  }
9551
10399
  delCachedData();
9552
10400
  return "Successfully deleted promo.";
9553
10401
  } catch (error2) {
9554
- if (error2 instanceof import_utils53.AppError) {
10402
+ if (error2 instanceof import_utils58.AppError) {
9555
10403
  throw error2;
9556
10404
  }
9557
- throw new import_utils53.InternalServerError("Failed to delete promo.");
10405
+ throw new import_utils58.InternalServerError("Failed to delete promo.");
9558
10406
  }
9559
10407
  }
9560
10408
  return {
@@ -9568,7 +10416,7 @@ function usePromoRepo() {
9568
10416
  }
9569
10417
 
9570
10418
  // src/resources/utils/github.service.ts
9571
- var import_utils54 = require("@goweekdays/utils");
10419
+ var import_utils59 = require("@goweekdays/utils");
9572
10420
  var import_rest = require("@octokit/rest");
9573
10421
  var import_libsodium_wrappers = __toESM(require("libsodium-wrappers"));
9574
10422
  function useGitHubService() {
@@ -9582,23 +10430,23 @@ function useGitHubService() {
9582
10430
  try {
9583
10431
  const { data: repoData } = await octokit.repos.get({ owner, repo });
9584
10432
  if (!repoData.permissions?.admin) {
9585
- throw new import_utils54.BadRequestError(
10433
+ throw new import_utils59.BadRequestError(
9586
10434
  "You do not have admin access to this repository."
9587
10435
  );
9588
10436
  }
9589
10437
  } catch (error) {
9590
10438
  if (error.status === 404) {
9591
- throw new import_utils54.BadRequestError(
10439
+ throw new import_utils59.BadRequestError(
9592
10440
  "Repository not found or you don't have access to it."
9593
10441
  );
9594
10442
  } else if (error.status === 401) {
9595
- throw new import_utils54.BadRequestError(
10443
+ throw new import_utils59.BadRequestError(
9596
10444
  "Invalid GitHub token or insufficient permissions."
9597
10445
  );
9598
10446
  } else if (error.message.includes("admin access")) {
9599
10447
  throw error;
9600
10448
  } else {
9601
- throw new import_utils54.BadRequestError(
10449
+ throw new import_utils59.BadRequestError(
9602
10450
  `Failed to check repository permissions: ${error.message}`
9603
10451
  );
9604
10452
  }
@@ -9647,7 +10495,7 @@ function useGitHubService() {
9647
10495
  key_id: publicKeyRes.key_id
9648
10496
  });
9649
10497
  } catch (encryptionError) {
9650
- throw new import_utils54.BadRequestError(
10498
+ throw new import_utils59.BadRequestError(
9651
10499
  `Failed to encrypt secret '${key}': ${encryptionError.message}`
9652
10500
  );
9653
10501
  }
@@ -9677,22 +10525,22 @@ function useGitHubService() {
9677
10525
  }
9678
10526
  return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
9679
10527
  } catch (error) {
9680
- if (error instanceof import_utils54.AppError)
10528
+ if (error instanceof import_utils59.AppError)
9681
10529
  throw error;
9682
10530
  if (error.status === 422) {
9683
- throw new import_utils54.BadRequestError(
10531
+ throw new import_utils59.BadRequestError(
9684
10532
  `GitHub API validation error: ${error.message}`
9685
10533
  );
9686
10534
  } else if (error.status === 404) {
9687
- throw new import_utils54.BadRequestError("Environment or repository not found.");
10535
+ throw new import_utils59.BadRequestError("Environment or repository not found.");
9688
10536
  } else if (error.status === 403) {
9689
- throw new import_utils54.BadRequestError(
10537
+ throw new import_utils59.BadRequestError(
9690
10538
  "Forbidden: Insufficient permissions or rate limit exceeded."
9691
10539
  );
9692
10540
  } else if (error.message.includes("admin access") || error.message.includes("permissions")) {
9693
10541
  throw error;
9694
10542
  } else {
9695
- throw new import_utils54.BadRequestError(
10543
+ throw new import_utils59.BadRequestError(
9696
10544
  `Failed to set GitHub variables: ${error.message}`
9697
10545
  );
9698
10546
  }
@@ -9704,8 +10552,8 @@ function useGitHubService() {
9704
10552
  }
9705
10553
 
9706
10554
  // src/resources/utils/util.controller.ts
9707
- var import_joi37 = __toESM(require("joi"));
9708
- var import_utils55 = require("@goweekdays/utils");
10555
+ var import_joi43 = __toESM(require("joi"));
10556
+ var import_utils60 = require("@goweekdays/utils");
9709
10557
  function useUtilController() {
9710
10558
  async function healthCheck(req, res, next) {
9711
10559
  try {
@@ -9721,32 +10569,32 @@ function useUtilController() {
9721
10569
  }
9722
10570
  });
9723
10571
  } catch (error) {
9724
- import_utils55.logger.error("Health check failed", { error: error.message });
9725
- next(new import_utils55.InternalServerError("Health check failed"));
10572
+ import_utils60.logger.error("Health check failed", { error: error.message });
10573
+ next(new import_utils60.InternalServerError("Health check failed"));
9726
10574
  }
9727
10575
  }
9728
10576
  async function setGitHubVariables(req, res, next) {
9729
10577
  try {
9730
10578
  const { githubToken, repoUrl, environment, type, keyValues } = req.body;
9731
- const validation = import_joi37.default.object({
9732
- githubToken: import_joi37.default.string().required().messages({
10579
+ const validation = import_joi43.default.object({
10580
+ githubToken: import_joi43.default.string().required().messages({
9733
10581
  "string.empty": "GitHub token is required",
9734
10582
  "any.required": "GitHub token is required"
9735
10583
  }),
9736
- repoUrl: import_joi37.default.string().uri().required().messages({
10584
+ repoUrl: import_joi43.default.string().uri().required().messages({
9737
10585
  "string.empty": "Repository URL is required",
9738
10586
  "string.uri": "Repository URL must be a valid URL",
9739
10587
  "any.required": "Repository URL is required"
9740
10588
  }),
9741
- environment: import_joi37.default.string().required().messages({
10589
+ environment: import_joi43.default.string().required().messages({
9742
10590
  "string.empty": "Environment name is required",
9743
10591
  "any.required": "Environment name is required"
9744
10592
  }),
9745
- type: import_joi37.default.string().valid("env", "secret").required().messages({
10593
+ type: import_joi43.default.string().valid("env", "secret").required().messages({
9746
10594
  "any.only": 'Type must be either "env" or "secret"',
9747
10595
  "any.required": "Type is required"
9748
10596
  }),
9749
- keyValues: import_joi37.default.string().required().messages({
10597
+ keyValues: import_joi43.default.string().required().messages({
9750
10598
  "string.empty": "Key-value pairs are required",
9751
10599
  "any.required": "Key-value pairs are required"
9752
10600
  })
@@ -9759,13 +10607,13 @@ function useUtilController() {
9759
10607
  keyValues
9760
10608
  });
9761
10609
  if (error) {
9762
- next(new import_utils55.BadRequestError(error.message));
10610
+ next(new import_utils60.BadRequestError(error.message));
9763
10611
  return;
9764
10612
  }
9765
10613
  const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
9766
10614
  if (!repoUrlPattern.test(repoUrl)) {
9767
10615
  next(
9768
- new import_utils55.BadRequestError(
10616
+ new import_utils60.BadRequestError(
9769
10617
  "Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
9770
10618
  )
9771
10619
  );
@@ -9777,7 +10625,7 @@ function useUtilController() {
9777
10625
  );
9778
10626
  if (invalidLines.length > 0) {
9779
10627
  next(
9780
- new import_utils55.BadRequestError(
10628
+ new import_utils60.BadRequestError(
9781
10629
  "Invalid key-value format. Each pair should be in format: KEY=value. Pairs should be separated by semicolons."
9782
10630
  )
9783
10631
  );
@@ -9791,7 +10639,7 @@ function useUtilController() {
9791
10639
  type,
9792
10640
  keyValues
9793
10641
  });
9794
- import_utils55.logger.info(`GitHub variables set successfully`, {
10642
+ import_utils60.logger.info(`GitHub variables set successfully`, {
9795
10643
  repoUrl,
9796
10644
  environment,
9797
10645
  type,
@@ -9808,49 +10656,63 @@ function useUtilController() {
9808
10656
  }
9809
10657
  });
9810
10658
  } catch (error) {
9811
- import_utils55.logger.error("Failed to set GitHub variables", {
10659
+ import_utils60.logger.error("Failed to set GitHub variables", {
9812
10660
  error: error.message,
9813
10661
  stack: error.stack
9814
10662
  });
9815
- if (error instanceof import_utils55.AppError) {
10663
+ if (error instanceof import_utils60.AppError) {
9816
10664
  next(error);
9817
10665
  } else {
9818
10666
  next(
9819
- new import_utils55.InternalServerError(
10667
+ new import_utils60.InternalServerError(
9820
10668
  `Failed to set GitHub variables: ${error.message}`
9821
10669
  )
9822
10670
  );
9823
10671
  }
9824
10672
  }
9825
10673
  }
9826
- const { verifySignature } = usePaypalService();
10674
+ const { verifySignature, captureOrder } = usePaypalService();
10675
+ const { addWithVerification } = useOrgService();
9827
10676
  async function paypalWebhook(req, res, next) {
9828
10677
  try {
9829
- const headers = req.headers;
9830
- const event = req.body;
9831
- const data = JSON.parse(event);
9832
- console.log(`headers`, headers);
9833
- console.log(`parsed json`, JSON.stringify(data, null, 2));
9834
- console.log(`raw event: ${event}`);
9835
10678
  const isSignatureValid = await verifySignature(
9836
- event,
9837
- headers,
10679
+ req.body,
10680
+ req.headers,
9838
10681
  PAYPAL_WEBHOOK_ID
9839
10682
  );
9840
10683
  if (isSignatureValid) {
9841
- console.log("Signature is valid.");
9842
- console.log(`Received event`, JSON.stringify(data, null, 2));
10684
+ const payload = JSON.parse(req.body);
10685
+ const eventType = payload.event_type;
10686
+ const resource = payload.resource;
10687
+ switch (eventType) {
10688
+ case "CHECKOUT.ORDER.APPROVED": {
10689
+ const orderId = resource.id;
10690
+ await captureOrder(orderId);
10691
+ break;
10692
+ }
10693
+ case "PAYMENT.CAPTURE.COMPLETED": {
10694
+ const customId = resource?.custom_id || resource?.purchase_units?.[0]?.custom_id;
10695
+ if (!customId) {
10696
+ throw new Error("Missing PayPal customId");
10697
+ }
10698
+ await addWithVerification(customId);
10699
+ break;
10700
+ }
10701
+ default:
10702
+ break;
10703
+ }
9843
10704
  } else {
9844
- console.log(
9845
- `Signature is not valid for ${data?.id} ${headers?.["correlation-id"]}`
9846
- );
10705
+ next(new import_utils60.BadRequestError("Invalid PayPal webhook signature."));
10706
+ return;
9847
10707
  }
9848
10708
  res.sendStatus(200);
10709
+ return;
9849
10710
  } catch (error) {
9850
- import_utils55.logger.log({
10711
+ import_utils60.logger.log({
9851
10712
  level: "error",
9852
10713
  message: `${error}`
9853
10714
  });
10715
+ next(new import_utils60.InternalServerError(`PayPal webhook error: ${error.message}`));
9854
10716
  }
9855
10717
  }
9856
10718
  return {
@@ -9861,256 +10723,234 @@ function useUtilController() {
9861
10723
  }
9862
10724
 
9863
10725
  // src/resources/utils/transaction.schema.ts
9864
- var import_joi38 = __toESM(require("joi"));
9865
- var transactionSchema = import_joi38.default.object({
9866
- _id: import_joi38.default.string().hex().optional().allow("", null),
9867
- payment: import_joi38.default.string().required(),
9868
- user: import_joi38.default.string().hex().optional().allow("", null),
9869
- org: import_joi38.default.string().hex().optional().allow("", null),
9870
- type: import_joi38.default.string().required(),
9871
- amount: import_joi38.default.number().positive().min(0).required(),
9872
- currency: import_joi38.default.string().required(),
9873
- description: import_joi38.default.string().optional().allow("", null),
9874
- metadata: import_joi38.default.object({
9875
- subscriptionId: import_joi38.default.string().hex().optional().allow("", null),
9876
- cycle: import_joi38.default.number().optional().allow("", null),
9877
- seats: import_joi38.default.number().optional().allow("", null),
9878
- promoCode: import_joi38.default.string().optional().allow("", null)
10726
+ var import_joi44 = __toESM(require("joi"));
10727
+ var transactionSchema = import_joi44.default.object({
10728
+ _id: import_joi44.default.string().hex().optional().allow("", null),
10729
+ payment: import_joi44.default.string().required(),
10730
+ user: import_joi44.default.string().hex().optional().allow("", null),
10731
+ org: import_joi44.default.string().hex().optional().allow("", null),
10732
+ type: import_joi44.default.string().required(),
10733
+ amount: import_joi44.default.number().positive().min(0).required(),
10734
+ currency: import_joi44.default.string().required(),
10735
+ description: import_joi44.default.string().optional().allow("", null),
10736
+ metadata: import_joi44.default.object({
10737
+ subscriptionId: import_joi44.default.string().hex().optional().allow("", null),
10738
+ cycle: import_joi44.default.number().optional().allow("", null),
10739
+ seats: import_joi44.default.number().optional().allow("", null),
10740
+ promoCode: import_joi44.default.string().optional().allow("", null)
9879
10741
  }).optional().allow("", null),
9880
- status: import_joi38.default.string().optional().allow("", null),
9881
- createdAt: import_joi38.default.string().optional().allow("", null),
9882
- updatedAt: import_joi38.default.string().optional().allow("", null),
9883
- deletedAt: import_joi38.default.string().optional().allow("", null)
10742
+ status: import_joi44.default.string().optional().allow("", null),
10743
+ createdAt: import_joi44.default.string().optional().allow("", null),
10744
+ updatedAt: import_joi44.default.string().optional().allow("", null),
10745
+ deletedAt: import_joi44.default.string().optional().allow("", null)
9884
10746
  });
9885
10747
 
9886
- // src/resources/verification/verification.controller.ts
9887
- var import_utils56 = require("@goweekdays/utils");
9888
- var import_joi39 = __toESM(require("joi"));
9889
- function useVerificationController() {
9890
- const {
9891
- createUserInvite: _createUserInvite,
9892
- createForgetPassword: _createForgetPassword,
9893
- cancelUserInvitation: _cancelUserInvitation,
9894
- verify: _verify,
9895
- inviteMember: _inviteMember,
9896
- signUp: _signUp,
9897
- cancelInviteMember: _cancelInviteMember,
9898
- forgetPassword: _forgetPassword
9899
- } = useVerificationService();
9900
- const { getVerifications: _getVerifications } = useVerificationRepo();
9901
- async function createUserInvite(req, res, next) {
9902
- const validation = import_joi39.default.object({
9903
- email: import_joi39.default.string().email().required(),
9904
- app: import_joi39.default.string().required(),
9905
- role: import_joi39.default.string().hex().required(),
9906
- roleName: import_joi39.default.string().required(),
9907
- org: import_joi39.default.string().hex().optional().optional().allow("", null),
9908
- orgName: import_joi39.default.string().optional().optional().allow("", null)
9909
- });
9910
- const { error } = validation.validate(req.body);
9911
- if (error) {
9912
- next(new import_utils56.BadRequestError(error.message));
9913
- return;
9914
- }
9915
- const email = req.body.email ?? "";
9916
- const app = req.body.app ?? "";
9917
- const role = req.body.role ?? "";
9918
- const roleName = req.body.roleName ?? "";
9919
- const org = req.body.org ?? "";
9920
- const orgName = req.body.orgName ?? "";
9921
- try {
9922
- await _createUserInvite({
9923
- email,
9924
- metadata: {
9925
- app,
9926
- role,
9927
- roleName,
9928
- org,
9929
- orgName
9930
- }
9931
- });
9932
- res.json({ message: "Successfully invited user." });
9933
- return;
9934
- } catch (error2) {
9935
- next(error2);
9936
- }
10748
+ // src/resources/job-post/job.post.model.ts
10749
+ var import_utils61 = require("@goweekdays/utils");
10750
+ var import_joi45 = __toESM(require("joi"));
10751
+ var import_mongodb27 = require("mongodb");
10752
+ var schemaJobPost = import_joi45.default.object({
10753
+ _id: import_joi45.default.string().hex().optional(),
10754
+ org: import_joi45.default.string().hex().optional(),
10755
+ title: import_joi45.default.string().trim().required(),
10756
+ setup: import_joi45.default.string().trim().required(),
10757
+ location: import_joi45.default.string().trim().required(),
10758
+ type: import_joi45.default.string().trim().required(),
10759
+ description: import_joi45.default.string().trim().required(),
10760
+ status: import_joi45.default.string().trim().required(),
10761
+ createdAt: import_joi45.default.date().optional(),
10762
+ updatedAt: import_joi45.default.date().optional(),
10763
+ deletedAt: import_joi45.default.date().optional()
10764
+ });
10765
+ function modelJobPost(value) {
10766
+ const { error } = schemaJobPost.validate(value);
10767
+ if (error) {
10768
+ throw new import_utils61.BadRequestError(`Invalid job post: ${error.message}`);
9937
10769
  }
9938
- async function createForgetPassword(req, res, next) {
9939
- const email = req.body.email || "";
9940
- const validation = import_joi39.default.string().email().required();
9941
- const { error } = validation.validate(email);
9942
- if (error) {
9943
- next(new import_utils56.BadRequestError(error.message));
9944
- return;
9945
- }
10770
+ if (!value._id) {
9946
10771
  try {
9947
- await _createForgetPassword(email);
9948
- res.json({
9949
- message: "Check your email to verify it before resetting your password."
9950
- });
9951
- return;
10772
+ value._id = new import_mongodb27.ObjectId();
9952
10773
  } catch (error2) {
9953
- if (error2 instanceof import_utils56.AppError) {
9954
- next(error2);
9955
- } else {
9956
- next(new import_utils56.InternalServerError("An unexpected error occurred"));
9957
- }
10774
+ throw new import_utils61.BadRequestError("Invalid job post ID.");
9958
10775
  }
9959
10776
  }
9960
- async function getVerifications(req, res, next) {
9961
- const validation = import_joi39.default.object({
9962
- status: import_joi39.default.string().required(),
9963
- search: import_joi39.default.string().optional().allow("", null),
9964
- page: import_joi39.default.number().required(),
9965
- type: import_joi39.default.string().optional().allow("", null),
9966
- email: import_joi39.default.string().optional().allow("", null),
9967
- app: import_joi39.default.string().optional().allow("", null),
9968
- org: import_joi39.default.string().optional().allow("", null)
9969
- });
9970
- const { error } = validation.validate(req.query);
9971
- if (error) {
9972
- next(new import_utils56.BadRequestError(error.message));
9973
- return;
9974
- }
9975
- const status = req.query.status ?? "";
9976
- const search = req.query.search ?? "";
9977
- const page = Number(req.query.page) ?? 1;
9978
- let type = req.query.type ?? "";
9979
- const email = req.query.email ?? "";
9980
- const app = req.query.app ?? "";
9981
- const org = req.query.org ?? "";
9982
- const hasMultipleTypes = type.includes(",");
9983
- let splitType = [];
9984
- if (hasMultipleTypes) {
9985
- splitType = type.split(",");
9986
- }
9987
- try {
9988
- const items = await _getVerifications({
9989
- status,
9990
- search,
9991
- page,
9992
- type: hasMultipleTypes ? splitType : type,
9993
- email,
9994
- app,
9995
- org
10777
+ try {
10778
+ value.org = new import_mongodb27.ObjectId(value.org);
10779
+ } catch (error2) {
10780
+ throw new import_utils61.BadRequestError("Invalid Org ID");
10781
+ }
10782
+ return {
10783
+ _id: value._id,
10784
+ org: value.org,
10785
+ title: value.title,
10786
+ setup: value.setup,
10787
+ location: value.location,
10788
+ type: value.type,
10789
+ description: value.description,
10790
+ status: value.status ?? "active",
10791
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
10792
+ updatedAt: value.updatedAt,
10793
+ deletedAt: value.deletedAt
10794
+ };
10795
+ }
10796
+
10797
+ // src/resources/job-post/job.post.controller.ts
10798
+ var import_utils64 = require("@goweekdays/utils");
10799
+
10800
+ // src/resources/job-post/job.post.repository.ts
10801
+ var import_utils62 = require("@goweekdays/utils");
10802
+ var import_mongodb28 = require("mongodb");
10803
+ function useJobPostRepo() {
10804
+ const db = import_utils62.useAtlas.getDb();
10805
+ if (!db) {
10806
+ throw new import_utils62.BadRequestError("Unable to connect to server.");
10807
+ }
10808
+ const namespace_collection = "job.posts";
10809
+ const collection = db.collection(namespace_collection);
10810
+ const { delNamespace } = (0, import_utils62.useCache)(namespace_collection);
10811
+ function delCachedData() {
10812
+ delNamespace().then(() => {
10813
+ import_utils62.logger.log({
10814
+ level: "info",
10815
+ message: `Cache namespace cleared for ${namespace_collection}`
9996
10816
  });
9997
- res.json(items);
9998
- return;
9999
- } catch (error2) {
10000
- next(error2);
10001
- }
10817
+ }).catch((err) => {
10818
+ import_utils62.logger.log({
10819
+ level: "error",
10820
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
10821
+ });
10822
+ });
10002
10823
  }
10003
- async function verify(req, res, next) {
10004
- const id = req.params.id || "";
10005
- const validation = import_joi39.default.string().hex().required();
10006
- const { error } = validation.validate(id);
10007
- if (error) {
10008
- next(new import_utils56.BadRequestError(error.message));
10009
- return;
10010
- }
10824
+ async function createIndexes() {
10011
10825
  try {
10012
- const message = await _verify(id);
10013
- res.json(message);
10014
- return;
10015
- } catch (error2) {
10016
- next(error2);
10826
+ await collection.createIndexes([
10827
+ { key: { title: 1 } },
10828
+ { key: { setup: 1 } },
10829
+ { key: { location: 1 } },
10830
+ { key: { type: 1 } },
10831
+ {
10832
+ key: {
10833
+ title: "text",
10834
+ setup: "text",
10835
+ location: "text",
10836
+ type: "text"
10837
+ },
10838
+ name: "jobpost_text_search"
10839
+ }
10840
+ ]);
10841
+ return "Successfully created job post indexes.";
10842
+ } catch (error) {
10843
+ throw new import_utils62.BadRequestError("Failed to create job post indexes.");
10017
10844
  }
10018
10845
  }
10019
- async function cancelUserInvitation(req, res, next) {
10020
- const otpId = req.params.id || "";
10021
- const validation = import_joi39.default.string().hex().required();
10022
- const { error } = validation.validate(otpId);
10023
- if (error) {
10024
- next(new import_utils56.BadRequestError(error.message));
10025
- return;
10026
- }
10846
+ async function add(value, session) {
10027
10847
  try {
10028
- await _cancelUserInvitation(otpId);
10029
- return res.json({
10030
- message: "User invite has been cancelled."
10848
+ value = modelJobPost(value);
10849
+ const res = await collection.insertOne(value, { session });
10850
+ delCachedData();
10851
+ return res.insertedId;
10852
+ } catch (error) {
10853
+ import_utils62.logger.log({
10854
+ level: "error",
10855
+ message: error.message
10031
10856
  });
10032
- } catch (error2) {
10033
- throw error2;
10857
+ throw new import_utils62.BadRequestError(`Failed to create job post: ${error.message}`);
10034
10858
  }
10035
10859
  }
10036
- async function signUp(req, res, next) {
10037
- const validation = import_joi39.default.string().email().required();
10038
- const { error } = validation.validate(req.body.email);
10039
- if (error) {
10040
- next(new import_utils56.BadRequestError(error.message));
10041
- return;
10860
+ async function deleteById(_id, session) {
10861
+ try {
10862
+ _id = new import_mongodb28.ObjectId(_id);
10863
+ } catch (error) {
10864
+ throw new import_utils62.BadRequestError("Invalid ID.");
10042
10865
  }
10043
- const email = req.body.email ?? "";
10044
10866
  try {
10045
- await _signUp({ email });
10046
- res.json({ message: "Successfully signed up user." });
10047
- return;
10048
- } catch (error2) {
10049
- next(error2);
10867
+ await collection.updateOne(
10868
+ { _id },
10869
+ {
10870
+ $set: {
10871
+ status: "deleted",
10872
+ updatedAt: /* @__PURE__ */ new Date(),
10873
+ deletedAt: /* @__PURE__ */ new Date()
10874
+ }
10875
+ },
10876
+ { session }
10877
+ );
10878
+ delCachedData();
10879
+ return "Successfully deleted job post.";
10880
+ } catch (error) {
10881
+ throw new import_utils62.InternalServerError("Failed to delete job post.");
10050
10882
  }
10051
10883
  }
10052
- async function inviteMember(req, res, next) {
10053
- const { error } = schemaInviteMember.validate(req.body);
10884
+ return {
10885
+ createIndexes,
10886
+ add,
10887
+ deleteById
10888
+ };
10889
+ }
10890
+
10891
+ // src/resources/job-post/job.post.service.ts
10892
+ var import_utils63 = require("@goweekdays/utils");
10893
+ var import_joi46 = __toESM(require("joi"));
10894
+ function useJobPostService() {
10895
+ const { deleteById: _deleteById } = useJobPostRepo();
10896
+ async function deleteById(id) {
10897
+ const { error } = import_joi46.default.string().hex().required().validate(id);
10054
10898
  if (error) {
10055
- next(new import_utils56.BadRequestError(error.message));
10056
- return;
10899
+ throw new import_utils63.BadRequestError(error.message);
10057
10900
  }
10058
10901
  try {
10059
- await _inviteMember(req.body);
10060
- res.json({ message: "Successfully invited member." });
10061
- return;
10902
+ await _deleteById(id);
10903
+ return "Successfully deleted job post.";
10062
10904
  } catch (error2) {
10063
- next(error2);
10905
+ if (error2 instanceof import_utils63.AppError) {
10906
+ throw error2;
10907
+ } else {
10908
+ throw new import_utils63.InternalServerError("Failed to delete job post.");
10909
+ }
10064
10910
  }
10065
10911
  }
10066
- async function cancelInviteMember(req, res, next) {
10067
- const id = req.params.id || "";
10068
- const validation = import_joi39.default.string().hex().required();
10069
- const { error } = validation.validate(id);
10912
+ return {
10913
+ deleteById
10914
+ };
10915
+ }
10916
+
10917
+ // src/resources/job-post/job.post.controller.ts
10918
+ function useJobPostController() {
10919
+ const { add: _add } = useJobPostRepo();
10920
+ const { deleteById: _deleteById } = useJobPostService();
10921
+ async function add(req, res, next) {
10922
+ const value = req.body;
10923
+ const { error } = schemaJobPost.validate(value);
10070
10924
  if (error) {
10071
- next(new import_utils56.BadRequestError(error.message));
10925
+ next(new import_utils64.BadRequestError(error.message));
10926
+ import_utils64.logger.info(`Controller: ${error.message}`);
10072
10927
  return;
10073
10928
  }
10074
10929
  try {
10075
- const message = await _cancelInviteMember(id);
10076
- res.json({ message });
10930
+ const result = await _add(value);
10931
+ res.json({ message: "Successfully created job post.", data: { result } });
10077
10932
  return;
10078
10933
  } catch (error2) {
10079
10934
  next(error2);
10080
10935
  }
10081
10936
  }
10082
- async function forgetPassword(req, res, next) {
10083
- const email = req.body.email ?? "";
10084
- const validation = import_joi39.default.string().email().required();
10085
- const { error } = validation.validate(email);
10086
- if (error) {
10087
- next(new import_utils56.BadRequestError(error.message));
10937
+ async function deleteById(req, res, next) {
10938
+ const id = req.params.id;
10939
+ if (!id) {
10940
+ next(new import_utils64.BadRequestError("Job Post ID is required."));
10088
10941
  return;
10089
10942
  }
10090
10943
  try {
10091
- const message = await _forgetPassword(email);
10092
- res.json({
10093
- message
10094
- });
10944
+ const message = await _deleteById(id);
10945
+ res.json(message);
10095
10946
  return;
10096
- } catch (error2) {
10097
- if (error2 instanceof import_utils56.AppError) {
10098
- next(error2);
10099
- } else {
10100
- next(new import_utils56.InternalServerError("An unexpected error occurred"));
10101
- }
10947
+ } catch (error) {
10948
+ next(error);
10102
10949
  }
10103
10950
  }
10104
10951
  return {
10105
- getVerifications,
10106
- createUserInvite,
10107
- createForgetPassword,
10108
- verify,
10109
- cancelUserInvitation,
10110
- inviteMember,
10111
- signUp,
10112
- cancelInviteMember,
10113
- forgetPassword
10952
+ add,
10953
+ deleteById
10114
10954
  };
10115
10955
  }
10116
10956
  // Annotate the CommonJS export names for ESM import in node:
@@ -10157,7 +10997,11 @@ function useVerificationController() {
10157
10997
  XENDIT_SECRET_KEY,
10158
10998
  currencies,
10159
10999
  isDev,
11000
+ ledgerBillStatuses,
11001
+ ledgerBillTypes,
10160
11002
  modelApp,
11003
+ modelJobPost,
11004
+ modelLedgerBill,
10161
11005
  modelMember,
10162
11006
  modelOrg,
10163
11007
  modelPermission,
@@ -10174,6 +11018,9 @@ function useVerificationController() {
10174
11018
  schemaBuilding,
10175
11019
  schemaBuildingUnit,
10176
11020
  schemaInviteMember,
11021
+ schemaJobPost,
11022
+ schemaLedgerBill,
11023
+ schemaLedgerBillingSummary,
10177
11024
  schemaMember,
10178
11025
  schemaMemberRole,
10179
11026
  schemaMemberStatus,
@@ -10213,6 +11060,11 @@ function useVerificationController() {
10213
11060
  useFileRepo,
10214
11061
  useFileService,
10215
11062
  useGitHubService,
11063
+ useJobPostController,
11064
+ useJobPostRepo,
11065
+ useJobPostService,
11066
+ useLedgerBillingController,
11067
+ useLedgerBillingRepo,
10216
11068
  useMemberController,
10217
11069
  useMemberRepo,
10218
11070
  useOrgController,