@goweekdays/core 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -807,25 +807,25 @@ function useAuthService() {
807
807
  }
808
808
 
809
809
  // src/resources/auth/auth.controller.ts
810
- import Joi24 from "joi";
810
+ import Joi32 from "joi";
811
811
  import {
812
- AppError as AppError14,
813
- BadRequestError as BadRequestError34,
814
- InternalServerError as InternalServerError18,
815
- logger as logger18
812
+ AppError as AppError17,
813
+ BadRequestError as BadRequestError42,
814
+ InternalServerError as InternalServerError21,
815
+ logger as logger21
816
816
  } from "@goweekdays/utils";
817
817
 
818
818
  // src/resources/verification/verification.service.ts
819
819
  import {
820
820
  useMailer,
821
821
  compileHandlebar,
822
- logger as logger17,
822
+ logger as logger20,
823
823
  getDirectory,
824
- BadRequestError as BadRequestError33,
824
+ BadRequestError as BadRequestError41,
825
825
  NotFoundError as NotFoundError4,
826
- InternalServerError as InternalServerError17,
827
- useAtlas as useAtlas15,
828
- AppError as AppError13
826
+ InternalServerError as InternalServerError20,
827
+ useAtlas as useAtlas19,
828
+ AppError as AppError16
829
829
  } from "@goweekdays/utils";
830
830
 
831
831
  // src/resources/verification/verification.model.ts
@@ -1228,15 +1228,15 @@ var DOMAIN = process.env.DOMAIN || "localhost";
1228
1228
 
1229
1229
  // src/resources/user/user.service.ts
1230
1230
  import {
1231
- AppError as AppError11,
1232
- BadRequestError as BadRequestError31,
1233
- InternalServerError as InternalServerError15,
1231
+ AppError as AppError14,
1232
+ BadRequestError as BadRequestError39,
1233
+ InternalServerError as InternalServerError18,
1234
1234
  NotFoundError as NotFoundError3,
1235
1235
  hashPassword,
1236
- logger as logger16,
1237
- makeCacheKey as makeCacheKey11,
1238
- useAtlas as useAtlas14,
1239
- useCache as useCache12,
1236
+ logger as logger19,
1237
+ makeCacheKey as makeCacheKey14,
1238
+ useAtlas as useAtlas18,
1239
+ useCache as useCache15,
1240
1240
  useS3
1241
1241
  } from "@goweekdays/utils";
1242
1242
 
@@ -4154,6 +4154,33 @@ function usePermissionGroupService() {
4154
4154
  description: "Allow user to revoke invitations"
4155
4155
  }
4156
4156
  ]
4157
+ },
4158
+ {
4159
+ key: "billing",
4160
+ label: "Billing",
4161
+ permissions: [
4162
+ {
4163
+ key: "billing.view",
4164
+ name: "View Billing",
4165
+ description: "Allow user to view billing"
4166
+ }
4167
+ ]
4168
+ },
4169
+ {
4170
+ key: "setting",
4171
+ label: "Setting",
4172
+ permissions: [
4173
+ {
4174
+ key: "setting.view",
4175
+ name: "View Setting",
4176
+ description: "Allow user to view setting"
4177
+ },
4178
+ {
4179
+ key: "setting.edit.details",
4180
+ name: "Edit Setting Details",
4181
+ description: "Allow user to edit setting details"
4182
+ }
4183
+ ]
4157
4184
  }
4158
4185
  ];
