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