@goweekdays/core 2.9.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -496,15 +496,15 @@ import {
496
496
  AppError as AppError22,
497
497
  BadRequestError as BadRequestError45,
498
498
  InternalServerError as InternalServerError25,
499
- logger as logger24
499
+ logger as logger25
500
500
  } from "@goweekdays/utils";
501
501
 
502
502
  // src/resources/verification/verification.service.ts
503
503
  import {
504
- useMailer,
505
- compileHandlebar,
506
- logger as logger23,
507
- getDirectory,
504
+ useMailer as useMailer2,
505
+ compileHandlebar as compileHandlebar2,
506
+ logger as logger24,
507
+ getDirectory as getDirectory2,
508
508
  BadRequestError as BadRequestError44,
509
509
  NotFoundError as NotFoundError3,
510
510
  InternalServerError as InternalServerError24,
@@ -923,7 +923,7 @@ import {
923
923
  InternalServerError as InternalServerError22,
924
924
  NotFoundError as NotFoundError2,
925
925
  hashPassword,
926
- logger as logger22,
926
+ logger as logger23,
927
927
  makeCacheKey as makeCacheKey14,
928
928
  useAtlas as useAtlas18,
929
929
  useCache as useCache15,
@@ -1154,6 +1154,7 @@ function useMemberRepo() {
1154
1154
  await collection.createIndexes([
1155
1155
  { key: { name: 1 } },
1156
1156
  { key: { status: 1 } },
1157
+ { key: { org: 1 } },
1157
1158
  { key: { name: "text", orgName: "text" }, name: "text_index" },
1158
1159
  {
1159
1160
  key: {
@@ -1859,6 +1860,38 @@ function useMemberRepo() {
1859
1860
  );
1860
1861
  }
1861
1862
  }
1863
+ async function updateStatusByOrg(org, status, session) {
1864
+ const { error } = Joi4.object({
1865
+ org: Joi4.string().hex().length(24).required(),
1866
+ status: Joi4.string().valid("active", "suspended").required()
1867
+ }).validate({ org, status });
1868
+ if (error) {
1869
+ throw new BadRequestError7(error.message);
1870
+ }
1871
+ try {
1872
+ org = new ObjectId7(org);
1873
+ } catch (error2) {
1874
+ throw new BadRequestError7("Invalid organization ID.");
1875
+ }
1876
+ try {
1877
+ await collection.updateMany(
1878
+ { org, status: { $ne: "deleted" }, app: { $ne: "org" } },
1879
+ {
1880
+ $set: {
1881
+ status,
1882
+ updatedAt: /* @__PURE__ */ new Date()
1883
+ }
1884
+ },
1885
+ { session }
1886
+ );
1887
+ delCachedData();
1888
+ return "Successfully updated member statuses by organization.";
1889
+ } catch (error2) {
1890
+ throw new InternalServerError5(
1891
+ "Internal server error, failed to update member statuses."
1892
+ );
1893
+ }
1894
+ }
1862
1895
  return {
1863
1896
  createIndexes,
1864
1897
  add,
@@ -1876,7 +1909,8 @@ function useMemberRepo() {
1876
1909
  getByApp,
1877
1910
  updateRoleById,
1878
1911
  updateStatusById,
1879
- deleteById
1912
+ deleteById,
1913
+ updateStatusByOrg
1880
1914
  };
1881
1915
  }
1882
1916
 
@@ -3508,8 +3542,13 @@ function useAppService() {
3508
3542
  },
3509
3543
  {
3510
3544
  code: "job",
3511
- name: "jobs",
3545
+ name: "Jobs",
3512
3546
  description: "Job listings and recruitment services."
3547
+ },
3548
+ {
3549
+ code: "circle",
3550
+ name: "Circle",
3551
+ description: "Community-based rotational system"
3513
3552
  }
3514
3553
  ];
3515
3554
  const session = useAtlas9.getClient()?.startSession();
@@ -4327,7 +4366,8 @@ var schema = {
4327
4366
  name: Joi15.string().max(255).required(),
4328
4367
  description: Joi15.string().max(1024).optional().allow("", null),
4329
4368
  email: Joi15.string().email().max(255).required(),
4330
- contact: Joi15.string().max(50).optional().allow("", null)
4369
+ contact: Joi15.string().max(50).optional().allow("", null),
4370
+ promoCode: Joi15.string().max(50).optional().allow("", null)
4331
4371
  };
4332
4372
  var schemaOrg = Joi15.object({
4333
4373
  ...schema,
@@ -4361,6 +4401,7 @@ function modelOrg(value) {
4361
4401
  email: value.email,
4362
4402
  contact: value.contact,
4363
4403
  createdBy: value.createdBy,
4404
+ promoCode: value.promoCode ?? "",
4364
4405
  status: value.status ?? "active",
4365
4406
  createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
4366
4407
  updatedAt: "",
@@ -4720,7 +4761,14 @@ function useOrgRepo() {
4720
4761
  }
4721
4762
 
4722
4763
  // src/resources/organization/organization.service.ts
4723
- import { BadRequestError as BadRequestError40, useAtlas as useAtlas17 } from "@goweekdays/utils";
4764
+ import {
4765
+ BadRequestError as BadRequestError40,
4766
+ compileHandlebar,
4767
+ getDirectory,
4768
+ logger as logger22,
4769
+ useAtlas as useAtlas17,
4770
+ useMailer
4771
+ } from "@goweekdays/utils";
4724
4772
 
4725
4773
  // src/resources/member/member.controller.ts
4726
4774
  import Joi19 from "joi";
@@ -5419,7 +5467,7 @@ function useSubscriptionRepo() {
5419
5467
  search = "",
5420
5468
  status = "active"
5421
5469
  } = {}) {
5422
- page = page < 1 ? page - 1 : page;
5470
+ page = page > 0 ? page - 1 : page;
5423
5471
  const query = { status };
5424
5472
  const cacheKeyOptions = {
5425
5473
  page,
@@ -7548,6 +7596,7 @@ function useSubscriptionService() {
7548
7596
  }
7549
7597
  }
7550
7598
  const { getOverdueForSuspension } = useSubscriptionRepo();
7599
+ const { updateStatusByOrg } = useMemberRepo();
7551
7600
  async function processSuspensions() {
7552
7601
  const DAYS_OVERDUE = 7;
7553
7602
  while (true) {
@@ -7569,8 +7618,10 @@ function useSubscriptionService() {
7569
7618
  session.startTransaction();
7570
7619
  await updateStatusById(subId, "suspended", session);
7571
7620
  await updateRetryById(subId, 0, session);
7572
- if (subscription.org) {
7573
- await updateOrgStatusById(subscription.org, "suspended", session);
7621
+ const orgId = String(subscription.org);
7622
+ if (orgId) {
7623
+ await updateOrgStatusById(orgId, "suspended", session);
7624
+ await updateStatusByOrg(orgId, "suspended", session);
7574
7625
  }
7575
7626
  await session.commitTransaction();
7576
7627
  logger21.log({
@@ -7634,6 +7685,7 @@ function useSubscriptionService() {
7634
7685
  session
7635
7686
  );
7636
7687
  await updateOrgStatusById(orgId, "active", session);
7688
+ await updateStatusByOrg(orgId, "active", session);
7637
7689
  await updateLedgerStatusById(String(ledgerBill._id), "paid", session);
7638
7690
  await session.commitTransaction();
7639
7691
  return "Successfully processed paid invoice.";
@@ -7713,7 +7765,8 @@ function useSubscriptionController() {
7713
7765
  const validation = Joi33.object({
7714
7766
  page: Joi33.number().min(1).max(100).optional().allow(null, "").default(1),
7715
7767
  limit: Joi33.number().min(1).max(100).optional().allow(null, "").default(10),
7716
- status: Joi33.string().valid("active", "suspended").optional().default("active")
7768
+ status: Joi33.string().valid("active", "suspended").optional().default("active"),
7769
+ search: Joi33.string().optional().allow("", null)
7717
7770
  });
7718
7771
  const query = req.query;
7719
7772
  const { error, value } = validation.validate(query);
@@ -8208,6 +8261,14 @@ function useOrgService() {
8208
8261
  }
8209
8262
  const { getById, updateStatusById: updateVerificationStatus } = useVerificationRepo();
8210
8263
  const { add: addLedgerBilling } = useLedgerBillingRepo();
8264
+ const MailerConfig = {
8265
+ host: MAILER_TRANSPORT_HOST,
8266
+ port: MAILER_TRANSPORT_PORT,
8267
+ secure: MAILER_TRANSPORT_SECURE,
8268
+ email: MAILER_EMAIL,
8269
+ password: MAILER_PASSWORD
8270
+ };
8271
+ const mailer = new useMailer(MailerConfig);
8211
8272
  async function addWithVerification(id) {
8212
8273
  const { error } = Joi36.string().hex().required().validate(id);
8213
8274
  if (error) {
@@ -8319,6 +8380,28 @@ function useOrgService() {
8319
8380
  },
8320
8381
  session
8321
8382
  );
8383
+ const filePath = getDirectory(
8384
+ __dirname,
8385
+ "./public/handlebars/org-created"
8386
+ );
8387
+ const emailContent = compileHandlebar({
8388
+ context: {
8389
+ app: APP_ORG,
8390
+ organization_name: verification.metadata.orgName
8391
+ },
8392
+ filePath
8393
+ });
8394
+ mailer.sendMail({
8395
+ to: verification.email,
8396
+ subject: "Welcome to GoWeekdays - Your Organization is Ready",
8397
+ html: emailContent,
8398
+ from: "GoWeekdays"
8399
+ }).catch((error2) => {
8400
+ logger22.log({
8401
+ level: "error",
8402
+ message: `Error sending user invite email: ${error2}`
8403
+ });
8404
+ });
8322
8405
  await session?.commitTransaction();
8323
8406
  return "Successfully created organization with verification.";
8324
8407
  } catch (error2) {
@@ -8779,9 +8862,9 @@ function useUserService() {
8779
8862
  const cacheKey = makeCacheKey14("users", { user: _id });
8780
8863
  try {
8781
8864
  useCache15().delCache(cacheKey).then(() => {
8782
- logger22.info(`Cache cleared for user: ${_id}`);
8865
+ logger23.info(`Cache cleared for user: ${_id}`);
8783
8866
  }).catch((error) => {
8784
- logger22.error(`Failed to clear cache for user: ${_id}`, error);
8867
+ logger23.error(`Failed to clear cache for user: ${_id}`, error);
8785
8868
  });
8786
8869
  await _updateName({ _id, firstName, lastName }, session);
8787
8870
  await updateMemberName(
@@ -9116,7 +9199,7 @@ function useVerificationService() {
9116
9199
  email: MAILER_EMAIL,
9117
9200
  password: MAILER_PASSWORD
9118
9201
  };
9119
- const mailer = new useMailer(MailerConfig);
9202
+ const mailer = new useMailer2(MailerConfig);
9120
9203
  const {
9121
9204
  add,
9122
9205
  getById: _getById,
@@ -9150,8 +9233,8 @@ function useVerificationService() {
9150
9233
  if (user) {
9151
9234
  value.type = "member-invite";
9152
9235
  const res2 = await add(value);
9153
- const filePath2 = getDirectory(dir, "./public/handlebars/member-invite");
9154
- const emailContent2 = compileHandlebar({
9236
+ const filePath2 = getDirectory2(dir, "./public/handlebars/member-invite");
9237
+ const emailContent2 = compileHandlebar2({
9155
9238
  context: {
9156
9239
  validity: VERIFICATION_USER_INVITE_DURATION,
9157
9240
  link: `${APP_MAIN}/verify/member-invite/${res2}`,
@@ -9165,7 +9248,7 @@ function useVerificationService() {
9165
9248
  html: emailContent2,
9166
9249
  from: "GoWeekdays"
9167
9250
  }).catch((error) => {
9168
- logger23.log({
9251
+ logger24.log({
9169
9252
  level: "error",
9170
9253
  message: `Error sending user invite email: ${error}`
9171
9254
  });
@@ -9173,8 +9256,8 @@ function useVerificationService() {
9173
9256
  return res2;
9174
9257
  }
9175
9258
  const res = await add(value);
9176
- const filePath = getDirectory(dir, "./public/handlebars/user-invite");
9177
- const emailContent = compileHandlebar({
9259
+ const filePath = getDirectory2(dir, "./public/handlebars/user-invite");
9260
+ const emailContent = compileHandlebar2({
9178
9261
  context: {
9179
9262
  validity: VERIFICATION_USER_INVITE_DURATION,
9180
9263
  link: `${APP_MAIN}/verify/invitation/${res}`
@@ -9187,7 +9270,7 @@ function useVerificationService() {
9187
9270
  html: emailContent,
9188
9271
  from: "GoWeekdays"
9189
9272
  }).catch((error) => {
9190
- logger23.log({
9273
+ logger24.log({
9191
9274
  level: "error",
9192
9275
  message: `Error sending user invite email: ${error}`
9193
9276
  });
@@ -9208,8 +9291,8 @@ function useVerificationService() {
9208
9291
  try {
9209
9292
  const res = await add(value);
9210
9293
  const dir = __dirname;
9211
- const filePath = getDirectory(dir, "./public/handlebars/forget-password");
9212
- const emailContent = compileHandlebar({
9294
+ const filePath = getDirectory2(dir, "./public/handlebars/forget-password");
9295
+ const emailContent = compileHandlebar2({
9213
9296
  context: {
9214
9297
  validity: VERIFICATION_FORGET_PASSWORD_DURATION,
9215
9298
  link: `${APP_MAIN}/reset-password/${res}`
@@ -9222,7 +9305,7 @@ function useVerificationService() {
9222
9305
  from: "GoWeekdays",
9223
9306
  html: emailContent
9224
9307
  }).catch((error) => {
9225
- logger23.log({
9308
+ logger24.log({
9226
9309
  level: "error",
9227
9310
  message: `Error sending forget password email: ${error}`
9228
9311
  });
@@ -9352,7 +9435,7 @@ function useVerificationService() {
9352
9435
  return _id;
9353
9436
  } catch (error) {
9354
9437
  await session?.abortTransaction();
9355
- logger23.log({
9438
+ logger24.log({
9356
9439
  level: "info",
9357
9440
  message: `Error verifying user invitation: ${error}`
9358
9441
  });
@@ -9398,8 +9481,8 @@ function useVerificationService() {
9398
9481
  };
9399
9482
  const res = await add(value);
9400
9483
  const dir = __dirname;
9401
- const filePath = getDirectory(dir, "./public/handlebars/sign-up");
9402
- const emailContent = compileHandlebar({
9484
+ const filePath = getDirectory2(dir, "./public/handlebars/sign-up");
9485
+ const emailContent = compileHandlebar2({
9403
9486
  context: {
9404
9487
  validity: "5 minutes",
9405
9488
  link: `${APP_MAIN}/sign-up/${res}`
@@ -9412,7 +9495,7 @@ function useVerificationService() {
9412
9495
  html: emailContent,
9413
9496
  from: "GoWeekdays"
9414
9497
  }).catch((error) => {
9415
- logger23.log({
9498
+ logger24.log({
9416
9499
  level: "error",
9417
9500
  message: `Error sending user invite email: ${error}`
9418
9501
  });
@@ -9455,8 +9538,8 @@ function useVerificationService() {
9455
9538
  if (user) {
9456
9539
  verificationData.type = "member-invite";
9457
9540
  const verificationId2 = await add(verificationData);
9458
- const filePath2 = getDirectory(dir, "./public/handlebars/member-invite");
9459
- const emailContent2 = compileHandlebar({
9541
+ const filePath2 = getDirectory2(dir, "./public/handlebars/member-invite");
9542
+ const emailContent2 = compileHandlebar2({
9460
9543
  context: {
9461
9544
  validity: VERIFICATION_USER_INVITE_DURATION,
9462
9545
  link: `${APP_MAIN}/verify/member-invite/${verificationId2}`,
@@ -9470,7 +9553,7 @@ function useVerificationService() {
9470
9553
  html: emailContent2,
9471
9554
  from: "GoWeekdays"
9472
9555
  }).catch((error2) => {
9473
- logger23.log({
9556
+ logger24.log({
9474
9557
  level: "error",
9475
9558
  message: `Error sending user invite email: ${error2}`
9476
9559
  });
@@ -9478,8 +9561,8 @@ function useVerificationService() {
9478
9561
  return verificationId2;
9479
9562
  }
9480
9563
  const verificationId = await add(verificationData);
9481
- const filePath = getDirectory(dir, "./public/handlebars/user-invite");
9482
- const emailContent = compileHandlebar({
9564
+ const filePath = getDirectory2(dir, "./public/handlebars/user-invite");
9565
+ const emailContent = compileHandlebar2({
9483
9566
  context: {
9484
9567
  validity: VERIFICATION_USER_INVITE_DURATION,
9485
9568
  link: `${APP_MAIN}/verify/invitation/${verificationId}`
@@ -9492,7 +9575,7 @@ function useVerificationService() {
9492
9575
  html: emailContent,
9493
9576
  from: "GoWeekdays"
9494
9577
  }).catch((error2) => {
9495
- logger23.log({
9578
+ logger24.log({
9496
9579
  level: "error",
9497
9580
  message: `Error sending user invite email: ${error2}`
9498
9581
  });
@@ -9550,8 +9633,8 @@ function useVerificationService() {
9550
9633
  };
9551
9634
  const res = await add(value);
9552
9635
  const dir = __dirname;
9553
- const filePath = getDirectory(dir, "./public/handlebars/forget-password");
9554
- const emailContent = compileHandlebar({
9636
+ const filePath = getDirectory2(dir, "./public/handlebars/forget-password");
9637
+ const emailContent = compileHandlebar2({
9555
9638
  context: {
9556
9639
  validity: VERIFICATION_FORGET_PASSWORD_DURATION,
9557
9640
  link: `${APP_MAIN}/reset-password/${res}`
@@ -9564,7 +9647,7 @@ function useVerificationService() {
9564
9647
  from: "GoWeekdays",
9565
9648
  html: emailContent
9566
9649
  }).catch((error2) => {
9567
- logger23.log({
9650
+ logger24.log({
9568
9651
  level: "error",
9569
9652
  message: `Error sending forget password email: ${error2}`
9570
9653
  });
@@ -9680,7 +9763,7 @@ function useAuthController() {
9680
9763
  res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json({ message: "Login successful" });
9681
9764
  return;
9682
9765
  } catch (error2) {
9683
- logger24.log({
9766
+ logger25.log({
9684
9767
  level: "error",
9685
9768
  message: `Error during login: ${error2.message}`
9686
9769
  });
@@ -9716,7 +9799,7 @@ function useAuthController() {
9716
9799
  }
9717
9800
 
9718
9801
  // src/resources/building/building.model.ts
9719
- import { BadRequestError as BadRequestError46, logger as logger25 } from "@goweekdays/utils";
9802
+ import { BadRequestError as BadRequestError46, logger as logger26 } from "@goweekdays/utils";
9720
9803
  import Joi41 from "joi";
9721
9804
  import { ObjectId as ObjectId22 } from "mongodb";
9722
9805
  var schemaBuilding = Joi41.object({
@@ -9760,7 +9843,7 @@ var schemaUpdateOptions = Joi41.object({
9760
9843
  function MBuilding(value) {
9761
9844
  const { error } = schemaBuilding.validate(value);
9762
9845
  if (error) {
9763
- logger25.info(`Building Model: ${error.message}`);
9846
+ logger26.info(`Building Model: ${error.message}`);
9764
9847
  throw new BadRequestError46(error.message);
9765
9848
  }
9766
9849
  if (value._id && typeof value._id === "string") {
@@ -9790,7 +9873,7 @@ function MBuilding(value) {
9790
9873
  function MBuildingUnit(value) {
9791
9874
  const { error } = schemaBuildingUnit.validate(value);
9792
9875
  if (error) {
9793
- logger25.info(`Building Unit Model: ${error.message}`);
9876
+ logger26.info(`Building Unit Model: ${error.message}`);
9794
9877
  throw new BadRequestError46(error.message);
9795
9878
  }
9796
9879
  if (value._id && typeof value._id === "string") {
@@ -9836,7 +9919,7 @@ import {
9836
9919
  AppError as AppError23,
9837
9920
  BadRequestError as BadRequestError47,
9838
9921
  InternalServerError as InternalServerError26,
9839
- logger as logger26,
9922
+ logger as logger27,
9840
9923
  makeCacheKey as makeCacheKey15,
9841
9924
  paginate as paginate13,
9842
9925
  useAtlas as useAtlas20,
@@ -9869,7 +9952,7 @@ function useBuildingRepo() {
9869
9952
  delCachedData();
9870
9953
  return res.insertedId;
9871
9954
  } catch (error) {
9872
- logger26.log({
9955
+ logger27.log({
9873
9956
  level: "error",
9874
9957
  message: error.message
9875
9958
  });
@@ -9899,7 +9982,7 @@ function useBuildingRepo() {
9899
9982
  delCachedData();
9900
9983
  return res;
9901
9984
  } catch (error) {
9902
- logger26.log({
9985
+ logger27.log({
9903
9986
  level: "error",
9904
9987
  message: error.message
9905
9988
  });
@@ -9945,14 +10028,14 @@ function useBuildingRepo() {
9945
10028
  if (status !== "active")
9946
10029
  cacheParams.status = status;
9947
10030
  const cacheKey = makeCacheKey15(namespace_collection, cacheParams);
9948
- logger26.log({
10031
+ logger27.log({
9949
10032
  level: "info",
9950
10033
  message: `Cache key for getAll buildings: ${cacheKey}`
9951
10034
  });
9952
10035
  try {
9953
10036
  const cached = await getCache(cacheKey);
9954
10037
  if (cached) {
9955
- logger26.log({
10038
+ logger27.log({
9956
10039
  level: "info",
9957
10040
  message: `Cache hit for getAll buildings: ${cacheKey}`
9958
10041
  });
@@ -9967,19 +10050,19 @@ function useBuildingRepo() {
9967
10050
  const length = await collection.countDocuments(query);
9968
10051
  const data = paginate13(items, page, limit, length);
9969
10052
  setCache(cacheKey, data, 600).then(() => {
9970
- logger26.log({
10053
+ logger27.log({
9971
10054
  level: "info",
9972
10055
  message: `Cache set for getAll buildings: ${cacheKey}`
9973
10056
  });
9974
10057
  }).catch((err) => {
9975
- logger26.log({
10058
+ logger27.log({
9976
10059
  level: "error",
9977
10060
  message: `Failed to set cache for getAll buildings: ${err.message}`
9978
10061
  });
9979
10062
  });
9980
10063
  return data;
9981
10064
  } catch (error) {
9982
- logger26.log({ level: "error", message: `${error}` });
10065
+ logger27.log({ level: "error", message: `${error}` });
9983
10066
  throw error;
9984
10067
  }
9985
10068
  }
@@ -9993,7 +10076,7 @@ function useBuildingRepo() {
9993
10076
  try {
9994
10077
  const cached = await getCache(cacheKey);
9995
10078
  if (cached) {
9996
- logger26.log({
10079
+ logger27.log({
9997
10080
  level: "info",
9998
10081
  message: `Cache hit for getById building: ${cacheKey}`
9999
10082
  });
@@ -10003,12 +10086,12 @@ function useBuildingRepo() {
10003
10086
  _id
10004
10087
  });
10005
10088
  setCache(cacheKey, result, 300).then(() => {
10006
- logger26.log({
10089
+ logger27.log({
10007
10090
  level: "info",
10008
10091
  message: `Cache set for building by id: ${cacheKey}`
10009
10092
  });
10010
10093
  }).catch((err) => {
10011
- logger26.log({
10094
+ logger27.log({
10012
10095
  level: "error",
10013
10096
  message: `Failed to set cache for building by id: ${err.message}`
10014
10097
  });
@@ -10036,7 +10119,7 @@ function useBuildingRepo() {
10036
10119
  delCachedData();
10037
10120
  return res;
10038
10121
  } catch (error) {
10039
- logger26.log({
10122
+ logger27.log({
10040
10123
  level: "error",
10041
10124
  message: error.message
10042
10125
  });
@@ -10049,12 +10132,12 @@ function useBuildingRepo() {
10049
10132
  }
10050
10133
  function delCachedData() {
10051
10134
  delNamespace().then(() => {
10052
- logger26.log({
10135
+ logger27.log({
10053
10136
  level: "info",
10054
10137
  message: `Cache namespace cleared for ${namespace_collection}`
10055
10138
  });
10056
10139
  }).catch((err) => {
10057
- logger26.log({
10140
+ logger27.log({
10058
10141
  level: "error",
10059
10142
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
10060
10143
  });
@@ -10078,7 +10161,7 @@ import {
10078
10161
  AppError as AppError24,
10079
10162
  BadRequestError as BadRequestError48,
10080
10163
  InternalServerError as InternalServerError27,
10081
- logger as logger27,
10164
+ logger as logger28,
10082
10165
  makeCacheKey as makeCacheKey16,
10083
10166
  paginate as paginate14,
10084
10167
  useAtlas as useAtlas21,
@@ -10120,12 +10203,12 @@ function useBuildingUnitRepo() {
10120
10203
  }
10121
10204
  function delCachedData() {
10122
10205
  delNamespace().then(() => {
10123
- logger27.log({
10206
+ logger28.log({
10124
10207
  level: "info",
10125
10208
  message: `Cache namespace cleared for ${namespace_collection}`
10126
10209
  });
10127
10210
  }).catch((err) => {
10128
- logger27.log({
10211
+ logger28.log({
10129
10212
  level: "error",
10130
10213
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
10131
10214
  });
@@ -10138,7 +10221,7 @@ function useBuildingUnitRepo() {
10138
10221
  delCachedData();
10139
10222
  return res.insertedId;
10140
10223
  } catch (error) {
10141
- logger27.log({
10224
+ logger28.log({
10142
10225
  level: "error",
10143
10226
  message: error.message
10144
10227
  });
@@ -10168,7 +10251,7 @@ function useBuildingUnitRepo() {
10168
10251
  delCachedData();
10169
10252
  return res;
10170
10253
  } catch (error2) {
10171
- logger27.log({
10254
+ logger28.log({
10172
10255
  level: "error",
10173
10256
  message: error2.message
10174
10257
  });
@@ -10198,7 +10281,7 @@ function useBuildingUnitRepo() {
10198
10281
  delCachedData();
10199
10282
  return res;
10200
10283
  } catch (error2) {
10201
- logger27.log({
10284
+ logger28.log({
10202
10285
  level: "error",
10203
10286
  message: error2.message
10204
10287
  });
@@ -10255,14 +10338,14 @@ function useBuildingUnitRepo() {
10255
10338
  if (status !== "active")
10256
10339
  cacheParams.status = status;
10257
10340
  const cacheKey = makeCacheKey16(namespace_collection, cacheParams);
10258
- logger27.log({
10341
+ logger28.log({
10259
10342
  level: "info",
10260
10343
  message: `Cache key for getAll building units: ${cacheKey}`
10261
10344
  });
10262
10345
  try {
10263
10346
  const cached = await getCache(cacheKey);
10264
10347
  if (cached) {
10265
- logger27.log({
10348
+ logger28.log({
10266
10349
  level: "info",
10267
10350
  message: `Cache hit for getAll building units: ${cacheKey}`
10268
10351
  });
@@ -10277,19 +10360,19 @@ function useBuildingUnitRepo() {
10277
10360
  const length = await collection.countDocuments(query);
10278
10361
  const data = paginate14(items, page, limit, length);
10279
10362
  setCache(cacheKey, data, 600).then(() => {
10280
- logger27.log({
10363
+ logger28.log({
10281
10364
  level: "info",
10282
10365
  message: `Cache set for getAll building units: ${cacheKey}`
10283
10366
  });
10284
10367
  }).catch((err) => {
10285
- logger27.log({
10368
+ logger28.log({
10286
10369
  level: "error",
10287
10370
  message: `Failed to set cache for getAll building units: ${err.message}`
10288
10371
  });
10289
10372
  });
10290
10373
  return data;
10291
10374
  } catch (error) {
10292
- logger27.log({ level: "error", message: `${error}` });
10375
+ logger28.log({ level: "error", message: `${error}` });
10293
10376
  throw error;
10294
10377
  }
10295
10378
  }
@@ -10303,7 +10386,7 @@ function useBuildingUnitRepo() {
10303
10386
  try {
10304
10387
  const cached = await getCache(cacheKey);
10305
10388
  if (cached) {
10306
- logger27.log({
10389
+ logger28.log({
10307
10390
  level: "info",
10308
10391
  message: `Cache hit for getById building unit: ${cacheKey}`
10309
10392
  });
@@ -10317,12 +10400,12 @@ function useBuildingUnitRepo() {
10317
10400
  throw new BadRequestError48("Building unit not found.");
10318
10401
  }
10319
10402
  setCache(cacheKey, result, 300).then(() => {
10320
- logger27.log({
10403
+ logger28.log({
10321
10404
  level: "info",
10322
10405
  message: `Cache set for building unit by id: ${cacheKey}`
10323
10406
  });
10324
10407
  }).catch((err) => {
10325
- logger27.log({
10408
+ logger28.log({
10326
10409
  level: "error",
10327
10410
  message: `Failed to set cache for building unit by id: ${err.message}`
10328
10411
  });
@@ -10349,7 +10432,7 @@ function useBuildingUnitRepo() {
10349
10432
  try {
10350
10433
  const cached = await getCache(cacheKey);
10351
10434
  if (cached) {
10352
- logger27.log({
10435
+ logger28.log({
10353
10436
  level: "info",
10354
10437
  message: `Cache hit for getById building unit: ${cacheKey}`
10355
10438
  });
@@ -10361,12 +10444,12 @@ function useBuildingUnitRepo() {
10361
10444
  status: "active"
10362
10445
  });
10363
10446
  setCache(cacheKey, result, 300).then(() => {
10364
- logger27.log({
10447
+ logger28.log({
10365
10448
  level: "info",
10366
10449
  message: `Cache set for building unit by id: ${cacheKey}`
10367
10450
  });
10368
10451
  }).catch((err) => {
10369
- logger27.log({
10452
+ logger28.log({
10370
10453
  level: "error",
10371
10454
  message: `Failed to set cache for building unit by id: ${err.message}`
10372
10455
  });
@@ -10392,7 +10475,7 @@ function useBuildingUnitRepo() {
10392
10475
  try {
10393
10476
  const cached = await getCache(cacheKey);
10394
10477
  if (cached) {
10395
- logger27.log({
10478
+ logger28.log({
10396
10479
  level: "info",
10397
10480
  message: `Cache hit for getById building unit: ${cacheKey}`
10398
10481
  });
@@ -10403,12 +10486,12 @@ function useBuildingUnitRepo() {
10403
10486
  status: "active"
10404
10487
  });
10405
10488
  setCache(cacheKey, result, 300).then(() => {
10406
- logger27.log({
10489
+ logger28.log({
10407
10490
  level: "info",
10408
10491
  message: `Cache set for building unit by id: ${cacheKey}`
10409
10492
  });
10410
10493
  }).catch((err) => {
10411
- logger27.log({
10494
+ logger28.log({
10412
10495
  level: "error",
10413
10496
  message: `Failed to set cache for building unit by id: ${err.message}`
10414
10497
  });
@@ -10437,7 +10520,7 @@ function useBuildingUnitRepo() {
10437
10520
  delCachedData();
10438
10521
  return "Room/Facility deleted successfully.";
10439
10522
  } catch (error) {
10440
- logger27.log({
10523
+ logger28.log({
10441
10524
  level: "error",
10442
10525
  message: error.message
10443
10526
  });
@@ -10520,7 +10603,7 @@ function useBuildingService() {
10520
10603
  }
10521
10604
 
10522
10605
  // src/resources/building/building.controller.ts
10523
- import { BadRequestError as BadRequestError50, logger as logger28 } from "@goweekdays/utils";
10606
+ import { BadRequestError as BadRequestError50, logger as logger29 } from "@goweekdays/utils";
10524
10607
  import Joi42 from "joi";
10525
10608
  function useBuildingController() {
10526
10609
  const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
@@ -10537,7 +10620,7 @@ function useBuildingController() {
10537
10620
  const { error } = validation.validate(value);
10538
10621
  if (error) {
10539
10622
  next(new BadRequestError50(error.message));
10540
- logger28.info(`Controller: ${error.message}`);
10623
+ logger29.info(`Controller: ${error.message}`);
10541
10624
  return;
10542
10625
  }
10543
10626
  try {
@@ -10562,7 +10645,7 @@ function useBuildingController() {
10562
10645
  const { error } = validation.validate({ id, value });
10563
10646
  if (error) {
10564
10647
  next(new BadRequestError50(error.message));
10565
- logger28.info(`Controller: ${error.message}`);
10648
+ logger29.info(`Controller: ${error.message}`);
10566
10649
  return;
10567
10650
  }
10568
10651
  try {
@@ -10892,7 +10975,7 @@ function useCounterModel(db) {
10892
10975
  }
10893
10976
 
10894
10977
  // src/resources/counter/counter.repository.ts
10895
- import { useAtlas as useAtlas24, useCache as useCache18, makeCacheKey as makeCacheKey17, logger as logger29 } from "@goweekdays/utils";
10978
+ import { useAtlas as useAtlas24, useCache as useCache18, makeCacheKey as makeCacheKey17, logger as logger30 } from "@goweekdays/utils";
10896
10979
  function useCounterRepo() {
10897
10980
  const db = useAtlas24.getDb();
10898
10981
  if (!db) {
@@ -10903,12 +10986,12 @@ function useCounterRepo() {
10903
10986
  const { getCache, setCache, delNamespace } = useCache18(namespace_collection);
10904
10987
  function delCachedData() {
10905
10988
  delNamespace().then(() => {
10906
- logger29.log({
10989
+ logger30.log({
10907
10990
  level: "info",
10908
10991
  message: `Cache namespace cleared for ${namespace_collection}`
10909
10992
  });
10910
10993
  }).catch((err) => {
10911
- logger29.log({
10994
+ logger30.log({
10912
10995
  level: "error",
10913
10996
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
10914
10997
  });
@@ -10956,7 +11039,7 @@ function useCounterRepo() {
10956
11039
  try {
10957
11040
  const cached = await getCache(cacheKey);
10958
11041
  if (cached) {
10959
- logger29.log({
11042
+ logger30.log({
10960
11043
  level: "info",
10961
11044
  message: `Cache hit for getByType counter: ${cacheKey}`
10962
11045
  });
@@ -10965,12 +11048,12 @@ function useCounterRepo() {
10965
11048
  const data = await collection.findOne({ type });
10966
11049
  if (data) {
10967
11050
  setCache(cacheKey, data, 300).then(() => {
10968
- logger29.log({
11051
+ logger30.log({
10969
11052
  level: "info",
10970
11053
  message: `Cache set for counter by type: ${cacheKey}`
10971
11054
  });
10972
11055
  }).catch((err) => {
10973
- logger29.log({
11056
+ logger30.log({
10974
11057
  level: "error",
10975
11058
  message: `Failed to set cache for counter by type: ${err.message}`
10976
11059
  });
@@ -10990,7 +11073,7 @@ function useCounterRepo() {
10990
11073
  }
10991
11074
 
10992
11075
  // src/resources/file/file.service.ts
10993
- import { logger as logger30, useS3 as useS32, useAtlas as useAtlas25 } from "@goweekdays/utils";
11076
+ import { logger as logger31, useS3 as useS32, useAtlas as useAtlas25 } from "@goweekdays/utils";
10994
11077
  import cron2 from "node-cron";
10995
11078
  import * as fs from "fs";
10996
11079
  function useFileService() {
@@ -11063,12 +11146,12 @@ function useFileService() {
11063
11146
  const file = files[index];
11064
11147
  try {
11065
11148
  await deleteFile(file._id.toString());
11066
- await logger30.log({
11149
+ await logger31.log({
11067
11150
  level: "info",
11068
11151
  message: "Successfully deleted draft files."
11069
11152
  });
11070
11153
  } catch (error) {
11071
- logger30.log({
11154
+ logger31.log({
11072
11155
  level: "info",
11073
11156
  message: "Successfully deleted draft files."
11074
11157
  });
@@ -11139,8 +11222,7 @@ function useFileController() {
11139
11222
  import Joi45 from "joi";
11140
11223
  var schemaPromo = Joi45.object({
11141
11224
  code: Joi45.string().min(3).max(50).required(),
11142
- description: Joi45.string().max(255).optional().allow("", null),
11143
- type: Joi45.string().valid("flat", "fixed", "tiered").required(),
11225
+ type: Joi45.string().valid("flat", "fixed", "volume").required(),
11144
11226
  flatRate: Joi45.number().positive().when("type", {
11145
11227
  is: "flat",
11146
11228
  then: Joi45.required(),
@@ -11162,9 +11244,12 @@ var schemaPromo = Joi45.object({
11162
11244
  then: Joi45.required(),
11163
11245
  otherwise: Joi45.forbidden()
11164
11246
  }),
11165
- currency: Joi45.string().length(3).required(),
11166
- startDate: Joi45.date().required(),
11167
- endDate: Joi45.date().greater(Joi45.ref("startDate")).optional().allow(null, "")
11247
+ currency: Joi45.string().length(3).allow("PHP").required(),
11248
+ startDate: Joi45.date().optional().allow(null, ""),
11249
+ endDate: Joi45.date().greater(Joi45.ref("startDate")).optional().allow(null, ""),
11250
+ apps: Joi45.array().items(Joi45.string()).optional().allow(null),
11251
+ seats: Joi45.number().integer().min(0).optional().allow(null, 0),
11252
+ usage: Joi45.number().integer().min(0).optional().allow(null, 0)
11168
11253
  });
11169
11254
  function modelPromo(data) {
11170
11255
  const { error } = schemaPromo.validate(data);
@@ -11174,17 +11259,17 @@ function modelPromo(data) {
11174
11259
  return {
11175
11260
  _id: data._id,
11176
11261
  code: data.code,
11177
- description: data.description ?? "",
11178
11262
  type: data.type,
11179
11263
  flatRate: data.flatRate ?? 0,
11180
11264
  fixedRate: data.fixedRate ?? 0,
11181
11265
  tiers: data.tiers ?? [],
11182
11266
  currency: data.currency,
11183
- startDate: data.startDate ?? /* @__PURE__ */ new Date(),
11267
+ startDate: data.startDate ?? "",
11184
11268
  endDate: data.endDate ?? "",
11185
- assignedTo: data.assignedTo ?? "",
11269
+ seats: data.seats ?? 0,
11270
+ usage: data.usage ?? 0,
11271
+ apps: data.apps ?? [],
11186
11272
  status: data.status ?? "active",
11187
- assignedAt: data.assignedAt ?? "",
11188
11273
  createdAt: data.createdAt ?? /* @__PURE__ */ new Date(),
11189
11274
  updatedAt: data.updatedAt ?? "",
11190
11275
  deletedAt: data.deletedAt ?? ""
@@ -11196,7 +11281,7 @@ import {
11196
11281
  AppError as AppError26,
11197
11282
  BadRequestError as BadRequestError54,
11198
11283
  InternalServerError as InternalServerError29,
11199
- logger as logger31,
11284
+ logger as logger32,
11200
11285
  makeCacheKey as makeCacheKey18,
11201
11286
  paginate as paginate15,
11202
11287
  useAtlas as useAtlas26,
@@ -11209,17 +11294,17 @@ function usePromoRepo() {
11209
11294
  if (!db) {
11210
11295
  throw new InternalServerError29("Unable to connect to server.");
11211
11296
  }
11212
- const namespace_collection = "users";
11297
+ const namespace_collection = "promos";
11213
11298
  const collection = db.collection(namespace_collection);
11214
11299
  const { getCache, setCache, delNamespace } = useCache19(namespace_collection);
11215
11300
  function delCachedData() {
11216
11301
  delNamespace().then(() => {
11217
- logger31.log({
11302
+ logger32.log({
11218
11303
  level: "info",
11219
11304
  message: `Cache namespace cleared for ${namespace_collection}`
11220
11305
  });
11221
11306
  }).catch((err) => {
11222
- logger31.log({
11307
+ logger32.log({
11223
11308
  level: "error",
11224
11309
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
11225
11310
  });
@@ -11260,7 +11345,7 @@ function usePromoRepo() {
11260
11345
  search = "",
11261
11346
  status = "active"
11262
11347
  } = {}) {
11263
- page = page < 1 ? page - 1 : page;
11348
+ page = page > 0 ? page - 1 : page;
11264
11349
  const query = { status };
11265
11350
  const cacheKeyOptions = {
11266
11351
  page,
@@ -11286,12 +11371,12 @@ function usePromoRepo() {
11286
11371
  const length = await collection.countDocuments(query);
11287
11372
  const data = paginate15(items, page, limit, length);
11288
11373
  setCache(cacheKey, data).then(() => {
11289
- logger31.log({
11374
+ logger32.log({
11290
11375
  level: "info",
11291
11376
  message: `Cache set for getAll promo: ${cacheKey}`
11292
11377
  });
11293
11378
  }).catch((err) => {
11294
- logger31.log({
11379
+ logger32.log({
11295
11380
  level: "error",
11296
11381
  message: `Failed to set cache for getAll promo: ${err.message}`
11297
11382
  });
@@ -11320,12 +11405,12 @@ function usePromoRepo() {
11320
11405
  status: { $ne: "deleted" }
11321
11406
  });
11322
11407
  setCache(cacheKey, data).then(() => {
11323
- logger31.log({
11408
+ logger32.log({
11324
11409
  level: "info",
11325
11410
  message: `Cache set for getByCode promo: ${cacheKey}`
11326
11411
  });
11327
11412
  }).catch((err) => {
11328
- logger31.log({
11413
+ logger32.log({
11329
11414
  level: "error",
11330
11415
  message: `Failed to set cache for getByCode promo: ${err.message}`
11331
11416
  });
@@ -11359,12 +11444,12 @@ function usePromoRepo() {
11359
11444
  status: { $ne: "deleted" }
11360
11445
  });
11361
11446
  setCache(cacheKey, data).then(() => {
11362
- logger31.log({
11447
+ logger32.log({
11363
11448
  level: "info",
11364
11449
  message: `Cache set for getById promo: ${cacheKey}`
11365
11450
  });
11366
11451
  }).catch((err) => {
11367
- logger31.log({
11452
+ logger32.log({
11368
11453
  level: "error",
11369
11454
  message: `Failed to set cache for getById promo: ${err.message}`
11370
11455
  });
@@ -11374,6 +11459,31 @@ function usePromoRepo() {
11374
11459
  throw new InternalServerError29("Failed to get promo.");
11375
11460
  }
11376
11461
  }
11462
+ async function updateById(_id, options) {
11463
+ const { error: errorId } = Joi46.string().hex().length(24).required().validate(_id);
11464
+ if (errorId) {
11465
+ throw new Error(`Invalid promo ID: ${errorId.message}`);
11466
+ }
11467
+ const { error } = schemaPromo.validate(options);
11468
+ if (error) {
11469
+ throw new Error(`Invalid promo ID: ${error.message}`);
11470
+ }
11471
+ try {
11472
+ _id = new ObjectId26(_id);
11473
+ } catch (error2) {
11474
+ throw new BadRequestError54("Invalid promo ID.");
11475
+ }
11476
+ try {
11477
+ await collection.updateOne(
11478
+ { _id },
11479
+ { $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } }
11480
+ );
11481
+ delCachedData();
11482
+ return "Successfully updated promo.";
11483
+ } catch (error2) {
11484
+ throw new InternalServerError29("Failed to update promo.");
11485
+ }
11486
+ }
11377
11487
  async function deleteById(_id) {
11378
11488
  const { error } = Joi46.string().hex().length(24).required().validate(_id);
11379
11489
  if (error) {
@@ -11407,99 +11517,94 @@ function usePromoRepo() {
11407
11517
  getAll,
11408
11518
  getByCode,
11409
11519
  getById,
11520
+ updateById,
11410
11521
  deleteById
11411
11522
  };
11412
11523
  }
11413
11524
 
11414
- // src/resources/job-post/job.post.model.ts
11525
+ // src/resources/promo/promo.controller.ts
11526
+ import Joi49 from "joi";
11527
+ import { BadRequestError as BadRequestError58 } from "@goweekdays/utils";
11528
+
11529
+ // src/resources/promo/promo.service.ts
11530
+ import { AppError as AppError28, BadRequestError as BadRequestError57 } from "@goweekdays/utils";
11531
+
11532
+ // src/resources/promo/promo.usage.repository.ts
11533
+ import {
11534
+ AppError as AppError27,
11535
+ BadRequestError as BadRequestError56,
11536
+ InternalServerError as InternalServerError30,
11537
+ logger as logger33,
11538
+ makeCacheKey as makeCacheKey19,
11539
+ paginate as paginate16,
11540
+ useAtlas as useAtlas27,
11541
+ useCache as useCache20
11542
+ } from "@goweekdays/utils";
11543
+
11544
+ // src/resources/promo/promo.usage.model.ts
11415
11545
  import { BadRequestError as BadRequestError55 } from "@goweekdays/utils";
11416
11546
  import Joi47 from "joi";
11417
11547
  import { ObjectId as ObjectId27 } from "mongodb";
11418
- var schemaJobPost = Joi47.object({
11419
- _id: Joi47.string().hex().optional(),
11420
- org: Joi47.string().hex().required(),
11421
- title: Joi47.string().trim().required(),
11422
- setup: Joi47.string().trim().required(),
11423
- location: Joi47.string().trim().required(),
11424
- type: Joi47.string().trim().required(),
11425
- description: Joi47.string().trim().required(),
11426
- status: Joi47.string().trim().optional().allow("", null),
11427
- createdAt: Joi47.date().optional(),
11428
- updatedAt: Joi47.date().optional(),
11429
- deletedAt: Joi47.date().optional()
11430
- });
11431
- var schemaJobPostUpdate = Joi47.object({
11432
- _id: Joi47.string().hex().required(),
11433
- title: Joi47.string().trim().required(),
11434
- setup: Joi47.string().trim().required(),
11435
- location: Joi47.string().trim().required(),
11436
- type: Joi47.string().trim().required(),
11437
- description: Joi47.string().trim().required()
11548
+ var schemaPromoUsage = Joi47.object({
11549
+ promo: Joi47.string().hex().length(24).required(),
11550
+ org: Joi47.string().hex().length(24).required(),
11551
+ usedBy: Joi47.string().email().required()
11438
11552
  });
11439
- function modelJobPost(value) {
11440
- const { error } = schemaJobPost.validate(value);
11553
+ function modelPromoUsage(value) {
11554
+ const { error } = schemaPromoUsage.validate(value);
11441
11555
  if (error) {
11442
- throw new BadRequestError55(`Invalid job post: ${error.message}`);
11556
+ throw new Error(`Invalid Promo Usage model: ${error.message}`);
11443
11557
  }
11444
- if (!value._id) {
11558
+ if (value._id && typeof value._id === "string") {
11445
11559
  try {
11446
- value._id = new ObjectId27();
11560
+ value._id = new ObjectId27(value._id);
11447
11561
  } catch (error2) {
11448
- throw new BadRequestError55("Invalid job post ID.");
11562
+ throw new BadRequestError55("Invalid Promo Usage _id");
11449
11563
  }
11450
11564
  }
11451
- try {
11452
- value.org = new ObjectId27(value.org);
11453
- } catch (error2) {
11454
- throw new BadRequestError55("Invalid Org ID");
11565
+ if (typeof value.promo === "string") {
11566
+ try {
11567
+ value.promo = new ObjectId27(value.promo);
11568
+ } catch (error2) {
11569
+ throw new BadRequestError55("Invalid Promo Usage promo");
11570
+ }
11571
+ }
11572
+ if (typeof value.org === "string") {
11573
+ try {
11574
+ value.org = new ObjectId27(value.org);
11575
+ } catch (error2) {
11576
+ throw new BadRequestError55("Invalid Promo Usage org");
11577
+ }
11455
11578
  }
11456
11579
  return {
11457
11580
  _id: value._id,
11581
+ promo: value.promo,
11458
11582
  org: value.org,
11459
- title: value.title,
11460
- setup: value.setup,
11461
- location: value.location,
11462
- type: value.type,
11463
- description: value.description,
11464
- status: value.status ?? "draft",
11465
- createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
11466
- updatedAt: value.updatedAt,
11467
- deletedAt: value.deletedAt
11583
+ usedBy: value.usedBy,
11584
+ createdAt: value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date(),
11585
+ updatedAt: value.updatedAt ?? ""
11468
11586
  };
11469
11587
  }
11470
11588
 
11471
- // src/resources/job-post/job.post.controller.ts
11472
- import Joi49 from "joi";
11473
- import { BadRequestError as BadRequestError58, logger as logger33 } from "@goweekdays/utils";
11474
-
11475
- // src/resources/job-post/job.post.repository.ts
11476
- import {
11477
- AppError as AppError27,
11478
- BadRequestError as BadRequestError56,
11479
- useAtlas as useAtlas27,
11480
- useCache as useCache20,
11481
- makeCacheKey as makeCacheKey19,
11482
- paginate as paginate16,
11483
- logger as logger32,
11484
- InternalServerError as InternalServerError30
11485
- } from "@goweekdays/utils";
11589
+ // src/resources/promo/promo.usage.repository.ts
11590
+ import Joi48 from "joi";
11486
11591
  import { ObjectId as ObjectId28 } from "mongodb";
11487
- function useJobPostRepo() {
11592
+ function usePromoUsageRepo() {
11488
11593
  const db = useAtlas27.getDb();
11489
11594
  if (!db) {
11490
- throw new BadRequestError56("Unable to connect to server.");
11595
+ throw new InternalServerError30("Unable to connect to server.");
11491
11596
  }
11492
- const namespace_collection = "job.posts";
11597
+ const namespace_collection = "promo.usages";
11493
11598
  const collection = db.collection(namespace_collection);
11494
11599
  const { getCache, setCache, delNamespace } = useCache20(namespace_collection);
11495
11600
  function delCachedData() {
11496
11601
  delNamespace().then(() => {
11497
- logger32.log({
11602
+ logger33.log({
11498
11603
  level: "info",
11499
11604
  message: `Cache namespace cleared for ${namespace_collection}`
11500
11605
  });
11501
11606
  }).catch((err) => {
11502
- logger32.log({
11607
+ logger33.log({
11503
11608
  level: "error",
11504
11609
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
11505
11610
  });
@@ -11508,77 +11613,587 @@ function useJobPostRepo() {
11508
11613
  async function createIndexes() {
11509
11614
  try {
11510
11615
  await collection.createIndexes([
11511
- { key: { title: 1 } },
11512
- { key: { setup: 1 } },
11513
- { key: { location: 1 } },
11514
- { key: { type: 1 } },
11515
11616
  {
11516
- key: {
11517
- title: "text",
11518
- setup: "text",
11519
- location: "text",
11520
- type: "text"
11521
- },
11522
- name: "jobpost_text_search"
11617
+ key: { promo: 1, org: 1 },
11618
+ name: "promo_org_index"
11619
+ },
11620
+ {
11621
+ key: { usedBy: 1 },
11622
+ name: "usedBy_index"
11523
11623
  }
11524
11624
  ]);
11525
- return "Successfully created job post indexes.";
11526
11625
  } catch (error) {
11527
- throw new BadRequestError56("Failed to create job post indexes.");
11528
11626
  }
11529
11627
  }
11530
- async function add(value, session) {
11628
+ async function add(value) {
11531
11629
  try {
11532
- value = modelJobPost(value);
11533
- const res = await collection.insertOne(value, { session });
11630
+ value = modelPromoUsage(value);
11631
+ await collection.insertOne(value);
11534
11632
  delCachedData();
11535
- return res.insertedId;
11633
+ return "Successfully added promo usage.";
11536
11634
  } catch (error) {
11537
- logger32.log({
11538
- level: "error",
11539
- message: error.message
11540
- });
11541
- throw new BadRequestError56(`Failed to create job post: ${error.message}`);
11635
+ throw new InternalServerError30("Failed to add promo usage.");
11542
11636
  }
11543
11637
  }
11544
11638
  async function getAll({
11545
- search = "",
11546
11639
  page = 1,
11547
11640
  limit = 10,
11548
- status = "active"
11641
+ promo,
11642
+ org
11549
11643
  } = {}) {
11550
- page = page > 0 ? page - 1 : 0;
11551
- const query = { status };
11552
- if (search) {
11553
- query.$text = { $search: search };
11554
- }
11555
- const cacheKey = makeCacheKey19(namespace_collection, {
11556
- search,
11644
+ page = page > 0 ? page - 1 : page;
11645
+ const query = {};
11646
+ const cacheKeyOptions = {
11557
11647
  page,
11558
11648
  limit,
11559
- status
11560
- });
11561
- logger32.log({
11562
- level: "info",
11563
- message: `Cache key for getAll job posts: ${cacheKey}`
11564
- });
11565
- try {
11566
- const cached = await getCache(cacheKey);
11567
- if (cached) {
11568
- logger32.log({
11569
- level: "info",
11570
- message: `Cache hit for getAll job posts: ${cacheKey}`
11571
- });
11572
- return cached;
11649
+ promo,
11650
+ org,
11651
+ tag: "getAll"
11652
+ };
11653
+ if (promo) {
11654
+ try {
11655
+ query.promo = new ObjectId28(promo);
11656
+ } catch (error) {
11657
+ throw new BadRequestError56("Invalid promo ID.");
11573
11658
  }
11574
- const items = await collection.aggregate([
11575
- { $match: query },
11576
- { $skip: page * limit },
11577
- { $limit: limit },
11578
- {
11579
- $project: {
11580
- _id: 1,
11581
- title: 1,
11659
+ }
11660
+ if (org) {
11661
+ try {
11662
+ query.org = new ObjectId28(org);
11663
+ } catch (error) {
11664
+ throw new BadRequestError56("Invalid org ID.");
11665
+ }
11666
+ }
11667
+ const cacheKey = makeCacheKey19(namespace_collection, cacheKeyOptions);
11668
+ try {
11669
+ const cachedData = await getCache(cacheKey);
11670
+ if (cachedData) {
11671
+ return cachedData;
11672
+ }
11673
+ const items = await collection.aggregate([
11674
+ { $match: query },
11675
+ { $skip: page * limit },
11676
+ { $limit: limit }
11677
+ ]).toArray();
11678
+ const length = await collection.countDocuments(query);
11679
+ const data = paginate16(items, page, limit, length);
11680
+ setCache(cacheKey, data).then(() => {
11681
+ logger33.log({
11682
+ level: "info",
11683
+ message: `Cache set for getAll promo usage: ${cacheKey}`
11684
+ });
11685
+ }).catch((err) => {
11686
+ logger33.log({
11687
+ level: "error",
11688
+ message: `Failed to set cache for getAll promo usage: ${err.message}`
11689
+ });
11690
+ });
11691
+ return data;
11692
+ } catch (error) {
11693
+ throw new InternalServerError30("Failed to get promo usages.");
11694
+ }
11695
+ }
11696
+ async function getByPromo(promo) {
11697
+ const { error } = Joi48.string().hex().length(24).required().validate(promo);
11698
+ if (error) {
11699
+ throw new Error(`Invalid promo ID: ${error.message}`);
11700
+ }
11701
+ try {
11702
+ promo = new ObjectId28(promo);
11703
+ } catch (error2) {
11704
+ throw new BadRequestError56("Invalid promo ID.");
11705
+ }
11706
+ try {
11707
+ const cacheKey = makeCacheKey19(namespace_collection, {
11708
+ promo: String(promo),
11709
+ tag: "getByPromoId"
11710
+ });
11711
+ const cachedData = await getCache(cacheKey);
11712
+ if (cachedData) {
11713
+ return cachedData;
11714
+ }
11715
+ const data = await collection.findOne({ promo });
11716
+ setCache(cacheKey, data).then(() => {
11717
+ logger33.log({
11718
+ level: "info",
11719
+ message: `Cache set for getByPromoId promo usage: ${cacheKey}`
11720
+ });
11721
+ }).catch((err) => {
11722
+ logger33.log({
11723
+ level: "error",
11724
+ message: `Failed to set cache for getByPromoId promo usage: ${err.message}`
11725
+ });
11726
+ });
11727
+ return data;
11728
+ } catch (error2) {
11729
+ throw new InternalServerError30("Failed to get promo usages.");
11730
+ }
11731
+ }
11732
+ async function getById(_id) {
11733
+ const { error } = Joi48.string().hex().length(24).required().validate(_id);
11734
+ if (error) {
11735
+ throw new Error(`Invalid promo usage ID: ${error.message}`);
11736
+ }
11737
+ try {
11738
+ _id = new ObjectId28(_id);
11739
+ } catch (error2) {
11740
+ throw new BadRequestError56("Invalid promo usage ID.");
11741
+ }
11742
+ try {
11743
+ const cacheKey = makeCacheKey19(namespace_collection, {
11744
+ _id: String(_id),
11745
+ tag: "getById"
11746
+ });
11747
+ const cachedData = await getCache(cacheKey);
11748
+ if (cachedData) {
11749
+ return cachedData;
11750
+ }
11751
+ const data = await collection.findOne({ _id });
11752
+ setCache(cacheKey, data).then(() => {
11753
+ logger33.log({
11754
+ level: "info",
11755
+ message: `Cache set for getById promo usage: ${cacheKey}`
11756
+ });
11757
+ }).catch((err) => {
11758
+ logger33.log({
11759
+ level: "error",
11760
+ message: `Failed to set cache for getById promo usage: ${err.message}`
11761
+ });
11762
+ });
11763
+ return data;
11764
+ } catch (error2) {
11765
+ throw new InternalServerError30("Failed to get promo usage.");
11766
+ }
11767
+ }
11768
+ async function getByOrgId(orgId) {
11769
+ const { error } = Joi48.string().hex().length(24).required().validate(orgId);
11770
+ if (error) {
11771
+ throw new Error(`Invalid org ID: ${error.message}`);
11772
+ }
11773
+ try {
11774
+ orgId = new ObjectId28(orgId);
11775
+ } catch (error2) {
11776
+ throw new BadRequestError56("Invalid org ID.");
11777
+ }
11778
+ try {
11779
+ const cacheKey = makeCacheKey19(namespace_collection, {
11780
+ org: String(orgId),
11781
+ tag: "getByOrgId"
11782
+ });
11783
+ const cachedData = await getCache(cacheKey);
11784
+ if (cachedData) {
11785
+ return cachedData;
11786
+ }
11787
+ const data = await collection.find({ org: orgId }).toArray();
11788
+ setCache(cacheKey, data).then(() => {
11789
+ logger33.log({
11790
+ level: "info",
11791
+ message: `Cache set for getByOrgId promo usage: ${cacheKey}`
11792
+ });
11793
+ }).catch((err) => {
11794
+ logger33.log({
11795
+ level: "error",
11796
+ message: `Failed to set cache for getByOrgId promo usage: ${err.message}`
11797
+ });
11798
+ });
11799
+ return data;
11800
+ } catch (error2) {
11801
+ throw new InternalServerError30("Failed to get promo usages.");
11802
+ }
11803
+ }
11804
+ async function countByPromoId(promoId) {
11805
+ const { error } = Joi48.string().hex().length(24).required().validate(promoId);
11806
+ if (error) {
11807
+ throw new Error(`Invalid promo ID: ${error.message}`);
11808
+ }
11809
+ try {
11810
+ promoId = new ObjectId28(promoId);
11811
+ } catch (error2) {
11812
+ throw new BadRequestError56("Invalid promo ID.");
11813
+ }
11814
+ try {
11815
+ const cacheKey = makeCacheKey19(namespace_collection, {
11816
+ promo: String(promoId),
11817
+ tag: "countByPromoId"
11818
+ });
11819
+ const cachedData = await getCache(cacheKey);
11820
+ if (cachedData !== null && cachedData !== void 0) {
11821
+ return cachedData;
11822
+ }
11823
+ const count = await collection.countDocuments({ promo: promoId });
11824
+ setCache(cacheKey, count).then(() => {
11825
+ logger33.log({
11826
+ level: "info",
11827
+ message: `Cache set for countByPromoId promo usage: ${cacheKey}`
11828
+ });
11829
+ }).catch((err) => {
11830
+ logger33.log({
11831
+ level: "error",
11832
+ message: `Failed to set cache for countByPromoId promo usage: ${err.message}`
11833
+ });
11834
+ });
11835
+ return count;
11836
+ } catch (error2) {
11837
+ throw new InternalServerError30("Failed to count promo usages.");
11838
+ }
11839
+ }
11840
+ async function deleteById(_id) {
11841
+ const { error } = Joi48.string().hex().length(24).required().validate(_id);
11842
+ if (error) {
11843
+ throw new Error(`Invalid promo usage ID: ${error.message}`);
11844
+ }
11845
+ try {
11846
+ _id = new ObjectId28(_id);
11847
+ } catch (error2) {
11848
+ throw new BadRequestError56("Invalid promo usage ID.");
11849
+ }
11850
+ try {
11851
+ const result = await collection.deleteOne({ _id });
11852
+ if (result.deletedCount === 0) {
11853
+ throw new InternalServerError30("Failed to delete promo usage.");
11854
+ }
11855
+ delCachedData();
11856
+ return "Successfully deleted promo usage.";
11857
+ } catch (error2) {
11858
+ if (error2 instanceof AppError27) {
11859
+ throw error2;
11860
+ }
11861
+ throw new InternalServerError30("Failed to delete promo usage.");
11862
+ }
11863
+ }
11864
+ return {
11865
+ createIndexes,
11866
+ add,
11867
+ getAll,
11868
+ getByPromo,
11869
+ getById,
11870
+ getByOrgId,
11871
+ countByPromoId,
11872
+ deleteById
11873
+ };
11874
+ }
11875
+
11876
+ // src/resources/promo/promo.service.ts
11877
+ function usePromoService() {
11878
+ const { getByPromo } = usePromoUsageRepo();
11879
+ const { deleteById: _deleteById } = usePromoRepo();
11880
+ async function deleteById(id) {
11881
+ const usage = await getByPromo(id);
11882
+ if (usage) {
11883
+ throw new BadRequestError57("Failed to delete, promo is in use.");
11884
+ }
11885
+ try {
11886
+ await _deleteById(id);
11887
+ return "Successfully deleted promo.";
11888
+ } catch (error) {
11889
+ if (error instanceof AppError28) {
11890
+ throw error;
11891
+ }
11892
+ throw new BadRequestError57("Failed to delete promo.");
11893
+ }
11894
+ }
11895
+ return {
11896
+ deleteById
11897
+ };
11898
+ }
11899
+
11900
+ // src/resources/promo/promo.controller.ts
11901
+ function usePromoController() {
11902
+ const {
11903
+ add: _add,
11904
+ getAll: _getAll,
11905
+ getByCode: _getByCode,
11906
+ getById: _getById,
11907
+ updateById: _updateById
11908
+ } = usePromoRepo();
11909
+ async function add(req, res, next) {
11910
+ const value = req.body;
11911
+ const { error } = schemaPromo.validate(value);
11912
+ if (error) {
11913
+ next(new BadRequestError58(error.message));
11914
+ return;
11915
+ }
11916
+ try {
11917
+ const message = await _add(value);
11918
+ res.json({ message });
11919
+ return;
11920
+ } catch (error2) {
11921
+ next(error2);
11922
+ }
11923
+ }
11924
+ async function getAll(req, res, next) {
11925
+ const status = req.query.status ?? "active";
11926
+ const search = req.query.search ?? "";
11927
+ const page = Number(req.query.page) ?? 1;
11928
+ const limit = Number(req.query.limit) ?? 10;
11929
+ const validation = Joi49.object({
11930
+ status: Joi49.string().required(),
11931
+ search: Joi49.string().optional().allow("", null),
11932
+ page: Joi49.number().required(),
11933
+ limit: Joi49.number().required()
11934
+ });
11935
+ const { error } = validation.validate({ status, search, page, limit });
11936
+ if (error) {
11937
+ next(new BadRequestError58(error.message));
11938
+ return;
11939
+ }
11940
+ try {
11941
+ const promos = await _getAll({ status, search, page, limit });
11942
+ res.json(promos);
11943
+ return;
11944
+ } catch (error2) {
11945
+ next(error2);
11946
+ }
11947
+ }
11948
+ async function getByCode(req, res, next) {
11949
+ const code = req.params.code;
11950
+ const validation = Joi49.string().min(3).max(50).required();
11951
+ const { error } = validation.validate(code);
11952
+ if (error) {
11953
+ next(new BadRequestError58(error.message));
11954
+ return;
11955
+ }
11956
+ try {
11957
+ const promo = await _getByCode(code);
11958
+ res.json(promo);
11959
+ return;
11960
+ } catch (error2) {
11961
+ next(error2);
11962
+ }
11963
+ }
11964
+ async function getById(req, res, next) {
11965
+ const id = req.params.id;
11966
+ const validation = Joi49.string().hex().length(24).required();
11967
+ const { error } = validation.validate(id);
11968
+ if (error) {
11969
+ next(new BadRequestError58(error.message));
11970
+ return;
11971
+ }
11972
+ try {
11973
+ const promo = await _getById(id);
11974
+ res.json(promo);
11975
+ return;
11976
+ } catch (error2) {
11977
+ next(error2);
11978
+ }
11979
+ }
11980
+ async function updateById(req, res, next) {
11981
+ const id = req.params.id;
11982
+ const value = req.body;
11983
+ const validationId = Joi49.string().hex().length(24).required();
11984
+ const { error: errorId } = validationId.validate(id);
11985
+ if (errorId) {
11986
+ next(new BadRequestError58(errorId.message));
11987
+ return;
11988
+ }
11989
+ const { error } = schemaPromo.validate(value);
11990
+ if (error) {
11991
+ next(new BadRequestError58(error.message));
11992
+ return;
11993
+ }
11994
+ try {
11995
+ const message = await _updateById(id, value);
11996
+ res.json({ message });
11997
+ return;
11998
+ } catch (error2) {
11999
+ next(error2);
12000
+ }
12001
+ }
12002
+ const { deleteById: _deleteById } = usePromoService();
12003
+ async function deleteById(req, res, next) {
12004
+ const id = req.params.id;
12005
+ const validation = Joi49.string().hex().length(24).required();
12006
+ const { error } = validation.validate(id);
12007
+ if (error) {
12008
+ next(new BadRequestError58(error.message));
12009
+ return;
12010
+ }
12011
+ try {
12012
+ const message = await _deleteById(id);
12013
+ res.json({ message });
12014
+ return;
12015
+ } catch (error2) {
12016
+ next(error2);
12017
+ }
12018
+ }
12019
+ return {
12020
+ add,
12021
+ getAll,
12022
+ getByCode,
12023
+ getById,
12024
+ updateById,
12025
+ deleteById
12026
+ };
12027
+ }
12028
+
12029
+ // src/resources/job-post/job.post.model.ts
12030
+ import { BadRequestError as BadRequestError59 } from "@goweekdays/utils";
12031
+ import Joi50 from "joi";
12032
+ import { ObjectId as ObjectId29 } from "mongodb";
12033
+ var schemaJobPost = Joi50.object({
12034
+ _id: Joi50.string().hex().optional(),
12035
+ org: Joi50.string().hex().required(),
12036
+ title: Joi50.string().trim().required(),
12037
+ setup: Joi50.string().trim().required(),
12038
+ location: Joi50.string().trim().required(),
12039
+ type: Joi50.string().trim().required(),
12040
+ description: Joi50.string().trim().required(),
12041
+ status: Joi50.string().trim().optional().allow("", null),
12042
+ createdAt: Joi50.date().optional(),
12043
+ updatedAt: Joi50.date().optional(),
12044
+ deletedAt: Joi50.date().optional()
12045
+ });
12046
+ var schemaJobPostUpdate = Joi50.object({
12047
+ _id: Joi50.string().hex().required(),
12048
+ title: Joi50.string().trim().required(),
12049
+ setup: Joi50.string().trim().required(),
12050
+ location: Joi50.string().trim().required(),
12051
+ type: Joi50.string().trim().required(),
12052
+ description: Joi50.string().trim().required()
12053
+ });
12054
+ function modelJobPost(value) {
12055
+ const { error } = schemaJobPost.validate(value);
12056
+ if (error) {
12057
+ throw new BadRequestError59(`Invalid job post: ${error.message}`);
12058
+ }
12059
+ if (!value._id) {
12060
+ try {
12061
+ value._id = new ObjectId29();
12062
+ } catch (error2) {
12063
+ throw new BadRequestError59("Invalid job post ID.");
12064
+ }
12065
+ }
12066
+ try {
12067
+ value.org = new ObjectId29(value.org);
12068
+ } catch (error2) {
12069
+ throw new BadRequestError59("Invalid Org ID");
12070
+ }
12071
+ return {
12072
+ _id: value._id,
12073
+ org: value.org,
12074
+ title: value.title,
12075
+ setup: value.setup,
12076
+ location: value.location,
12077
+ type: value.type,
12078
+ description: value.description,
12079
+ status: value.status ?? "draft",
12080
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
12081
+ updatedAt: value.updatedAt,
12082
+ deletedAt: value.deletedAt
12083
+ };
12084
+ }
12085
+
12086
+ // src/resources/job-post/job.post.controller.ts
12087
+ import Joi52 from "joi";
12088
+ import { BadRequestError as BadRequestError62, logger as logger35 } from "@goweekdays/utils";
12089
+
12090
+ // src/resources/job-post/job.post.repository.ts
12091
+ import {
12092
+ AppError as AppError29,
12093
+ BadRequestError as BadRequestError60,
12094
+ useAtlas as useAtlas28,
12095
+ useCache as useCache21,
12096
+ makeCacheKey as makeCacheKey20,
12097
+ paginate as paginate17,
12098
+ logger as logger34,
12099
+ InternalServerError as InternalServerError31
12100
+ } from "@goweekdays/utils";
12101
+ import { ObjectId as ObjectId30 } from "mongodb";
12102
+ function useJobPostRepo() {
12103
+ const db = useAtlas28.getDb();
12104
+ if (!db) {
12105
+ throw new BadRequestError60("Unable to connect to server.");
12106
+ }
12107
+ const namespace_collection = "job.posts";
12108
+ const collection = db.collection(namespace_collection);
12109
+ const { getCache, setCache, delNamespace } = useCache21(namespace_collection);
12110
+ function delCachedData() {
12111
+ delNamespace().then(() => {
12112
+ logger34.log({
12113
+ level: "info",
12114
+ message: `Cache namespace cleared for ${namespace_collection}`
12115
+ });
12116
+ }).catch((err) => {
12117
+ logger34.log({
12118
+ level: "error",
12119
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
12120
+ });
12121
+ });
12122
+ }
12123
+ async function createIndexes() {
12124
+ try {
12125
+ await collection.createIndexes([
12126
+ { key: { title: 1 } },
12127
+ { key: { setup: 1 } },
12128
+ { key: { location: 1 } },
12129
+ { key: { type: 1 } },
12130
+ {
12131
+ key: {
12132
+ title: "text",
12133
+ setup: "text",
12134
+ location: "text",
12135
+ type: "text"
12136
+ },
12137
+ name: "jobpost_text_search"
12138
+ }
12139
+ ]);
12140
+ return "Successfully created job post indexes.";
12141
+ } catch (error) {
12142
+ throw new BadRequestError60("Failed to create job post indexes.");
12143
+ }
12144
+ }
12145
+ async function add(value, session) {
12146
+ try {
12147
+ value = modelJobPost(value);
12148
+ const res = await collection.insertOne(value, { session });
12149
+ delCachedData();
12150
+ return res.insertedId;
12151
+ } catch (error) {
12152
+ logger34.log({
12153
+ level: "error",
12154
+ message: error.message
12155
+ });
12156
+ throw new BadRequestError60(`Failed to create job post: ${error.message}`);
12157
+ }
12158
+ }
12159
+ async function getAll({
12160
+ search = "",
12161
+ page = 1,
12162
+ limit = 10,
12163
+ status = "active"
12164
+ } = {}) {
12165
+ page = page > 0 ? page - 1 : 0;
12166
+ const query = { status };
12167
+ if (search) {
12168
+ query.$text = { $search: search };
12169
+ }
12170
+ const cacheKey = makeCacheKey20(namespace_collection, {
12171
+ search,
12172
+ page,
12173
+ limit,
12174
+ status
12175
+ });
12176
+ logger34.log({
12177
+ level: "info",
12178
+ message: `Cache key for getAll job posts: ${cacheKey}`
12179
+ });
12180
+ try {
12181
+ const cached = await getCache(cacheKey);
12182
+ if (cached) {
12183
+ logger34.log({
12184
+ level: "info",
12185
+ message: `Cache hit for getAll job posts: ${cacheKey}`
12186
+ });
12187
+ return cached;
12188
+ }
12189
+ const items = await collection.aggregate([
12190
+ { $match: query },
12191
+ { $skip: page * limit },
12192
+ { $limit: limit },
12193
+ {
12194
+ $project: {
12195
+ _id: 1,
12196
+ title: 1,
11582
12197
  setup: 1,
11583
12198
  location: 1,
11584
12199
  type: 1,
@@ -11587,21 +12202,21 @@ function useJobPostRepo() {
11587
12202
  }
11588
12203
  ]).toArray();
11589
12204
  const length = await collection.countDocuments(query);
11590
- const data = paginate16(items, page, limit, length);
12205
+ const data = paginate17(items, page, limit, length);
11591
12206
  setCache(cacheKey, data, 600).then(() => {
11592
- logger32.log({
12207
+ logger34.log({
11593
12208
  level: "info",
11594
12209
  message: `Cache set for getAll job posts: ${cacheKey}`
11595
12210
  });
11596
12211
  }).catch((err) => {
11597
- logger32.log({
12212
+ logger34.log({
11598
12213
  level: "error",
11599
12214
  message: `Failed to set cache for getAll job posts: ${err.message}`
11600
12215
  });
11601
12216
  });
11602
12217
  return data;
11603
12218
  } catch (error) {
11604
- logger32.log({ level: "error", message: `${error}` });
12219
+ logger34.log({ level: "error", message: `${error}` });
11605
12220
  throw error;
11606
12221
  }
11607
12222
  }
@@ -11614,9 +12229,9 @@ function useJobPostRepo() {
11614
12229
  } = {}) {
11615
12230
  page = page > 0 ? page - 1 : 0;
11616
12231
  try {
11617
- org = new ObjectId28(org);
12232
+ org = new ObjectId30(org);
11618
12233
  } catch (error) {
11619
- throw new BadRequestError56("Invalid organization ID.");
12234
+ throw new BadRequestError60("Invalid organization ID.");
11620
12235
  }
11621
12236
  const query = { org, status };
11622
12237
  const cacheKeyOptions = {
@@ -11630,12 +12245,12 @@ function useJobPostRepo() {
11630
12245
  query.$text = { $search: search };
11631
12246
  }
11632
12247
  try {
11633
- const cacheKey = makeCacheKey19(namespace_collection, cacheKeyOptions);
12248
+ const cacheKey = makeCacheKey20(namespace_collection, cacheKeyOptions);
11634
12249
  const cached = await getCache(
11635
12250
  cacheKey
11636
12251
  );
11637
12252
  if (cached) {
11638
- logger32.log({
12253
+ logger34.log({
11639
12254
  level: "info",
11640
12255
  message: `Cache hit for getJobPostsByOrg : ${cacheKey}`
11641
12256
  });
@@ -11657,36 +12272,36 @@ function useJobPostRepo() {
11657
12272
  }
11658
12273
  ]).toArray();
11659
12274
  const length = await collection.countDocuments(query);
11660
- const data = paginate16(items, page, limit, length);
12275
+ const data = paginate17(items, page, limit, length);
11661
12276
  setCache(cacheKey, data, 300).then(() => {
11662
- logger32.log({
12277
+ logger34.log({
11663
12278
  level: "info",
11664
12279
  message: `Cache set for getJobPostsByOrg: ${cacheKey}`
11665
12280
  });
11666
12281
  }).catch((err) => {
11667
- logger32.log({
12282
+ logger34.log({
11668
12283
  level: "error",
11669
12284
  message: `Failed to set cache for getJobPostsByOrg: ${err.message}`
11670
12285
  });
11671
12286
  });
11672
12287
  return data;
11673
12288
  } catch (error) {
11674
- throw new InternalServerError30(
12289
+ throw new InternalServerError31(
11675
12290
  "Internal server error, failed to retrieve job posts."
11676
12291
  );
11677
12292
  }
11678
12293
  }
11679
12294
  async function getById(_id) {
11680
12295
  try {
11681
- _id = new ObjectId28(_id);
12296
+ _id = new ObjectId30(_id);
11682
12297
  } catch (error) {
11683
- throw new BadRequestError56("Invalid ID.");
12298
+ throw new BadRequestError60("Invalid ID.");
11684
12299
  }
11685
- const cacheKey = makeCacheKey19(namespace_collection, { _id: String(_id) });
12300
+ const cacheKey = makeCacheKey20(namespace_collection, { _id: String(_id) });
11686
12301
  try {
11687
12302
  const cached = await getCache(cacheKey);
11688
12303
  if (cached) {
11689
- logger32.log({
12304
+ logger34.log({
11690
12305
  level: "info",
11691
12306
  message: `Cache hit for getById job post: ${cacheKey}`
11692
12307
  });
@@ -11694,37 +12309,37 @@ function useJobPostRepo() {
11694
12309
  }
11695
12310
  const result = await collection.findOne({ _id });
11696
12311
  if (!result) {
11697
- throw new BadRequestError56("Job post not found.");
12312
+ throw new BadRequestError60("Job post not found.");
11698
12313
  }
11699
12314
  setCache(cacheKey, result, 300).then(() => {
11700
- logger32.log({
12315
+ logger34.log({
11701
12316
  level: "info",
11702
12317
  message: `Cache set for job post by id: ${cacheKey}`
11703
12318
  });
11704
12319
  }).catch((err) => {
11705
- logger32.log({
12320
+ logger34.log({
11706
12321
  level: "error",
11707
12322
  message: `Failed to set cache for job post by id: ${err.message}`
11708
12323
  });
11709
12324
  });
11710
12325
  return result;
11711
12326
  } catch (error) {
11712
- if (error instanceof AppError27) {
12327
+ if (error instanceof AppError29) {
11713
12328
  throw error;
11714
12329
  } else {
11715
- throw new InternalServerError30("Failed to get job post.");
12330
+ throw new InternalServerError31("Failed to get job post.");
11716
12331
  }
11717
12332
  }
11718
12333
  }
11719
12334
  async function updateById(_id, options) {
11720
12335
  const { error } = schemaJobPostUpdate.validate({ ...options, _id });
11721
12336
  if (error) {
11722
- throw new BadRequestError56(error.message);
12337
+ throw new BadRequestError60(error.message);
11723
12338
  }
11724
12339
  try {
11725
- _id = new ObjectId28(_id);
12340
+ _id = new ObjectId30(_id);
11726
12341
  } catch (error2) {
11727
- throw new BadRequestError56("Invalid JobPost ID.");
12342
+ throw new BadRequestError60("Invalid JobPost ID.");
11728
12343
  }
11729
12344
  try {
11730
12345
  await collection.updateOne(
@@ -11734,14 +12349,14 @@ function useJobPostRepo() {
11734
12349
  delCachedData();
11735
12350
  return "Successfully updated job post.";
11736
12351
  } catch (error2) {
11737
- throw new InternalServerError30("Failed to update job post.");
12352
+ throw new InternalServerError31("Failed to update job post.");
11738
12353
  }
11739
12354
  }
11740
12355
  async function deleteById(_id, session) {
11741
12356
  try {
11742
- _id = new ObjectId28(_id);
12357
+ _id = new ObjectId30(_id);
11743
12358
  } catch (error) {
11744
- throw new BadRequestError56("Invalid ID.");
12359
+ throw new BadRequestError60("Invalid ID.");
11745
12360
  }
11746
12361
  try {
11747
12362
  await collection.updateOne(
@@ -11758,7 +12373,35 @@ function useJobPostRepo() {
11758
12373
  delCachedData();
11759
12374
  return "Successfully deleted job post.";
11760
12375
  } catch (error) {
11761
- throw new InternalServerError30("Failed to delete job post.");
12376
+ throw new InternalServerError31("Failed to delete job post.");
12377
+ }
12378
+ }
12379
+ async function updateStatusById(_id, status) {
12380
+ try {
12381
+ _id = new ObjectId30(_id);
12382
+ } catch (error) {
12383
+ throw new BadRequestError60("Invalid ID.");
12384
+ }
12385
+ try {
12386
+ const result = await collection.updateOne(
12387
+ { _id },
12388
+ {
12389
+ $set: {
12390
+ status,
12391
+ updatedAt: /* @__PURE__ */ new Date()
12392
+ }
12393
+ }
12394
+ );
12395
+ if (result.matchedCount === 0) {
12396
+ throw new BadRequestError60("Job post not found.");
12397
+ }
12398
+ delCachedData();
12399
+ return "Successfully updated job post status.";
12400
+ } catch (error) {
12401
+ if (error instanceof AppError29) {
12402
+ throw error;
12403
+ }
12404
+ throw new InternalServerError31("Failed to update job post status.");
11762
12405
  }
11763
12406
  }
11764
12407
  return {
@@ -11768,32 +12411,33 @@ function useJobPostRepo() {
11768
12411
  getJobPostsByOrg,
11769
12412
  getById,
11770
12413
  updateById,
11771
- deleteById
12414
+ deleteById,
12415
+ updateStatusById
11772
12416
  };
11773
12417
  }
11774
12418
 
11775
12419
  // src/resources/job-post/job.post.service.ts
11776
12420
  import {
11777
- AppError as AppError28,
11778
- BadRequestError as BadRequestError57,
11779
- InternalServerError as InternalServerError31
12421
+ AppError as AppError30,
12422
+ BadRequestError as BadRequestError61,
12423
+ InternalServerError as InternalServerError32
11780
12424
  } from "@goweekdays/utils";
11781
- import Joi48 from "joi";
12425
+ import Joi51 from "joi";
11782
12426
  function useJobPostService() {
11783
12427
  const { deleteById: _deleteById } = useJobPostRepo();
11784
12428
  async function deleteById(id) {
11785
- const { error } = Joi48.string().hex().required().validate(id);
12429
+ const { error } = Joi51.string().hex().required().validate(id);
11786
12430
  if (error) {
11787
- throw new BadRequestError57(error.message);
12431
+ throw new BadRequestError61(error.message);
11788
12432
  }
11789
12433
  try {
11790
12434
  await _deleteById(id);
11791
12435
  return "Successfully deleted job post.";
11792
12436
  } catch (error2) {
11793
- if (error2 instanceof AppError28) {
12437
+ if (error2 instanceof AppError30) {
11794
12438
  throw error2;
11795
12439
  } else {
11796
- throw new InternalServerError31("Failed to delete job post.");
12440
+ throw new InternalServerError32("Failed to delete job post.");
11797
12441
  }
11798
12442
  }
11799
12443
  }
@@ -11809,15 +12453,16 @@ function useJobPostController() {
11809
12453
  getAll: _getAll,
11810
12454
  getJobPostsByOrg: _getJobPostsByOrg,
11811
12455
  getById: _getById,
11812
- updateById: _updateById
12456
+ updateById: _updateById,
12457
+ updateStatusById: _updateStatusById
11813
12458
  } = useJobPostRepo();
11814
12459
  const { deleteById: _deleteById } = useJobPostService();
11815
12460
  async function add(req, res, next) {
11816
12461
  const value = req.body;
11817
12462
  const { error } = schemaJobPost.validate(value);
11818
12463
  if (error) {
11819
- next(new BadRequestError58(error.message));
11820
- logger33.info(`Controller: ${error.message}`);
12464
+ next(new BadRequestError62(error.message));
12465
+ logger35.info(`Controller: ${error.message}`);
11821
12466
  return;
11822
12467
  }
11823
12468
  try {
@@ -11830,11 +12475,11 @@ function useJobPostController() {
11830
12475
  }
11831
12476
  async function getAll(req, res, next) {
11832
12477
  const query = req.query;
11833
- const validation = Joi49.object({
11834
- page: Joi49.number().min(1).optional().allow("", null),
11835
- limit: Joi49.number().min(1).optional().allow("", null),
11836
- search: Joi49.string().optional().allow("", null),
11837
- status: Joi49.string().optional()
12478
+ const validation = Joi52.object({
12479
+ page: Joi52.number().min(1).optional().allow("", null),
12480
+ limit: Joi52.number().min(1).optional().allow("", null),
12481
+ search: Joi52.string().optional().allow("", null),
12482
+ status: Joi52.string().optional()
11838
12483
  });
11839
12484
  const { error } = validation.validate(query);
11840
12485
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -11843,16 +12488,16 @@ function useJobPostController() {
11843
12488
  const status = req.query.status ?? "active";
11844
12489
  const isPageNumber = isFinite(page);
11845
12490
  if (!isPageNumber) {
11846
- next(new BadRequestError58("Invalid page number."));
12491
+ next(new BadRequestError62("Invalid page number."));
11847
12492
  return;
11848
12493
  }
11849
12494
  const isLimitNumber = isFinite(limit);
11850
12495
  if (!isLimitNumber) {
11851
- next(new BadRequestError58("Invalid limit number."));
12496
+ next(new BadRequestError62("Invalid limit number."));
11852
12497
  return;
11853
12498
  }
11854
12499
  if (error) {
11855
- next(new BadRequestError58(error.message));
12500
+ next(new BadRequestError62(error.message));
11856
12501
  return;
11857
12502
  }
11858
12503
  try {
@@ -11871,24 +12516,24 @@ function useJobPostController() {
11871
12516
  const org = req.params.org ?? "";
11872
12517
  const isPageNumber = isFinite(page);
11873
12518
  if (!isPageNumber) {
11874
- next(new BadRequestError58("Invalid page number."));
12519
+ next(new BadRequestError62("Invalid page number."));
11875
12520
  return;
11876
12521
  }
11877
12522
  const isLimitNumber = isFinite(limit);
11878
12523
  if (!isLimitNumber) {
11879
- next(new BadRequestError58("Invalid limit number."));
12524
+ next(new BadRequestError62("Invalid limit number."));
11880
12525
  return;
11881
12526
  }
11882
- const validation = Joi49.object({
11883
- org: Joi49.string().hex().required(),
11884
- page: Joi49.number().min(1).optional().allow("", null),
11885
- limit: Joi49.number().min(1).optional().allow("", null),
11886
- search: Joi49.string().optional().allow("", null),
11887
- status: Joi49.string().optional()
12527
+ const validation = Joi52.object({
12528
+ org: Joi52.string().hex().required(),
12529
+ page: Joi52.number().min(1).optional().allow("", null),
12530
+ limit: Joi52.number().min(1).optional().allow("", null),
12531
+ search: Joi52.string().optional().allow("", null),
12532
+ status: Joi52.string().optional()
11888
12533
  });
11889
12534
  const { error } = validation.validate({ org, page, limit, search, status });
11890
12535
  if (error) {
11891
- next(new BadRequestError58(error.message));
12536
+ next(new BadRequestError62(error.message));
11892
12537
  return;
11893
12538
  }
11894
12539
  try {
@@ -11901,12 +12546,12 @@ function useJobPostController() {
11901
12546
  }
11902
12547
  async function getById(req, res, next) {
11903
12548
  const id = req.params.id;
11904
- const validation = Joi49.object({
11905
- id: Joi49.string().hex().required()
12549
+ const validation = Joi52.object({
12550
+ id: Joi52.string().hex().required()
11906
12551
  });
11907
12552
  const { error } = validation.validate({ id });
11908
12553
  if (error) {
11909
- next(new BadRequestError58(error.message));
12554
+ next(new BadRequestError62(error.message));
11910
12555
  return;
11911
12556
  }
11912
12557
  try {
@@ -11922,7 +12567,7 @@ function useJobPostController() {
11922
12567
  const payload = req.body;
11923
12568
  const { error } = schemaJobPostUpdate.validate({ _id, ...payload });
11924
12569
  if (error) {
11925
- next(new BadRequestError58(error.message));
12570
+ next(new BadRequestError62(error.message));
11926
12571
  return;
11927
12572
  }
11928
12573
  try {
@@ -11936,7 +12581,7 @@ function useJobPostController() {
11936
12581
  async function deleteById(req, res, next) {
11937
12582
  const id = req.params.id;
11938
12583
  if (!id) {
11939
- next(new BadRequestError58("Job Post ID is required."));
12584
+ next(new BadRequestError62("Job Post ID is required."));
11940
12585
  return;
11941
12586
  }
11942
12587
  try {
@@ -11947,13 +12592,34 @@ function useJobPostController() {
11947
12592
  next(error);
11948
12593
  }
11949
12594
  }
12595
+ async function updateStatusById(req, res, next) {
12596
+ const id = req.params.id;
12597
+ const status = req.params.status;
12598
+ const validation = Joi52.object({
12599
+ id: Joi52.string().hex().required(),
12600
+ status: Joi52.string().valid("draft", "open", "paused", "in-review", "closed").required()
12601
+ });
12602
+ const { error } = validation.validate({ id, status });
12603
+ if (error) {
12604
+ next(new BadRequestError62(error.message));
12605
+ return;
12606
+ }
12607
+ try {
12608
+ const message = await _updateStatusById(id, status);
12609
+ res.json({ message });
12610
+ return;
12611
+ } catch (error2) {
12612
+ next(error2);
12613
+ }
12614
+ }
11950
12615
  return {
11951
12616
  add,
11952
12617
  getAll,
11953
12618
  getJobPostsByOrg,
11954
12619
  getById,
11955
12620
  updateById,
11956
- deleteById
12621
+ deleteById,
12622
+ updateStatusById
11957
12623
  };
11958
12624
  }
11959
12625
  export {
@@ -12083,6 +12749,7 @@ export {
12083
12749
  usePlanController,
12084
12750
  usePlanRepo,
12085
12751
  usePlanService,
12752
+ usePromoController,
12086
12753
  usePromoRepo,
12087
12754
  useRoleController,
12088
12755
  useRoleRepo,