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