@goweekdays/core 2.9.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,76 +11613,605 @@ 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
- });
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.");
11658
+ }
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);
11565
11668
  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;
11669
+ const cachedData = await getCache(cacheKey);
11670
+ if (cachedData) {
11671
+ return cachedData;
11573
11672
  }
11574
11673
  const items = await collection.aggregate([
11575
11674
  { $match: query },
11576
11675
  { $skip: page * limit },
11577
- { $limit: 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
+ orgName: Joi50.string().optional().allow("", null),
12037
+ title: Joi50.string().trim().required(),
12038
+ setup: Joi50.string().trim().required(),
12039
+ location: Joi50.string().trim().required(),
12040
+ type: Joi50.string().trim().required(),
12041
+ minSalary: Joi50.number().optional(),
12042
+ maxSalary: Joi50.number().optional(),
12043
+ currency: Joi50.string().trim().optional(),
12044
+ payPeriod: Joi50.string().trim().optional(),
12045
+ description: Joi50.string().trim().required(),
12046
+ status: Joi50.string().trim().optional().allow("", null),
12047
+ createdAt: Joi50.date().optional(),
12048
+ updatedAt: Joi50.date().optional(),
12049
+ deletedAt: Joi50.date().optional()
12050
+ });
12051
+ var schemaJobPostUpdate = Joi50.object({
12052
+ _id: Joi50.string().hex().required(),
12053
+ title: Joi50.string().trim().required(),
12054
+ setup: Joi50.string().trim().required(),
12055
+ location: Joi50.string().trim().required(),
12056
+ type: Joi50.string().trim().required(),
12057
+ minSalary: Joi50.number().optional(),
12058
+ maxSalary: Joi50.number().optional(),
12059
+ currency: Joi50.string().trim().optional(),
12060
+ payPeriod: Joi50.string().trim().optional(),
12061
+ description: Joi50.string().trim().required()
12062
+ });
12063
+ function modelJobPost(value) {
12064
+ const { error } = schemaJobPost.validate(value);
12065
+ if (error) {
12066
+ throw new BadRequestError59(`Invalid job post: ${error.message}`);
12067
+ }
12068
+ if (!value._id) {
12069
+ try {
12070
+ value._id = new ObjectId29();
12071
+ } catch (error2) {
12072
+ throw new BadRequestError59("Invalid job post ID.");
12073
+ }
12074
+ }
12075
+ try {
12076
+ value.org = new ObjectId29(value.org);
12077
+ } catch (error2) {
12078
+ throw new BadRequestError59("Invalid Org ID");
12079
+ }
12080
+ return {
12081
+ _id: value._id,
12082
+ org: value.org,
12083
+ orgName: value.orgName ?? "",
12084
+ title: value.title,
12085
+ setup: value.setup,
12086
+ location: value.location,
12087
+ type: value.type,
12088
+ minSalary: value.minSalary,
12089
+ maxSalary: value.maxSalary ?? 0,
12090
+ currency: value.currency ?? "PHP",
12091
+ payPeriod: value.payPeriod ?? "monthly",
12092
+ description: value.description,
12093
+ status: value.status ?? "draft",
12094
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
12095
+ updatedAt: value.updatedAt ?? "",
12096
+ deletedAt: value.deletedAt ?? ""
12097
+ };
12098
+ }
12099
+
12100
+ // src/resources/job-post/job.post.controller.ts
12101
+ import Joi53 from "joi";
12102
+ import { BadRequestError as BadRequestError64, logger as logger36 } from "@goweekdays/utils";
12103
+
12104
+ // src/resources/job-post/job.post.repository.ts
12105
+ import {
12106
+ AppError as AppError29,
12107
+ BadRequestError as BadRequestError60,
12108
+ useAtlas as useAtlas28,
12109
+ useCache as useCache21,
12110
+ makeCacheKey as makeCacheKey20,
12111
+ paginate as paginate17,
12112
+ logger as logger34,
12113
+ InternalServerError as InternalServerError31
12114
+ } from "@goweekdays/utils";
12115
+ import { ObjectId as ObjectId30 } from "mongodb";
12116
+ function useJobPostRepo() {
12117
+ const db = useAtlas28.getDb();
12118
+ if (!db) {
12119
+ throw new BadRequestError60("Unable to connect to server.");
12120
+ }
12121
+ const namespace_collection = "job.posts";
12122
+ const collection = db.collection(namespace_collection);
12123
+ const { getCache, setCache, delNamespace } = useCache21(namespace_collection);
12124
+ function delCachedData() {
12125
+ delNamespace().then(() => {
12126
+ logger34.log({
12127
+ level: "info",
12128
+ message: `Cache namespace cleared for ${namespace_collection}`
12129
+ });
12130
+ }).catch((err) => {
12131
+ logger34.log({
12132
+ level: "error",
12133
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
12134
+ });
12135
+ });
12136
+ }
12137
+ async function createIndexes() {
12138
+ try {
12139
+ await collection.createIndexes([
12140
+ { key: { title: 1 } },
12141
+ { key: { setup: 1 } },
12142
+ { key: { location: 1 } },
12143
+ { key: { type: 1 } },
12144
+ {
12145
+ key: {
12146
+ title: "text",
12147
+ setup: "text",
12148
+ location: "text",
12149
+ type: "text"
12150
+ },
12151
+ name: "jobpost_text_search"
12152
+ }
12153
+ ]);
12154
+ return "Successfully created job post indexes.";
12155
+ } catch (error) {
12156
+ throw new BadRequestError60("Failed to create job post indexes.");
12157
+ }
12158
+ }
12159
+ async function add(value, session) {
12160
+ try {
12161
+ value = modelJobPost(value);
12162
+ const res = await collection.insertOne(value, { session });
12163
+ delCachedData();
12164
+ return res.insertedId;
12165
+ } catch (error) {
12166
+ logger34.log({
12167
+ level: "error",
12168
+ message: error.message
12169
+ });
12170
+ throw new BadRequestError60(`Failed to create job post: ${error.message}`);
12171
+ }
12172
+ }
12173
+ async function getAll({
12174
+ search = "",
12175
+ page = 1,
12176
+ limit = 10,
12177
+ status = "active"
12178
+ } = {}) {
12179
+ page = page > 0 ? page - 1 : 0;
12180
+ const query = { status };
12181
+ if (search) {
12182
+ query.$text = { $search: search };
12183
+ }
12184
+ const cacheKey = makeCacheKey20(namespace_collection, {
12185
+ search,
12186
+ page,
12187
+ limit,
12188
+ status
12189
+ });
12190
+ logger34.log({
12191
+ level: "info",
12192
+ message: `Cache key for getAll job posts: ${cacheKey}`
12193
+ });
12194
+ try {
12195
+ const cached = await getCache(cacheKey);
12196
+ if (cached) {
12197
+ logger34.log({
12198
+ level: "info",
12199
+ message: `Cache hit for getAll job posts: ${cacheKey}`
12200
+ });
12201
+ return cached;
12202
+ }
12203
+ const items = await collection.aggregate([
12204
+ { $match: query },
12205
+ { $skip: page * limit },
12206
+ { $limit: limit },
11578
12207
  {
11579
12208
  $project: {
11580
12209
  _id: 1,
12210
+ orgName: 1,
12211
+ minSalary: 1,
12212
+ maxSalary: 1,
12213
+ currency: 1,
12214
+ payPeriod: 1,
11581
12215
  title: 1,
11582
12216
  setup: 1,
11583
12217
  location: 1,
@@ -11587,36 +12221,30 @@ function useJobPostRepo() {
11587
12221
  }
11588
12222
  ]).toArray();
11589
12223
  const length = await collection.countDocuments(query);
11590
- const data = paginate16(items, page, limit, length);
12224
+ const data = paginate17(items, page, limit, length);
11591
12225
  setCache(cacheKey, data, 600).then(() => {
11592
- logger32.log({
12226
+ logger34.log({
11593
12227
  level: "info",
11594
12228
  message: `Cache set for getAll job posts: ${cacheKey}`
11595
12229
  });
11596
12230
  }).catch((err) => {
11597
- logger32.log({
12231
+ logger34.log({
11598
12232
  level: "error",
11599
12233
  message: `Failed to set cache for getAll job posts: ${err.message}`
11600
12234
  });
11601
12235
  });
11602
12236
  return data;
11603
12237
  } catch (error) {
11604
- logger32.log({ level: "error", message: `${error}` });
12238
+ logger34.log({ level: "error", message: `${error}` });
11605
12239
  throw error;
11606
12240
  }
11607
12241
  }
11608
- async function getJobPostsByOrg({
11609
- search = "",
11610
- page = 1,
11611
- limit = 10,
11612
- org = "",
11613
- status = "active"
11614
- } = {}) {
12242
+ async function getJobPostsByOrg({ search = "", page = 1, limit = 10, org = "", status = "active" } = {}) {
11615
12243
  page = page > 0 ? page - 1 : 0;
11616
12244
  try {
11617
- org = new ObjectId28(org);
12245
+ org = new ObjectId30(org);
11618
12246
  } catch (error) {
11619
- throw new BadRequestError56("Invalid organization ID.");
12247
+ throw new BadRequestError60("Invalid organization ID.");
11620
12248
  }
11621
12249
  const query = { org, status };
11622
12250
  const cacheKeyOptions = {
@@ -11626,203 +12254,500 @@ function useJobPostRepo() {
11626
12254
  page
11627
12255
  };
11628
12256
  if (search) {
11629
- cacheKeyOptions.search = search;
12257
+ cacheKeyOptions.search = search;
12258
+ query.$text = { $search: search };
12259
+ }
12260
+ try {
12261
+ const cacheKey = makeCacheKey20(namespace_collection, cacheKeyOptions);
12262
+ const cached = await getCache(
12263
+ cacheKey
12264
+ );
12265
+ if (cached) {
12266
+ logger34.log({
12267
+ level: "info",
12268
+ message: `Cache hit for getJobPostsByOrg : ${cacheKey}`
12269
+ });
12270
+ return cached;
12271
+ }
12272
+ const items = await collection.aggregate([
12273
+ { $match: query },
12274
+ { $skip: page * limit },
12275
+ { $limit: limit },
12276
+ {
12277
+ $project: {
12278
+ _id: 1,
12279
+ title: 1,
12280
+ setup: 1,
12281
+ location: 1,
12282
+ type: 1,
12283
+ createdAt: 1
12284
+ }
12285
+ }
12286
+ ]).toArray();
12287
+ const length = await collection.countDocuments(query);
12288
+ const data = paginate17(items, page, limit, length);
12289
+ setCache(cacheKey, data, 300).then(() => {
12290
+ logger34.log({
12291
+ level: "info",
12292
+ message: `Cache set for getJobPostsByOrg: ${cacheKey}`
12293
+ });
12294
+ }).catch((err) => {
12295
+ logger34.log({
12296
+ level: "error",
12297
+ message: `Failed to set cache for getJobPostsByOrg: ${err.message}`
12298
+ });
12299
+ });
12300
+ return data;
12301
+ } catch (error) {
12302
+ throw new InternalServerError31(
12303
+ "Internal server error, failed to retrieve job posts."
12304
+ );
12305
+ }
12306
+ }
12307
+ async function getById(_id) {
12308
+ try {
12309
+ _id = new ObjectId30(_id);
12310
+ } catch (error) {
12311
+ throw new BadRequestError60("Invalid ID.");
12312
+ }
12313
+ const cacheKey = makeCacheKey20(namespace_collection, { _id: String(_id) });
12314
+ try {
12315
+ const cached = await getCache(cacheKey);
12316
+ if (cached) {
12317
+ logger34.log({
12318
+ level: "info",
12319
+ message: `Cache hit for getById job post: ${cacheKey}`
12320
+ });
12321
+ return cached;
12322
+ }
12323
+ const result = await collection.findOne({ _id });
12324
+ if (!result) {
12325
+ throw new BadRequestError60("Job post not found.");
12326
+ }
12327
+ setCache(cacheKey, result, 300).then(() => {
12328
+ logger34.log({
12329
+ level: "info",
12330
+ message: `Cache set for job post by id: ${cacheKey}`
12331
+ });
12332
+ }).catch((err) => {
12333
+ logger34.log({
12334
+ level: "error",
12335
+ message: `Failed to set cache for job post by id: ${err.message}`
12336
+ });
12337
+ });
12338
+ return result;
12339
+ } catch (error) {
12340
+ if (error instanceof AppError29) {
12341
+ throw error;
12342
+ } else {
12343
+ throw new InternalServerError31("Failed to get job post.");
12344
+ }
12345
+ }
12346
+ }
12347
+ async function updateById(_id, options) {
12348
+ const { error } = schemaJobPostUpdate.validate({ ...options, _id });
12349
+ if (error) {
12350
+ throw new BadRequestError60(error.message);
12351
+ }
12352
+ try {
12353
+ _id = new ObjectId30(_id);
12354
+ } catch (error2) {
12355
+ throw new BadRequestError60("Invalid JobPost ID.");
12356
+ }
12357
+ try {
12358
+ await collection.updateOne(
12359
+ { _id },
12360
+ { $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } }
12361
+ );
12362
+ delCachedData();
12363
+ return "Successfully updated job post.";
12364
+ } catch (error2) {
12365
+ throw new InternalServerError31("Failed to update job post.");
12366
+ }
12367
+ }
12368
+ async function deleteById(_id, session) {
12369
+ try {
12370
+ _id = new ObjectId30(_id);
12371
+ } catch (error) {
12372
+ throw new BadRequestError60("Invalid ID.");
12373
+ }
12374
+ try {
12375
+ await collection.updateOne(
12376
+ { _id },
12377
+ {
12378
+ $set: {
12379
+ status: "deleted",
12380
+ updatedAt: /* @__PURE__ */ new Date(),
12381
+ deletedAt: /* @__PURE__ */ new Date()
12382
+ }
12383
+ },
12384
+ { session }
12385
+ );
12386
+ delCachedData();
12387
+ return "Successfully deleted job post.";
12388
+ } catch (error) {
12389
+ throw new InternalServerError31("Failed to delete job post.");
12390
+ }
12391
+ }
12392
+ async function updateStatusById(_id, status) {
12393
+ try {
12394
+ _id = new ObjectId30(_id);
12395
+ } catch (error) {
12396
+ throw new BadRequestError60("Invalid ID.");
12397
+ }
12398
+ try {
12399
+ const result = await collection.updateOne(
12400
+ { _id },
12401
+ {
12402
+ $set: {
12403
+ status,
12404
+ updatedAt: /* @__PURE__ */ new Date()
12405
+ }
12406
+ }
12407
+ );
12408
+ if (result.matchedCount === 0) {
12409
+ throw new BadRequestError60("Job post not found.");
12410
+ }
12411
+ delCachedData();
12412
+ return "Successfully updated job post status.";
12413
+ } catch (error) {
12414
+ if (error instanceof AppError29) {
12415
+ throw error;
12416
+ }
12417
+ throw new InternalServerError31("Failed to update job post status.");
12418
+ }
12419
+ }
12420
+ return {
12421
+ createIndexes,
12422
+ add,
12423
+ getAll,
12424
+ getJobPostsByOrg,
12425
+ getById,
12426
+ updateById,
12427
+ deleteById,
12428
+ updateStatusById
12429
+ };
12430
+ }
12431
+
12432
+ // src/resources/job-post/job.post.service.ts
12433
+ import {
12434
+ AppError as AppError31,
12435
+ BadRequestError as BadRequestError63,
12436
+ InternalServerError as InternalServerError33,
12437
+ useAtlas as useAtlas30
12438
+ } from "@goweekdays/utils";
12439
+ import Joi52 from "joi";
12440
+
12441
+ // src/resources/job-post/job.post.attr.repository.ts
12442
+ import {
12443
+ AppError as AppError30,
12444
+ BadRequestError as BadRequestError62,
12445
+ InternalServerError as InternalServerError32,
12446
+ logger as logger35,
12447
+ makeCacheKey as makeCacheKey21,
12448
+ paginate as paginate18,
12449
+ useAtlas as useAtlas29,
12450
+ useCache as useCache22
12451
+ } from "@goweekdays/utils";
12452
+
12453
+ // src/resources/job-post/job.post.attr.model.ts
12454
+ import { BadRequestError as BadRequestError61 } from "@goweekdays/utils";
12455
+ import Joi51 from "joi";
12456
+ import { ObjectId as ObjectId31 } from "mongodb";
12457
+ var schemaJobPostAttr = Joi51.string().min(2).max(100).required();
12458
+ function modelJobPostAttr(value) {
12459
+ const { error } = schemaJobPostAttr.validate(value.name);
12460
+ if (error) {
12461
+ throw new BadRequestError61(`Invalid job post attribute: ${error.message}`);
12462
+ }
12463
+ if (value._id && typeof value._id === "string") {
12464
+ try {
12465
+ value._id = new ObjectId31(value._id);
12466
+ } catch (error2) {
12467
+ throw new BadRequestError61(`Invalid job post attribute id: ${error2}`);
12468
+ }
12469
+ }
12470
+ return {
12471
+ _id: value._id,
12472
+ name: value.name,
12473
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date()
12474
+ };
12475
+ }
12476
+
12477
+ // src/resources/job-post/job.post.attr.repository.ts
12478
+ function useJobPostAttrRepo(namespace_collection) {
12479
+ const db = useAtlas29.getDb();
12480
+ if (!db) {
12481
+ throw new BadRequestError62("Unable to connect to server.");
12482
+ }
12483
+ const collection = db.collection(namespace_collection);
12484
+ const { getCache, setCache, delNamespace } = useCache22(namespace_collection);
12485
+ function delCachedData() {
12486
+ delNamespace().then(() => {
12487
+ logger35.log({
12488
+ level: "info",
12489
+ message: `Cache namespace cleared for ${namespace_collection}`
12490
+ });
12491
+ }).catch((err) => {
12492
+ logger35.log({
12493
+ level: "error",
12494
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
12495
+ });
12496
+ });
12497
+ }
12498
+ async function createIndexes() {
12499
+ try {
12500
+ await collection.createIndexes([
12501
+ { key: { name: 1 } },
12502
+ { key: { createdAt: 1 } },
12503
+ { key: { name: "text" } },
12504
+ { key: { name: 1 }, unique: true, name: "unique_location" }
12505
+ ]);
12506
+ return "Successfully created job post location indexes.";
12507
+ } catch (error) {
12508
+ throw new BadRequestError62("Failed to create job post location indexes.");
12509
+ }
12510
+ }
12511
+ async function add(value, session) {
12512
+ try {
12513
+ value = modelJobPostAttr(value);
12514
+ const res = await collection.insertOne(value, { session });
12515
+ delCachedData();
12516
+ return res.insertedId;
12517
+ } catch (error) {
12518
+ logger35.log({
12519
+ level: "error",
12520
+ message: error.message
12521
+ });
12522
+ throw new BadRequestError62(
12523
+ `Failed to create job post location: ${error.message}`
12524
+ );
12525
+ }
12526
+ }
12527
+ async function getAll({ search = "", page = 1, limit = 10 } = {}) {
12528
+ page = page > 0 ? page - 1 : 0;
12529
+ const query = {};
12530
+ if (search) {
11630
12531
  query.$text = { $search: search };
11631
12532
  }
12533
+ const cacheKey = makeCacheKey21(namespace_collection, {
12534
+ search,
12535
+ page,
12536
+ limit
12537
+ });
12538
+ logger35.log({
12539
+ level: "info",
12540
+ message: `Cache key for getAll job post locations: ${cacheKey}`
12541
+ });
11632
12542
  try {
11633
- const cacheKey = makeCacheKey19(namespace_collection, cacheKeyOptions);
11634
- const cached = await getCache(
11635
- cacheKey
11636
- );
12543
+ const cached = await getCache(cacheKey);
11637
12544
  if (cached) {
11638
- logger32.log({
12545
+ logger35.log({
11639
12546
  level: "info",
11640
- message: `Cache hit for getJobPostsByOrg : ${cacheKey}`
12547
+ message: `Cache hit for getAll job post locations: ${cacheKey}`
11641
12548
  });
11642
12549
  return cached;
11643
12550
  }
11644
- const items = await collection.aggregate([
12551
+ let items = await collection.aggregate([
11645
12552
  { $match: query },
11646
12553
  { $skip: page * limit },
11647
- { $limit: limit },
11648
- {
11649
- $project: {
11650
- _id: 1,
11651
- title: 1,
11652
- setup: 1,
11653
- location: 1,
11654
- type: 1,
11655
- createdAt: 1
11656
- }
11657
- }
12554
+ { $limit: limit }
11658
12555
  ]).toArray();
12556
+ if (items) {
12557
+ items = items.map((item) => item.name);
12558
+ }
11659
12559
  const length = await collection.countDocuments(query);
11660
- const data = paginate16(items, page, limit, length);
11661
- setCache(cacheKey, data, 300).then(() => {
11662
- logger32.log({
12560
+ const data = paginate18(items, page, limit, length);
12561
+ setCache(cacheKey, data, 600).then(() => {
12562
+ logger35.log({
11663
12563
  level: "info",
11664
- message: `Cache set for getJobPostsByOrg: ${cacheKey}`
12564
+ message: `Cache set for getAll job post locations: ${cacheKey}`
11665
12565
  });
11666
12566
  }).catch((err) => {
11667
- logger32.log({
12567
+ logger35.log({
11668
12568
  level: "error",
11669
- message: `Failed to set cache for getJobPostsByOrg: ${err.message}`
12569
+ message: `Failed to set cache for getAll job post locations: ${err.message}`
11670
12570
  });
11671
12571
  });
11672
12572
  return data;
11673
12573
  } catch (error) {
11674
- throw new InternalServerError30(
11675
- "Internal server error, failed to retrieve job posts."
11676
- );
12574
+ logger35.log({ level: "error", message: `${error}` });
12575
+ throw error;
11677
12576
  }
11678
12577
  }
11679
- async function getById(_id) {
11680
- try {
11681
- _id = new ObjectId28(_id);
11682
- } catch (error) {
11683
- throw new BadRequestError56("Invalid ID.");
11684
- }
11685
- const cacheKey = makeCacheKey19(namespace_collection, { _id: String(_id) });
12578
+ async function getByName(name) {
12579
+ const cacheKey = makeCacheKey21(namespace_collection, {
12580
+ name,
12581
+ tag: "by-name"
12582
+ });
11686
12583
  try {
11687
12584
  const cached = await getCache(cacheKey);
11688
12585
  if (cached) {
11689
- logger32.log({
12586
+ logger35.log({
11690
12587
  level: "info",
11691
- message: `Cache hit for getById job post: ${cacheKey}`
12588
+ message: `Cache hit for getById job post location: ${cacheKey}`
11692
12589
  });
11693
12590
  return cached;
11694
12591
  }
11695
- const result = await collection.findOne({ _id });
11696
- if (!result) {
11697
- throw new BadRequestError56("Job post not found.");
11698
- }
12592
+ const result = await collection.findOne({ name });
11699
12593
  setCache(cacheKey, result, 300).then(() => {
11700
- logger32.log({
12594
+ logger35.log({
11701
12595
  level: "info",
11702
- message: `Cache set for job post by id: ${cacheKey}`
12596
+ message: `Cache set for job post by location: ${cacheKey}`
11703
12597
  });
11704
12598
  }).catch((err) => {
11705
- logger32.log({
12599
+ logger35.log({
11706
12600
  level: "error",
11707
- message: `Failed to set cache for job post by id: ${err.message}`
12601
+ message: `Failed to set cache for job post by location: ${err.message}`
11708
12602
  });
11709
12603
  });
11710
12604
  return result;
11711
12605
  } catch (error) {
11712
- if (error instanceof AppError27) {
12606
+ if (error instanceof AppError30) {
11713
12607
  throw error;
11714
12608
  } else {
11715
- throw new InternalServerError30("Failed to get job post.");
12609
+ throw new InternalServerError32("Failed to get job post.");
11716
12610
  }
11717
12611
  }
11718
12612
  }
11719
- async function updateById(_id, options) {
11720
- const { error } = schemaJobPostUpdate.validate({ ...options, _id });
11721
- if (error) {
11722
- throw new BadRequestError56(error.message);
11723
- }
11724
- try {
11725
- _id = new ObjectId28(_id);
11726
- } catch (error2) {
11727
- throw new BadRequestError56("Invalid JobPost ID.");
11728
- }
11729
- try {
11730
- await collection.updateOne(
11731
- { _id },
11732
- { $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } }
11733
- );
11734
- delCachedData();
11735
- return "Successfully updated job post.";
11736
- } catch (error2) {
11737
- throw new InternalServerError30("Failed to update job post.");
11738
- }
11739
- }
11740
- async function deleteById(_id, session) {
11741
- try {
11742
- _id = new ObjectId28(_id);
11743
- } catch (error) {
11744
- throw new BadRequestError56("Invalid ID.");
11745
- }
11746
- try {
11747
- await collection.updateOne(
11748
- { _id },
11749
- {
11750
- $set: {
11751
- status: "deleted",
11752
- updatedAt: /* @__PURE__ */ new Date(),
11753
- deletedAt: /* @__PURE__ */ new Date()
11754
- }
11755
- },
11756
- { session }
11757
- );
11758
- delCachedData();
11759
- return "Successfully deleted job post.";
11760
- } catch (error) {
11761
- throw new InternalServerError30("Failed to delete job post.");
11762
- }
11763
- }
11764
12613
  return {
11765
12614
  createIndexes,
12615
+ delCachedData,
11766
12616
  add,
11767
12617
  getAll,
11768
- getJobPostsByOrg,
11769
- getById,
11770
- updateById,
11771
- deleteById
12618
+ getByName
11772
12619
  };
11773
12620
  }
11774
12621
 
11775
12622
  // src/resources/job-post/job.post.service.ts
11776
- import {
11777
- AppError as AppError28,
11778
- BadRequestError as BadRequestError57,
11779
- InternalServerError as InternalServerError31
11780
- } from "@goweekdays/utils";
11781
- import Joi48 from "joi";
11782
12623
  function useJobPostService() {
11783
- const { deleteById: _deleteById } = useJobPostRepo();
12624
+ const {
12625
+ add: _add,
12626
+ deleteById: _deleteById,
12627
+ getById: _getById,
12628
+ updateStatusById: _updateStatusById
12629
+ } = useJobPostRepo();
12630
+ const { getById: getOrgById } = useOrgRepo();
12631
+ const { getByName: getLocationByName, add: addLocation } = useJobPostAttrRepo("job.post.locations");
12632
+ const { getByName: getJobTitleByName, add: addJobTitle } = useJobPostAttrRepo("job.post.titles");
12633
+ const { getByName: getCurrencyByName, add: addCurrency } = useJobPostAttrRepo(
12634
+ "job.post.currencies"
12635
+ );
12636
+ async function add(value) {
12637
+ const session = useAtlas30.getClient()?.startSession();
12638
+ if (!session) {
12639
+ throw new InternalServerError33("Failed to start database session.");
12640
+ }
12641
+ try {
12642
+ session.startTransaction();
12643
+ const org = await getOrgById(String(value.org));
12644
+ if (!org) {
12645
+ throw new BadRequestError63("Organization not found.");
12646
+ }
12647
+ const location = await getLocationByName(value.location);
12648
+ if (!location) {
12649
+ await addLocation({ name: value.location }, session);
12650
+ }
12651
+ const jobTitle = await getJobTitleByName(value.title);
12652
+ if (!jobTitle) {
12653
+ await addJobTitle({ name: value.title }, session);
12654
+ }
12655
+ if (value.currency) {
12656
+ const currency = await getCurrencyByName(value.currency);
12657
+ if (!currency) {
12658
+ await addCurrency({ name: value.currency }, session);
12659
+ }
12660
+ }
12661
+ value.orgName = org.name;
12662
+ await _add(value, session);
12663
+ await session.commitTransaction();
12664
+ return "Successfully created job post.";
12665
+ } catch (error) {
12666
+ await session.abortTransaction();
12667
+ if (error instanceof AppError31) {
12668
+ throw error;
12669
+ }
12670
+ throw new InternalServerError33("Failed to create job post.");
12671
+ } finally {
12672
+ await session.endSession();
12673
+ }
12674
+ }
11784
12675
  async function deleteById(id) {
11785
- const { error } = Joi48.string().hex().required().validate(id);
12676
+ const { error } = Joi52.string().hex().required().validate(id);
11786
12677
  if (error) {
11787
- throw new BadRequestError57(error.message);
12678
+ throw new BadRequestError63(error.message);
11788
12679
  }
11789
12680
  try {
11790
12681
  await _deleteById(id);
11791
12682
  return "Successfully deleted job post.";
11792
12683
  } catch (error2) {
11793
- if (error2 instanceof AppError28) {
12684
+ if (error2 instanceof AppError31) {
11794
12685
  throw error2;
11795
12686
  } else {
11796
- throw new InternalServerError31("Failed to delete job post.");
12687
+ throw new InternalServerError33("Failed to delete job post.");
12688
+ }
12689
+ }
12690
+ }
12691
+ async function updateStatusById(id, newStatus) {
12692
+ const jobPost = await _getById(id);
12693
+ if (!jobPost) {
12694
+ throw new BadRequestError63("Job post not found.");
12695
+ }
12696
+ const currentStatus = jobPost.status ?? "draft";
12697
+ const allowedTransitions = {
12698
+ draft: ["open", "in-review", "deleted"],
12699
+ open: ["paused", "closed"],
12700
+ paused: ["open", "in-review", "deleted"],
12701
+ "in-review": ["open"],
12702
+ closed: ["open", "in-review", "draft", "deleted"]
12703
+ };
12704
+ const allowed = allowedTransitions[currentStatus];
12705
+ if (!allowed || !allowed.includes(newStatus)) {
12706
+ throw new BadRequestError63(
12707
+ `Cannot change status from "${currentStatus}" to "${newStatus}".`
12708
+ );
12709
+ }
12710
+ try {
12711
+ await _updateStatusById(id, newStatus);
12712
+ return "Successfully updated job post status.";
12713
+ } catch (error) {
12714
+ if (error instanceof AppError31) {
12715
+ throw error;
11797
12716
  }
12717
+ throw new InternalServerError33("Failed to update job post status.");
11798
12718
  }
11799
12719
  }
11800
12720
  return {
11801
- deleteById
12721
+ add,
12722
+ deleteById,
12723
+ updateStatusById
11802
12724
  };
11803
12725
  }
11804
12726
 
11805
12727
  // src/resources/job-post/job.post.controller.ts
11806
12728
  function useJobPostController() {
11807
12729
  const {
11808
- add: _add,
11809
12730
  getAll: _getAll,
11810
12731
  getJobPostsByOrg: _getJobPostsByOrg,
11811
12732
  getById: _getById,
11812
12733
  updateById: _updateById
11813
12734
  } = useJobPostRepo();
11814
- const { deleteById: _deleteById } = useJobPostService();
12735
+ const {
12736
+ add: _add,
12737
+ deleteById: _deleteById,
12738
+ updateStatusById: _updateStatusById
12739
+ } = useJobPostService();
11815
12740
  async function add(req, res, next) {
11816
12741
  const value = req.body;
11817
12742
  const { error } = schemaJobPost.validate(value);
11818
12743
  if (error) {
11819
- next(new BadRequestError58(error.message));
11820
- logger33.info(`Controller: ${error.message}`);
12744
+ next(new BadRequestError64(error.message));
12745
+ logger36.info(`Controller: ${error.message}`);
11821
12746
  return;
11822
12747
  }
11823
12748
  try {
11824
- const result = await _add(value);
11825
- res.json({ message: "Successfully created job post.", data: { result } });
12749
+ const message = await _add(value);
12750
+ res.json({ message });
11826
12751
  return;
11827
12752
  } catch (error2) {
11828
12753
  next(error2);
@@ -11830,29 +12755,29 @@ function useJobPostController() {
11830
12755
  }
11831
12756
  async function getAll(req, res, next) {
11832
12757
  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()
12758
+ const validation = Joi53.object({
12759
+ page: Joi53.number().min(1).optional().allow("", null),
12760
+ limit: Joi53.number().min(1).optional().allow("", null),
12761
+ search: Joi53.string().optional().allow("", null),
12762
+ status: Joi53.string().optional()
11838
12763
  });
11839
12764
  const { error } = validation.validate(query);
11840
12765
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
11841
12766
  const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
11842
12767
  const search = req.query.search ?? "";
11843
- const status = req.query.status ?? "active";
12768
+ const status = req.query.status ?? "open";
11844
12769
  const isPageNumber = isFinite(page);
11845
12770
  if (!isPageNumber) {
11846
- next(new BadRequestError58("Invalid page number."));
12771
+ next(new BadRequestError64("Invalid page number."));
11847
12772
  return;
11848
12773
  }
11849
12774
  const isLimitNumber = isFinite(limit);
11850
12775
  if (!isLimitNumber) {
11851
- next(new BadRequestError58("Invalid limit number."));
12776
+ next(new BadRequestError64("Invalid limit number."));
11852
12777
  return;
11853
12778
  }
11854
12779
  if (error) {
11855
- next(new BadRequestError58(error.message));
12780
+ next(new BadRequestError64(error.message));
11856
12781
  return;
11857
12782
  }
11858
12783
  try {
@@ -11871,28 +12796,34 @@ function useJobPostController() {
11871
12796
  const org = req.params.org ?? "";
11872
12797
  const isPageNumber = isFinite(page);
11873
12798
  if (!isPageNumber) {
11874
- next(new BadRequestError58("Invalid page number."));
12799
+ next(new BadRequestError64("Invalid page number."));
11875
12800
  return;
11876
12801
  }
11877
12802
  const isLimitNumber = isFinite(limit);
11878
12803
  if (!isLimitNumber) {
11879
- next(new BadRequestError58("Invalid limit number."));
12804
+ next(new BadRequestError64("Invalid limit number."));
11880
12805
  return;
11881
12806
  }
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()
12807
+ const validation = Joi53.object({
12808
+ org: Joi53.string().hex().required(),
12809
+ page: Joi53.number().min(1).optional().allow("", null),
12810
+ limit: Joi53.number().min(1).optional().allow("", null),
12811
+ search: Joi53.string().optional().allow("", null),
12812
+ status: Joi53.string().optional()
11888
12813
  });
11889
12814
  const { error } = validation.validate({ org, page, limit, search, status });
11890
12815
  if (error) {
11891
- next(new BadRequestError58(error.message));
12816
+ next(new BadRequestError64(error.message));
11892
12817
  return;
11893
12818
  }
11894
12819
  try {
11895
- const jobPosts = await _getJobPostsByOrg({ org, page, limit, search, status });
12820
+ const jobPosts = await _getJobPostsByOrg({
12821
+ org,
12822
+ page,
12823
+ limit,
12824
+ search,
12825
+ status
12826
+ });
11896
12827
  res.json(jobPosts);
11897
12828
  return;
11898
12829
  } catch (error2) {
@@ -11901,12 +12832,12 @@ function useJobPostController() {
11901
12832
  }
11902
12833
  async function getById(req, res, next) {
11903
12834
  const id = req.params.id;
11904
- const validation = Joi49.object({
11905
- id: Joi49.string().hex().required()
12835
+ const validation = Joi53.object({
12836
+ id: Joi53.string().hex().required()
11906
12837
  });
11907
12838
  const { error } = validation.validate({ id });
11908
12839
  if (error) {
11909
- next(new BadRequestError58(error.message));
12840
+ next(new BadRequestError64(error.message));
11910
12841
  return;
11911
12842
  }
11912
12843
  try {
@@ -11922,7 +12853,7 @@ function useJobPostController() {
11922
12853
  const payload = req.body;
11923
12854
  const { error } = schemaJobPostUpdate.validate({ _id, ...payload });
11924
12855
  if (error) {
11925
- next(new BadRequestError58(error.message));
12856
+ next(new BadRequestError64(error.message));
11926
12857
  return;
11927
12858
  }
11928
12859
  try {
@@ -11936,7 +12867,7 @@ function useJobPostController() {
11936
12867
  async function deleteById(req, res, next) {
11937
12868
  const id = req.params.id;
11938
12869
  if (!id) {
11939
- next(new BadRequestError58("Job Post ID is required."));
12870
+ next(new BadRequestError64("Job Post ID is required."));
11940
12871
  return;
11941
12872
  }
11942
12873
  try {
@@ -11947,13 +12878,141 @@ function useJobPostController() {
11947
12878
  next(error);
11948
12879
  }
11949
12880
  }
12881
+ async function updateStatusById(req, res, next) {
12882
+ const id = req.params.id;
12883
+ const status = req.params.status;
12884
+ const validation = Joi53.object({
12885
+ id: Joi53.string().hex().required(),
12886
+ status: Joi53.string().valid("draft", "open", "paused", "in-review", "closed").required()
12887
+ });
12888
+ const { error } = validation.validate({ id, status });
12889
+ if (error) {
12890
+ next(new BadRequestError64(error.message));
12891
+ return;
12892
+ }
12893
+ try {
12894
+ const message = await _updateStatusById(id, status);
12895
+ res.json({ message });
12896
+ return;
12897
+ } catch (error2) {
12898
+ next(error2);
12899
+ }
12900
+ }
12901
+ const { getAll: _getAllLocation } = useJobPostAttrRepo("job.post.locations");
12902
+ async function getLocations(req, res, next) {
12903
+ const query = req.query;
12904
+ const validation = Joi53.object({
12905
+ page: Joi53.number().min(1).optional().allow("", null),
12906
+ limit: Joi53.number().min(1).optional().allow("", null),
12907
+ search: Joi53.string().optional().allow("", null)
12908
+ });
12909
+ const { error } = validation.validate(query);
12910
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
12911
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
12912
+ const search = req.query.search ?? "";
12913
+ const isPageNumber = isFinite(page);
12914
+ if (!isPageNumber) {
12915
+ next(new BadRequestError64("Invalid page number."));
12916
+ return;
12917
+ }
12918
+ const isLimitNumber = isFinite(limit);
12919
+ if (!isLimitNumber) {
12920
+ next(new BadRequestError64("Invalid limit number."));
12921
+ return;
12922
+ }
12923
+ if (error) {
12924
+ next(new BadRequestError64(error.message));
12925
+ return;
12926
+ }
12927
+ try {
12928
+ const locations = await _getAllLocation({ page, limit, search });
12929
+ res.json(locations);
12930
+ return;
12931
+ } catch (error2) {
12932
+ next(error2);
12933
+ }
12934
+ }
12935
+ const { getAll: _getAllJobTitles } = useJobPostAttrRepo("job.post.titles");
12936
+ async function getJobTitles(req, res, next) {
12937
+ const query = req.query;
12938
+ const validation = Joi53.object({
12939
+ page: Joi53.number().min(1).optional().allow("", null),
12940
+ limit: Joi53.number().min(1).optional().allow("", null),
12941
+ search: Joi53.string().optional().allow("", null)
12942
+ });
12943
+ const { error } = validation.validate(query);
12944
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
12945
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
12946
+ const search = req.query.search ?? "";
12947
+ const isPageNumber = isFinite(page);
12948
+ if (!isPageNumber) {
12949
+ next(new BadRequestError64("Invalid page number."));
12950
+ return;
12951
+ }
12952
+ const isLimitNumber = isFinite(limit);
12953
+ if (!isLimitNumber) {
12954
+ next(new BadRequestError64("Invalid limit number."));
12955
+ return;
12956
+ }
12957
+ if (error) {
12958
+ next(new BadRequestError64(error.message));
12959
+ return;
12960
+ }
12961
+ try {
12962
+ const locations = await _getAllJobTitles({ page, limit, search });
12963
+ res.json(locations);
12964
+ return;
12965
+ } catch (error2) {
12966
+ next(error2);
12967
+ }
12968
+ }
12969
+ const { getAll: _getAllCurrencies } = useJobPostAttrRepo(
12970
+ "job.post.currencies"
12971
+ );
12972
+ async function getCurrencies(req, res, next) {
12973
+ const query = req.query;
12974
+ const validation = Joi53.object({
12975
+ page: Joi53.number().min(1).optional().allow("", null),
12976
+ limit: Joi53.number().min(1).optional().allow("", null),
12977
+ search: Joi53.string().optional().allow("", null)
12978
+ });
12979
+ const { error } = validation.validate(query);
12980
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
12981
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
12982
+ const search = req.query.search ?? "";
12983
+ const isPageNumber = isFinite(page);
12984
+ if (!isPageNumber) {
12985
+ next(new BadRequestError64("Invalid page number."));
12986
+ return;
12987
+ }
12988
+ const isLimitNumber = isFinite(limit);
12989
+ if (!isLimitNumber) {
12990
+ next(new BadRequestError64("Invalid limit number."));
12991
+ return;
12992
+ }
12993
+ if (error) {
12994
+ next(new BadRequestError64(error.message));
12995
+ return;
12996
+ }
12997
+ try {
12998
+ const locations = await _getAllCurrencies({ page, limit, search });
12999
+ res.json(locations);
13000
+ return;
13001
+ } catch (error2) {
13002
+ next(error2);
13003
+ }
13004
+ }
11950
13005
  return {
11951
13006
  add,
11952
13007
  getAll,
11953
13008
  getJobPostsByOrg,
11954
13009
  getById,
11955
13010
  updateById,
11956
- deleteById
13011
+ deleteById,
13012
+ updateStatusById,
13013
+ getLocations,
13014
+ getJobTitles,
13015
+ getCurrencies
11957
13016
  };
11958
13017
  }
11959
13018
  export {
@@ -12083,6 +13142,7 @@ export {
12083
13142
  usePlanController,
12084
13143
  usePlanRepo,
12085
13144
  usePlanService,
13145
+ usePromoController,
12086
13146
  usePromoRepo,
12087
13147
  useRoleController,
12088
13148
  useRoleRepo,