4159
4186
  for (const app of apps.items) {
@@ -4588,13 +4615,25 @@ function usePermissionGroupController() {
4588
4615
  import { BadRequestError as BadRequestError23 } from "@goweekdays/utils";
4589
4616
  import Joi17 from "joi";
4590
4617
  import { ObjectId as ObjectId15 } from "mongodb";
4591
- var schemaOrg = Joi17.object({
4618
+ var schema = {
4592
4619
  name: Joi17.string().max(255).required(),
4593
4620
  description: Joi17.string().max(1024).optional().allow("", null),
4594
- email: Joi17.string().email().max(255).optional().allow("", null),
4595
- contact: Joi17.string().max(50).optional().allow("", null),
4621
+ email: Joi17.string().email().max(255).required(),
4622
+ contact: Joi17.string().max(50).optional().allow("", null)
4623
+ };
4624
+ var schemaOrg = Joi17.object({
4625
+ ...schema,
4596
4626
  createdBy: Joi17.string().hex().required()
4597
4627
  });
4628
+ var schemaOrgAdd = Joi17.object({
4629
+ ...schema,
4630
+ createdBy: Joi17.string().hex().required(),
4631
+ seats: Joi17.number().required()
4632
+ });
4633
+ var schemaOrgUpdate = Joi17.object({
4634
+ ...schema,
4635
+ _id: Joi17.string().hex().required()
4636
+ });
4598
4637
  function modelOrg(value) {
4599
4638
  const { error } = schemaOrg.validate(value);
4600
4639
  if (error) {
@@ -4877,6 +4916,30 @@ function useOrgRepo() {
4877
4916
  throw new InternalServerError11("Failed to delete organization.");
4878
4917
  }
4879
4918
  }
4919
+ async function updateById(_id, options) {
4920
+ const { error } = schemaOrgUpdate.validate({ ...options, _id });
4921
+ if (error) {
4922
+ throw new BadRequestError24(error.message);
4923
+ }
4924
+ try {
4925
+ _id = new ObjectId16(_id);
4926
+ } catch (error2) {
4927
+ throw new BadRequestError24("Invalid org ID.");
4928
+ }
4929
+ try {
4930
+ await collection.updateOne(
4931
+ { _id },
4932
+ { $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } }
4933
+ );
4934
+ delCachedData();
4935
+ } catch (error2) {
4936
+ const isDuplicated = error2.message.includes("duplicate");
4937
+ if (isDuplicated) {
4938
+ throw new BadRequestError24("Organization name already exist.");
4939
+ }
4940
+ throw new InternalServerError11("Failed to update org info.");
4941
+ }
4942
+ }
4880
4943
  return {
4881
4944
  createIndexes,
4882
4945
  add,
@@ -4884,12 +4947,13 @@ function useOrgRepo() {
4884
4947
  getById,
4885
4948
  updateFieldById,
4886
4949
  deleteById,
4887
- getByName
4950
+ getByName,
4951
+ updateById
4888
4952
  };
4889
4953
  }
4890
4954
 
4891
4955
  // src/resources/organization/organization.service.ts
4892
- import { BadRequestError as BadRequestError29, useAtlas as useAtlas13 } from "@goweekdays/utils";
4956
+ import { BadRequestError as BadRequestError37, useAtlas as useAtlas17 } from "@goweekdays/utils";
4893
4957
 
4894
4958
  // src/resources/member/member.controller.ts
4895
4959
  import Joi20 from "joi";
@@ -5414,162 +5478,1353 @@ function useMemberController() {
5414
5478
  };
5415
5479
  }
5416
5480
 
5417
- // src/resources/organization/organization.service.ts
5418
- function useOrgService() {
5419
- const { add: addOrg } = useOrgRepo();
5420
- const { addRole } = useRoleRepo();
5421
- const { getAll: getAllPermission } = usePermissionRepo();
5422
- const { add: addMember, updateRoleById: _updateRoleById } = useMemberRepo();
5423
- const { getUserById } = useUserRepo();
5424
- async function add(value) {
5425
- const session = useAtlas13.getClient()?.startSession();
5426
- if (!session) {
5427
- throw new BadRequestError29("Unable to start database session.");
5428
- }
5481
+ // src/resources/subscription/subscription.model.ts
5482
+ import { BadRequestError as BadRequestError29 } from "@goweekdays/utils";
5483
+ import Joi21 from "joi";
5484
+ import { ObjectId as ObjectId17 } from "mongodb";
5485
+ var schema2 = {
5486
+ seats: Joi21.number().integer().min(1).required(),
5487
+ paidSeats: Joi21.number().integer().min(0).required(),
5488
+ amount: Joi21.number().positive().required(),
5489
+ promoCode: Joi21.string().optional().allow("", null),
5490
+ nextBillingDate: Joi21.date().optional().allow("", null)
5491
+ };
5492
+ var schemaSubscription = Joi21.object({
5493
+ ...schema2,
5494
+ org: Joi21.string().hex().length(24).required(),
5495
+ currency: Joi21.string().length(3).required(),
5496
+ billingCycle: Joi21.string().valid("monthly", "yearly").required()
5497
+ });
5498
+ var schemaSubscriptionUpdate = Joi21.object({
5499
+ ...schema2,
5500
+ status: Joi21.string().optional().allow("", null)
5501
+ });
5502
+ var schemaSubscriptionSeats = Joi21.object({
5503
+ id: Joi21.string().hex().length(24).required(),
5504
+ seats: Joi21.number().integer().min(1).required(),
5505
+ amount: Joi21.number().positive().optional().allow(null, 0),
5506
+ user: Joi21.string().hex().length(24).required()
5507
+ });
5508
+ function modelSubscription(data) {
5509
+ const { error } = schemaSubscription.validate(data);
5510
+ if (error) {
5511
+ throw new BadRequestError29(`Invalid subscription data: ${error.message}`);
5512
+ }
5513
+ if (data._id && typeof data._id === "string") {
5429
5514
  try {
5430
- session?.startTransaction();
5431
- const org = await addOrg(value, session);
5432
- const allPermissions = await getAllPermission({
5433
- app: "org",
5434
- limit: 100
5435
- });
5436
- let permissions = [];
5437
- if (allPermissions && allPermissions.items && allPermissions.items.length) {
5438
- permissions = allPermissions.items.map((perm) => perm.key);
5439
- }
5440
- if (permissions.length === 0) {
5441
- throw new Error("No permissions found for the organization type.");
5442
- }
5443
- const createdBy = String(value.createdBy);
5444
- const roleData = {
5445
- org: String(org),
5446
- name: "Owner",
5447
- description: "Owner of the organization",
5448
- permissions,
5449
- createdBy,
5450
- app: "org"
5451
- };
5452
- const role = await addRole(roleData, session);
5453
- if (!role) {
5454
- throw new BadRequestError29("Role is required to create org member.");
5455
- }
5456
- const user = await getUserById(createdBy);
5457
- if (!user) {
5458
- throw new BadRequestError29("User is required to create org member.");
5459
- }
5460
- await addMember(
5461
- {
5462
- role: String(role),
5463
- roleName: roleData.name,
5464
- org: String(org),
5465
- name: `${user.firstName} ${user.lastName}`,
5466
- user: createdBy,
5467
- app: "org"
5468
- },
5469
- session
5470
- );
5471
- await session?.commitTransaction();
5472
- return String(org);
5473
- } catch (error) {
5474
- await session?.abortTransaction();
5475
- throw error;
5476
- } finally {
5477
- await session?.endSession();
5515
+ data._id = new ObjectId17(data._id);
5516
+ } catch (error2) {
5517
+ throw new BadRequestError29("Invalid subscription ID.");
5478
5518
  }
5479
5519
  }
5520
+ try {
5521
+ data.org = new ObjectId17(data.org);
5522
+ } catch (error2) {
5523
+ throw new BadRequestError29("Invalid organization ID.");
5524
+ }
5480
5525
  return {
5481
- add
5526
+ _id: data._id,
5527
+ org: data.org,
5528
+ seats: data.seats,
5529
+ paidSeats: data.paidSeats,
5530
+ amount: data.amount,
5531
+ currency: data.currency,
5532
+ billingCycle: data.billingCycle,
5533
+ promoCode: data.promoCode,
5534
+ status: data.status ?? "active",
5535
+ nextBillingDate: data.nextBillingDate,
5536
+ createdAt: data.createdAt ?? /* @__PURE__ */ new Date(),
5537
+ updatedAt: data.updatedAt ?? ""
5482
5538
  };
5483
5539
  }
5484
5540
 
5485
- // src/resources/organization/organization.controller.ts
5486
- import { BadRequestError as BadRequestError30 } from "@goweekdays/utils";
5487
- import Joi21 from "joi";
5488
- function useOrgController() {
5489
- const { add: _add } = useOrgService();
5490
- const { getOrgsByMembership } = useMemberRepo();
5491
- const {
5492
- getByName: _getByName,
5493
- getAll: getAllOrg,
5494
- getById: _getById
5495
- } = useOrgRepo();
5496
- async function add(req, res, next) {
5497
- const value = req.body;
5498
- const { error } = schemaOrg.validate(value);
5499
- if (error) {
5500
- next(new BadRequestError30(error.message));
5501
- return;
5541
+ // src/resources/subscription/subscription.repository.ts
5542
+ import {
5543
+ AppError as AppError11,
5544
+ BadRequestError as BadRequestError30,
5545
+ InternalServerError as InternalServerError15,
5546
+ logger as logger16,
5547
+ makeCacheKey as makeCacheKey11,
5548
+ paginate as paginate9,
5549
+ useAtlas as useAtlas13,
5550
+ useCache as useCache12
5551
+ } from "@goweekdays/utils";
5552
+ import Joi22 from "joi";
5553
+ import { ObjectId as ObjectId18 } from "mongodb";
5554
+ function useSubscriptionRepo() {
5555
+ const db = useAtlas13.getDb();
5556
+ if (!db) {
5557
+ throw new InternalServerError15("Unable to connect to server.");
5558
+ }
5559
+ const namespace_collection = "subscriptions";
5560
+ const collection = db.collection(namespace_collection);
5561
+ const { getCache, setCache, delNamespace } = useCache12(namespace_collection);
5562
+ function delCachedData() {
5563
+ delNamespace().then(() => {
5564
+ logger16.log({
5565
+ level: "info",
5566
+ message: `Cache namespace cleared for ${namespace_collection}`
5567
+ });
5568
+ }).catch((err) => {
5569
+ logger16.log({
5570
+ level: "error",
5571
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
5572
+ });
5573
+ });
5574
+ }
5575
+ async function createIndexes() {
5576
+ try {
5577
+ await collection.createIndexes([
5578
+ {
5579
+ key: {
5580
+ org: 1
5581
+ },
5582
+ name: "org_index"
5583
+ },
5584
+ {
5585
+ key: { org: 1, status: 1 },
5586
+ name: "org_status_index"
5587
+ }
5588
+ ]);
5589
+ } catch (error) {
5502
5590
  }
5591
+ }
5592
+ createIndexes().catch((error) => {
5593
+ logger16.log({
5594
+ level: "error",
5595
+ message: `Failed to create indexes for subscriptions collection: ${error.message}`
5596
+ });
5597
+ });
5598
+ async function add(value, session) {
5503
5599
  try {
5504
- const org = await _add(value);
5505
- res.json({
5506
- message: "Organization created successfully.",
5507
- data: { org }
5600
+ value = modelSubscription(value);
5601
+ const result = await collection.insertOne(value, { session });
5602
+ delCachedData();
5603
+ return result.insertedId.toString();
5604
+ } catch (error) {
5605
+ logger16.log({
5606
+ level: "error",
5607
+ message: `${error}`
5508
5608
  });
5509
- return;
5510
- } catch (error2) {
5511
- next(error2);
5609
+ if (error instanceof AppError11) {
5610
+ throw error;
5611
+ }
5612
+ throw new InternalServerError15("Failed to add subscription.");
5512
5613
  }
5513
5614
  }
5514
- async function getOrgsByUserId(req, res, next) {
5515
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
5516
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
5517
- const search = req.query.search ?? "";
5518
- const user = req.params.user ?? "";
5519
- const isPageNumber = isFinite(page);
5520
- if (!isPageNumber) {
5521
- next(new BadRequestError30("Invalid page number."));
5522
- return;
5615
+ async function getAll({
5616
+ page = 1,
5617
+ limit = 10,
5618
+ search = "",
5619
+ status = "active"
5620
+ } = {}) {
5621
+ page = page < 1 ? page - 1 : page;
5622
+ const query = { status };
5623
+ const cacheKeyOptions = {
5624
+ page,
5625
+ limit,
5626
+ search,
5627
+ status,
5628
+ tag: "getAll"
5629
+ };
5630
+ if (search) {
5631
+ query.$text = { $search: search };
5523
5632
  }
5524
- const isLimitNumber = isFinite(limit);
5525
- if (!isLimitNumber) {
5526
- next(new BadRequestError30("Invalid limit number."));
5527
- return;
5633
+ const cacheKey = makeCacheKey11(namespace_collection, cacheKeyOptions);
5634
+ try {
5635
+ const cachedData = await getCache(cacheKey);
5636
+ if (cachedData) {
5637
+ return cachedData;
5638
+ }
5639
+ const items = await collection.aggregate([
5640
+ { $match: query },
5641
+ { $skip: page * limit },
5642
+ { $limit: limit }
5643
+ ]).toArray();
5644
+ const length = await collection.countDocuments(query);
5645
+ const data = paginate9(
5646
+ items,
5647
+ page,
5648
+ limit,
5649
+ length
5650
+ );
5651
+ setCache(cacheKey, data).then(() => {
5652
+ logger16.log({
5653
+ level: "info",
5654
+ message: `Cache set for getAll subscription: ${cacheKey}`
5655
+ });
5656
+ }).catch((err) => {
5657
+ logger16.log({
5658
+ level: "error",
5659
+ message: `Failed to set cache for getAll subscription: ${err.message}`
5660
+ });
5661
+ });
5662
+ return data;
5663
+ } catch (error) {
5664
+ throw new InternalServerError15("Failed to get subscriptions.");
5528
5665
  }
5529
- const validation = Joi21.object({
5530
- user: Joi21.string().hex().required(),
5531
- page: Joi21.number().min(1).optional().allow("", null),
5532
- limit: Joi21.number().min(1).optional().allow("", null),
5533
- search: Joi21.string().optional().allow("", null)
5534
- });
5535
- const { error } = validation.validate({ user, page, limit, search });
5666
+ }
5667
+ async function getByOrg(org) {
5668
+ const { error } = Joi22.string().hex().length(24).required().validate(org);
5536
5669
  if (error) {
5537
- next(new BadRequestError30(error.message));
5538
- return;
5670
+ throw new Error(`Invalid org ID: ${error.message}`);
5539
5671
  }
5540
5672
  try {
5541
- const orgs = await getOrgsByMembership({ user, page, limit, search });
5542
- res.json(orgs);
5543
- return;
5673
+ org = new ObjectId18(org);
5544
5674
  } catch (error2) {
5545
- next(error2);
5675
+ throw new BadRequestError30("Invalid org ID.");
5546
5676
  }
5547
- }
5548
- async function getAll(req, res, next) {
5549
- const query = req.query;
5550
- const validation = Joi21.object({
5551
- page: Joi21.number().min(1).optional().allow("", null),
5552
- limit: Joi21.number().min(1).optional().allow("", null),
5553
- search: Joi21.string().optional().allow("", null),
5554
- status: Joi21.string().valid("active", "suspended", "inactive", "deleted").optional()
5555
- });
5556
- const { error } = validation.validate(query);
5557
- const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
5558
- const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
5559
- const search = req.query.search ?? "";
5560
- const status = req.query.status ?? "active";
5561
- const isPageNumber = isFinite(page);
5677
+ try {
5678
+ const cacheKey = makeCacheKey11(namespace_collection, {
5679
+ org: String(org),
5680
+ tag: "getByOrg"
5681
+ });
5682
+ const cachedData = await getCache(cacheKey);
5683
+ if (cachedData) {
5684
+ return cachedData;
5685
+ }
5686
+ const data = await collection.findOne({
5687
+ org,
5688
+ status: { $ne: "deleted" }
5689
+ });
5690
+ setCache(cacheKey, data).then(() => {
5691
+ logger16.log({
5692
+ level: "info",
5693
+ message: `Cache set for getByOrg subscription: ${cacheKey}`
5694
+ });
5695
+ }).catch((err) => {
5696
+ logger16.log({
5697
+ level: "error",
5698
+ message: `Failed to set cache for getByOrg subscription: ${err.message}`
5699
+ });
5700
+ });
5701
+ return data;
5702
+ } catch (error2) {
5703
+ throw new InternalServerError15("Failed to get subscription.");
5704
+ }
5705
+ }
5706
+ async function getById(_id) {
5707
+ const { error } = Joi22.string().hex().length(24).required().validate(_id);
5708
+ if (error) {
5709
+ throw new Error(`Invalid subscription ID: ${error.message}`);
5710
+ }
5711
+ try {
5712
+ _id = new ObjectId18(_id);
5713
+ } catch (error2) {
5714
+ throw new BadRequestError30("Invalid subscription ID.");
5715
+ }
5716
+ try {
5717
+ const cacheKey = makeCacheKey11(namespace_collection, {
5718
+ _id: String(_id),
5719
+ tag: "getById"
5720
+ });
5721
+ const cachedData = await getCache(cacheKey);
5722
+ if (cachedData) {
5723
+ return cachedData;
5724
+ }
5725
+ const data = await collection.findOne({
5726
+ _id,
5727
+ status: { $ne: "deleted" }
5728
+ });
5729
+ setCache(cacheKey, data).then(() => {
5730
+ logger16.log({
5731
+ level: "info",
5732
+ message: `Cache set for getById subscription: ${cacheKey}`
5733
+ });
5734
+ }).catch((err) => {
5735
+ logger16.log({
5736
+ level: "error",
5737
+ message: `Failed to set cache for getById subscription: ${err.message}`
5738
+ });
5739
+ });
5740
+ return data;
5741
+ } catch (error2) {
5742
+ throw new InternalServerError15("Failed to get subscription.");
5743
+ }
5744
+ }
5745
+ async function deleteById(_id) {
5746
+ const { error } = Joi22.string().hex().length(24).required().validate(_id);
5747
+ if (error) {
5748
+ throw new Error(`Invalid subscription ID: ${error.message}`);
5749
+ }
5750
+ try {
5751
+ _id = new ObjectId18(_id);
5752
+ } catch (error2) {
5753
+ throw new BadRequestError30("Invalid subscription ID.");
5754
+ }
5755
+ try {
5756
+ const result = await collection.updateOne(
5757
+ { _id },
5758
+ { $set: { status: "deleted" } }
5759
+ );
5760
+ if (result.modifiedCount === 0) {
5761
+ throw new InternalServerError15("Failed to delete subscription.");
5762
+ }
5763
+ delCachedData();
5764
+ return "Successfully deleted subscription.";
5765
+ } catch (error2) {
5766
+ if (error2 instanceof AppError11) {
5767
+ throw error2;
5768
+ }
5769
+ throw new InternalServerError15("Failed to delete subscription.");
5770
+ }
5771
+ }
5772
+ async function updateById(_id, options, session) {
5773
+ const { error: errorId } = Joi22.string().hex().length(24).required().validate(_id);
5774
+ if (errorId) {
5775
+ throw new Error(`Invalid subscription ID: ${errorId.message}`);
5776
+ }
5777
+ const { error } = schemaSubscriptionUpdate.validate(options);
5778
+ if (error) {
5779
+ throw new BadRequestError30(
5780
+ `Invalid subscription update data: ${error.message}`
5781
+ );
5782
+ }
5783
+ try {
5784
+ _id = new ObjectId18(_id);
5785
+ } catch (error2) {
5786
+ throw new BadRequestError30("Invalid subscription ID.");
5787
+ }
5788
+ try {
5789
+ const result = await collection.updateOne(
5790
+ { _id },
5791
+ { $set: { ...options, updatedAt: /* @__PURE__ */ new Date() } },
5792
+ { session }
5793
+ );
5794
+ if (result.modifiedCount === 0) {
5795
+ throw new InternalServerError15("Failed to update subscription.");
5796
+ }
5797
+ delCachedData();
5798
+ return "Successfully updated subscription.";
5799
+ } catch (error2) {
5800
+ if (error2 instanceof AppError11) {
5801
+ throw error2;
5802
+ }
5803
+ throw new InternalServerError15("Failed to update subscription.");
5804
+ }
5805
+ }
5806
+ return {
5807
+ add,
5808
+ getAll,
5809
+ getByOrg,
5810
+ getById,
5811
+ deleteById,
5812
+ updateById
5813
+ };
5814
+ }
5815
+
5816
+ // src/resources/subscription/subscription.controller.ts
5817
+ import Joi24 from "joi";
5818
+ import { BadRequestError as BadRequestError33 } from "@goweekdays/utils";
5819
+
5820
+ // src/resources/subscription/subscription.service.ts
5821
+ import { BadRequestError as BadRequestError32, useAtlas as useAtlas15 } from "@goweekdays/utils";
5822
+
5823
+ // src/resources/subscription/subscription.transaction.repository.ts
5824
+ import {
5825
+ AppError as AppError12,
5826
+ InternalServerError as InternalServerError16,
5827
+ logger as logger17,
5828
+ makeCacheKey as makeCacheKey12,
5829
+ paginate as paginate10,
5830
+ useAtlas as useAtlas14,
5831
+ useCache as useCache13
5832
+ } from "@goweekdays/utils";
5833
+
5834
+ // src/resources/subscription/subscription.transaction.model.ts
5835
+ import { BadRequestError as BadRequestError31 } from "@goweekdays/utils";
5836
+ import Joi23 from "joi";
5837
+ import { ObjectId as ObjectId19 } from "mongodb";
5838
+ var schemaSubscriptionTransaction = Joi23.object({
5839
+ subscription: Joi23.string().hex().length(24).required(),
5840
+ amount: Joi23.number().positive().required(),
5841
+ currency: Joi23.string().length(3).required(),
5842
+ type: Joi23.string().valid("initiate", "add-seat", "remove-seat", "renewal").required(),
5843
+ description: Joi23.string().max(255).optional().allow("", null),
5844
+ createdBy: Joi23.string().hex().length(24).required(),
5845
+ createdByName: Joi23.string().optional().allow("", null)
5846
+ });
5847
+ function modelSubscriptionTransaction(data) {
5848
+ const { error } = schemaSubscriptionTransaction.validate(data);
5849
+ if (error) {
5850
+ throw new BadRequestError31(
5851
+ `Invalid subscription transaction data: ${error.message}`
5852
+ );
5853
+ }
5854
+ if (data._id && typeof data._id === "string") {
5855
+ try {
5856
+ data._id = new ObjectId19(data._id);
5857
+ } catch (error2) {
5858
+ throw new BadRequestError31("Invalid subscription transaction ID.");
5859
+ }
5860
+ }
5861
+ if (data.subscription && typeof data.subscription === "string") {
5862
+ try {
5863
+ data.subscription = new ObjectId19(data.subscription);
5864
+ } catch (error2) {
5865
+ throw new BadRequestError31("Invalid subscription ID.");
5866
+ }
5867
+ }
5868
+ if (data.createdBy && typeof data.createdBy === "string") {
5869
+ try {
5870
+ data.createdBy = new ObjectId19(data.createdBy);
5871
+ } catch (error2) {
5872
+ throw new BadRequestError31("Invalid createdBy ID.");
5873
+ }
5874
+ }
5875
+ return {
5876
+ _id: data._id,
5877
+ subscription: data.subscription,
5878
+ amount: data.amount,
5879
+ currency: data.currency,
5880
+ type: data.type,
5881
+ description: data.description ?? "",
5882
+ createdBy: data.createdBy,
5883
+ createdByName: data.createdByName,
5884
+ createdAt: data.createdAt ?? /* @__PURE__ */ new Date(),
5885
+ updatedAt: data.updatedAt ?? ""
5886
+ };
5887
+ }
5888
+
5889
+ // src/resources/subscription/subscription.transaction.repository.ts
5890
+ import { ObjectId as ObjectId20 } from "mongodb";
5891
+ function useSubscriptionTransactionRepo() {
5892
+ const db = useAtlas14.getDb();
5893
+ if (!db) {
5894
+ throw new InternalServerError16("Unable to connect to server.");
5895
+ }
5896
+ const namespace_collection = "subscription.transactions";
5897
+ const collection = db.collection(namespace_collection);
5898
+ const { getCache, setCache, delNamespace } = useCache13(namespace_collection);
5899
+ function delCachedData() {
5900
+ delNamespace().then(() => {
5901
+ logger17.log({
5902
+ level: "info",
5903
+ message: `Cache namespace cleared for ${namespace_collection}`
5904
+ });
5905
+ }).catch((err) => {
5906
+ logger17.log({
5907
+ level: "error",
5908
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
5909
+ });
5910
+ });
5911
+ }
5912
+ async function createIndexes() {
5913
+ try {
5914
+ await collection.createIndexes([
5915
+ {
5916
+ key: {
5917
+ subscription: 1
5918
+ },
5919
+ name: "subscription_index"
5920
+ },
5921
+ {
5922
+ key: { subscription: 1, type: 1 },
5923
+ name: "subscription_type_index"
5924
+ },
5925
+ {
5926
+ key: { createdAt: -1 },
5927
+ name: "createdAt_index"
5928
+ }
5929
+ ]);
5930
+ } catch (error) {
5931
+ }
5932
+ }
5933
+ createIndexes().catch((error) => {
5934
+ logger17.log({
5935
+ level: "error",
5936
+ message: `Failed to create indexes for subscription_transactions collection: ${error.message}`
5937
+ });
5938
+ });
5939
+ async function add(value, session) {
5940
+ try {
5941
+ value = modelSubscriptionTransaction(value);
5942
+ await collection.insertOne(value, { session });
5943
+ delCachedData();
5944
+ return "Successfully added subscription transaction.";
5945
+ } catch (error) {
5946
+ logger17.log({
5947
+ level: "error",
5948
+ message: `${error}`
5949
+ });
5950
+ if (error instanceof AppError12) {
5951
+ throw error;
5952
+ }
5953
+ throw new InternalServerError16("Failed to add subscription transaction.");
5954
+ }
5955
+ }
5956
+ async function getAll({ page = 1, limit = 10, search = "", id = "" } = {}) {
5957
+ page = page > 0 ? page - 1 : page;
5958
+ const query = {};
5959
+ const cacheKeyOptions = {
5960
+ page,
5961
+ limit,
5962
+ search,
5963
+ tag: "getAll"
5964
+ };
5965
+ try {
5966
+ query.subscription = new ObjectId20(id);
5967
+ cacheKeyOptions.subscription = id;
5968
+ } catch (error) {
5969
+ throw new InternalServerError16("Invalid organization ID.");
5970
+ }
5971
+ if (search) {
5972
+ query.$text = { $search: search };
5973
+ }
5974
+ const cacheKey = makeCacheKey12(namespace_collection, cacheKeyOptions);
5975
+ try {
5976
+ const cachedData = await getCache(
5977
+ cacheKey
5978
+ );
5979
+ if (cachedData) {
5980
+ logger17.log({
5981
+ level: "info",
5982
+ message: `Cache hit for getAll subscription transaction: ${cacheKey}`
5983
+ });
5984
+ return cachedData;
5985
+ }
5986
+ const items = await collection.aggregate([
5987
+ { $match: query },
5988
+ { $skip: page * limit },
5989
+ { $limit: limit }
5990
+ ]).toArray();
5991
+ const length = await collection.countDocuments(query);
5992
+ const data = paginate10(
5993
+ items,
5994
+ page,
5995
+ limit,
5996
+ length
5997
+ );
5998
+ setCache(cacheKey, data).then(() => {
5999
+ logger17.log({
6000
+ level: "info",
6001
+ message: `Cache set for getAll subscription transaction: ${cacheKey}`
6002
+ });
6003
+ }).catch((err) => {
6004
+ logger17.log({
6005
+ level: "error",
6006
+ message: `Failed to set cache for getAll subscription transaction: ${err.message}`
6007
+ });
6008
+ });
6009
+ return data;
6010
+ } catch (error) {
6011
+ throw new InternalServerError16("Failed to get subscription transactions.");
6012
+ }
6013
+ }
6014
+ return {
6015
+ add,
6016
+ getAll
6017
+ };
6018
+ }
6019
+
6020
+ // src/resources/subscription/subscription.service.ts
6021
+ function useSubscriptionService() {
6022
+ const { getById, updateById } = useSubscriptionRepo();
6023
+ const { add: addTransaction } = useSubscriptionTransactionRepo();
6024
+ const { getUserById } = useUserRepo();
6025
+ async function updateSeats({
6026
+ id = "",
6027
+ user = "",
6028
+ amount = 0,
6029
+ seats = 0
6030
+ } = {}) {
6031
+ const { error } = schemaSubscriptionSeats.validate({
6032
+ id,
6033
+ seats,
6034
+ amount,
6035
+ user
6036
+ });
6037
+ if (error) {
6038
+ throw new BadRequestError32(error.message);
6039
+ }
6040
+ const subscription = await getById(id);
6041
+ if (!subscription) {
6042
+ throw new Error("Subscription not found");
6043
+ }
6044
+ if (subscription.seats === seats) {
6045
+ throw new Error("Failed to update subscription, no changes detected.");
6046
+ }
6047
+ const userData = await getUserById(user);
6048
+ if (!userData) {
6049
+ throw new Error("User not found.");
6050
+ }
6051
+ const session = useAtlas15.getClient()?.startSession();
6052
+ if (!session) {
6053
+ throw new Error("Unable to start database session.");
6054
+ }
6055
+ let subscriptionAmount = subscription.amount;
6056
+ const seatIncreased = seats > subscription.paidSeats;
6057
+ let paidSeats = subscription.paidSeats;
6058
+ if (seatIncreased) {
6059
+ subscriptionAmount += amount ?? 0;
6060
+ paidSeats = seats;
6061
+ }
6062
+ try {
6063
+ session.startTransaction();
6064
+ await updateById(
6065
+ id,
6066
+ { seats, amount: subscriptionAmount, paidSeats },
6067
+ session
6068
+ );
6069
+ if (seatIncreased) {
6070
+ await addTransaction(
6071
+ {
6072
+ type: "add-seat",
6073
+ description: `Added ${seats - subscription.paidSeats} seats.`,
6074
+ amount: amount ?? 0,
6075
+ currency: subscription.currency,
6076
+ subscription: id,
6077
+ createdBy: user,
6078
+ createdByName: `${userData.firstName} ${userData.lastName}`
6079
+ },
6080
+ session
6081
+ );
6082
+ }
6083
+ await session.commitTransaction();
6084
+ return "Successfully updated subscription seats.";
6085
+ } catch (error2) {
6086
+ await session.abortTransaction();
6087
+ throw error2;
6088
+ } finally {
6089
+ session.endSession();
6090
+ }
6091
+ }
6092
+ return {
6093
+ updateSeats
6094
+ };
6095
+ }
6096
+
6097
+ // src/resources/subscription/subscription.controller.ts
6098
+ function useSubscriptionController() {
6099
+ const {
6100
+ getAll: _getAll,
6101
+ getById: _getById,
6102
+ getByOrg: _getByOrg
6103
+ } = useSubscriptionRepo();
6104
+ const { updateSeats: _updateSeats } = useSubscriptionService();
6105
+ async function getAll(req, res, next) {
6106
+ const validation = Joi24.object({
6107
+ page: Joi24.number().min(1).max(100).optional().allow(null, "").default(1),
6108
+ limit: Joi24.number().min(1).max(100).optional().allow(null, "").default(10),
6109
+ status: Joi24.string().valid("active", "suspended").optional().default("active")
6110
+ });
6111
+ const query = req.query;
6112
+ const { error, value } = validation.validate(query);
6113
+ if (error) {
6114
+ next(new BadRequestError33(error.message));
6115
+ return;
6116
+ }
6117
+ try {
6118
+ const data = await _getAll(value);
6119
+ res.json(data);
6120
+ return;
6121
+ } catch (error2) {
6122
+ next(error2);
6123
+ }
6124
+ }
6125
+ async function getById(req, res, next) {
6126
+ const id = req.params.id ?? "";
6127
+ const validation = Joi24.object({
6128
+ id: Joi24.string().hex().length(24).required()
6129
+ });
6130
+ const { error, value } = validation.validate({ id });
6131
+ if (error) {
6132
+ next(new BadRequestError33(error.message));
6133
+ return;
6134
+ }
6135
+ try {
6136
+ const data = await _getById(value.id);
6137
+ res.json(data);
6138
+ return;
6139
+ } catch (error2) {
6140
+ next(error2);
6141
+ }
6142
+ }
6143
+ async function getByOrg(req, res, next) {
6144
+ const org = req.params.org ?? "";
6145
+ const validation = Joi24.object({
6146
+ org: Joi24.string().hex().length(24).required()
6147
+ });
6148
+ const { error, value } = validation.validate({ org });
6149
+ if (error) {
6150
+ next(new BadRequestError33(error.message));
6151
+ return;
6152
+ }
6153
+ try {
6154
+ const data = await _getByOrg(value.org);
6155
+ res.json(data);
6156
+ return;
6157
+ } catch (error2) {
6158
+ next(error2);
6159
+ }
6160
+ }
6161
+ async function updateSeats(req, res, next) {
6162
+ const id = req.params.id ?? "";
6163
+ const payload = req.body;
6164
+ const { error } = schemaSubscriptionSeats.validate({ ...payload, id });
6165
+ if (error) {
6166
+ next(new BadRequestError33(error.message));
6167
+ return;
6168
+ }
6169
+ const user = payload.user ?? "";
6170
+ const seats = payload.seats ?? 0;
6171
+ const amount = payload.amount ?? 0;
6172
+ try {
6173
+ const message = await _updateSeats({ id, seats, amount, user });
6174
+ res.json({ message });
6175
+ return;
6176
+ } catch (error2) {
6177
+ next(error2);
6178
+ }
6179
+ }
6180
+ return {
6181
+ getAll,
6182
+ getById,
6183
+ getByOrg,
6184
+ updateSeats
6185
+ };
6186
+ }
6187
+
6188
+ // src/resources/subscription/subscription.transaction.controller.ts
6189
+ import Joi25 from "joi";
6190
+ import { BadRequestError as BadRequestError34 } from "@goweekdays/utils";
6191
+ function useSubscriptionTransactionController() {
6192
+ const { getAll: _getAll } = useSubscriptionTransactionRepo();
6193
+ async function getAll(req, res, next) {
6194
+ const validation = Joi25.object({
6195
+ id: Joi25.string().hex().length(24).required(),
6196
+ page: Joi25.number().min(1).max(100).optional().allow(null, "").default(1),
6197
+ limit: Joi25.number().min(1).max(100).optional().allow(null, "").default(10)
6198
+ });
6199
+ const query = req.query;
6200
+ const id = req.params.id ?? "";
6201
+ const { error, value } = validation.validate({ ...query, id });
6202
+ if (error) {
6203
+ next(new BadRequestError34(error.message));
6204
+ return;
6205
+ }
6206
+ try {
6207
+ const data = await _getAll(value);
6208
+ res.json(data);
6209
+ return;
6210
+ } catch (error2) {
6211
+ next(error2);
6212
+ }
6213
+ }
6214
+ return {
6215
+ getAll
6216
+ };
6217
+ }
6218
+
6219
+ // src/resources/plan/plan.model.ts
6220
+ import Joi26 from "joi";
6221
+ var currencies = ["USD", "PHP"];
6222
+ var schemaPlan = Joi26.object({
6223
+ name: Joi26.string().min(3).max(100).required(),
6224
+ description: Joi26.string().max(255).optional().allow("", null),
6225
+ features: Joi26.array().items(Joi26.string().max(100)).optional(),
6226
+ price: Joi26.number().positive().required(),
6227
+ currency: Joi26.string().length(3).allow(...currencies).required(),
6228
+ default: Joi26.boolean().optional().allow(null, ""),
6229
+ billingCycle: Joi26.string().valid("monthly", "yearly").required()
6230
+ });
6231
+ function modelPlan(data) {
6232
+ const { error } = schemaPlan.validate(data);
6233
+ if (error) {
6234
+ throw new Error(`Invalid plan data: ${error.message}`);
6235
+ }
6236
+ return {
6237
+ _id: data._id,
6238
+ name: data.name,
6239
+ description: data.description,
6240
+ features: data.features,
6241
+ price: data.price,
6242
+ currency: data.currency,
6243
+ billingCycle: data.billingCycle,
6244
+ status: data.status ?? "active",
6245
+ default: data.default ?? false,
6246
+ createdAt: data.createdAt ?? /* @__PURE__ */ new Date(),
6247
+ updatedAt: data.updatedAt ?? ""
6248
+ };
6249
+ }
6250
+
6251
+ // src/resources/plan/plan.repository.ts
6252
+ import {
6253
+ AppError as AppError13,
6254
+ BadRequestError as BadRequestError35,
6255
+ InternalServerError as InternalServerError17,
6256
+ logger as logger18,
6257
+ makeCacheKey as makeCacheKey13,
6258
+ paginate as paginate11,
6259
+ useAtlas as useAtlas16,
6260
+ useCache as useCache14
6261
+ } from "@goweekdays/utils";
6262
+ import Joi27 from "joi";
6263
+ import { ObjectId as ObjectId21 } from "mongodb";
6264
+ function usePlanRepo() {
6265
+ const db = useAtlas16.getDb();
6266
+ if (!db) {
6267
+ throw new InternalServerError17("Unable to connect to server.");
6268
+ }
6269
+ const namespace_collection = "plans";
6270
+ const collection = db.collection(namespace_collection);
6271
+ const { getCache, setCache, delNamespace } = useCache14(namespace_collection);
6272
+ function delCachedData() {
6273
+ delNamespace().then(() => {
6274
+ logger18.log({
6275
+ level: "info",
6276
+ message: `Cache namespace cleared for ${namespace_collection}`
6277
+ });
6278
+ }).catch((err) => {
6279
+ logger18.log({
6280
+ level: "error",
6281
+ message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
6282
+ });
6283
+ });
6284
+ }
6285
+ async function createIndexes() {
6286
+ try {
6287
+ await collection.createIndexes([
6288
+ {
6289
+ key: {
6290
+ status: 1
6291
+ }
6292
+ },
6293
+ {
6294
+ key: {
6295
+ name: 1
6296
+ }
6297
+ },
6298
+ {
6299
+ key: { billingCycle: 1 }
6300
+ },
6301
+ {
6302
+ key: { name: "text", description: "text" },
6303
+ name: "name_description_text_index"
6304
+ },
6305
+ {
6306
+ key: { name: 1, status: 1 },
6307
+ partialFilterExpression: { status: "active" },
6308
+ unique: true,
6309
+ name: "unique_name_index"
6310
+ },
6311
+ {
6312
+ key: { default: 1 },
6313
+ unique: true,
6314
+ partialFilterExpression: { status: "active" }
6315
+ }
6316
+ ]);
6317
+ } catch (error) {
6318
+ }
6319
+ }
6320
+ createIndexes().catch((error) => {
6321
+ logger18.log({
6322
+ level: "error",
6323
+ message: `Failed to create indexes for plans collection: ${error.message}`
6324
+ });
6325
+ });
6326
+ async function add(value) {
6327
+ try {
6328
+ value = modelPlan(value);
6329
+ await collection.insertOne(value);
6330
+ delCachedData();
6331
+ return "Successfully added plan.";
6332
+ } catch (error) {
6333
+ const isDuplicated = error.message.includes("duplicate");
6334
+ if (isDuplicated) {
6335
+ throw new BadRequestError35("Plan name already exist.");
6336
+ }
6337
+ throw new InternalServerError17("Failed to add plan.");
6338
+ }
6339
+ }
6340
+ async function getAll({
6341
+ page = 1,
6342
+ limit = 10,
6343
+ search = "",
6344
+ status = "active"
6345
+ } = {}) {
6346
+ page = page < 1 ? page - 1 : page;
6347
+ const query = { status };
6348
+ const cacheKeyOptions = {
6349
+ page,
6350
+ limit,
6351
+ search,
6352
+ status,
6353
+ tag: "getAll"
6354
+ };
6355
+ if (search) {
6356
+ query.$text = { $search: search };
6357
+ }
6358
+ const cacheKey = makeCacheKey13(namespace_collection, cacheKeyOptions);
6359
+ try {
6360
+ const cachedData = await getCache(cacheKey);
6361
+ if (cachedData) {
6362
+ return cachedData;
6363
+ }
6364
+ const items = await collection.aggregate([
6365
+ { $match: query },
6366
+ { $skip: page * limit },
6367
+ { $limit: limit }
6368
+ ]).toArray();
6369
+ const length = await collection.countDocuments(query);
6370
+ const data = paginate11(items, page, limit, length);
6371
+ setCache(cacheKey, data).then(() => {
6372
+ logger18.log({
6373
+ level: "info",
6374
+ message: `Cache set for getAll plan: ${cacheKey}`
6375
+ });
6376
+ }).catch((err) => {
6377
+ logger18.log({
6378
+ level: "error",
6379
+ message: `Failed to set cache for getAll plan: ${err.message}`
6380
+ });
6381
+ });
6382
+ return data;
6383
+ } catch (error) {
6384
+ throw new InternalServerError17("Failed to get plans.");
6385
+ }
6386
+ }
6387
+ async function getById(_id) {
6388
+ const { error } = Joi27.string().hex().length(24).required().validate(_id);
6389
+ if (error) {
6390
+ throw new Error(`Invalid plan ID: ${error.message}`);
6391
+ }
6392
+ try {
6393
+ _id = new ObjectId21(_id);
6394
+ } catch (error2) {
6395
+ throw new BadRequestError35("Invalid plan ID.");
6396
+ }
6397
+ try {
6398
+ const cacheKey = makeCacheKey13(namespace_collection, {
6399
+ _id: String(_id),
6400
+ tag: "getById"
6401
+ });
6402
+ const cachedData = await getCache(cacheKey);
6403
+ if (cachedData) {
6404
+ return cachedData;
6405
+ }
6406
+ const data = await collection.findOne({
6407
+ _id,
6408
+ status: { $ne: "deleted" }
6409
+ });
6410
+ setCache(cacheKey, data).then(() => {
6411
+ logger18.log({
6412
+ level: "info",
6413
+ message: `Cache set for getById plan: ${cacheKey}`
6414
+ });
6415
+ }).catch((err) => {
6416
+ logger18.log({
6417
+ level: "error",
6418
+ message: `Failed to set cache for getById plan: ${err.message}`
6419
+ });
6420
+ });
6421
+ return data;
6422
+ } catch (error2) {
6423
+ throw new InternalServerError17("Failed to get plan.");
6424
+ }
6425
+ }
6426
+ async function getDefault() {
6427
+ try {
6428
+ const cacheKey = makeCacheKey13(namespace_collection, {
6429
+ default: true,
6430
+ tag: "getDefault"
6431
+ });
6432
+ const cachedData = await getCache(cacheKey);
6433
+ if (cachedData) {
6434
+ return cachedData;
6435
+ }
6436
+ const data = await collection.findOne({
6437
+ default: true,
6438
+ status: "active"
6439
+ });
6440
+ setCache(cacheKey, data).then(() => {
6441
+ logger18.log({
6442
+ level: "info",
6443
+ message: `Cache set for default plan: ${cacheKey}`
6444
+ });
6445
+ }).catch((err) => {
6446
+ logger18.log({
6447
+ level: "error",
6448
+ message: `Failed to set cache for default plan: ${err.message}`
6449
+ });
6450
+ });
6451
+ return data;
6452
+ } catch (error) {
6453
+ throw new InternalServerError17("Failed to get default plan.");
6454
+ }
6455
+ }
6456
+ async function deleteById(_id) {
6457
+ const { error } = Joi27.string().hex().length(24).required().validate(_id);
6458
+ if (error) {
6459
+ throw new Error(`Invalid plan ID: ${error.message}`);
6460
+ }
6461
+ try {
6462
+ _id = new ObjectId21(_id);
6463
+ } catch (error2) {
6464
+ throw new BadRequestError35("Invalid plan ID.");
6465
+ }
6466
+ try {
6467
+ const result = await collection.updateOne(
6468
+ { _id },
6469
+ { $set: { status: "deleted" } }
6470
+ );
6471
+ if (result.modifiedCount === 0) {
6472
+ throw new InternalServerError17("Failed to delete plan.");
6473
+ }
6474
+ delCachedData();
6475
+ return "Successfully deleted plan.";
6476
+ } catch (error2) {
6477
+ if (error2 instanceof AppError13) {
6478
+ throw error2;
6479
+ }
6480
+ throw new InternalServerError17("Failed to delete plan.");
6481
+ }
6482
+ }
6483
+ return {
6484
+ add,
6485
+ getAll,
6486
+ getById,
6487
+ getDefault,
6488
+ deleteById
6489
+ };
6490
+ }
6491
+
6492
+ // src/resources/plan/plan.service.ts
6493
+ function usePlanService() {
6494
+ const { add } = usePlanRepo();
6495
+ async function addDefaultPlan() {
6496
+ try {
6497
+ await add({
6498
+ name: "Standard",
6499
+ description: "Default standard plan",
6500
+ price: 1e3,
6501
+ currency: "PHP",
6502
+ billingCycle: "monthly",
6503
+ default: true
6504
+ });
6505
+ } catch (error) {
6506
+ throw error;
6507
+ }
6508
+ }
6509
+ return {
6510
+ addDefaultPlan
6511
+ };
6512
+ }
6513
+
6514
+ // src/resources/plan/plan.controller.ts
6515
+ import Joi28 from "joi";
6516
+ import { BadRequestError as BadRequestError36 } from "@goweekdays/utils";
6517
+ function usePlanController() {
6518
+ const {
6519
+ add: _add,
6520
+ getAll: _getAll,
6521
+ getById: _getById,
6522
+ deleteById: _deleteById,
6523
+ getDefault: _getDefault
6524
+ } = usePlanRepo();
6525
+ async function add(req, res, next) {
6526
+ const value = req.body;
6527
+ const validation = Joi28.object({
6528
+ name: Joi28.string().min(3).max(100).required(),
6529
+ description: Joi28.string().max(255).optional().allow("", null),
6530
+ features: Joi28.array().items(Joi28.string().max(100)).optional(),
6531
+ price: Joi28.number().positive().required(),
6532
+ currency: Joi28.string().length(3).required(),
6533
+ billingCycle: Joi28.string().valid("monthly", "yearly").required()
6534
+ });
6535
+ const { error } = validation.validate(value);
6536
+ if (error) {
6537
+ next(new BadRequestError36(error.message));
6538
+ return;
6539
+ }
6540
+ try {
6541
+ const message = await _add(value);
6542
+ res.json({ message });
6543
+ return;
6544
+ } catch (error2) {
6545
+ next(error2);
6546
+ }
6547
+ }
6548
+ async function getAll(req, res, next) {
6549
+ const status = req.query.status ?? "active";
6550
+ const search = req.query.search ?? "";
6551
+ const page = Number(req.query.page) ?? 1;
6552
+ const limit = Number(req.query.limit) ?? 10;
6553
+ const validation = Joi28.object({
6554
+ status: Joi28.string().required(),
6555
+ search: Joi28.string().optional().allow("", null),
6556
+ page: Joi28.number().required(),
6557
+ limit: Joi28.number().required()
6558
+ });
6559
+ const { error } = validation.validate({ status, search, page, limit });
6560
+ if (error) {
6561
+ next(new BadRequestError36(error.message));
6562
+ return;
6563
+ }
6564
+ try {
6565
+ const plans = await _getAll({ status, search, page, limit });
6566
+ res.json(plans);
6567
+ return;
6568
+ } catch (error2) {
6569
+ next(error2);
6570
+ }
6571
+ }
6572
+ async function getById(req, res, next) {
6573
+ const id = req.params.id;
6574
+ const validation = Joi28.string().hex().length(24).required();
6575
+ const { error } = validation.validate(id);
6576
+ if (error) {
6577
+ next(new BadRequestError36(error.message));
6578
+ return;
6579
+ }
6580
+ try {
6581
+ const plan = await _getById(id);
6582
+ res.json(plan);
6583
+ return;
6584
+ } catch (error2) {
6585
+ next(error2);
6586
+ }
6587
+ }
6588
+ async function deleteById(req, res, next) {
6589
+ const id = req.params.id;
6590
+ const validation = Joi28.string().hex().length(24).required();
6591
+ const { error } = validation.validate(id);
6592
+ if (error) {
6593
+ next(new BadRequestError36(error.message));
6594
+ return;
6595
+ }
6596
+ try {
6597
+ const message = await _deleteById(id);
6598
+ res.json({ message });
6599
+ return;
6600
+ } catch (error2) {
6601
+ next(error2);
6602
+ }
6603
+ }
6604
+ async function getDefault(req, res, next) {
6605
+ try {
6606
+ const plan = await _getDefault();
6607
+ res.json(plan);
6608
+ return;
6609
+ } catch (error) {
6610
+ next(error);
6611
+ }
6612
+ }
6613
+ return {
6614
+ add,
6615
+ getAll,
6616
+ getById,
6617
+ deleteById,
6618
+ getDefault
6619
+ };
6620
+ }
6621
+
6622
+ // src/resources/organization/organization.service.ts
6623
+ function useOrgService() {
6624
+ const { add: addOrg } = useOrgRepo();
6625
+ const { addRole } = useRoleRepo();
6626
+ const { getAll: getAllPermission } = usePermissionRepo();
6627
+ const { add: addMember, updateRoleById: _updateRoleById } = useMemberRepo();
6628
+ const { getUserById } = useUserRepo();
6629
+ const { getDefault } = usePlanRepo();
6630
+ const { add: addSubscription } = useSubscriptionRepo();
6631
+ const { add: addSubscriptionTransaction } = useSubscriptionTransactionRepo();
6632
+ async function add(value) {
6633
+ const { error } = schemaOrgAdd.validate(value);
6634
+ if (error) {
6635
+ throw new BadRequestError37(error.message);
6636
+ }
6637
+ const session = useAtlas17.getClient()?.startSession();
6638
+ if (!session) {
6639
+ throw new BadRequestError37("Unable to start database session.");
6640
+ }
6641
+ try {
6642
+ session?.startTransaction();
6643
+ const org = await addOrg(
6644
+ {
6645
+ email: value.email,
6646
+ name: value.name,
6647
+ contact: value.contact,
6648
+ createdBy: value.createdBy
6649
+ },
6650
+ session
6651
+ );
6652
+ const plan = await getDefault();
6653
+ if (!plan) {
6654
+ throw new BadRequestError37(
6655
+ "Failed to create organization, plan not found."
6656
+ );
6657
+ }
6658
+ const currentDate = /* @__PURE__ */ new Date();
6659
+ const nextBillingDate = new Date(currentDate);
6660
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
6661
+ const amount = plan.price * value.seats;
6662
+ const subscriptionId = await addSubscription(
6663
+ {
6664
+ amount,
6665
+ org: String(org),
6666
+ seats: value.seats,
6667
+ paidSeats: value.seats,
6668
+ currency: plan.currency,
6669
+ billingCycle: plan.billingCycle,
6670
+ nextBillingDate
6671
+ },
6672
+ session
6673
+ );
6674
+ const createdBy = String(value.createdBy);
6675
+ const user = await getUserById(createdBy);
6676
+ if (!user) {
6677
+ throw new BadRequestError37("User is required to create org member.");
6678
+ }
6679
+ await addSubscriptionTransaction(
6680
+ {
6681
+ subscription: subscriptionId,
6682
+ type: "initiate",
6683
+ amount,
6684
+ currency: plan.currency,
6685
+ description: "Initial subscription transaction",
6686
+ createdBy: value.createdBy,
6687
+ createdByName: `${user.firstName} ${user.lastName}`
6688
+ },
6689
+ session
6690
+ );
6691
+ const allPermissions = await getAllPermission({
6692
+ app: "org",
6693
+ limit: 100
6694
+ });
6695
+ let permissions = [];
6696
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
6697
+ permissions = allPermissions.items.map((perm) => perm.key);
6698
+ }
6699
+ if (permissions.length === 0) {
6700
+ throw new Error("No permissions found for the organization type.");
6701
+ }
6702
+ const roleData = {
6703
+ org: String(org),
6704
+ name: "Owner",
6705
+ description: "Owner of the organization",
6706
+ permissions,
6707
+ createdBy,
6708
+ app: "org"
6709
+ };
6710
+ const role = await addRole(roleData, session);
6711
+ if (!role) {
6712
+ throw new BadRequestError37("Role is required to create org member.");
6713
+ }
6714
+ await addMember(
6715
+ {
6716
+ role: String(role),
6717
+ roleName: roleData.name,
6718
+ org: String(org),
6719
+ name: `${user.firstName} ${user.lastName}`,
6720
+ user: createdBy,
6721
+ app: "org"
6722
+ },
6723
+ session
6724
+ );
6725
+ await session?.commitTransaction();
6726
+ return String(org);
6727
+ } catch (error2) {
6728
+ await session?.abortTransaction();
6729
+ throw error2;
6730
+ } finally {
6731
+ await session?.endSession();
6732
+ }
6733
+ }
6734
+ return {
6735
+ add
6736
+ };
6737
+ }
6738
+
6739
+ // src/resources/organization/organization.controller.ts
6740
+ import { BadRequestError as BadRequestError38 } from "@goweekdays/utils";
6741
+ import Joi29 from "joi";
6742
+ function useOrgController() {
6743
+ const { add: _add } = useOrgService();
6744
+ const { getOrgsByMembership } = useMemberRepo();
6745
+ const {
6746
+ getByName: _getByName,
6747
+ getAll: getAllOrg,
6748
+ getById: _getById,
6749
+ updateById: _updateById
6750
+ } = useOrgRepo();
6751
+ async function add(req, res, next) {
6752
+ const value = req.body;
6753
+ const { error } = schemaOrgAdd.validate(value);
6754
+ if (error) {
6755
+ next(new BadRequestError38(error.message));
6756
+ return;
6757
+ }
6758
+ try {
6759
+ const org = await _add(value);
6760
+ res.json({
6761
+ message: "Organization created successfully.",
6762
+ data: { org }
6763
+ });
6764
+ return;
6765
+ } catch (error2) {
6766
+ next(error2);
6767
+ }
6768
+ }
6769
+ async function getOrgsByUserId(req, res, next) {
6770
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
6771
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
6772
+ const search = req.query.search ?? "";
6773
+ const user = req.params.user ?? "";
6774
+ const isPageNumber = isFinite(page);
6775
+ if (!isPageNumber) {
6776
+ next(new BadRequestError38("Invalid page number."));
6777
+ return;
6778
+ }
6779
+ const isLimitNumber = isFinite(limit);
6780
+ if (!isLimitNumber) {
6781
+ next(new BadRequestError38("Invalid limit number."));
6782
+ return;
6783
+ }
6784
+ const validation = Joi29.object({
6785
+ user: Joi29.string().hex().required(),
6786
+ page: Joi29.number().min(1).optional().allow("", null),
6787
+ limit: Joi29.number().min(1).optional().allow("", null),
6788
+ search: Joi29.string().optional().allow("", null)
6789
+ });
6790
+ const { error } = validation.validate({ user, page, limit, search });
6791
+ if (error) {
6792
+ next(new BadRequestError38(error.message));
6793
+ return;
6794
+ }
6795
+ try {
6796
+ const orgs = await getOrgsByMembership({ user, page, limit, search });
6797
+ res.json(orgs);
6798
+ return;
6799
+ } catch (error2) {
6800
+ next(error2);
6801
+ }
6802
+ }
6803
+ async function getAll(req, res, next) {
6804
+ const query = req.query;
6805
+ const validation = Joi29.object({
6806
+ page: Joi29.number().min(1).optional().allow("", null),
6807
+ limit: Joi29.number().min(1).optional().allow("", null),
6808
+ search: Joi29.string().optional().allow("", null),
6809
+ status: Joi29.string().valid("active", "suspended", "inactive", "deleted").optional()
6810
+ });
6811
+ const { error } = validation.validate(query);
6812
+ const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
6813
+ const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
6814
+ const search = req.query.search ?? "";
6815
+ const status = req.query.status ?? "active";
6816
+ const isPageNumber = isFinite(page);
5562
6817
  if (!isPageNumber) {
5563
- next(new BadRequestError30("Invalid page number."));
6818
+ next(new BadRequestError38("Invalid page number."));
5564
6819
  return;
5565
6820
  }
5566
6821
  const isLimitNumber = isFinite(limit);
5567
6822
  if (!isLimitNumber) {
5568
- next(new BadRequestError30("Invalid limit number."));
6823
+ next(new BadRequestError38("Invalid limit number."));
5569
6824
  return;
5570
6825
  }
5571
6826
  if (error) {
5572
- next(new BadRequestError30(error.message));
6827
+ next(new BadRequestError38(error.message));
5573
6828
  return;
5574
6829
  }
5575
6830
  try {
@@ -5582,12 +6837,12 @@ function useOrgController() {
5582
6837
  }
5583
6838
  async function getByName(req, res, next) {
5584
6839
  const name = req.params.name;
5585
- const validation = Joi21.object({
5586
- name: Joi21.string().required()
6840
+ const validation = Joi29.object({
6841
+ name: Joi29.string().required()
5587
6842
  });
5588
6843
  const { error } = validation.validate({ name });
5589
6844
  if (error) {
5590
- next(new BadRequestError30(error.message));
6845
+ next(new BadRequestError38(error.message));
5591
6846
  return;
5592
6847
  }
5593
6848
  try {
@@ -5600,12 +6855,12 @@ function useOrgController() {
5600
6855
  }
5601
6856
  async function getById(req, res, next) {
5602
6857
  const id = req.params.id;
5603
- const validation = Joi21.object({
5604
- id: Joi21.string().hex().required()
6858
+ const validation = Joi29.object({
6859
+ id: Joi29.string().hex().required()
5605
6860
  });
5606
6861
  const { error } = validation.validate({ id });
5607
6862
  if (error) {
5608
- next(new BadRequestError30(error.message));
6863
+ next(new BadRequestError38(error.message));
5609
6864
  return;
5610
6865
  }
5611
6866
  try {
@@ -5616,12 +6871,29 @@ function useOrgController() {
5616
6871
  next(error2);
5617
6872
  }
5618
6873
  }
6874
+ async function updateById(req, res, next) {
6875
+ const _id = req.params.id ?? "";
6876
+ const payload = req.body;
6877
+ const { error } = schemaOrgUpdate.validate({ _id, ...payload });
6878
+ if (error) {
6879
+ next(new BadRequestError38(error.message));
6880
+ return;
6881
+ }
6882
+ try {
6883
+ const message = await _updateById(_id, payload);
6884
+ res.json({ message });
6885
+ return;
6886
+ } catch (error2) {
6887
+ next(error2);
6888
+ }
6889
+ }
5619
6890
  return {
5620
6891
  add,
5621
6892
  getOrgsByUserId,
5622
6893
  getByName,
5623
6894
  getAll,
5624
- getById
6895
+ getById,
6896
+ updateById
5625
6897
  };
5626
6898
  }
5627
6899
 
@@ -5640,12 +6912,12 @@ function useUserService() {
5640
6912
  const { getAll: getAllPermission } = usePermissionRepo();
5641
6913
  const { getById: getOrgById } = useOrgRepo();
5642
6914
  async function createDefaultUser() {
5643
- const session = useAtlas14.getClient()?.startSession();
6915
+ const session = useAtlas18.getClient()?.startSession();
5644
6916
  try {
5645
6917
  session?.startTransaction();
5646
6918
  const _user = await getUserByEmail(DEFAULT_USER_EMAIL);
5647
6919
  if (_user) {
5648
- throw new BadRequestError31(
6920
+ throw new BadRequestError39(
5649
6921
  `User already exists: ${DEFAULT_USER_EMAIL}.`
5650
6922
  );
5651
6923
  }
@@ -5695,7 +6967,7 @@ function useUserService() {
5695
6967
  try {
5696
6968
  const _user = await getUserByEmail(value.email);
5697
6969
  if (_user) {
5698
- throw new BadRequestError31(`User already exists: ${value.email}.`);
6970
+ throw new BadRequestError39(`User already exists: ${value.email}.`);
5699
6971
  }
5700
6972
  const hashedPassword = await hashPassword(value.password);
5701
6973
  const insertedId = await addUser({
@@ -5707,10 +6979,10 @@ function useUserService() {
5707
6979
  });
5708
6980
  return insertedId;
5709
6981
  } catch (error) {
5710
- if (error instanceof AppError11) {
6982
+ if (error instanceof AppError14) {
5711
6983
  throw error;
5712
6984
  } else {
5713
- throw new InternalServerError15(`Error creating user: ${error}`);
6985
+ throw new InternalServerError18(`Error creating user: ${error}`);
5714
6986
  }
5715
6987
  }
5716
6988
  }
@@ -5721,22 +6993,22 @@ function useUserService() {
5721
6993
  lastName = "",
5722
6994
  password = ""
5723
6995
  } = {}) {
5724
- const session = useAtlas14.getClient()?.startSession();
6996
+ const session = useAtlas18.getClient()?.startSession();
5725
6997
  session?.startTransaction();
5726
6998
  try {
5727
6999
  const invitation = await _getVerificationById(id);
5728
7000
  if (!invitation || !invitation.metadata?.app || !invitation.metadata?.role) {
5729
- throw new BadRequestError31("Invalid invitation.");
7001
+ throw new BadRequestError39("Invalid invitation.");
5730
7002
  }
5731
7003
  if (invitation.status === "complete") {
5732
- throw new BadRequestError31("Invitation already used.");
7004
+ throw new BadRequestError39("Invitation already used.");
5733
7005
  }
5734
7006
  if (!invitation.expireAt) {
5735
- throw new BadRequestError31("Expiration date is required.");
7007
+ throw new BadRequestError39("Expiration date is required.");
5736
7008
  }
5737
7009
  const expired = new Date(invitation.expireAt) < /* @__PURE__ */ new Date();
5738
7010
  if (invitation.status === "expired" || expired) {
5739
- throw new BadRequestError31("Invitation expired.");
7011
+ throw new BadRequestError39("Invitation expired.");
5740
7012
  }
5741
7013
  const email = invitation.email;
5742
7014
  const user = await getUserByEmail(invitation.email);
@@ -5787,10 +7059,10 @@ function useUserService() {
5787
7059
  return userId;
5788
7060
  } catch (error) {
5789
7061
  await session?.abortTransaction();
5790
- if (error instanceof AppError11) {
7062
+ if (error instanceof AppError14) {
5791
7063
  throw error;
5792
7064
  } else {
5793
- throw new InternalServerError15("Failed to create user by invite.");
7065
+ throw new InternalServerError18("Failed to create user by invite.");
5794
7066
  }
5795
7067
  } finally {
5796
7068
  session?.endSession();
@@ -5802,29 +7074,29 @@ function useUserService() {
5802
7074
  lastName = "",
5803
7075
  password = ""
5804
7076
  } = {}) {
5805
- const session = useAtlas14.getClient()?.startSession();
7077
+ const session = useAtlas18.getClient()?.startSession();
5806
7078
  session?.startTransaction();
5807
7079
  try {
5808
7080
  const signUp = await _getVerificationById(id);
5809
7081
  if (!signUp) {
5810
- throw new BadRequestError31("Invalid sign up link.");
7082
+ throw new BadRequestError39("Invalid sign up link.");
5811
7083
  }
5812
7084
  if (signUp.status === "complete") {
5813
- throw new BadRequestError31(
7085
+ throw new BadRequestError39(
5814
7086
  "You have already an account created using this link."
5815
7087
  );
5816
7088
  }
5817
7089
  if (!signUp.expireAt) {
5818
- throw new BadRequestError31("Expiration date is required.");
7090
+ throw new BadRequestError39("Expiration date is required.");
5819
7091
  }
5820
7092
  const expired = new Date(signUp.expireAt) < /* @__PURE__ */ new Date();
5821
7093
  if (signUp.status === "expired" || expired) {
5822
- throw new BadRequestError31("Sign up link expired.");
7094
+ throw new BadRequestError39("Sign up link expired.");
5823
7095
  }
5824
7096
  const email = signUp.email;
5825
7097
  const _user = await getUserByEmail(signUp.email);
5826
7098
  if (_user) {
5827
- throw new BadRequestError31(`User already exists: ${email}.`);
7099
+ throw new BadRequestError39(`User already exists: ${email}.`);
5828
7100
  }
5829
7101
  const hashedPassword = await hashPassword(password);
5830
7102
  const userId = await addUser(
@@ -5850,17 +7122,17 @@ function useUserService() {
5850
7122
  const { updateStatusById: updateVerificationStatusById } = useVerificationRepo();
5851
7123
  async function resetPassword(value) {
5852
7124
  if (value.newPassword !== value.confirmPassword) {
5853
- throw new BadRequestError31("Passwords do not match.");
7125
+ throw new BadRequestError39("Passwords do not match.");
5854
7126
  }
5855
7127
  let hashedPassword = "";
5856
7128
  try {
5857
7129
  hashedPassword = await hashPassword(value.newPassword);
5858
7130
  } catch (error) {
5859
- throw new InternalServerError15(`Error hashing password: ${error}`);
7131
+ throw new InternalServerError18(`Error hashing password: ${error}`);
5860
7132
  }
5861
- const session = useAtlas14.getClient()?.startSession();
7133
+ const session = useAtlas18.getClient()?.startSession();
5862
7134
  if (!session) {
5863
- throw new InternalServerError15("Failed to start database session.");
7135
+ throw new InternalServerError18("Failed to start database session.");
5864
7136
  }
5865
7137
  try {
5866
7138
  session.startTransaction();
@@ -5876,7 +7148,7 @@ function useUserService() {
5876
7148
  throw new NotFoundError3("User ID is invalid.");
5877
7149
  }
5878
7150
  if (otpDoc.status === "used") {
5879
- throw new BadRequestError31("This link has already been invalidated.");
7151
+ throw new BadRequestError39("This link has already been invalidated.");
5880
7152
  }
5881
7153
  await updateVerificationStatusById(value.id, "used", session);
5882
7154
  await _updateUserFieldById(
@@ -5887,31 +7159,31 @@ function useUserService() {
5887
7159
  return "Successfully reset password.";
5888
7160
  } catch (error) {
5889
7161
  await session.abortTransaction();
5890
- if (error instanceof AppError11) {
7162
+ if (error instanceof AppError14) {
5891
7163
  throw error;
5892
7164
  }
5893
- throw new InternalServerError15("Failed to reset password.");
7165
+ throw new InternalServerError18("Failed to reset password.");
5894
7166
  }
5895
7167
  }
5896
7168
  const { updateName: updateMemberName } = useMemberRepo();
5897
7169
  async function updateName(_id, firstName, lastName) {
5898
7170
  if (!_id) {
5899
- throw new BadRequestError31("Invalid user ID");
7171
+ throw new BadRequestError39("Invalid user ID");
5900
7172
  }
5901
7173
  if (!firstName) {
5902
- throw new BadRequestError31("Invalid firstName");
7174
+ throw new BadRequestError39("Invalid firstName");
5903
7175
  }
5904
7176
  if (!lastName) {
5905
- throw new BadRequestError31("Invalid lastName");
7177
+ throw new BadRequestError39("Invalid lastName");
5906
7178
  }
5907
- const session = useAtlas14.getClient()?.startSession();
7179
+ const session = useAtlas18.getClient()?.startSession();
5908
7180
  session?.startTransaction();
5909
- const cacheKey = makeCacheKey11("users", { user: _id });
7181
+ const cacheKey = makeCacheKey14("users", { user: _id });
5910
7182
  try {
5911
- useCache12().delCache(cacheKey).then(() => {
5912
- logger16.info(`Cache cleared for user: ${_id}`);
7183
+ useCache15().delCache(cacheKey).then(() => {
7184
+ logger19.info(`Cache cleared for user: ${_id}`);
5913
7185
  }).catch((error) => {
5914
- logger16.error(`Failed to clear cache for user: ${_id}`, error);
7186
+ logger19.error(`Failed to clear cache for user: ${_id}`, error);
5915
7187
  });
5916
7188
  await _updateName({ _id, firstName, lastName }, session);
5917
7189
  await updateMemberName(
@@ -5929,16 +7201,16 @@ function useUserService() {
5929
7201
  }
5930
7202
  async function updateBirthday(_id, month, day, year) {
5931
7203
  if (!_id) {
5932
- throw new BadRequestError31("Invalid user ID");
7204
+ throw new BadRequestError39("Invalid user ID");
5933
7205
  }
5934
7206
  if (!month) {
5935
- throw new BadRequestError31("Invalid birth month.");
7207
+ throw new BadRequestError39("Invalid birth month.");
5936
7208
  }
5937
7209
  if (!day) {
5938
- throw new BadRequestError31("Invalid birthday.");
7210
+ throw new BadRequestError39("Invalid birthday.");
5939
7211
  }
5940
7212
  if (!year) {
5941
- throw new BadRequestError31("Invalid birth year.");
7213
+ throw new BadRequestError39("Invalid birth year.");
5942
7214
  }
5943
7215
  try {
5944
7216
  await _updateBirthday({ _id, month, day, year });
@@ -5963,7 +7235,7 @@ function useUserService() {
5963
7235
  bucket: SPACES_BUCKET
5964
7236
  });
5965
7237
  async function updateUserProfile({ file, user, previousProfile } = {}) {
5966
- const session = useAtlas14.getClient()?.startSession();
7238
+ const session = useAtlas18.getClient()?.startSession();
5967
7239
  session?.startTransaction();
5968
7240
  const _file = {
5969
7241
  name: file.originalname,
@@ -6008,11 +7280,11 @@ function useUserService() {
6008
7280
 
6009
7281
  // src/resources/user/user.controller.ts
6010
7282
  import {
6011
- AppError as AppError12,
6012
- BadRequestError as BadRequestError32,
6013
- InternalServerError as InternalServerError16
7283
+ AppError as AppError15,
7284
+ BadRequestError as BadRequestError40,
7285
+ InternalServerError as InternalServerError19
6014
7286
  } from "@goweekdays/utils";
6015
- import Joi22 from "joi";
7287
+ import Joi30 from "joi";
6016
7288
  function useUserController() {
6017
7289
  const {
6018
7290
  updateName: _updateName,
@@ -6028,14 +7300,14 @@ function useUserController() {
6028
7300
  const status = req.query.status ?? "";
6029
7301
  const search = req.query.search ?? "";
6030
7302
  const page = Number(req.query.page) ?? 1;
6031
- const validation = Joi22.object({
6032
- status: Joi22.string().required(),
6033
- search: Joi22.string().optional().allow("", null),
6034
- page: Joi22.number().required()
7303
+ const validation = Joi30.object({
7304
+ status: Joi30.string().required(),
7305
+ search: Joi30.string().optional().allow("", null),
7306
+ page: Joi30.number().required()
6035
7307
  });
6036
7308
  const { error } = validation.validate({ status, search, page });
6037
7309
  if (error) {
6038
- next(new BadRequestError32(error.message));
7310
+ next(new BadRequestError40(error.message));
6039
7311
  return;
6040
7312
  }
6041
7313
  try {
@@ -6048,14 +7320,14 @@ function useUserController() {
6048
7320
  }
6049
7321
  async function getUserById(req, res, next) {
6050
7322
  const id = req.params.id || "";
6051
- const validation = Joi22.string().hex().validate(id);
7323
+ const validation = Joi30.string().hex().validate(id);
6052
7324
  if (validation.error) {
6053
- throw new BadRequestError32("Invalid id.");
7325
+ throw new BadRequestError40("Invalid id.");
6054
7326
  }
6055
7327
  try {
6056
7328
  const user = await _getUserById(id);
6057
7329
  if (!user) {
6058
- throw new BadRequestError32("User not found.");
7330
+ throw new BadRequestError40("User not found.");
6059
7331
  }
6060
7332
  res.json(user);
6061
7333
  } catch (error) {
@@ -6066,13 +7338,13 @@ function useUserController() {
6066
7338
  const id = req.headers.user ?? "";
6067
7339
  const firstName = req.body.firstName ?? "";
6068
7340
  const lastName = req.body.lastName ?? "";
6069
- const validation = Joi22.object({
6070
- firstName: Joi22.string().required(),
6071
- lastName: Joi22.string().required()
7341
+ const validation = Joi30.object({
7342
+ firstName: Joi30.string().required(),
7343
+ lastName: Joi30.string().required()
6072
7344
  });
6073
7345
  const { error } = validation.validate({ firstName, lastName });
6074
7346
  if (error) {
6075
- next(new BadRequestError32(error.message));
7347
+ next(new BadRequestError40(error.message));
6076
7348
  return;
6077
7349
  }
6078
7350
  try {
@@ -6088,14 +7360,14 @@ function useUserController() {
6088
7360
  const month = req.body.month ?? "";
6089
7361
  const day = req.body.day ?? 0;
6090
7362
  const year = req.body.year ?? 0;
6091
- const validation = Joi22.object({
6092
- month: Joi22.string().required(),
6093
- day: Joi22.number().integer().min(1).max(31).required(),
6094
- year: Joi22.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
7363
+ const validation = Joi30.object({
7364
+ month: Joi30.string().required(),
7365
+ day: Joi30.number().integer().min(1).max(31).required(),
7366
+ year: Joi30.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
6095
7367
  });
6096
7368
  const { error } = validation.validate({ month, day, year });
6097
7369
  if (error) {
6098
- next(new BadRequestError32(error.message));
7370
+ next(new BadRequestError40(error.message));
6099
7371
  return;
6100
7372
  }
6101
7373
  try {
@@ -6109,18 +7381,18 @@ function useUserController() {
6109
7381
  async function updateUserFieldById(req, res, next) {
6110
7382
  const _id = req.params.id;
6111
7383
  const { field, value } = req.body;
6112
- const validation = Joi22.object({
6113
- _id: Joi22.string().hex().required(),
6114
- field: Joi22.string().valid("gender", "email", "contact", "profile").required(),
6115
- value: Joi22.alternatives().conditional("field", {
7384
+ const validation = Joi30.object({
7385
+ _id: Joi30.string().hex().required(),
7386
+ field: Joi30.string().valid("gender", "email", "contact", "profile").required(),
7387
+ value: Joi30.alternatives().conditional("field", {
6116
7388
  is: "email",
6117
- then: Joi22.string().email().required(),
6118
- otherwise: Joi22.string().required()
7389
+ then: Joi30.string().email().required(),
7390
+ otherwise: Joi30.string().required()
6119
7391
  })
6120
7392
  });
6121
7393
  const { error } = validation.validate({ _id, field, value });
6122
7394
  if (error) {
6123
- next(new BadRequestError32(error.message));
7395
+ next(new BadRequestError40(error.message));
6124
7396
  return;
6125
7397
  }
6126
7398
  try {
@@ -6136,12 +7408,12 @@ function useUserController() {
6136
7408
  return;
6137
7409
  }
6138
7410
  const previousProfile = req.body.previousProfile ?? "";
6139
- const validation = Joi22.object({
6140
- previousProfile: Joi22.string().hex().optional().allow("", null)
7411
+ const validation = Joi30.object({
7412
+ previousProfile: Joi30.string().hex().optional().allow("", null)
6141
7413
  });
6142
7414
  const { error } = validation.validate({ previousProfile });
6143
7415
  if (error) {
6144
- next(new BadRequestError32(error.message));
7416
+ next(new BadRequestError40(error.message));
6145
7417
  return;
6146
7418
  }
6147
7419
  const user = req.headers["user"] ?? "";
@@ -6154,10 +7426,10 @@ function useUserController() {
6154
7426
  res.json({ message: "Successfully updated profile picture." });
6155
7427
  return;
6156
7428
  } catch (error2) {
6157
- if (error2 instanceof AppError12) {
7429
+ if (error2 instanceof AppError15) {
6158
7430
  next(error2);
6159
7431
  } else {
6160
- next(new InternalServerError16(error2));
7432
+ next(new InternalServerError19(error2));
6161
7433
  }
6162
7434
  }
6163
7435
  }
@@ -6167,12 +7439,12 @@ function useUserController() {
6167
7439
  const password = req.body.password ?? "";
6168
7440
  const id = req.params.id ?? "";
6169
7441
  const type = req.body.type ?? "";
6170
- const validation = Joi22.object({
6171
- firstName: Joi22.string().required(),
6172
- lastName: Joi22.string().required(),
6173
- password: Joi22.string().required(),
6174
- id: Joi22.string().hex().required(),
6175
- type: Joi22.string().required()
7442
+ const validation = Joi30.object({
7443
+ firstName: Joi30.string().required(),
7444
+ lastName: Joi30.string().required(),
7445
+ password: Joi30.string().required(),
7446
+ id: Joi30.string().hex().required(),
7447
+ type: Joi30.string().required()
6176
7448
  });
6177
7449
  const { error } = validation.validate({
6178
7450
  firstName,
@@ -6182,7 +7454,7 @@ function useUserController() {
6182
7454
  type
6183
7455
  });
6184
7456
  if (error) {
6185
- next(new BadRequestError32(error.message));
7457
+ next(new BadRequestError40(error.message));
6186
7458
  return;
6187
7459
  }
6188
7460
  try {
@@ -6205,14 +7477,14 @@ function useUserController() {
6205
7477
  }
6206
7478
  async function resetPassword(req, res, next) {
6207
7479
  const payload = req.body;
6208
- const validation = Joi22.object({
6209
- id: Joi22.string().hex().required(),
6210
- newPassword: Joi22.string().min(8).required(),
6211
- confirmPassword: Joi22.string().min(8).required()
7480
+ const validation = Joi30.object({
7481
+ id: Joi30.string().hex().required(),
7482
+ newPassword: Joi30.string().min(8).required(),
7483
+ confirmPassword: Joi30.string().min(8).required()
6212
7484
  });
6213
7485
  const { error } = validation.validate(payload);
6214
7486
  if (error) {
6215
- next(new BadRequestError32(error.message));
7487
+ next(new BadRequestError40(error.message));
6216
7488
  return;
6217
7489
  }
6218
7490
  try {
@@ -6237,7 +7509,7 @@ function useUserController() {
6237
7509
  }
6238
7510
 
6239
7511
  // src/resources/verification/verification.service.ts
6240
- import Joi23 from "joi";
7512
+ import Joi31 from "joi";
6241
7513
  function useVerificationService() {
6242
7514
  const MailerConfig = {
6243
7515
  host: MAILER_TRANSPORT_HOST,
@@ -6272,7 +7544,7 @@ function useVerificationService() {
6272
7544
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
6273
7545
  };
6274
7546
  if (!metadata.app) {
6275
- throw new BadRequestError33("App metadata is required.");
7547
+ throw new BadRequestError41("App metadata is required.");
6276
7548
  }
6277
7549
  try {
6278
7550
  const user = await getUserByEmail(email);
@@ -6295,7 +7567,7 @@ function useVerificationService() {
6295
7567
  html: emailContent2,
6296
7568
  from: "GoWeekdays"
6297
7569
  }).catch((error) => {
6298
- logger17.log({
7570
+ logger20.log({
6299
7571
  level: "error",
6300
7572
  message: `Error sending user invite email: ${error}`
6301
7573
  });
@@ -6317,7 +7589,7 @@ function useVerificationService() {
6317
7589
  html: emailContent,
6318
7590
  from: "GoWeekdays"
6319
7591
  }).catch((error) => {
6320
- logger17.log({
7592
+ logger20.log({
6321
7593
  level: "error",
6322
7594
  message: `Error sending user invite email: ${error}`
6323
7595
  });
@@ -6352,14 +7624,14 @@ function useVerificationService() {
6352
7624
  from: "GoWeekdays",
6353
7625
  html: emailContent
6354
7626
  }).catch((error) => {
6355
- logger17.log({
7627
+ logger20.log({
6356
7628
  level: "error",
6357
7629
  message: `Error sending forget password email: ${error}`
6358
7630
  });
6359
7631
  });
6360
7632
  return "Successfully created a link to reset password. Please check your email.";
6361
7633
  } catch (error) {
6362
- throw new InternalServerError17("Failed to create forget password link.");
7634
+ throw new InternalServerError20("Failed to create forget password link.");
6363
7635
  }
6364
7636
  }
6365
7637
  async function getById(id) {
@@ -6398,34 +7670,34 @@ function useVerificationService() {
6398
7670
  }
6399
7671
  function errorByType(type, status) {
6400
7672
  if (type === "user-invite" && status === "expired") {
6401
- throw new BadRequestError33(
7673
+ throw new BadRequestError41(
6402
7674
  "Invitation has already expired, please contact admin to resend the invitation."
6403
7675
  );
6404
7676
  }
6405
7677
  if (type === "user-sign-up" && status === "expired") {
6406
- throw new BadRequestError33(
7678
+ throw new BadRequestError41(
6407
7679
  "Sign up verification has expired, please sign up again to get a new verification link."
6408
7680
  );
6409
7681
  }
6410
7682
  if (type === "user-invite" && status === "complete") {
6411
- throw new BadRequestError33(
7683
+ throw new BadRequestError41(
6412
7684
  "User already registered, please login to continue."
6413
7685
  );
6414
7686
  }
6415
7687
  if (type === "forget-password" && status === "complete") {
6416
- throw new BadRequestError33(
7688
+ throw new BadRequestError41(
6417
7689
  "Forget password verification has already been used, please request a new one."
6418
7690
  );
6419
7691
  }
6420
7692
  if (type === "forget-password" && status === "expired") {
6421
- throw new BadRequestError33(
7693
+ throw new BadRequestError41(
6422
7694
  "Forget password verification has expired, please request a new one."
6423
7695
  );
6424
7696
  }
6425
- throw new BadRequestError33("Invalid verification.");
7697
+ throw new BadRequestError41("Invalid verification.");
6426
7698
  }
6427
7699
  async function verify(id) {
6428
- const session = useAtlas15.getClient()?.startSession();
7700
+ const session = useAtlas19.getClient()?.startSession();
6429
7701
  session?.startTransaction();
6430
7702
  try {
6431
7703
  const _id = await _getById(id);
@@ -6436,10 +7708,10 @@ function useVerificationService() {
6436
7708
  errorByType(_id.type, "expired");
6437
7709
  }
6438
7710
  if (_id.status === "complete") {
6439
- throw new BadRequestError33("Verification already completed.");
7711
+ throw new BadRequestError41("Verification already completed.");
6440
7712
  }
6441
7713
  if (!_id.expireAt) {
6442
- throw new BadRequestError33("Expiration date is required.");
7714
+ throw new BadRequestError41("Expiration date is required.");
6443
7715
  }
6444
7716
  const expiration = new Date(_id.expireAt).getTime();
6445
7717
  const now = (/* @__PURE__ */ new Date()).getTime();
@@ -6455,12 +7727,12 @@ function useVerificationService() {
6455
7727
  throw new NotFoundError4("User not found for member invite.");
6456
7728
  }
6457
7729
  if (!_id.metadata?.app) {
6458
- throw new BadRequestError33(
7730
+ throw new BadRequestError41(
6459
7731
  "App metadata is required for member invite."
6460
7732
  );
6461
7733
  }
6462
7734
  if (!_id.metadata?.role || !_id.metadata?.roleName) {
6463
- throw new BadRequestError33(
7735
+ throw new BadRequestError41(
6464
7736
  "Role metadata is required for member invite."
6465
7737
  );
6466
7738
  }
@@ -6482,7 +7754,7 @@ function useVerificationService() {
6482
7754
  return _id;
6483
7755
  } catch (error) {
6484
7756
  await session?.abortTransaction();
6485
- logger17.log({
7757
+ logger20.log({
6486
7758
  level: "info",
6487
7759
  message: `Error verifying user invitation: ${error}`
6488
7760
  });
@@ -6495,7 +7767,7 @@ function useVerificationService() {
6495
7767
  try {
6496
7768
  await updateStatusById(id, "cancelled");
6497
7769
  } catch (error) {
6498
- throw new InternalServerError17(
7770
+ throw new InternalServerError20(
6499
7771
  `Error cancelling user invitation: ${error}`
6500
7772
  );
6501
7773
  }
@@ -6515,7 +7787,7 @@ function useVerificationService() {
6515
7787
  try {
6516
7788
  const user = await getUserByEmail(email);
6517
7789
  if (user) {
6518
- throw new BadRequestError33(
7790
+ throw new BadRequestError41(
6519
7791
  `Email ${email} is already registered, please login to continue.`
6520
7792
  );
6521
7793
  }
@@ -6542,7 +7814,7 @@ function useVerificationService() {
6542
7814
  html: emailContent,
6543
7815
  from: "GoWeekdays"
6544
7816
  }).catch((error) => {
6545
- logger17.log({
7817
+ logger20.log({
6546
7818
  level: "error",
6547
7819
  message: `Error sending user invite email: ${error}`
6548
7820
  });
@@ -6555,7 +7827,7 @@ function useVerificationService() {
6555
7827
  async function inviteMember(value) {
6556
7828
  const { error } = schemaInviteMember.validate(value);
6557
7829
  if (error) {
6558
- throw new BadRequestError33(error.message);
7830
+ throw new BadRequestError41(error.message);
6559
7831
  }
6560
7832
  const role = await getRoleById(value.role);
6561
7833
  if (!role) {
@@ -6599,7 +7871,7 @@ function useVerificationService() {
6599
7871
  html: emailContent2,
6600
7872
  from: "GoWeekdays"
6601
7873
  }).catch((error2) => {
6602
- logger17.log({
7874
+ logger20.log({
6603
7875
  level: "error",
6604
7876
  message: `Error sending user invite email: ${error2}`
6605
7877
  });
@@ -6621,24 +7893,24 @@ function useVerificationService() {
6621
7893
  html: emailContent,
6622
7894
  from: "GoWeekdays"
6623
7895
  }).catch((error2) => {
6624
- logger17.log({
7896
+ logger20.log({
6625
7897
  level: "error",
6626
7898
  message: `Error sending user invite email: ${error2}`
6627
7899
  });
6628
7900
  });
6629
7901
  return verificationId;
6630
7902
  } catch (error2) {
6631
- if (error2 instanceof AppError13) {
7903
+ if (error2 instanceof AppError16) {
6632
7904
  throw error2;
6633
7905
  } else {
6634
- throw new InternalServerError17("Failed to invite member.");
7906
+ throw new InternalServerError20("Failed to invite member.");
6635
7907
  }
6636
7908
  }
6637
7909
  }
6638
7910
  async function cancelInviteMember(id) {
6639
- const { error } = Joi23.string().hex().required().validate(id);
7911
+ const { error } = Joi31.string().hex().required().validate(id);
6640
7912
  if (error) {
6641
- throw new BadRequestError33("Invalid verification ID.");
7913
+ throw new BadRequestError41("Invalid verification ID.");
6642
7914
  }
6643
7915
  try {
6644
7916
  const invite = await _getById(id);
@@ -6646,25 +7918,25 @@ function useVerificationService() {
6646
7918
  throw new NotFoundError4("Invitation not found.");
6647
7919
  }
6648
7920
  if (invite.status === "cancelled") {
6649
- throw new BadRequestError33("Invitation already cancelled.");
7921
+ throw new BadRequestError41("Invitation already cancelled.");
6650
7922
  }
6651
7923
  if (invite.status === "complete") {
6652
- throw new BadRequestError33("Cannot cancel a completed invitation.");
7924
+ throw new BadRequestError41("Cannot cancel a completed invitation.");
6653
7925
  }
6654
7926
  await _updateStatusById(id, "cancelled");
6655
7927
  return "Successfully cancelled the invitation.";
6656
7928
  } catch (error2) {
6657
- if (error2 instanceof AppError13) {
7929
+ if (error2 instanceof AppError16) {
6658
7930
  throw error2;
6659
7931
  } else {
6660
- throw new InternalServerError17("Failed to cancel the invitation.");
7932
+ throw new InternalServerError20("Failed to cancel the invitation.");
6661
7933
  }
6662
7934
  }
6663
7935
  }
6664
7936
  async function forgetPassword(email) {
6665
- const { error } = Joi23.string().email().required().validate(email);
7937
+ const { error } = Joi31.string().email().required().validate(email);
6666
7938
  if (error) {
6667
- throw new BadRequestError33("Invalid email address.");
7939
+ throw new BadRequestError41("Invalid email address.");
6668
7940
  }
6669
7941
  try {
6670
7942
  const member = await getUserByEmail(email);
@@ -6693,17 +7965,17 @@ function useVerificationService() {
6693
7965
  from: "GoWeekdays",
6694
7966
  html: emailContent
6695
7967
  }).catch((error2) => {
6696
- logger17.log({
7968
+ logger20.log({
6697
7969
  level: "error",
6698
7970
  message: `Error sending forget password email: ${error2}`
6699
7971
  });
6700
7972
  });
6701
7973
  return "Successfully created a link to reset password. Please check your email.";
6702
7974
  } catch (error2) {
6703
- if (error2 instanceof AppError13) {
7975
+ if (error2 instanceof AppError16) {
6704
7976
  throw error2;
6705
7977
  } else {
6706
- throw new InternalServerError17(
7978
+ throw new InternalServerError20(
6707
7979
  "Failed to process forget password request."
6708
7980
  );
6709
7981
  }
@@ -6730,13 +8002,13 @@ function useAuthController() {
6730
8002
  async function login(req, res, next) {
6731
8003
  const email = req.body.email;
6732
8004
  const password = req.body.password;
6733
- const validation = Joi24.object({
6734
- email: Joi24.string().email().required(),
6735
- password: Joi24.string().required()
8005
+ const validation = Joi32.object({
8006
+ email: Joi32.string().email().required(),
8007
+ password: Joi32.string().required()
6736
8008
  });
6737
8009
  const { error } = validation.validate({ email, password });
6738
8010
  if (error) {
6739
- next(new BadRequestError34(error.message));
8011
+ next(new BadRequestError42(error.message));
6740
8012
  return;
6741
8013
  }
6742
8014
  try {
@@ -6752,14 +8024,14 @@ function useAuthController() {
6752
8024
  res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json({ message: "Login successful" });
6753
8025
  return;
6754
8026
  } catch (error2) {
6755
- logger18.log({
8027
+ logger21.log({
6756
8028
  level: "error",
6757
8029
  message: `Error during login: ${error2.message}`
6758
8030
  });
6759
- if (error2 instanceof AppError14) {
8031
+ if (error2 instanceof AppError17) {
6760
8032
  next(error2);
6761
8033
  } else {
6762
- next(new InternalServerError18("An unexpected error occurred"));
8034
+ next(new InternalServerError21("An unexpected error occurred"));
6763
8035
  }
6764
8036
  return;
6765
8037
  }
@@ -6767,17 +8039,17 @@ function useAuthController() {
6767
8039
  async function logout(req, res, next) {
6768
8040
  const sid = req.headers["authorization"] ?? "";
6769
8041
  if (!sid) {
6770
- next(new BadRequestError34("Session ID is required"));
8042
+ next(new BadRequestError42("Session ID is required"));
6771
8043
  return;
6772
8044
  }
6773
8045
  try {
6774
8046
  await useAuthService().logout(sid);
6775
8047
  res.json({ message: "Logged out successfully" });
6776
8048
  } catch (error) {
6777
- if (error instanceof AppError14) {
8049
+ if (error instanceof AppError17) {
6778
8050
  next(error);
6779
8051
  } else {
6780
- next(new InternalServerError18("An unexpected error occurred"));
8052
+ next(new InternalServerError21("An unexpected error occurred"));
6781
8053
  }
6782
8054
  }
6783
8055
  }
@@ -6788,64 +8060,64 @@ function useAuthController() {
6788
8060
  }
6789
8061
 
6790
8062
  // src/resources/building/building.model.ts
6791
- import { BadRequestError as BadRequestError35, logger as logger19 } from "@goweekdays/utils";
6792
- import Joi25 from "joi";
6793
- import { ObjectId as ObjectId17 } from "mongodb";
6794
- var schemaBuilding = Joi25.object({
6795
- _id: Joi25.string().hex().optional(),
6796
- school: Joi25.string().hex().required(),
6797
- serial: Joi25.string().optional().allow("", null),
6798
- name: Joi25.string().required(),
6799
- levels: Joi25.number().integer().min(1).required(),
6800
- createdAt: Joi25.date().optional().allow("", null),
6801
- updatedAt: Joi25.date().optional().allow("", null),
6802
- deletedAt: Joi25.date().optional().allow("", null),
6803
- status: Joi25.string().optional().allow("", null)
8063
+ import { BadRequestError as BadRequestError43, logger as logger22 } from "@goweekdays/utils";
8064
+ import Joi33 from "joi";
8065
+ import { ObjectId as ObjectId22 } from "mongodb";
8066
+ var schemaBuilding = Joi33.object({
8067
+ _id: Joi33.string().hex().optional(),
8068
+ school: Joi33.string().hex().required(),
8069
+ serial: Joi33.string().optional().allow("", null),
8070
+ name: Joi33.string().required(),
8071
+ levels: Joi33.number().integer().min(1).required(),
8072
+ createdAt: Joi33.date().optional().allow("", null),
8073
+ updatedAt: Joi33.date().optional().allow("", null),
8074
+ deletedAt: Joi33.date().optional().allow("", null),
8075
+ status: Joi33.string().optional().allow("", null)
6804
8076
  });
6805
- var schemaBuildingUnit = Joi25.object({
6806
- _id: Joi25.string().hex().optional(),
6807
- school: Joi25.string().hex().required(),
6808
- name: Joi25.string().optional().allow("", null),
6809
- building: Joi25.string().hex().required(),
6810
- buildingName: Joi25.string().optional().allow("", null),
6811
- level: Joi25.number().integer().min(1).required(),
6812
- category: Joi25.string().required(),
6813
- type: Joi25.string().required(),
6814
- seating_capacity: Joi25.number().integer().min(0).required(),
6815
- standing_capacity: Joi25.number().integer().min(0).required(),
6816
- description: Joi25.string().optional().allow("", null),
6817
- unit_of_measurement: Joi25.string().valid("sqm").required(),
6818
- area: Joi25.number().positive().required(),
6819
- status: Joi25.string().optional().allow("", null)
8077
+ var schemaBuildingUnit = Joi33.object({
8078
+ _id: Joi33.string().hex().optional(),
8079
+ school: Joi33.string().hex().required(),
8080
+ name: Joi33.string().optional().allow("", null),
8081
+ building: Joi33.string().hex().required(),
8082
+ buildingName: Joi33.string().optional().allow("", null),
8083
+ level: Joi33.number().integer().min(1).required(),
8084
+ category: Joi33.string().required(),
8085
+ type: Joi33.string().required(),
8086
+ seating_capacity: Joi33.number().integer().min(0).required(),
8087
+ standing_capacity: Joi33.number().integer().min(0).required(),
8088
+ description: Joi33.string().optional().allow("", null),
8089
+ unit_of_measurement: Joi33.string().valid("sqm").required(),
8090
+ area: Joi33.number().positive().required(),
8091
+ status: Joi33.string().optional().allow("", null)
6820
8092
  });
6821
- var schemaUpdateOptions = Joi25.object({
6822
- name: Joi25.string().optional().allow("", null),
6823
- building: Joi25.string().hex().optional().allow("", null),
6824
- buildingName: Joi25.string().optional().allow("", null),
6825
- level: Joi25.number().integer().min(1).optional().allow("", null),
6826
- category: Joi25.string().optional().allow("", null),
6827
- type: Joi25.string().optional().allow("", null),
6828
- seating_capacity: Joi25.number().integer().min(0).optional().allow("", null),
6829
- standing_capacity: Joi25.number().integer().min(0).optional().allow("", null),
6830
- area: Joi25.number().positive().optional().allow("", null)
8093
+ var schemaUpdateOptions = Joi33.object({
8094
+ name: Joi33.string().optional().allow("", null),
8095
+ building: Joi33.string().hex().optional().allow("", null),
8096
+ buildingName: Joi33.string().optional().allow("", null),
8097
+ level: Joi33.number().integer().min(1).optional().allow("", null),
8098
+ category: Joi33.string().optional().allow("", null),
8099
+ type: Joi33.string().optional().allow("", null),
8100
+ seating_capacity: Joi33.number().integer().min(0).optional().allow("", null),
8101
+ standing_capacity: Joi33.number().integer().min(0).optional().allow("", null),
8102
+ area: Joi33.number().positive().optional().allow("", null)
6831
8103
  });
6832
8104
  function MBuilding(value) {
6833
8105
  const { error } = schemaBuilding.validate(value);
6834
8106
  if (error) {
6835
- logger19.info(`Building Model: ${error.message}`);
6836
- throw new BadRequestError35(error.message);
8107
+ logger22.info(`Building Model: ${error.message}`);
8108
+ throw new BadRequestError43(error.message);
6837
8109
  }
6838
8110
  if (value._id && typeof value._id === "string") {
6839
8111
  try {
6840
- value._id = new ObjectId17(value._id);
8112
+ value._id = new ObjectId22(value._id);
6841
8113
  } catch (error2) {
6842
- throw new BadRequestError35("Invalid _id format");
8114
+ throw new BadRequestError43("Invalid _id format");
6843
8115
  }
6844
8116
  }
6845
8117
  try {
6846
- value.school = new ObjectId17(value.school);
8118
+ value.school = new ObjectId22(value.school);
6847
8119
  } catch (error2) {
6848
- throw new BadRequestError35("Invalid school format");
8120
+ throw new BadRequestError43("Invalid school format");
6849
8121
  }
6850
8122
  return {
6851
8123
  _id: value._id ?? void 0,
@@ -6862,25 +8134,25 @@ function MBuilding(value) {
6862
8134
  function MBuildingUnit(value) {
6863
8135
  const { error } = schemaBuildingUnit.validate(value);
6864
8136
  if (error) {
6865
- logger19.info(`Building Unit Model: ${error.message}`);
6866
- throw new BadRequestError35(error.message);
8137
+ logger22.info(`Building Unit Model: ${error.message}`);
8138
+ throw new BadRequestError43(error.message);
6867
8139
  }
6868
8140
  if (value._id && typeof value._id === "string") {
6869
8141
  try {
6870
- value._id = new ObjectId17(value._id);
8142
+ value._id = new ObjectId22(value._id);
6871
8143
  } catch (error2) {
6872
- throw new BadRequestError35("Invalid ID");
8144
+ throw new BadRequestError43("Invalid ID");
6873
8145
  }
6874
8146
  }
6875
8147
  try {
6876
- value.school = new ObjectId17(value.school);
8148
+ value.school = new ObjectId22(value.school);
6877
8149
  } catch (error2) {
6878
- throw new BadRequestError35("Invalid school ID");
8150
+ throw new BadRequestError43("Invalid school ID");
6879
8151
  }
6880
8152
  try {
6881
- value.building = new ObjectId17(value.building);
8153
+ value.building = new ObjectId22(value.building);
6882
8154
  } catch (error2) {
6883
- throw new BadRequestError35("Invalid building ID");
8155
+ throw new BadRequestError43("Invalid building ID");
6884
8156
  }
6885
8157
  return {
6886
8158
  _id: value._id ?? void 0,
@@ -6905,24 +8177,24 @@ function MBuildingUnit(value) {
6905
8177
 
6906
8178
  // src/resources/building/building.repository.ts
6907
8179
  import {
6908
- AppError as AppError15,
6909
- BadRequestError as BadRequestError36,
6910
- InternalServerError as InternalServerError19,
6911
- logger as logger20,
6912
- makeCacheKey as makeCacheKey12,
6913
- paginate as paginate9,
6914
- useAtlas as useAtlas16,
6915
- useCache as useCache13
8180
+ AppError as AppError18,
8181
+ BadRequestError as BadRequestError44,
8182
+ InternalServerError as InternalServerError22,
8183
+ logger as logger23,
8184
+ makeCacheKey as makeCacheKey15,
8185
+ paginate as paginate12,
8186
+ useAtlas as useAtlas20,
8187
+ useCache as useCache16
6916
8188
  } from "@goweekdays/utils";
6917
- import { ObjectId as ObjectId18 } from "mongodb";
8189
+ import { ObjectId as ObjectId23 } from "mongodb";
6918
8190
  function useBuildingRepo() {
6919
- const db = useAtlas16.getDb();
8191
+ const db = useAtlas20.getDb();
6920
8192
  if (!db) {
6921
8193
  throw new Error("Unable to connect to server.");
6922
8194
  }
6923
8195
  const namespace_collection = "school.buildings";
6924
8196
  const collection = db.collection(namespace_collection);
6925
- const { getCache, setCache, delNamespace } = useCache13(namespace_collection);
8197
+ const { getCache, setCache, delNamespace } = useCache16(namespace_collection);
6926
8198
  async function createIndexes() {
6927
8199
  try {
6928
8200
  await collection.createIndexes([
@@ -6935,7 +8207,7 @@ function useBuildingRepo() {
6935
8207
  }
6936
8208
  }
6937
8209
  createIndexes().catch((error) => {
6938
- logger20.log({ level: "error", message: `Index creation error: ${error}` });
8210
+ logger23.log({ level: "error", message: `Index creation error: ${error}` });
6939
8211
  });
6940
8212
  async function add(value, session) {
6941
8213
  try {
@@ -6944,16 +8216,16 @@ function useBuildingRepo() {
6944
8216
  delCachedData();
6945
8217
  return res.insertedId;
6946
8218
  } catch (error) {
6947
- logger20.log({
8219
+ logger23.log({
6948
8220
  level: "error",
6949
8221
  message: error.message
6950
8222
  });
6951
- if (error instanceof AppError15) {
8223
+ if (error instanceof AppError18) {
6952
8224
  throw error;
6953
8225
  } else {
6954
8226
  const isDuplicated = error.message.includes("duplicate");
6955
8227
  if (isDuplicated) {
6956
- throw new BadRequestError36("Building already exists.");
8228
+ throw new BadRequestError44("Building already exists.");
6957
8229
  }
6958
8230
  throw new Error("Failed to create building.");
6959
8231
  }
@@ -6961,9 +8233,9 @@ function useBuildingRepo() {
6961
8233
  }
6962
8234
  async function updateById(_id, value, session) {
6963
8235
  try {
6964
- _id = new ObjectId18(_id);
8236
+ _id = new ObjectId23(_id);
6965
8237
  } catch (error) {
6966
- throw new BadRequestError36("Invalid ID.");
8238
+ throw new BadRequestError44("Invalid ID.");
6967
8239
  }
6968
8240
  try {
6969
8241
  const res = await collection.updateOne(
@@ -6974,11 +8246,11 @@ function useBuildingRepo() {
6974
8246
  delCachedData();
6975
8247
  return res;
6976
8248
  } catch (error) {
6977
- logger20.log({
8249
+ logger23.log({
6978
8250
  level: "error",
6979
8251
  message: error.message
6980
8252
  });
6981
- if (error instanceof AppError15) {
8253
+ if (error instanceof AppError18) {
6982
8254
  throw error;
6983
8255
  } else {
6984
8256
  throw new Error("Failed to update building.");
@@ -7003,9 +8275,9 @@ function useBuildingRepo() {
7003
8275
  }
7004
8276
  if (school) {
7005
8277
  try {
7006
- query.school = new ObjectId18(school);
8278
+ query.school = new ObjectId23(school);
7007
8279
  } catch (error) {
7008
- throw new BadRequestError36("Invalid school ID.");
8280
+ throw new BadRequestError44("Invalid school ID.");
7009
8281
  }
7010
8282
  }
7011
8283
  const cacheParams = {
@@ -7019,15 +8291,15 @@ function useBuildingRepo() {
7019
8291
  cacheParams.school = school;
7020
8292
  if (status !== "active")
7021
8293
  cacheParams.status = status;
7022
- const cacheKey = makeCacheKey12(namespace_collection, cacheParams);
7023
- logger20.log({
8294
+ const cacheKey = makeCacheKey15(namespace_collection, cacheParams);
8295
+ logger23.log({
7024
8296
  level: "info",
7025
8297
  message: `Cache key for getAll buildings: ${cacheKey}`
7026
8298
  });
7027
8299
  try {
7028
8300
  const cached = await getCache(cacheKey);
7029
8301
  if (cached) {
7030
- logger20.log({
8302
+ logger23.log({
7031
8303
  level: "info",
7032
8304
  message: `Cache hit for getAll buildings: ${cacheKey}`
7033
8305
  });
@@ -7040,35 +8312,35 @@ function useBuildingRepo() {
7040
8312
  { $limit: limit }
7041
8313
  ]).toArray();
7042
8314
  const length = await collection.countDocuments(query);
7043
- const data = paginate9(items, page, limit, length);
8315
+ const data = paginate12(items, page, limit, length);
7044
8316
  setCache(cacheKey, data, 600).then(() => {
7045
- logger20.log({
8317
+ logger23.log({
7046
8318
  level: "info",
7047
8319
  message: `Cache set for getAll buildings: ${cacheKey}`
7048
8320
  });
7049
8321
  }).catch((err) => {
7050
- logger20.log({
8322
+ logger23.log({
7051
8323
  level: "error",
7052
8324
  message: `Failed to set cache for getAll buildings: ${err.message}`
7053
8325
  });
7054
8326
  });
7055
8327
  return data;
7056
8328
  } catch (error) {
7057
- logger20.log({ level: "error", message: `${error}` });
8329
+ logger23.log({ level: "error", message: `${error}` });
7058
8330
  throw error;
7059
8331
  }
7060
8332
  }
7061
8333
  async function getById(_id) {
7062
8334
  try {
7063
- _id = new ObjectId18(_id);
8335
+ _id = new ObjectId23(_id);
7064
8336
  } catch (error) {
7065
- throw new BadRequestError36("Invalid ID.");
8337
+ throw new BadRequestError44("Invalid ID.");
7066
8338
  }
7067
- const cacheKey = makeCacheKey12(namespace_collection, { _id: String(_id) });
8339
+ const cacheKey = makeCacheKey15(namespace_collection, { _id: String(_id) });
7068
8340
  try {
7069
8341
  const cached = await getCache(cacheKey);
7070
8342
  if (cached) {
7071
- logger20.log({
8343
+ logger23.log({
7072
8344
  level: "info",
7073
8345
  message: `Cache hit for getById building: ${cacheKey}`
7074
8346
  });
@@ -7078,30 +8350,30 @@ function useBuildingRepo() {
7078
8350
  _id
7079
8351
  });
7080
8352
  setCache(cacheKey, result, 300).then(() => {
7081
- logger20.log({
8353
+ logger23.log({
7082
8354
  level: "info",
7083
8355
  message: `Cache set for building by id: ${cacheKey}`
7084
8356
  });
7085
8357
  }).catch((err) => {
7086
- logger20.log({
8358
+ logger23.log({
7087
8359
  level: "error",
7088
8360
  message: `Failed to set cache for building by id: ${err.message}`
7089
8361
  });
7090
8362
  });
7091
8363
  return result;
7092
8364
  } catch (error) {
7093
- if (error instanceof AppError15) {
8365
+ if (error instanceof AppError18) {
7094
8366
  throw error;
7095
8367
  } else {
7096
- throw new InternalServerError19("Failed to get building.");
8368
+ throw new InternalServerError22("Failed to get building.");
7097
8369
  }
7098
8370
  }
7099
8371
  }
7100
8372
  async function deleteById(_id, session) {
7101
8373
  try {
7102
- _id = new ObjectId18(_id);
8374
+ _id = new ObjectId23(_id);
7103
8375
  } catch (error) {
7104
- throw new BadRequestError36("Invalid ID.");
8376
+ throw new BadRequestError44("Invalid ID.");
7105
8377
  }
7106
8378
  try {
7107
8379
  const res = await collection.updateOne(
@@ -7111,25 +8383,25 @@ function useBuildingRepo() {
7111
8383
  delCachedData();
7112
8384
  return res;
7113
8385
  } catch (error) {
7114
- logger20.log({
8386
+ logger23.log({
7115
8387
  level: "error",
7116
8388
  message: error.message
7117
8389
  });
7118
- if (error instanceof AppError15) {
8390
+ if (error instanceof AppError18) {
7119
8391
  throw error;
7120
8392
  } else {
7121
- throw new InternalServerError19("Failed to delete building.");
8393
+ throw new InternalServerError22("Failed to delete building.");
7122
8394
  }
7123
8395
  }
7124
8396
  }
7125
8397
  function delCachedData() {
7126
8398
  delNamespace().then(() => {
7127
- logger20.log({
8399
+ logger23.log({
7128
8400
  level: "info",
7129
8401
  message: `Cache namespace cleared for ${namespace_collection}`
7130
8402
  });
7131
8403
  }).catch((err) => {
7132
- logger20.log({
8404
+ logger23.log({
7133
8405
  level: "error",
7134
8406
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
7135
8407
  });
@@ -7146,28 +8418,28 @@ function useBuildingRepo() {
7146
8418
  }
7147
8419
 
7148
8420
  // src/resources/building/building.service.ts
7149
- import { BadRequestError as BadRequestError38, NotFoundError as NotFoundError5, useAtlas as useAtlas18 } from "@goweekdays/utils";
8421
+ import { BadRequestError as BadRequestError46, NotFoundError as NotFoundError5, useAtlas as useAtlas22 } from "@goweekdays/utils";
7150
8422
 
7151
8423
  // src/resources/building/building-unit.repository.ts
7152
8424
  import {
7153
- AppError as AppError16,
7154
- BadRequestError as BadRequestError37,
7155
- InternalServerError as InternalServerError20,
7156
- logger as logger21,
7157
- makeCacheKey as makeCacheKey13,
7158
- paginate as paginate10,
7159
- useAtlas as useAtlas17,
7160
- useCache as useCache14
8425
+ AppError as AppError19,
8426
+ BadRequestError as BadRequestError45,
8427
+ InternalServerError as InternalServerError23,
8428
+ logger as logger24,
8429
+ makeCacheKey as makeCacheKey16,
8430
+ paginate as paginate13,
8431
+ useAtlas as useAtlas21,
8432
+ useCache as useCache17
7161
8433
  } from "@goweekdays/utils";
7162
- import { ObjectId as ObjectId19 } from "mongodb";
8434
+ import { ObjectId as ObjectId24 } from "mongodb";
7163
8435
  function useBuildingUnitRepo() {
7164
- const db = useAtlas17.getDb();
8436
+ const db = useAtlas21.getDb();
7165
8437
  if (!db) {
7166
8438
  throw new Error("Unable to connect to server.");
7167
8439
  }
7168
8440
  const namespace_collection = "school.building-units";
7169
8441
  const collection = db.collection(namespace_collection);
7170
- const { getCache, setCache, delNamespace } = useCache14(namespace_collection);
8442
+ const { getCache, setCache, delNamespace } = useCache17(namespace_collection);
7171
8443
  async function createIndexes() {
7172
8444
  try {
7173
8445
  await collection.createIndexes([
@@ -7195,12 +8467,12 @@ function useBuildingUnitRepo() {
7195
8467
  }
7196
8468
  function delCachedData() {
7197
8469
  delNamespace().then(() => {
7198
- logger21.log({
8470
+ logger24.log({
7199
8471
  level: "info",
7200
8472
  message: `Cache namespace cleared for ${namespace_collection}`
7201
8473
  });
7202
8474
  }).catch((err) => {
7203
- logger21.log({
8475
+ logger24.log({
7204
8476
  level: "error",
7205
8477
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
7206
8478
  });
@@ -7213,11 +8485,11 @@ function useBuildingUnitRepo() {
7213
8485
  delCachedData();
7214
8486
  return res.insertedId;
7215
8487
  } catch (error) {
7216
- logger21.log({
8488
+ logger24.log({
7217
8489
  level: "error",
7218
8490
  message: error.message
7219
8491
  });
7220
- if (error instanceof AppError16) {
8492
+ if (error instanceof AppError19) {
7221
8493
  throw error;
7222
8494
  } else {
7223
8495
  throw new Error("Failed to create building unit.");
@@ -7227,12 +8499,12 @@ function useBuildingUnitRepo() {
7227
8499
  async function updateById(_id, value, session) {
7228
8500
  const { error } = schemaUpdateOptions.validate(value);
7229
8501
  if (error) {
7230
- throw new BadRequestError37(error.message);
8502
+ throw new BadRequestError45(error.message);
7231
8503
  }
7232
8504
  try {
7233
- _id = new ObjectId19(_id);
8505
+ _id = new ObjectId24(_id);
7234
8506
  } catch (error2) {
7235
- throw new BadRequestError37("Invalid ID.");
8507
+ throw new BadRequestError45("Invalid ID.");
7236
8508
  }
7237
8509
  try {
7238
8510
  const res = await collection.updateOne(
@@ -7243,11 +8515,11 @@ function useBuildingUnitRepo() {
7243
8515
  delCachedData();
7244
8516
  return res;
7245
8517
  } catch (error2) {
7246
- logger21.log({
8518
+ logger24.log({
7247
8519
  level: "error",
7248
8520
  message: error2.message
7249
8521
  });
7250
- if (error2 instanceof AppError16) {
8522
+ if (error2 instanceof AppError19) {
7251
8523
  throw error2;
7252
8524
  } else {
7253
8525
  throw new Error("Failed to create building unit.");
@@ -7257,12 +8529,12 @@ function useBuildingUnitRepo() {
7257
8529
  async function updateByBuildingId(building, value, session) {
7258
8530
  const { error } = schemaUpdateOptions.validate(value);
7259
8531
  if (error) {
7260
- throw new BadRequestError37(error.message);
8532
+ throw new BadRequestError45(error.message);
7261
8533
  }
7262
8534
  try {
7263
- building = new ObjectId19(building);
8535
+ building = new ObjectId24(building);
7264
8536
  } catch (error2) {
7265
- throw new BadRequestError37("Invalid building ID.");
8537
+ throw new BadRequestError45("Invalid building ID.");
7266
8538
  }
7267
8539
  try {
7268
8540
  const res = await collection.updateMany(
@@ -7273,11 +8545,11 @@ function useBuildingUnitRepo() {
7273
8545
  delCachedData();
7274
8546
  return res;
7275
8547
  } catch (error2) {
7276
- logger21.log({
8548
+ logger24.log({
7277
8549
  level: "error",
7278
8550
  message: error2.message
7279
8551
  });
7280
- if (error2 instanceof AppError16) {
8552
+ if (error2 instanceof AppError19) {
7281
8553
  throw error2;
7282
8554
  } else {
7283
8555
  throw new Error("Failed to update building unit.");
@@ -7304,16 +8576,16 @@ function useBuildingUnitRepo() {
7304
8576
  }
7305
8577
  if (school) {
7306
8578
  try {
7307
- query.school = new ObjectId19(school);
8579
+ query.school = new ObjectId24(school);
7308
8580
  } catch (error) {
7309
- throw new BadRequestError37("Invalid school ID.");
8581
+ throw new BadRequestError45("Invalid school ID.");
7310
8582
  }
7311
8583
  }
7312
8584
  if (building) {
7313
8585
  try {
7314
- query.building = new ObjectId19(building);
8586
+ query.building = new ObjectId24(building);
7315
8587
  } catch (error) {
7316
- throw new BadRequestError37("Invalid building ID.");
8588
+ throw new BadRequestError45("Invalid building ID.");
7317
8589
  }
7318
8590
  }
7319
8591
  const cacheParams = {
@@ -7329,15 +8601,15 @@ function useBuildingUnitRepo() {
7329
8601
  cacheParams.building = building;
7330
8602
  if (status !== "active")
7331
8603
  cacheParams.status = status;
7332
- const cacheKey = makeCacheKey13(namespace_collection, cacheParams);
7333
- logger21.log({
8604
+ const cacheKey = makeCacheKey16(namespace_collection, cacheParams);
8605
+ logger24.log({
7334
8606
  level: "info",
7335
8607
  message: `Cache key for getAll building units: ${cacheKey}`
7336
8608
  });
7337
8609
  try {
7338
8610
  const cached = await getCache(cacheKey);
7339
8611
  if (cached) {
7340
- logger21.log({
8612
+ logger24.log({
7341
8613
  level: "info",
7342
8614
  message: `Cache hit for getAll building units: ${cacheKey}`
7343
8615
  });
@@ -7350,35 +8622,35 @@ function useBuildingUnitRepo() {
7350
8622
  { $limit: limit }
7351
8623
  ]).toArray();
7352
8624
  const length = await collection.countDocuments(query);
7353
- const data = paginate10(items, page, limit, length);
8625
+ const data = paginate13(items, page, limit, length);
7354
8626
  setCache(cacheKey, data, 600).then(() => {
7355
- logger21.log({
8627
+ logger24.log({
7356
8628
  level: "info",
7357
8629
  message: `Cache set for getAll building units: ${cacheKey}`
7358
8630
  });
7359
8631
  }).catch((err) => {
7360
- logger21.log({
8632
+ logger24.log({
7361
8633
  level: "error",
7362
8634
  message: `Failed to set cache for getAll building units: ${err.message}`
7363
8635
  });
7364
8636
  });
7365
8637
  return data;
7366
8638
  } catch (error) {
7367
- logger21.log({ level: "error", message: `${error}` });
8639
+ logger24.log({ level: "error", message: `${error}` });
7368
8640
  throw error;
7369
8641
  }
7370
8642
  }
7371
8643
  async function getById(_id) {
7372
8644
  try {
7373
- _id = new ObjectId19(_id);
8645
+ _id = new ObjectId24(_id);
7374
8646
  } catch (error) {
7375
- throw new BadRequestError37("Invalid ID.");
8647
+ throw new BadRequestError45("Invalid ID.");
7376
8648
  }
7377
- const cacheKey = makeCacheKey13(namespace_collection, { _id: String(_id) });
8649
+ const cacheKey = makeCacheKey16(namespace_collection, { _id: String(_id) });
7378
8650
  try {
7379
8651
  const cached = await getCache(cacheKey);
7380
8652
  if (cached) {
7381
- logger21.log({
8653
+ logger24.log({
7382
8654
  level: "info",
7383
8655
  message: `Cache hit for getById building unit: ${cacheKey}`
7384
8656
  });
@@ -7389,42 +8661,42 @@ function useBuildingUnitRepo() {
7389
8661
  deletedAt: { $in: ["", null] }
7390
8662
  });
7391
8663
  if (!result) {
7392
- throw new BadRequestError37("Building unit not found.");
8664
+ throw new BadRequestError45("Building unit not found.");
7393
8665
  }
7394
8666
  setCache(cacheKey, result, 300).then(() => {
7395
- logger21.log({
8667
+ logger24.log({
7396
8668
  level: "info",
7397
8669
  message: `Cache set for building unit by id: ${cacheKey}`
7398
8670
  });
7399
8671
  }).catch((err) => {
7400
- logger21.log({
8672
+ logger24.log({
7401
8673
  level: "error",
7402
8674
  message: `Failed to set cache for building unit by id: ${err.message}`
7403
8675
  });
7404
8676
  });
7405
8677
  return result;
7406
8678
  } catch (error) {
7407
- if (error instanceof AppError16) {
8679
+ if (error instanceof AppError19) {
7408
8680
  throw error;
7409
8681
  } else {
7410
- throw new InternalServerError20("Failed to get building unit.");
8682
+ throw new InternalServerError23("Failed to get building unit.");
7411
8683
  }
7412
8684
  }
7413
8685
  }
7414
8686
  async function getByBuildingLevel(building, level) {
7415
8687
  try {
7416
- building = new ObjectId19(building);
8688
+ building = new ObjectId24(building);
7417
8689
  } catch (error) {
7418
- throw new BadRequestError37("Invalid building ID.");
8690
+ throw new BadRequestError45("Invalid building ID.");
7419
8691
  }
7420
- const cacheKey = makeCacheKey13(namespace_collection, {
8692
+ const cacheKey = makeCacheKey16(namespace_collection, {
7421
8693
  building: String(building),
7422
8694
  level
7423
8695
  });
7424
8696
  try {
7425
8697
  const cached = await getCache(cacheKey);
7426
8698
  if (cached) {
7427
- logger21.log({
8699
+ logger24.log({
7428
8700
  level: "info",
7429
8701
  message: `Cache hit for getById building unit: ${cacheKey}`
7430
8702
  });
@@ -7436,38 +8708,38 @@ function useBuildingUnitRepo() {
7436
8708
  status: "active"
7437
8709
  });
7438
8710
  setCache(cacheKey, result, 300).then(() => {
7439
- logger21.log({
8711
+ logger24.log({
7440
8712
  level: "info",
7441
8713
  message: `Cache set for building unit by id: ${cacheKey}`
7442
8714
  });
7443
8715
  }).catch((err) => {
7444
- logger21.log({
8716
+ logger24.log({
7445
8717
  level: "error",
7446
8718
  message: `Failed to set cache for building unit by id: ${err.message}`
7447
8719
  });
7448
8720
  });
7449
8721
  return result;
7450
8722
  } catch (error) {
7451
- if (error instanceof AppError16) {
8723
+ if (error instanceof AppError19) {
7452
8724
  throw error;
7453
8725
  } else {
7454
- throw new InternalServerError20("Failed to get building unit.");
8726
+ throw new InternalServerError23("Failed to get building unit.");
7455
8727
  }
7456
8728
  }
7457
8729
  }
7458
8730
  async function getByBuilding(building) {
7459
8731
  try {
7460
- building = new ObjectId19(building);
8732
+ building = new ObjectId24(building);
7461
8733
  } catch (error) {
7462
- throw new BadRequestError37("Invalid building ID.");
8734
+ throw new BadRequestError45("Invalid building ID.");
7463
8735
  }
7464
- const cacheKey = makeCacheKey13(namespace_collection, {
8736
+ const cacheKey = makeCacheKey16(namespace_collection, {
7465
8737
  building: String(building)
7466
8738
  });
7467
8739
  try {
7468
8740
  const cached = await getCache(cacheKey);
7469
8741
  if (cached) {
7470
- logger21.log({
8742
+ logger24.log({
7471
8743
  level: "info",
7472
8744
  message: `Cache hit for getById building unit: ${cacheKey}`
7473
8745
  });
@@ -7478,30 +8750,30 @@ function useBuildingUnitRepo() {
7478
8750
  status: "active"
7479
8751
  });
7480
8752
  setCache(cacheKey, result, 300).then(() => {
7481
- logger21.log({
8753
+ logger24.log({
7482
8754
  level: "info",
7483
8755
  message: `Cache set for building unit by id: ${cacheKey}`
7484
8756
  });
7485
8757
  }).catch((err) => {
7486
- logger21.log({
8758
+ logger24.log({
7487
8759
  level: "error",
7488
8760
  message: `Failed to set cache for building unit by id: ${err.message}`
7489
8761
  });
7490
8762
  });
7491
8763
  return result;
7492
8764
  } catch (error) {
7493
- if (error instanceof AppError16) {
8765
+ if (error instanceof AppError19) {
7494
8766
  throw error;
7495
8767
  } else {
7496
- throw new InternalServerError20("Failed to get building unit.");
8768
+ throw new InternalServerError23("Failed to get building unit.");
7497
8769
  }
7498
8770
  }
7499
8771
  }
7500
8772
  async function deleteById(_id, session) {
7501
8773
  try {
7502
- _id = new ObjectId19(_id);
8774
+ _id = new ObjectId24(_id);
7503
8775
  } catch (error) {
7504
- throw new BadRequestError37("Invalid ID.");
8776
+ throw new BadRequestError45("Invalid ID.");
7505
8777
  }
7506
8778
  try {
7507
8779
  const res = await collection.updateOne(
@@ -7512,11 +8784,11 @@ function useBuildingUnitRepo() {
7512
8784
  delCachedData();
7513
8785
  return "Room/Facility deleted successfully.";
7514
8786
  } catch (error) {
7515
- logger21.log({
8787
+ logger24.log({
7516
8788
  level: "error",
7517
8789
  message: error.message
7518
8790
  });
7519
- if (error instanceof AppError16) {
8791
+ if (error instanceof AppError19) {
7520
8792
  throw error;
7521
8793
  } else {
7522
8794
  throw new Error("Failed to deleted room/facility.");
@@ -7546,7 +8818,7 @@ function useBuildingService() {
7546
8818
  const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
7547
8819
  async function updateById(id, data) {
7548
8820
  data.levels = Number(data.levels);
7549
- const session = useAtlas18.getClient()?.startSession();
8821
+ const session = useAtlas22.getClient()?.startSession();
7550
8822
  try {
7551
8823
  const building = await _getById(id);
7552
8824
  if (!building) {
@@ -7555,7 +8827,7 @@ function useBuildingService() {
7555
8827
  if (data.levels < building.levels) {
7556
8828
  const unit = await getByBuildingLevel(id, building.levels);
7557
8829
  if (unit) {
7558
- throw new BadRequestError38(
8830
+ throw new BadRequestError46(
7559
8831
  "Cannot reduce floors, there are existing building units at higher floors."
7560
8832
  );
7561
8833
  }
@@ -7577,7 +8849,7 @@ function useBuildingService() {
7577
8849
  async function deleteById(id) {
7578
8850
  const building = await getByBuilding(id);
7579
8851
  if (building) {
7580
- throw new BadRequestError38(
8852
+ throw new BadRequestError46(
7581
8853
  "Cannot delete building with existing room/facility. Please delete room/facility first."
7582
8854
  );
7583
8855
  }
@@ -7595,24 +8867,24 @@ function useBuildingService() {
7595
8867
  }
7596
8868
 
7597
8869
  // src/resources/building/building.controller.ts
7598
- import { BadRequestError as BadRequestError39, logger as logger22 } from "@goweekdays/utils";
7599
- import Joi26 from "joi";
8870
+ import { BadRequestError as BadRequestError47, logger as logger25 } from "@goweekdays/utils";
8871
+ import Joi34 from "joi";
7600
8872
  function useBuildingController() {
7601
8873
  const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
7602
8874
  const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
7603
8875
  async function createBuilding(req, res, next) {
7604
8876
  const value = req.body;
7605
- const validation = Joi26.object({
7606
- name: Joi26.string().required(),
7607
- school: Joi26.string().hex().required(),
7608
- levels: Joi26.number().integer().min(1).required(),
7609
- serial: Joi26.string().optional().allow("", null),
7610
- status: Joi26.string().optional().allow("", null)
8877
+ const validation = Joi34.object({
8878
+ name: Joi34.string().required(),
8879
+ school: Joi34.string().hex().required(),
8880
+ levels: Joi34.number().integer().min(1).required(),
8881
+ serial: Joi34.string().optional().allow("", null),
8882
+ status: Joi34.string().optional().allow("", null)
7611
8883
  });
7612
8884
  const { error } = validation.validate(value);
7613
8885
  if (error) {
7614
- next(new BadRequestError39(error.message));
7615
- logger22.info(`Controller: ${error.message}`);
8886
+ next(new BadRequestError47(error.message));
8887
+ logger25.info(`Controller: ${error.message}`);
7616
8888
  return;
7617
8889
  }
7618
8890
  try {
@@ -7626,18 +8898,18 @@ function useBuildingController() {
7626
8898
  async function updateById(req, res, next) {
7627
8899
  const value = req.body;
7628
8900
  const id = req.params.id ?? "";
7629
- const validation = Joi26.object({
7630
- id: Joi26.string().hex().required(),
7631
- value: Joi26.object({
7632
- name: Joi26.string().required(),
7633
- serial: Joi26.string().optional().allow("", null),
7634
- levels: Joi26.number().integer().min(1).required()
8901
+ const validation = Joi34.object({
8902
+ id: Joi34.string().hex().required(),
8903
+ value: Joi34.object({
8904
+ name: Joi34.string().required(),
8905
+ serial: Joi34.string().optional().allow("", null),
8906
+ levels: Joi34.number().integer().min(1).required()
7635
8907
  })
7636
8908
  });
7637
8909
  const { error } = validation.validate({ id, value });
7638
8910
  if (error) {
7639
- next(new BadRequestError39(error.message));
7640
- logger22.info(`Controller: ${error.message}`);
8911
+ next(new BadRequestError47(error.message));
8912
+ logger25.info(`Controller: ${error.message}`);
7641
8913
  return;
7642
8914
  }
7643
8915
  try {
@@ -7650,16 +8922,16 @@ function useBuildingController() {
7650
8922
  }
7651
8923
  async function getAll(req, res, next) {
7652
8924
  const query = req.query;
7653
- const validation = Joi26.object({
7654
- page: Joi26.number().min(1).optional().allow("", null),
7655
- limit: Joi26.number().min(1).optional().allow("", null),
7656
- search: Joi26.string().optional().allow("", null),
7657
- school: Joi26.string().hex().optional().allow("", null),
7658
- status: Joi26.string().optional().allow("", null)
8925
+ const validation = Joi34.object({
8926
+ page: Joi34.number().min(1).optional().allow("", null),
8927
+ limit: Joi34.number().min(1).optional().allow("", null),
8928
+ search: Joi34.string().optional().allow("", null),
8929
+ school: Joi34.string().hex().optional().allow("", null),
8930
+ status: Joi34.string().optional().allow("", null)
7659
8931
  });
7660
8932
  const { error } = validation.validate(query);
7661
8933
  if (error) {
7662
- next(new BadRequestError39(error.message));
8934
+ next(new BadRequestError47(error.message));
7663
8935
  return;
7664
8936
  }
7665
8937
  const page = parseInt(req.query.page) ?? 1;
@@ -7693,12 +8965,12 @@ function useBuildingController() {
7693
8965
  }
7694
8966
  async function getById(req, res, next) {
7695
8967
  const id = req.params.id;
7696
- const validation = Joi26.object({
7697
- id: Joi26.string().hex().required()
8968
+ const validation = Joi34.object({
8969
+ id: Joi34.string().hex().required()
7698
8970
  });
7699
8971
  const { error } = validation.validate({ id });
7700
8972
  if (error) {
7701
- next(new BadRequestError39(error.message));
8973
+ next(new BadRequestError47(error.message));
7702
8974
  return;
7703
8975
  }
7704
8976
  try {
@@ -7714,12 +8986,12 @@ function useBuildingController() {
7714
8986
  }
7715
8987
  async function deleteById(req, res, next) {
7716
8988
  const id = req.params.id;
7717
- const validation = Joi26.object({
7718
- id: Joi26.string().hex().required()
8989
+ const validation = Joi34.object({
8990
+ id: Joi34.string().hex().required()
7719
8991
  });
7720
8992
  const { error } = validation.validate({ id });
7721
8993
  if (error) {
7722
- next(new BadRequestError39(error.message));
8994
+ next(new BadRequestError47(error.message));
7723
8995
  return;
7724
8996
  }
7725
8997
  try {
@@ -7740,11 +9012,11 @@ function useBuildingController() {
7740
9012
  }
7741
9013
 
7742
9014
  // src/resources/building/building-unit.service.ts
7743
- import { useAtlas as useAtlas19 } from "@goweekdays/utils";
9015
+ import { useAtlas as useAtlas23 } from "@goweekdays/utils";
7744
9016
  function useBuildingUnitService() {
7745
9017
  const { add: _add } = useBuildingUnitRepo();
7746
9018
  async function add(value) {
7747
- const session = useAtlas19.getClient()?.startSession();
9019
+ const session = useAtlas23.getClient()?.startSession();
7748
9020
  if (!session) {
7749
9021
  throw new Error("Unable to start session for building unit service.");
7750
9022
  }
@@ -7771,8 +9043,8 @@ function useBuildingUnitService() {
7771
9043
  }
7772
9044
 
7773
9045
  // src/resources/building/building-unit.controller.ts
7774
- import { BadRequestError as BadRequestError40 } from "@goweekdays/utils";
7775
- import Joi27 from "joi";
9046
+ import { BadRequestError as BadRequestError48 } from "@goweekdays/utils";
9047
+ import Joi35 from "joi";
7776
9048
  function useBuildingUnitController() {
7777
9049
  const {
7778
9050
  getAll: _getAll,
@@ -7783,27 +9055,27 @@ function useBuildingUnitController() {
7783
9055
  const { add: _add } = useBuildingUnitService();
7784
9056
  async function add(req, res, next) {
7785
9057
  const data = req.body;
7786
- const validation = Joi27.object({
7787
- building: Joi27.object({
7788
- school: Joi27.string().hex().required(),
7789
- name: Joi27.string().optional().allow("", null),
7790
- building: Joi27.string().hex().required(),
7791
- buildingName: Joi27.string().optional().allow("", null),
7792
- level: Joi27.number().integer().min(1).required(),
7793
- category: Joi27.string().required(),
7794
- type: Joi27.string().required(),
7795
- seating_capacity: Joi27.number().integer().min(0).required(),
7796
- standing_capacity: Joi27.number().integer().min(0).required(),
7797
- description: Joi27.string().optional().allow("", null),
7798
- unit_of_measurement: Joi27.string().valid("sqm").required(),
7799
- area: Joi27.number().positive().required(),
7800
- status: Joi27.string().optional().allow("", null)
9058
+ const validation = Joi35.object({
9059
+ building: Joi35.object({
9060
+ school: Joi35.string().hex().required(),
9061
+ name: Joi35.string().optional().allow("", null),
9062
+ building: Joi35.string().hex().required(),
9063
+ buildingName: Joi35.string().optional().allow("", null),
9064
+ level: Joi35.number().integer().min(1).required(),
9065
+ category: Joi35.string().required(),
9066
+ type: Joi35.string().required(),
9067
+ seating_capacity: Joi35.number().integer().min(0).required(),
9068
+ standing_capacity: Joi35.number().integer().min(0).required(),
9069
+ description: Joi35.string().optional().allow("", null),
9070
+ unit_of_measurement: Joi35.string().valid("sqm").required(),
9071
+ area: Joi35.number().positive().required(),
9072
+ status: Joi35.string().optional().allow("", null)
7801
9073
  }),
7802
- qty: Joi27.number().integer().min(1).max(20).optional().default(1)
9074
+ qty: Joi35.number().integer().min(1).max(20).optional().default(1)
7803
9075
  });
7804
9076
  const { error } = validation.validate(data);
7805
9077
  if (error) {
7806
- next(new BadRequestError40(error.message));
9078
+ next(new BadRequestError48(error.message));
7807
9079
  return;
7808
9080
  }
7809
9081
  try {
@@ -7819,13 +9091,13 @@ function useBuildingUnitController() {
7819
9091
  async function updateById(req, res, next) {
7820
9092
  const data = req.body;
7821
9093
  const id = req.params.id ?? "";
7822
- const validation = Joi27.object({
7823
- id: Joi27.string().hex().required(),
9094
+ const validation = Joi35.object({
9095
+ id: Joi35.string().hex().required(),
7824
9096
  value: schemaUpdateOptions
7825
9097
  });
7826
9098
  const { error } = validation.validate({ id, value: data });
7827
9099
  if (error) {
7828
- next(new BadRequestError40(error.message));
9100
+ next(new BadRequestError48(error.message));
7829
9101
  return;
7830
9102
  }
7831
9103
  try {
@@ -7840,17 +9112,17 @@ function useBuildingUnitController() {
7840
9112
  }
7841
9113
  async function getAll(req, res, next) {
7842
9114
  const query = req.query;
7843
- const validation = Joi27.object({
7844
- page: Joi27.number().min(1).optional().allow("", null),
7845
- limit: Joi27.number().min(1).optional().allow("", null),
7846
- search: Joi27.string().optional().allow("", null),
7847
- school: Joi27.string().hex().optional().allow("", null),
7848
- building: Joi27.string().hex().optional().allow("", null),
7849
- status: Joi27.string().optional().allow("", null)
9115
+ const validation = Joi35.object({
9116
+ page: Joi35.number().min(1).optional().allow("", null),
9117
+ limit: Joi35.number().min(1).optional().allow("", null),
9118
+ search: Joi35.string().optional().allow("", null),
9119
+ school: Joi35.string().hex().optional().allow("", null),
9120
+ building: Joi35.string().hex().optional().allow("", null),
9121
+ status: Joi35.string().optional().allow("", null)
7850
9122
  });
7851
9123
  const { error } = validation.validate(query);
7852
9124
  if (error) {
7853
- next(new BadRequestError40(error.message));
9125
+ next(new BadRequestError48(error.message));
7854
9126
  return;
7855
9127
  }
7856
9128
  const page = parseInt(req.query.page) ?? 1;
@@ -7886,12 +9158,12 @@ function useBuildingUnitController() {
7886
9158
  }
7887
9159
  async function getById(req, res, next) {
7888
9160
  const id = req.params.id;
7889
- const validation = Joi27.object({
7890
- id: Joi27.string().hex().required()
9161
+ const validation = Joi35.object({
9162
+ id: Joi35.string().hex().required()
7891
9163
  });
7892
9164
  const { error } = validation.validate({ id });
7893
9165
  if (error) {
7894
- next(new BadRequestError40(error.message));
9166
+ next(new BadRequestError48(error.message));
7895
9167
  return;
7896
9168
  }
7897
9169
  try {
@@ -7907,12 +9179,12 @@ function useBuildingUnitController() {
7907
9179
  }
7908
9180
  async function deleteById(req, res, next) {
7909
9181
  const id = req.params.id;
7910
- const validation = Joi27.object({
7911
- id: Joi27.string().hex().required()
9182
+ const validation = Joi35.object({
9183
+ id: Joi35.string().hex().required()
7912
9184
  });
7913
9185
  const { error } = validation.validate({ id });
7914
9186
  if (error) {
7915
- next(new BadRequestError40(error.message));
9187
+ next(new BadRequestError48(error.message));
7916
9188
  return;
7917
9189
  }
7918
9190
  try {
@@ -7933,14 +9205,14 @@ function useBuildingUnitController() {
7933
9205
  }
7934
9206
 
7935
9207
  // src/resources/counter/counter.model.ts
7936
- import { BadRequestError as BadRequestError41 } from "@goweekdays/utils";
7937
- import { ObjectId as ObjectId20 } from "mongodb";
9208
+ import { BadRequestError as BadRequestError49 } from "@goweekdays/utils";
9209
+ import { ObjectId as ObjectId25 } from "mongodb";
7938
9210
  import { z } from "zod";
7939
9211
  var TCounter = z.object({
7940
9212
  _id: z.union([
7941
9213
  z.string().length(24, "Invalid ObjectId hex string"),
7942
- z.instanceof(ObjectId20)
7943
- ]).transform((val) => typeof val === "string" ? new ObjectId20(val) : val).optional(),
9214
+ z.instanceof(ObjectId25)
9215
+ ]).transform((val) => typeof val === "string" ? new ObjectId25(val) : val).optional(),
7944
9216
  count: z.number().int().min(0).default(0),
7945
9217
  type: z.string(),
7946
9218
  createdAt: z.date().optional().default(() => /* @__PURE__ */ new Date()),
@@ -7953,7 +9225,7 @@ function useCounterModel(db) {
7953
9225
  try {
7954
9226
  return TCounter.parse(value);
7955
9227
  } catch (error) {
7956
- throw new BadRequestError41(error.issues[0].message);
9228
+ throw new BadRequestError49(error.issues[0].message);
7957
9229
  }
7958
9230
  }
7959
9231
  function validateCounter(data) {
@@ -7967,23 +9239,23 @@ function useCounterModel(db) {
7967
9239
  }
7968
9240
 
7969
9241
  // src/resources/counter/counter.repository.ts
7970
- import { useAtlas as useAtlas20, useCache as useCache15, makeCacheKey as makeCacheKey14, logger as logger23 } from "@goweekdays/utils";
9242
+ import { useAtlas as useAtlas24, useCache as useCache18, makeCacheKey as makeCacheKey17, logger as logger26 } from "@goweekdays/utils";
7971
9243
  function useCounterRepo() {
7972
- const db = useAtlas20.getDb();
9244
+ const db = useAtlas24.getDb();
7973
9245
  if (!db) {
7974
9246
  throw new Error("Unable to connect to server.");
7975
9247
  }
7976
9248
  const namespace_collection = "counters";
7977
9249
  const { collection, createCounter } = useCounterModel(db);
7978
- const { getCache, setCache, delNamespace } = useCache15(namespace_collection);
9250
+ const { getCache, setCache, delNamespace } = useCache18(namespace_collection);
7979
9251
  function delCachedData() {
7980
9252
  delNamespace().then(() => {
7981
- logger23.log({
9253
+ logger26.log({
7982
9254
  level: "info",
7983
9255
  message: `Cache namespace cleared for ${namespace_collection}`
7984
9256
  });
7985
9257
  }).catch((err) => {
7986
- logger23.log({
9258
+ logger26.log({
7987
9259
  level: "error",
7988
9260
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
7989
9261
  });
@@ -8035,11 +9307,11 @@ function useCounterRepo() {
8035
9307
  }
8036
9308
  }
8037
9309
  async function getByType(type) {
8038
- const cacheKey = makeCacheKey14(namespace_collection, { type });
9310
+ const cacheKey = makeCacheKey17(namespace_collection, { type });
8039
9311
  try {
8040
9312
  const cached = await getCache(cacheKey);
8041
9313
  if (cached) {
8042
- logger23.log({
9314
+ logger26.log({
8043
9315
  level: "info",
8044
9316
  message: `Cache hit for getByType counter: ${cacheKey}`
8045
9317
  });
@@ -8048,12 +9320,12 @@ function useCounterRepo() {
8048
9320
  const data = await collection.findOne({ type });
8049
9321
  if (data) {
8050
9322
  setCache(cacheKey, data, 300).then(() => {
8051
- logger23.log({
9323
+ logger26.log({
8052
9324
  level: "info",
8053
9325
  message: `Cache set for counter by type: ${cacheKey}`
8054
9326
  });
8055
9327
  }).catch((err) => {
8056
- logger23.log({
9328
+ logger26.log({
8057
9329
  level: "error",
8058
9330
  message: `Failed to set cache for counter by type: ${err.message}`
8059
9331
  });
@@ -8074,7 +9346,7 @@ function useCounterRepo() {
8074
9346
  }
8075
9347
 
8076
9348
  // src/resources/file/file.service.ts
8077
- import { logger as logger24, useS3 as useS32, useAtlas as useAtlas21 } from "@goweekdays/utils";
9349
+ import { logger as logger27, useS3 as useS32, useAtlas as useAtlas25 } from "@goweekdays/utils";
8078
9350
  import cron from "node-cron";
8079
9351
  import * as fs from "fs";
8080
9352
  function useFileService() {
@@ -8092,7 +9364,7 @@ function useFileService() {
8092
9364
  forcePathStyle: true
8093
9365
  });
8094
9366
  async function createFile(value) {
8095
- const session = useAtlas21.getClient()?.startSession();
9367
+ const session = useAtlas25.getClient()?.startSession();
8096
9368
  session?.startTransaction();
8097
9369
  const file = {
8098
9370
  name: value.originalname,
@@ -8126,7 +9398,7 @@ function useFileService() {
8126
9398
  }
8127
9399
  }
8128
9400
  async function deleteFile(id) {
8129
- const session = useAtlas21.getClient()?.startSession();
9401
+ const session = useAtlas25.getClient()?.startSession();
8130
9402
  session?.startTransaction();
8131
9403
  try {
8132
9404
  await deleteFileById(id, session);
@@ -8147,12 +9419,12 @@ function useFileService() {
8147
9419
  const file = files[index];
8148
9420
  try {
8149
9421
  await deleteFile(file._id.toString());
8150
- await logger24.log({
9422
+ await logger27.log({
8151
9423
  level: "info",
8152
9424
  message: "Successfully deleted draft files."
8153
9425
  });
8154
9426
  } catch (error) {
8155
- logger24.log({
9427
+ logger27.log({
8156
9428
  level: "info",
8157
9429
  message: "Successfully deleted draft files."
8158
9430
  });
@@ -8170,11 +9442,11 @@ function useFileService() {
8170
9442
 
8171
9443
  // src/resources/file/file.controller.ts
8172
9444
  import {
8173
- AppError as AppError17,
8174
- BadRequestError as BadRequestError42,
8175
- InternalServerError as InternalServerError21
9445
+ AppError as AppError20,
9446
+ BadRequestError as BadRequestError50,
9447
+ InternalServerError as InternalServerError24
8176
9448
  } from "@goweekdays/utils";
8177
- import Joi28 from "joi";
9449
+ import Joi36 from "joi";
8178
9450
  function useFileController() {
8179
9451
  const { createFile, deleteFile: _deleteFile } = useFileService();
8180
9452
  async function upload(req, res, next) {
@@ -8187,29 +9459,29 @@ function useFileController() {
8187
9459
  res.json({ message: "Successfully uploaded file", id });
8188
9460
  return;
8189
9461
  } catch (error) {
8190
- if (error instanceof AppError17) {
9462
+ if (error instanceof AppError20) {
8191
9463
  next(error);
8192
9464
  } else {
8193
- next(new InternalServerError21(error));
9465
+ next(new InternalServerError24(error));
8194
9466
  }
8195
9467
  }
8196
9468
  }
8197
9469
  async function deleteFile(req, res, next) {
8198
9470
  const id = req.params.id;
8199
- const validation = Joi28.string().required();
9471
+ const validation = Joi36.string().required();
8200
9472
  const { error } = validation.validate(id);
8201
9473
  if (error) {
8202
- next(new BadRequestError42(error.message));
9474
+ next(new BadRequestError50(error.message));
8203
9475
  }
8204
9476
  try {
8205
9477
  const message = await _deleteFile(id);
8206
9478
  res.json({ message });
8207
9479
  return;
8208
9480
  } catch (error2) {
8209
- if (error2 instanceof AppError17) {
9481
+ if (error2 instanceof AppError20) {
8210
9482
  next(error2);
8211
9483
  } else {
8212
- next(new InternalServerError21(error2));
9484
+ next(new InternalServerError24(error2));
8213
9485
  }
8214
9486
  }
8215
9487
  }
@@ -8220,11 +9492,11 @@ function useFileController() {
8220
9492
  }
8221
9493
 
8222
9494
  // src/resources/psgc/psgc.model.ts
8223
- import Joi29 from "joi";
8224
- var schemaPSGC = Joi29.object({
8225
- code: Joi29.string().length(10).required(),
8226
- name: Joi29.string().required(),
8227
- type: Joi29.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required()
9495
+ import Joi37 from "joi";
9496
+ var schemaPSGC = Joi37.object({
9497
+ code: Joi37.string().length(10).required(),
9498
+ name: Joi37.string().required(),
9499
+ type: Joi37.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required()
8228
9500
  });
8229
9501
  function modelPSGC(data) {
8230
9502
  const { error } = schemaPSGC.validate(data);
@@ -8240,24 +9512,24 @@ function modelPSGC(data) {
8240
9512
 
8241
9513
  // src/resources/psgc/psgc.repository.ts
8242
9514
  import {
8243
- AppError as AppError18,
8244
- BadRequestError as BadRequestError43,
8245
- InternalServerError as InternalServerError22,
8246
- logger as logger25,
8247
- makeCacheKey as makeCacheKey15,
8248
- paginate as paginate11,
8249
- useAtlas as useAtlas22,
8250
- useCache as useCache16
9515
+ AppError as AppError21,
9516
+ BadRequestError as BadRequestError51,
9517
+ InternalServerError as InternalServerError25,
9518
+ logger as logger28,
9519
+ makeCacheKey as makeCacheKey18,
9520
+ paginate as paginate14,
9521
+ useAtlas as useAtlas26,
9522
+ useCache as useCache19
8251
9523
  } from "@goweekdays/utils";
8252
- import { ObjectId as ObjectId21 } from "mongodb";
9524
+ import { ObjectId as ObjectId26 } from "mongodb";
8253
9525
  function usePSGCRepo() {
8254
- const db = useAtlas22.getDb();
9526
+ const db = useAtlas26.getDb();
8255
9527
  if (!db) {
8256
9528
  throw new Error("Unable to connect to server.");
8257
9529
  }
8258
9530
  const namespace_collection = "psgc";
8259
9531
  const collection = db.collection(namespace_collection);
8260
- const { getCache, setCache, delNamespace } = useCache16(namespace_collection);
9532
+ const { getCache, setCache, delNamespace } = useCache19(namespace_collection);
8261
9533
  async function createIndexes() {
8262
9534
  try {
8263
9535
  await collection.createIndexes([
@@ -8271,12 +9543,12 @@ function usePSGCRepo() {
8271
9543
  }
8272
9544
  function delCachedData() {
8273
9545
  delNamespace().then(() => {
8274
- logger25.log({
9546
+ logger28.log({
8275
9547
  level: "info",
8276
9548
  message: `Cache namespace cleared for ${namespace_collection}`
8277
9549
  });
8278
9550
  }).catch((err) => {
8279
- logger25.log({
9551
+ logger28.log({
8280
9552
  level: "error",
8281
9553
  message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
8282
9554
  });
@@ -8289,16 +9561,16 @@ function usePSGCRepo() {
8289
9561
  delCachedData();
8290
9562
  return res.insertedId;
8291
9563
  } catch (error) {
8292
- logger25.log({
9564
+ logger28.log({
8293
9565
  level: "error",
8294
9566
  message: error.message
8295
9567
  });
8296
- if (error instanceof AppError18) {
9568
+ if (error instanceof AppError21) {
8297
9569
  throw error;
8298
9570
  } else {
8299
9571
  const isDuplicated = error.message.includes("duplicate");
8300
9572
  if (isDuplicated) {
8301
- throw new BadRequestError43("Region already exists.");
9573
+ throw new BadRequestError51("Region already exists.");
8302
9574
  }
8303
9575
  throw new Error("Failed to create PSGC.");
8304
9576
  }
@@ -8334,15 +9606,15 @@ function usePSGCRepo() {
8334
9606
  query.$text = { $search: search };
8335
9607
  cacheKeyOptions.search = search;
8336
9608
  }
8337
- const cacheKey = makeCacheKey15(namespace_collection, cacheKeyOptions);
8338
- logger25.log({
9609
+ const cacheKey = makeCacheKey18(namespace_collection, cacheKeyOptions);
9610
+ logger28.log({
8339
9611
  level: "info",
8340
9612
  message: `Cache key for getAll PSGC: ${cacheKey}`
8341
9613
  });
8342
9614
  try {
8343
9615
  const cached = await getCache(cacheKey);
8344
9616
  if (cached) {
8345
- logger25.log({
9617
+ logger28.log({
8346
9618
  level: "info",
8347
9619
  message: `Cache hit for getAll PSGC: ${cacheKey}`
8348
9620
  });
@@ -8355,35 +9627,35 @@ function usePSGCRepo() {
8355
9627
  { $limit: limit }
8356
9628
  ]).toArray();
8357
9629
  const length = await collection.countDocuments(query);
8358
- const data = paginate11(items, page, limit, length);
9630
+ const data = paginate14(items, page, limit, length);
8359
9631
  setCache(cacheKey, data, 600).then(() => {
8360
- logger25.log({
9632
+ logger28.log({
8361
9633
  level: "info",
8362
9634
  message: `Cache set for getAll PSGC: ${cacheKey}`
8363
9635
  });
8364
9636
  }).catch((err) => {
8365
- logger25.log({
9637
+ logger28.log({
8366
9638
  level: "error",
8367
9639
  message: `Failed to set cache for getAll PSGC: ${err.message}`
8368
9640
  });
8369
9641
  });
8370
9642
  return data;
8371
9643
  } catch (error) {
8372
- logger25.log({ level: "error", message: `${error}` });
9644
+ logger28.log({ level: "error", message: `${error}` });
8373
9645
  throw error;
8374
9646
  }
8375
9647
  }
8376
9648
  async function getById(_id) {
8377
9649
  try {
8378
- _id = new ObjectId21(_id);
9650
+ _id = new ObjectId26(_id);
8379
9651
  } catch (error) {
8380
- throw new BadRequestError43("Invalid ID.");
9652
+ throw new BadRequestError51("Invalid ID.");
8381
9653
  }
8382
- const cacheKey = makeCacheKey15(namespace_collection, { _id: String(_id) });
9654
+ const cacheKey = makeCacheKey18(namespace_collection, { _id: String(_id) });
8383
9655
  try {
8384
9656
  const cached = await getCache(cacheKey);
8385
9657
  if (cached) {
8386
- logger25.log({
9658
+ logger28.log({
8387
9659
  level: "info",
8388
9660
  message: `Cache hit for getById PSGC: ${cacheKey}`
8389
9661
  });
@@ -8394,25 +9666,25 @@ function usePSGCRepo() {
8394
9666
  deletedAt: { $in: ["", null] }
8395
9667
  });
8396
9668
  if (!result) {
8397
- throw new BadRequestError43("Region not found.");
9669
+ throw new BadRequestError51("Region not found.");
8398
9670
  }
8399
9671
  setCache(cacheKey, result, 300).then(() => {
8400
- logger25.log({
9672
+ logger28.log({
8401
9673
  level: "info",
8402
9674
  message: `Cache set for PSGC by id: ${cacheKey}`
8403
9675
  });
8404
9676
  }).catch((err) => {
8405
- logger25.log({
9677
+ logger28.log({
8406
9678
  level: "error",
8407
9679
  message: `Failed to set cache for PSGC by id: ${err.message}`
8408
9680
  });
8409
9681
  });
8410
9682
  return result;
8411
9683
  } catch (error) {
8412
- if (error instanceof AppError18) {
9684
+ if (error instanceof AppError21) {
8413
9685
  throw error;
8414
9686
  } else {
8415
- throw new InternalServerError22("Failed to get PSGC.");
9687
+ throw new InternalServerError25("Failed to get PSGC.");
8416
9688
  }
8417
9689
  }
8418
9690
  }
@@ -8436,15 +9708,15 @@ function usePSGCRepo() {
8436
9708
  query.code = { $regex: `^${prefix}` };
8437
9709
  cacheKeyOptions.prefix = prefix;
8438
9710
  }
8439
- const cacheKey = makeCacheKey15(namespace_collection, { name });
8440
- logger25.log({
9711
+ const cacheKey = makeCacheKey18(namespace_collection, { name });
9712
+ logger28.log({
8441
9713
  level: "info",
8442
9714
  message: `Query for getByName PSGC: ${JSON.stringify(query)}`
8443
9715
  });
8444
9716
  try {
8445
9717
  const cached = await getCache(cacheKey);
8446
9718
  if (cached) {
8447
- logger25.log({
9719
+ logger28.log({
8448
9720
  level: "info",
8449
9721
  message: `Cache hit for getByName PSGC: ${cacheKey}`
8450
9722
  });
@@ -8452,36 +9724,36 @@ function usePSGCRepo() {
8452
9724
  }
8453
9725
  const result = await collection.findOne(query);
8454
9726
  setCache(cacheKey, result, 300).then(() => {
8455
- logger25.log({
9727
+ logger28.log({
8456
9728
  level: "info",
8457
9729
  message: `Cache set for PSGC by name: ${cacheKey}`
8458
9730
  });
8459
9731
  }).catch((err) => {
8460
- logger25.log({
9732
+ logger28.log({
8461
9733
  level: "error",
8462
9734
  message: `Failed to set cache for PSGC by name: ${err.message}`
8463
9735
  });
8464
9736
  });
8465
9737
  return result;
8466
9738
  } catch (error) {
8467
- if (error instanceof AppError18) {
9739
+ if (error instanceof AppError21) {
8468
9740
  throw error;
8469
9741
  } else {
8470
- throw new InternalServerError22("Failed to get PSGC.");
9742
+ throw new InternalServerError25("Failed to get PSGC.");
8471
9743
  }
8472
9744
  }
8473
9745
  }
8474
9746
  async function updateFieldById({ _id, field, value } = {}, session) {
8475
9747
  const allowedFields = ["name"];
8476
9748
  if (!allowedFields.includes(field)) {
8477
- throw new BadRequestError43(
9749
+ throw new BadRequestError51(
8478
9750
  `Field "${field}" is not allowed to be updated.`
8479
9751
  );
8480
9752
  }
8481
9753
  try {
8482
- _id = new ObjectId21(_id);
9754
+ _id = new ObjectId26(_id);
8483
9755
  } catch (error) {
8484
- throw new BadRequestError43("Invalid ID.");
9756
+ throw new BadRequestError51("Invalid ID.");
8485
9757
  }
8486
9758
  try {
8487
9759
  await collection.updateOne(
@@ -8492,14 +9764,14 @@ function usePSGCRepo() {
8492
9764
  delCachedData();
8493
9765
  return `Successfully updated PSGC ${field}.`;
8494
9766
  } catch (error) {
8495
- throw new InternalServerError22(`Failed to update PSGC ${field}.`);
9767
+ throw new InternalServerError25(`Failed to update PSGC ${field}.`);
8496
9768
  }
8497
9769
  }
8498
9770
  async function deleteById(_id) {
8499
9771
  try {
8500
- _id = new ObjectId21(_id);
9772
+ _id = new ObjectId26(_id);
8501
9773
  } catch (error) {
8502
- throw new BadRequestError43("Invalid ID.");
9774
+ throw new BadRequestError51("Invalid ID.");
8503
9775
  }
8504
9776
  try {
8505
9777
  await collection.updateOne(
@@ -8509,7 +9781,7 @@ function usePSGCRepo() {
8509
9781
  delCachedData();
8510
9782
  return "Successfully deleted PSGC.";
8511
9783
  } catch (error) {
8512
- throw new InternalServerError22("Failed to delete PSGC.");
9784
+ throw new InternalServerError25("Failed to delete PSGC.");
8513
9785
  }
8514
9786
  }
8515
9787
  return {
@@ -8524,8 +9796,8 @@ function usePSGCRepo() {
8524
9796
  }
8525
9797
 
8526
9798
  // src/resources/psgc/psgc.controller.ts
8527
- import { BadRequestError as BadRequestError44 } from "@goweekdays/utils";
8528
- import Joi30 from "joi";
9799
+ import { BadRequestError as BadRequestError52 } from "@goweekdays/utils";
9800
+ import Joi38 from "joi";
8529
9801
  function usePSGCController() {
8530
9802
  const {
8531
9803
  add: _add,
@@ -8539,7 +9811,7 @@ function usePSGCController() {
8539
9811
  const value = req.body;
8540
9812
  const { error } = schemaPSGC.validate(value);
8541
9813
  if (error) {
8542
- next(new BadRequestError44(error.message));
9814
+ next(new BadRequestError52(error.message));
8543
9815
  return;
8544
9816
  }
8545
9817
  try {
@@ -8555,12 +9827,12 @@ function usePSGCController() {
8555
9827
  }
8556
9828
  async function getAll(req, res, next) {
8557
9829
  const query = req.query;
8558
- const validation = Joi30.object({
8559
- page: Joi30.number().min(1).optional().allow("", null),
8560
- limit: Joi30.number().min(1).optional().allow("", null),
8561
- search: Joi30.string().optional().allow("", null),
8562
- type: Joi30.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required(),
8563
- prefix: Joi30.string().optional().allow("", null)
9830
+ const validation = Joi38.object({
9831
+ page: Joi38.number().min(1).optional().allow("", null),
9832
+ limit: Joi38.number().min(1).optional().allow("", null),
9833
+ search: Joi38.string().optional().allow("", null),
9834
+ type: Joi38.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required(),
9835
+ prefix: Joi38.string().optional().allow("", null)
8564
9836
  });
8565
9837
  const { error } = validation.validate(query);
8566
9838
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
@@ -8570,16 +9842,16 @@ function usePSGCController() {
8570
9842
  const prefix = req.query.prefix ? String(req.query.prefix) : "";
8571
9843
  const isPageNumber = isFinite(page);
8572
9844
  if (!isPageNumber) {
8573
- next(new BadRequestError44("Invalid page number."));
9845
+ next(new BadRequestError52("Invalid page number."));
8574
9846
  return;
8575
9847
  }
8576
9848
  const isLimitNumber = isFinite(limit);
8577
9849
  if (!isLimitNumber) {
8578
- next(new BadRequestError44("Invalid limit number."));
9850
+ next(new BadRequestError52("Invalid limit number."));
8579
9851
  return;
8580
9852
  }
8581
9853
  if (error) {
8582
- next(new BadRequestError44(error.message));
9854
+ next(new BadRequestError52(error.message));
8583
9855
  return;
8584
9856
  }
8585
9857
  try {
@@ -8598,12 +9870,12 @@ function usePSGCController() {
8598
9870
  }
8599
9871
  async function getById(req, res, next) {
8600
9872
  const id = req.params.id;
8601
- const validation = Joi30.object({
8602
- id: Joi30.string().hex().required()
9873
+ const validation = Joi38.object({
9874
+ id: Joi38.string().hex().required()
8603
9875
  });
8604
9876
  const { error } = validation.validate({ id });
8605
9877
  if (error) {
8606
- next(new BadRequestError44(error.message));
9878
+ next(new BadRequestError52(error.message));
8607
9879
  return;
8608
9880
  }
8609
9881
  try {
@@ -8619,12 +9891,12 @@ function usePSGCController() {
8619
9891
  }
8620
9892
  async function getByName(req, res, next) {
8621
9893
  const name = req.params.name;
8622
- const validation = Joi30.object({
8623
- name: Joi30.string().required()
9894
+ const validation = Joi38.object({
9895
+ name: Joi38.string().required()
8624
9896
  });
8625
9897
  const { error } = validation.validate({ name });
8626
9898
  if (error) {
8627
- next(new BadRequestError44(error.message));
9899
+ next(new BadRequestError52(error.message));
8628
9900
  return;
8629
9901
  }
8630
9902
  try {
@@ -8641,14 +9913,14 @@ function usePSGCController() {
8641
9913
  async function updateField(req, res, next) {
8642
9914
  const _id = req.params.id;
8643
9915
  const { field, value } = req.body;
8644
- const validation = Joi30.object({
8645
- _id: Joi30.string().hex().required(),
8646
- field: Joi30.string().valid("name", "director", "directorName").required(),
8647
- value: Joi30.string().required()
9916
+ const validation = Joi38.object({
9917
+ _id: Joi38.string().hex().required(),
9918
+ field: Joi38.string().valid("name", "director", "directorName").required(),
9919
+ value: Joi38.string().required()
8648
9920
  });
8649
9921
  const { error } = validation.validate({ _id, field, value });
8650
9922
  if (error) {
8651
- next(new BadRequestError44(error.message));
9923
+ next(new BadRequestError52(error.message));
8652
9924
  return;
8653
9925
  }
8654
9926
  try {
@@ -8661,12 +9933,12 @@ function usePSGCController() {
8661
9933
  }
8662
9934
  async function deleteById(req, res, next) {
8663
9935
  const _id = req.params.id;
8664
- const validation = Joi30.object({
8665
- _id: Joi30.string().hex().required()
9936
+ const validation = Joi38.object({
9937
+ _id: Joi38.string().hex().required()
8666
9938
  });
8667
9939
  const { error } = validation.validate({ _id });
8668
9940
  if (error) {
8669
- next(new BadRequestError44(error.message));
9941
+ next(new BadRequestError52(error.message));
8670
9942
  return;
8671
9943
  }
8672
9944
  try {
@@ -8688,7 +9960,7 @@ function usePSGCController() {
8688
9960
  }
8689
9961
 
8690
9962
  // src/resources/utils/github.service.ts
8691
- import { AppError as AppError19, BadRequestError as BadRequestError45 } from "@goweekdays/utils";
9963
+ import { AppError as AppError22, BadRequestError as BadRequestError53 } from "@goweekdays/utils";
8692
9964
  import { Octokit } from "@octokit/rest";
8693
9965
  import _sodium from "libsodium-wrappers";
8694
9966
  function useGitHubService() {
@@ -8702,23 +9974,23 @@ function useGitHubService() {
8702
9974
  try {
8703
9975
  const { data: repoData } = await octokit.repos.get({ owner, repo });
8704
9976
  if (!repoData.permissions?.admin) {
8705
- throw new BadRequestError45(
9977
+ throw new BadRequestError53(
8706
9978
  "You do not have admin access to this repository."
8707
9979
  );
8708
9980
  }
8709
9981
  } catch (error) {
8710
9982
  if (error.status === 404) {
8711
- throw new BadRequestError45(
9983
+ throw new BadRequestError53(
8712
9984
  "Repository not found or you don't have access to it."
8713
9985
  );
8714
9986
  } else if (error.status === 401) {
8715
- throw new BadRequestError45(
9987
+ throw new BadRequestError53(
8716
9988
  "Invalid GitHub token or insufficient permissions."
8717
9989
  );
8718
9990
  } else if (error.message.includes("admin access")) {
8719
9991
  throw error;
8720
9992
  } else {
8721
- throw new BadRequestError45(
9993
+ throw new BadRequestError53(
8722
9994
  `Failed to check repository permissions: ${error.message}`
8723
9995
  );
8724
9996
  }
@@ -8767,7 +10039,7 @@ function useGitHubService() {
8767
10039
  key_id: publicKeyRes.key_id
8768
10040
  });
8769
10041
  } catch (encryptionError) {
8770
- throw new BadRequestError45(
10042
+ throw new BadRequestError53(
8771
10043
  `Failed to encrypt secret '${key}': ${encryptionError.message}`
8772
10044
  );
8773
10045
  }
@@ -8797,22 +10069,22 @@ function useGitHubService() {
8797
10069
  }
8798
10070
  return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
8799
10071
  } catch (error) {
8800
- if (error instanceof AppError19)
10072
+ if (error instanceof AppError22)
8801
10073
  throw error;
8802
10074
  if (error.status === 422) {
8803
- throw new BadRequestError45(
10075
+ throw new BadRequestError53(
8804
10076
  `GitHub API validation error: ${error.message}`
8805
10077
  );
8806
10078
  } else if (error.status === 404) {
8807
- throw new BadRequestError45("Environment or repository not found.");
10079
+ throw new BadRequestError53("Environment or repository not found.");
8808
10080
  } else if (error.status === 403) {
8809
- throw new BadRequestError45(
10081
+ throw new BadRequestError53(
8810
10082
  "Forbidden: Insufficient permissions or rate limit exceeded."
8811
10083
  );
8812
10084
  } else if (error.message.includes("admin access") || error.message.includes("permissions")) {
8813
10085
  throw error;
8814
10086
  } else {
8815
- throw new BadRequestError45(
10087
+ throw new BadRequestError53(
8816
10088
  `Failed to set GitHub variables: ${error.message}`
8817
10089
  );
8818
10090
  }
@@ -8824,12 +10096,12 @@ function useGitHubService() {
8824
10096
  }
8825
10097
 
8826
10098
  // src/resources/utils/util.controller.ts
8827
- import Joi31 from "joi";
10099
+ import Joi39 from "joi";
8828
10100
  import {
8829
- AppError as AppError20,
8830
- BadRequestError as BadRequestError46,
8831
- InternalServerError as InternalServerError23,
8832
- logger as logger26
10101
+ AppError as AppError23,
10102
+ BadRequestError as BadRequestError54,
10103
+ InternalServerError as InternalServerError26,
10104
+ logger as logger29
8833
10105
  } from "@goweekdays/utils";
8834
10106
  function useUtilController() {
8835
10107
  async function healthCheck(req, res, next) {
@@ -8846,32 +10118,32 @@ function useUtilController() {
8846
10118
  }
8847
10119
  });
8848
10120
  } catch (error) {
8849
- logger26.error("Health check failed", { error: error.message });
8850
- next(new InternalServerError23("Health check failed"));
10121
+ logger29.error("Health check failed", { error: error.message });
10122
+ next(new InternalServerError26("Health check failed"));
8851
10123
  }
8852
10124
  }
8853
10125
  async function setGitHubVariables(req, res, next) {
8854
10126
  try {
8855
10127
  const { githubToken, repoUrl, environment, type, keyValues } = req.body;
8856
- const validation = Joi31.object({
8857
- githubToken: Joi31.string().required().messages({
10128
+ const validation = Joi39.object({
10129
+ githubToken: Joi39.string().required().messages({
8858
10130
  "string.empty": "GitHub token is required",
8859
10131
  "any.required": "GitHub token is required"
8860
10132
  }),
8861
- repoUrl: Joi31.string().uri().required().messages({
10133
+ repoUrl: Joi39.string().uri().required().messages({
8862
10134
  "string.empty": "Repository URL is required",
8863
10135
  "string.uri": "Repository URL must be a valid URL",
8864
10136
  "any.required": "Repository URL is required"
8865
10137
  }),
8866
- environment: Joi31.string().required().messages({
10138
+ environment: Joi39.string().required().messages({
8867
10139
  "string.empty": "Environment name is required",
8868
10140
  "any.required": "Environment name is required"
8869
10141
  }),
8870
- type: Joi31.string().valid("env", "secret").required().messages({
10142
+ type: Joi39.string().valid("env", "secret").required().messages({
8871
10143
  "any.only": 'Type must be either "env" or "secret"',
8872
10144
  "any.required": "Type is required"
8873
10145
  }),
8874
- keyValues: Joi31.string().required().messages({
10146
+ keyValues: Joi39.string().required().messages({
8875
10147
  "string.empty": "Key-value pairs are required",
8876
10148
  "any.required": "Key-value pairs are required"
8877
10149
  })
@@ -8884,13 +10156,13 @@ function useUtilController() {
8884
10156
  keyValues
8885
10157
  });
8886
10158
  if (error) {
8887
- next(new BadRequestError46(error.message));
10159
+ next(new BadRequestError54(error.message));
8888
10160
  return;
8889
10161
  }
8890
10162
  const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
8891
10163
  if (!repoUrlPattern.test(repoUrl)) {
8892
10164
  next(
8893
- new BadRequestError46(
10165
+ new BadRequestError54(
8894
10166
  "Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
8895
10167
  )
8896
10168
  );
@@ -8902,7 +10174,7 @@ function useUtilController() {
8902
10174
  );
8903
10175
  if (invalidLines.length > 0) {
8904
10176
  next(
8905
- new BadRequestError46(
10177
+ new BadRequestError54(
8906
10178
  "Invalid key-value format. Each pair should be in format: KEY=value. Pairs should be separated by semicolons."
8907
10179
  )
8908
10180
  );
@@ -8916,7 +10188,7 @@ function useUtilController() {
8916
10188
  type,
8917
10189
  keyValues
8918
10190
  });
8919
- logger26.info(`GitHub variables set successfully`, {
10191
+ logger29.info(`GitHub variables set successfully`, {
8920
10192
  repoUrl,
8921
10193
  environment,
8922
10194
  type,
@@ -8933,15 +10205,15 @@ function useUtilController() {
8933
10205
  }
8934
10206
  });
8935
10207
  } catch (error) {
8936
- logger26.error("Failed to set GitHub variables", {
10208
+ logger29.error("Failed to set GitHub variables", {
8937
10209
  error: error.message,
8938
10210
  stack: error.stack
8939
10211
  });
8940
- if (error instanceof AppError20) {
10212
+ if (error instanceof AppError23) {
8941
10213
  next(error);
8942
10214
  } else {
8943
10215
  next(
8944
- new InternalServerError23(
10216
+ new InternalServerError26(
8945
10217
  `Failed to set GitHub variables: ${error.message}`
8946
10218
  )
8947
10219
  );
@@ -8955,35 +10227,35 @@ function useUtilController() {
8955
10227
  }
8956
10228
 
8957
10229
  // src/resources/utils/transaction.schema.ts
8958
- import Joi32 from "joi";
8959
- var transactionSchema = Joi32.object({
8960
- _id: Joi32.string().hex().optional().allow("", null),
8961
- payment: Joi32.string().required(),
8962
- user: Joi32.string().hex().optional().allow("", null),
8963
- org: Joi32.string().hex().optional().allow("", null),
8964
- type: Joi32.string().required(),
8965
- amount: Joi32.number().positive().min(0).required(),
8966
- currency: Joi32.string().required(),
8967
- description: Joi32.string().optional().allow("", null),
8968
- metadata: Joi32.object({
8969
- subscriptionId: Joi32.string().hex().optional().allow("", null),
8970
- cycle: Joi32.number().optional().allow("", null),
8971
- seats: Joi32.number().optional().allow("", null),
8972
- promoCode: Joi32.string().optional().allow("", null)
10230
+ import Joi40 from "joi";
10231
+ var transactionSchema = Joi40.object({
10232
+ _id: Joi40.string().hex().optional().allow("", null),
10233
+ payment: Joi40.string().required(),
10234
+ user: Joi40.string().hex().optional().allow("", null),
10235
+ org: Joi40.string().hex().optional().allow("", null),
10236
+ type: Joi40.string().required(),
10237
+ amount: Joi40.number().positive().min(0).required(),
10238
+ currency: Joi40.string().required(),
10239
+ description: Joi40.string().optional().allow("", null),
10240
+ metadata: Joi40.object({
10241
+ subscriptionId: Joi40.string().hex().optional().allow("", null),
10242
+ cycle: Joi40.number().optional().allow("", null),
10243
+ seats: Joi40.number().optional().allow("", null),
10244
+ promoCode: Joi40.string().optional().allow("", null)
8973
10245
  }).optional().allow("", null),
8974
- status: Joi32.string().optional().allow("", null),
8975
- createdAt: Joi32.string().optional().allow("", null),
8976
- updatedAt: Joi32.string().optional().allow("", null),
8977
- deletedAt: Joi32.string().optional().allow("", null)
10246
+ status: Joi40.string().optional().allow("", null),
10247
+ createdAt: Joi40.string().optional().allow("", null),
10248
+ updatedAt: Joi40.string().optional().allow("", null),
10249
+ deletedAt: Joi40.string().optional().allow("", null)
8978
10250
  });
8979
10251
 
8980
10252
  // src/resources/verification/verification.controller.ts
8981
10253
  import {
8982
- AppError as AppError21,
8983
- BadRequestError as BadRequestError47,
8984
- InternalServerError as InternalServerError24
10254
+ AppError as AppError24,
10255
+ BadRequestError as BadRequestError55,
10256
+ InternalServerError as InternalServerError27
8985
10257
  } from "@goweekdays/utils";
8986
- import Joi33 from "joi";
10258
+ import Joi41 from "joi";
8987
10259
  function useVerificationController() {
8988
10260
  const {
8989
10261
  createUserInvite: _createUserInvite,
@@ -8997,17 +10269,17 @@ function useVerificationController() {
8997
10269
  } = useVerificationService();
8998
10270
  const { getVerifications: _getVerifications } = useVerificationRepo();
8999
10271
  async function createUserInvite(req, res, next) {
9000
- const validation = Joi33.object({
9001
- email: Joi33.string().email().required(),
9002
- app: Joi33.string().required(),
9003
- role: Joi33.string().hex().required(),
9004
- roleName: Joi33.string().required(),
9005
- org: Joi33.string().hex().optional().optional().allow("", null),
9006
- orgName: Joi33.string().optional().optional().allow("", null)
10272
+ const validation = Joi41.object({
10273
+ email: Joi41.string().email().required(),
10274
+ app: Joi41.string().required(),
10275
+ role: Joi41.string().hex().required(),
10276
+ roleName: Joi41.string().required(),
10277
+ org: Joi41.string().hex().optional().optional().allow("", null),
10278
+ orgName: Joi41.string().optional().optional().allow("", null)
9007
10279
  });
9008
10280
  const { error } = validation.validate(req.body);
9009
10281
  if (error) {
9010
- next(new BadRequestError47(error.message));
10282
+ next(new BadRequestError55(error.message));
9011
10283
  return;
9012
10284
  }
9013
10285
  const email = req.body.email ?? "";
@@ -9035,10 +10307,10 @@ function useVerificationController() {
9035
10307
  }
9036
10308
  async function createForgetPassword(req, res, next) {
9037
10309
  const email = req.body.email || "";
9038
- const validation = Joi33.string().email().required();
10310
+ const validation = Joi41.string().email().required();
9039
10311
  const { error } = validation.validate(email);
9040
10312
  if (error) {
9041
- next(new BadRequestError47(error.message));
10313
+ next(new BadRequestError55(error.message));
9042
10314
  return;
9043
10315
  }
9044
10316
  try {
@@ -9048,26 +10320,26 @@ function useVerificationController() {
9048
10320
  });
9049
10321
  return;
9050
10322
  } catch (error2) {
9051
- if (error2 instanceof AppError21) {
10323
+ if (error2 instanceof AppError24) {
9052
10324
  next(error2);
9053
10325
  } else {
9054
- next(new InternalServerError24("An unexpected error occurred"));
10326
+ next(new InternalServerError27("An unexpected error occurred"));
9055
10327
  }
9056
10328
  }
9057
10329
  }
9058
10330
  async function getVerifications(req, res, next) {
9059
- const validation = Joi33.object({
9060
- status: Joi33.string().required(),
9061
- search: Joi33.string().optional().allow("", null),
9062
- page: Joi33.number().required(),
9063
- type: Joi33.string().optional().allow("", null),
9064
- email: Joi33.string().optional().allow("", null),
9065
- app: Joi33.string().optional().allow("", null),
9066
- org: Joi33.string().optional().allow("", null)
10331
+ const validation = Joi41.object({
10332
+ status: Joi41.string().required(),
10333
+ search: Joi41.string().optional().allow("", null),
10334
+ page: Joi41.number().required(),
10335
+ type: Joi41.string().optional().allow("", null),
10336
+ email: Joi41.string().optional().allow("", null),
10337
+ app: Joi41.string().optional().allow("", null),
10338
+ org: Joi41.string().optional().allow("", null)
9067
10339
  });
9068
10340
  const { error } = validation.validate(req.query);
9069
10341
  if (error) {
9070
- next(new BadRequestError47(error.message));
10342
+ next(new BadRequestError55(error.message));
9071
10343
  return;
9072
10344
  }
9073
10345
  const status = req.query.status ?? "";
@@ -9100,10 +10372,10 @@ function useVerificationController() {
9100
10372
  }
9101
10373
  async function verify(req, res, next) {
9102
10374
  const id = req.params.id || "";
9103
- const validation = Joi33.string().hex().required();
10375
+ const validation = Joi41.string().hex().required();
9104
10376
  const { error } = validation.validate(id);
9105
10377
  if (error) {
9106
- next(new BadRequestError47(error.message));
10378
+ next(new BadRequestError55(error.message));
9107
10379
  return;
9108
10380
  }
9109
10381
  try {
@@ -9116,10 +10388,10 @@ function useVerificationController() {
9116
10388
  }
9117
10389
  async function cancelUserInvitation(req, res, next) {
9118
10390
  const otpId = req.params.id || "";
9119
- const validation = Joi33.string().hex().required();
10391
+ const validation = Joi41.string().hex().required();
9120
10392
  const { error } = validation.validate(otpId);
9121
10393
  if (error) {
9122
- next(new BadRequestError47(error.message));
10394
+ next(new BadRequestError55(error.message));
9123
10395
  return;
9124
10396
  }
9125
10397
  try {
@@ -9132,10 +10404,10 @@ function useVerificationController() {
9132
10404
  }
9133
10405
  }
9134
10406
  async function signUp(req, res, next) {
9135
- const validation = Joi33.string().email().required();
10407
+ const validation = Joi41.string().email().required();
9136
10408
  const { error } = validation.validate(req.body.email);
9137
10409
  if (error) {
9138
- next(new BadRequestError47(error.message));
10410
+ next(new BadRequestError55(error.message));
9139
10411
  return;
9140
10412
  }
9141
10413
  const email = req.body.email ?? "";
@@ -9150,7 +10422,7 @@ function useVerificationController() {
9150
10422
  async function inviteMember(req, res, next) {
9151
10423
  const { error } = schemaInviteMember.validate(req.body);
9152
10424
  if (error) {
9153
- next(new BadRequestError47(error.message));
10425
+ next(new BadRequestError55(error.message));
9154
10426
  return;
9155
10427
  }
9156
10428
  try {
@@ -9163,10 +10435,10 @@ function useVerificationController() {
9163
10435
  }
9164
10436
  async function cancelInviteMember(req, res, next) {
9165
10437
  const id = req.params.id || "";
9166
- const validation = Joi33.string().hex().required();
10438
+ const validation = Joi41.string().hex().required();
9167
10439
  const { error } = validation.validate(id);
9168
10440
  if (error) {
9169
- next(new BadRequestError47(error.message));
10441
+ next(new BadRequestError55(error.message));
9170
10442
  return;
9171
10443
  }
9172
10444
  try {
@@ -9179,10 +10451,10 @@ function useVerificationController() {
9179
10451
  }
9180
10452
  async function forgetPassword(req, res, next) {
9181
10453
  const email = req.body.email ?? "";
9182
- const validation = Joi33.string().email().required();
10454
+ const validation = Joi41.string().email().required();
9183
10455
  const { error } = validation.validate(email);
9184
10456
  if (error) {
9185
- next(new BadRequestError47(error.message));
10457
+ next(new BadRequestError55(error.message));
9186
10458
  return;
9187
10459
  }
9188
10460
  try {
@@ -9192,10 +10464,10 @@ function useVerificationController() {
9192
10464
  });
9193
10465
  return;
9194
10466
  } catch (error2) {
9195
- if (error2 instanceof AppError21) {
10467
+ if (error2 instanceof AppError24) {
9196
10468
  next(error2);
9197
10469
  } else {
9198
- next(new InternalServerError24("An unexpected error occurred"));
10470
+ next(new InternalServerError27("An unexpected error occurred"));
9199
10471
  }
9200
10472
  }
9201
10473
  }
@@ -9252,6 +10524,7 @@ export {
9252
10524
  XENDIT_BASE_URL,
9253
10525
  XENDIT_SECRET_KEY,
9254
10526
  addressSchema,
10527
+ currencies,
9255
10528
  isDev,
9256
10529
  modelApp,
9257
10530
  modelMember,
@@ -9259,7 +10532,10 @@ export {
9259
10532
  modelPSGC,
9260
10533
  modelPermission,
9261
10534
  modelPermissionGroup,
10535
+ modelPlan,
9262
10536
  modelRole,
10537
+ modelSubscription,
10538
+ modelSubscriptionTransaction,
9263
10539
  modelUser,
9264
10540
  modelVerification,
9265
10541
  schemaApp,
@@ -9271,13 +10547,20 @@ export {
9271
10547
  schemaMemberRole,
9272
10548
  schemaMemberStatus,
9273
10549
  schemaOrg,
10550
+ schemaOrgAdd,
10551
+ schemaOrgUpdate,
9274
10552
  schemaPSGC,
9275
10553
  schemaPermission,
9276
10554
  schemaPermissionGroup,
9277
10555
  schemaPermissionGroupUpdate,
9278
10556
  schemaPermissionUpdate,
10557
+ schemaPlan,
9279
10558
  schemaRole,
9280
10559
  schemaRoleUpdate,
10560
+ schemaSubscription,
10561
+ schemaSubscriptionSeats,
10562
+ schemaSubscriptionTransaction,
10563
+ schemaSubscriptionUpdate,
9281
10564
  schemaUpdateOptions,
9282
10565
  schemaUser,
9283
10566
  schemaVerification,
@@ -9314,9 +10597,16 @@ export {
9314
10597
  usePermissionGroupService,
9315
10598
  usePermissionRepo,
9316
10599
  usePermissionService,
10600
+ usePlanController,
10601
+ usePlanRepo,
10602
+ usePlanService,
9317
10603
  useRoleController,
9318
10604
  useRoleRepo,
9319
10605
  useRoleService,
10606
+ useSubscriptionController,
10607
+ useSubscriptionRepo,
10608
+ useSubscriptionTransactionController,
10609
+ useSubscriptionTransactionRepo,
9320
10610
  useUserController,
9321
10611
  useUserRepo,
9322
10612
  useUserService,