@eeplatform/core 1.8.4 → 1.8.6
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/CONVENTION.md +632 -0
- package/dist/index.d.ts +2 -154
- package/dist/index.js +702 -1774
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +698 -1777
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1279,6 +1279,44 @@ function useMemberRepo() {
|
|
|
1279
1279
|
);
|
|
1280
1280
|
}
|
|
1281
1281
|
}
|
|
1282
|
+
async function getByOrg(org) {
|
|
1283
|
+
try {
|
|
1284
|
+
org = new ObjectId8(org);
|
|
1285
|
+
} catch (error) {
|
|
1286
|
+
throw new BadRequestError7("Invalid ID.");
|
|
1287
|
+
}
|
|
1288
|
+
try {
|
|
1289
|
+
const cacheKey = makeCacheKey5(namespace_collection, {
|
|
1290
|
+
org: String(org),
|
|
1291
|
+
tag: "byOrg"
|
|
1292
|
+
});
|
|
1293
|
+
const cached = await getCache(cacheKey);
|
|
1294
|
+
if (cached) {
|
|
1295
|
+
logger5.log({
|
|
1296
|
+
level: "info",
|
|
1297
|
+
message: `Cache hit for getByOrg member: ${cacheKey}`
|
|
1298
|
+
});
|
|
1299
|
+
return cached;
|
|
1300
|
+
}
|
|
1301
|
+
const data = await collection.findOne({ org });
|
|
1302
|
+
setCache(cacheKey, data, 300).then(() => {
|
|
1303
|
+
logger5.log({
|
|
1304
|
+
level: "info",
|
|
1305
|
+
message: `Cache set for member by org: ${cacheKey}`
|
|
1306
|
+
});
|
|
1307
|
+
}).catch((err) => {
|
|
1308
|
+
logger5.log({
|
|
1309
|
+
level: "error",
|
|
1310
|
+
message: `Failed to set cache for member by org: ${err.message}`
|
|
1311
|
+
});
|
|
1312
|
+
});
|
|
1313
|
+
return data;
|
|
1314
|
+
} catch (error) {
|
|
1315
|
+
throw new InternalServerError6(
|
|
1316
|
+
"Internal server error, failed to retrieve member."
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1282
1320
|
async function getByUserId(user) {
|
|
1283
1321
|
try {
|
|
1284
1322
|
user = new ObjectId8(user);
|
|
@@ -1433,9 +1471,6 @@ function useMemberRepo() {
|
|
|
1433
1471
|
{
|
|
1434
1472
|
$match: query
|
|
1435
1473
|
},
|
|
1436
|
-
{
|
|
1437
|
-
$sort: { _id: -1 }
|
|
1438
|
-
},
|
|
1439
1474
|
{
|
|
1440
1475
|
$limit: limit
|
|
1441
1476
|
},
|
|
@@ -1729,6 +1764,7 @@ function useMemberRepo() {
|
|
|
1729
1764
|
createTextIndex,
|
|
1730
1765
|
add,
|
|
1731
1766
|
getById,
|
|
1767
|
+
getByOrg,
|
|
1732
1768
|
getAll,
|
|
1733
1769
|
getOrgsByUserId,
|
|
1734
1770
|
updateStatusByUserId,
|
|
@@ -2431,8 +2467,9 @@ function useRoleRepo() {
|
|
|
2431
2467
|
throw new BadRequestError9("Invalid ID.");
|
|
2432
2468
|
}
|
|
2433
2469
|
try {
|
|
2434
|
-
await collection.
|
|
2470
|
+
await collection.updateOne(
|
|
2435
2471
|
{ _id },
|
|
2472
|
+
{ $set: { status: "deleted", updateAt: /* @__PURE__ */ new Date() } },
|
|
2436
2473
|
{
|
|
2437
2474
|
session
|
|
2438
2475
|
}
|
|
@@ -2858,7 +2895,6 @@ function useAuthController() {
|
|
|
2858
2895
|
level: "error",
|
|
2859
2896
|
message: `Error during login: ${error2.message}`
|
|
2860
2897
|
});
|
|
2861
|
-
console.log(`Error during login: ${error2}`);
|
|
2862
2898
|
if (error2 instanceof AppError3) {
|
|
2863
2899
|
next(error2);
|
|
2864
2900
|
} else {
|
|
@@ -3676,8 +3712,214 @@ function useOrgController() {
|
|
|
3676
3712
|
}
|
|
3677
3713
|
|
|
3678
3714
|
// src/resources/role/role.controller.ts
|
|
3715
|
+
import Joi8 from "joi";
|
|
3716
|
+
import { BadRequestError as BadRequestError18 } from "@eeplatform/nodejs-utils";
|
|
3717
|
+
|
|
3718
|
+
// src/resources/role/role.service.ts
|
|
3719
|
+
import {
|
|
3720
|
+
AppError as AppError6,
|
|
3721
|
+
BadRequestError as BadRequestError17,
|
|
3722
|
+
InternalServerError as InternalServerError13
|
|
3723
|
+
} from "@eeplatform/nodejs-utils";
|
|
3724
|
+
import Joi7 from "joi";
|
|
3725
|
+
|
|
3726
|
+
// src/resources/member/member.controller.ts
|
|
3679
3727
|
import Joi6 from "joi";
|
|
3680
3728
|
import { BadRequestError as BadRequestError16 } from "@eeplatform/nodejs-utils";
|
|
3729
|
+
function useMemberController() {
|
|
3730
|
+
const {
|
|
3731
|
+
getByUserId: _getByUserId,
|
|
3732
|
+
getAll: _getAll,
|
|
3733
|
+
getOrgsByMembership: _getOrgsByMembership,
|
|
3734
|
+
updateStatusByUserId: _updateStatusByUserId,
|
|
3735
|
+
getByUserType: _getByUserType
|
|
3736
|
+
} = useMemberRepo();
|
|
3737
|
+
async function getByUserId(req, res, next) {
|
|
3738
|
+
const userId = req.params.id;
|
|
3739
|
+
const validation = Joi6.object({
|
|
3740
|
+
id: Joi6.string().hex().required()
|
|
3741
|
+
});
|
|
3742
|
+
const { error } = validation.validate({ id: userId });
|
|
3743
|
+
if (error) {
|
|
3744
|
+
next(new BadRequestError16(error.message));
|
|
3745
|
+
return;
|
|
3746
|
+
}
|
|
3747
|
+
try {
|
|
3748
|
+
const member = await _getByUserId(userId);
|
|
3749
|
+
if (!member) {
|
|
3750
|
+
res.status(404).json({ message: "Member not found." });
|
|
3751
|
+
return;
|
|
3752
|
+
}
|
|
3753
|
+
res.json(member);
|
|
3754
|
+
} catch (error2) {
|
|
3755
|
+
next(error2);
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
async function getByUserType(req, res, next) {
|
|
3759
|
+
const validation = Joi6.object({
|
|
3760
|
+
org: Joi6.string().hex().optional().allow("", null),
|
|
3761
|
+
user: Joi6.string().hex().required(),
|
|
3762
|
+
type: Joi6.string().required()
|
|
3763
|
+
});
|
|
3764
|
+
const { error } = validation.validate({ ...req.params, ...req.query });
|
|
3765
|
+
if (error) {
|
|
3766
|
+
next(new BadRequestError16(error.message));
|
|
3767
|
+
return;
|
|
3768
|
+
}
|
|
3769
|
+
const orgId = req.query.org;
|
|
3770
|
+
const userId = req.params.user;
|
|
3771
|
+
const type = req.params.type;
|
|
3772
|
+
try {
|
|
3773
|
+
const member = await _getByUserType(userId, type, orgId);
|
|
3774
|
+
if (!member) {
|
|
3775
|
+
res.status(404).json({ message: "Member not found." });
|
|
3776
|
+
return;
|
|
3777
|
+
}
|
|
3778
|
+
res.json(member);
|
|
3779
|
+
} catch (error2) {
|
|
3780
|
+
next(error2);
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
async function getAll(req, res, next) {
|
|
3784
|
+
const limit = Number(req.query.limit) ?? 10;
|
|
3785
|
+
const search = req.query.search ?? "";
|
|
3786
|
+
const page = Number(req.query.page) ?? 1;
|
|
3787
|
+
const user = req.query.user ?? "";
|
|
3788
|
+
const org = req.query.org ?? "";
|
|
3789
|
+
const type = req.query.type ?? "main";
|
|
3790
|
+
const status = req.query.status ?? "active";
|
|
3791
|
+
const validation = Joi6.object({
|
|
3792
|
+
limit: Joi6.number().min(10).max(300).required(),
|
|
3793
|
+
search: Joi6.string().optional().allow("", null),
|
|
3794
|
+
page: Joi6.number().required(),
|
|
3795
|
+
user: Joi6.string().hex().optional().allow("", null),
|
|
3796
|
+
org: Joi6.string().hex().optional().allow("", null),
|
|
3797
|
+
type: Joi6.string().required(),
|
|
3798
|
+
status: Joi6.string().required()
|
|
3799
|
+
});
|
|
3800
|
+
const { error } = validation.validate({
|
|
3801
|
+
search,
|
|
3802
|
+
page,
|
|
3803
|
+
user,
|
|
3804
|
+
org,
|
|
3805
|
+
type,
|
|
3806
|
+
limit,
|
|
3807
|
+
status
|
|
3808
|
+
});
|
|
3809
|
+
if (error) {
|
|
3810
|
+
next(new BadRequestError16(error.message));
|
|
3811
|
+
return;
|
|
3812
|
+
}
|
|
3813
|
+
try {
|
|
3814
|
+
const items = await _getAll({
|
|
3815
|
+
search,
|
|
3816
|
+
page,
|
|
3817
|
+
user,
|
|
3818
|
+
org,
|
|
3819
|
+
type,
|
|
3820
|
+
limit,
|
|
3821
|
+
status
|
|
3822
|
+
});
|
|
3823
|
+
res.json(items);
|
|
3824
|
+
return;
|
|
3825
|
+
} catch (error2) {
|
|
3826
|
+
next(error2);
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
async function getOrgsByMembership(req, res, next) {
|
|
3830
|
+
const limit = Number(req.query.limit) ?? 10;
|
|
3831
|
+
const search = req.query.search ?? "";
|
|
3832
|
+
const page = Number(req.query.page) ?? 1;
|
|
3833
|
+
const user = req.query.user ?? "";
|
|
3834
|
+
const validation = Joi6.object({
|
|
3835
|
+
limit: Joi6.number().min(10).max(50).required(),
|
|
3836
|
+
search: Joi6.string().optional().allow("", null),
|
|
3837
|
+
page: Joi6.number().required(),
|
|
3838
|
+
user: Joi6.string().hex().optional().allow("", null)
|
|
3839
|
+
});
|
|
3840
|
+
const { error } = validation.validate({
|
|
3841
|
+
search,
|
|
3842
|
+
page,
|
|
3843
|
+
user,
|
|
3844
|
+
limit
|
|
3845
|
+
});
|
|
3846
|
+
if (error) {
|
|
3847
|
+
next(new BadRequestError16(error.message));
|
|
3848
|
+
}
|
|
3849
|
+
try {
|
|
3850
|
+
const items = await _getOrgsByMembership({
|
|
3851
|
+
search,
|
|
3852
|
+
page,
|
|
3853
|
+
user,
|
|
3854
|
+
limit
|
|
3855
|
+
});
|
|
3856
|
+
res.json(items);
|
|
3857
|
+
return;
|
|
3858
|
+
} catch (error2) {
|
|
3859
|
+
next(error2);
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3862
|
+
async function updateStatusByUserId(req, res, next) {
|
|
3863
|
+
const validation = Joi6.object({
|
|
3864
|
+
id: Joi6.string().hex().required(),
|
|
3865
|
+
status: Joi6.string().valid("active", "suspended", "deleted").required()
|
|
3866
|
+
});
|
|
3867
|
+
const { error } = validation.validate(req.params);
|
|
3868
|
+
if (error) {
|
|
3869
|
+
next(new BadRequestError16(error.message));
|
|
3870
|
+
return;
|
|
3871
|
+
}
|
|
3872
|
+
const id = req.params.id;
|
|
3873
|
+
const status = req.params.status;
|
|
3874
|
+
try {
|
|
3875
|
+
const message = await _updateStatusByUserId(id, status);
|
|
3876
|
+
res.json({ message });
|
|
3877
|
+
} catch (error2) {
|
|
3878
|
+
next(error2);
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
return {
|
|
3882
|
+
getByUserId,
|
|
3883
|
+
getAll,
|
|
3884
|
+
getOrgsByMembership,
|
|
3885
|
+
updateStatusByUserId,
|
|
3886
|
+
getByUserType
|
|
3887
|
+
};
|
|
3888
|
+
}
|
|
3889
|
+
|
|
3890
|
+
// src/resources/role/role.service.ts
|
|
3891
|
+
function useRoleService() {
|
|
3892
|
+
const { getByOrg } = useMemberRepo();
|
|
3893
|
+
const { deleteRole, getRoleById } = useRoleRepo();
|
|
3894
|
+
async function deleteById(_id) {
|
|
3895
|
+
const { error } = Joi7.string().hex().length(24).validate(_id);
|
|
3896
|
+
if (error) {
|
|
3897
|
+
throw new BadRequestError17("Invalid Role ID");
|
|
3898
|
+
}
|
|
3899
|
+
try {
|
|
3900
|
+
const role = await getRoleById(_id);
|
|
3901
|
+
if (!role) {
|
|
3902
|
+
throw new BadRequestError17("Role not found");
|
|
3903
|
+
}
|
|
3904
|
+
const org = await getByOrg(String(role.id));
|
|
3905
|
+
if (org) {
|
|
3906
|
+
throw new BadRequestError17("Cannot delete role assigned to members");
|
|
3907
|
+
}
|
|
3908
|
+
await deleteRole(_id);
|
|
3909
|
+
return "Role deleted successfully";
|
|
3910
|
+
} catch (error2) {
|
|
3911
|
+
if (error2 instanceof AppError6) {
|
|
3912
|
+
throw error2;
|
|
3913
|
+
}
|
|
3914
|
+
throw new InternalServerError13("Failed to delete role");
|
|
3915
|
+
}
|
|
3916
|
+
}
|
|
3917
|
+
return {
|
|
3918
|
+
deleteById
|
|
3919
|
+
};
|
|
3920
|
+
}
|
|
3921
|
+
|
|
3922
|
+
// src/resources/role/role.controller.ts
|
|
3681
3923
|
function useRoleController() {
|
|
3682
3924
|
const {
|
|
3683
3925
|
addRole: _createRole,
|
|
@@ -3685,20 +3927,19 @@ function useRoleController() {
|
|
|
3685
3927
|
getRoleByUserId: _getRoleByUserId,
|
|
3686
3928
|
getRoles: _getRoles,
|
|
3687
3929
|
updateRole: _updateRole,
|
|
3688
|
-
deleteRole: _deleteRole,
|
|
3689
3930
|
updatePermissionsById: _updatePermissionsById
|
|
3690
3931
|
} = useRoleRepo();
|
|
3691
3932
|
async function createRole(req, res, next) {
|
|
3692
3933
|
const payload = req.body;
|
|
3693
|
-
const validation =
|
|
3694
|
-
name:
|
|
3695
|
-
permissions:
|
|
3696
|
-
type:
|
|
3697
|
-
id:
|
|
3934
|
+
const validation = Joi8.object({
|
|
3935
|
+
name: Joi8.string().required(),
|
|
3936
|
+
permissions: Joi8.array().items(Joi8.string()).required(),
|
|
3937
|
+
type: Joi8.string().valid("school", "division", "region", "account").required(),
|
|
3938
|
+
id: Joi8.string().hex().optional().allow("", null)
|
|
3698
3939
|
});
|
|
3699
3940
|
const { error } = validation.validate(payload);
|
|
3700
3941
|
if (error) {
|
|
3701
|
-
next(new
|
|
3942
|
+
next(new BadRequestError18(error.message));
|
|
3702
3943
|
return;
|
|
3703
3944
|
}
|
|
3704
3945
|
try {
|
|
@@ -3715,16 +3956,16 @@ function useRoleController() {
|
|
|
3715
3956
|
const limit = parseInt(req.query.limit ?? "10");
|
|
3716
3957
|
const type = req.query.type ?? "";
|
|
3717
3958
|
const id = req.query.id ?? "";
|
|
3718
|
-
const validation =
|
|
3719
|
-
search:
|
|
3720
|
-
page:
|
|
3721
|
-
limit:
|
|
3722
|
-
type:
|
|
3723
|
-
id:
|
|
3959
|
+
const validation = Joi8.object({
|
|
3960
|
+
search: Joi8.string().optional().allow("", null),
|
|
3961
|
+
page: Joi8.number().required(),
|
|
3962
|
+
limit: Joi8.number().required(),
|
|
3963
|
+
type: Joi8.string().optional().allow("", null),
|
|
3964
|
+
id: Joi8.string().hex().optional().allow("", null)
|
|
3724
3965
|
});
|
|
3725
3966
|
const { error } = validation.validate({ search, page, limit, type, id });
|
|
3726
3967
|
if (error) {
|
|
3727
|
-
next(new
|
|
3968
|
+
next(new BadRequestError18(error.message));
|
|
3728
3969
|
return;
|
|
3729
3970
|
}
|
|
3730
3971
|
try {
|
|
@@ -3737,12 +3978,12 @@ function useRoleController() {
|
|
|
3737
3978
|
}
|
|
3738
3979
|
async function getRoleByUserId(req, res, next) {
|
|
3739
3980
|
const userId = req.params.userId;
|
|
3740
|
-
const validation =
|
|
3741
|
-
userId:
|
|
3981
|
+
const validation = Joi8.object({
|
|
3982
|
+
userId: Joi8.string().required()
|
|
3742
3983
|
});
|
|
3743
3984
|
const { error } = validation.validate({ userId });
|
|
3744
3985
|
if (error) {
|
|
3745
|
-
next(new
|
|
3986
|
+
next(new BadRequestError18(error.message));
|
|
3746
3987
|
return;
|
|
3747
3988
|
}
|
|
3748
3989
|
try {
|
|
@@ -3755,12 +3996,12 @@ function useRoleController() {
|
|
|
3755
3996
|
}
|
|
3756
3997
|
async function getRoleById(req, res, next) {
|
|
3757
3998
|
const _id = req.params.id;
|
|
3758
|
-
const validation =
|
|
3759
|
-
_id:
|
|
3999
|
+
const validation = Joi8.object({
|
|
4000
|
+
_id: Joi8.string().hex().required()
|
|
3760
4001
|
});
|
|
3761
4002
|
const { error } = validation.validate({ _id });
|
|
3762
4003
|
if (error) {
|
|
3763
|
-
next(new
|
|
4004
|
+
next(new BadRequestError18(error.message));
|
|
3764
4005
|
return;
|
|
3765
4006
|
}
|
|
3766
4007
|
try {
|
|
@@ -3775,14 +4016,14 @@ function useRoleController() {
|
|
|
3775
4016
|
const _id = req.params.id;
|
|
3776
4017
|
const name = req.body.name ?? "";
|
|
3777
4018
|
const permissions = req.body.permissions ?? [];
|
|
3778
|
-
const validation =
|
|
3779
|
-
_id:
|
|
3780
|
-
name:
|
|
3781
|
-
permissions:
|
|
4019
|
+
const validation = Joi8.object({
|
|
4020
|
+
_id: Joi8.string().required(),
|
|
4021
|
+
name: Joi8.string().required(),
|
|
4022
|
+
permissions: Joi8.array().items(Joi8.string()).required()
|
|
3782
4023
|
});
|
|
3783
4024
|
const { error } = validation.validate({ _id, name, permissions });
|
|
3784
4025
|
if (error) {
|
|
3785
|
-
next(new
|
|
4026
|
+
next(new BadRequestError18(error.message));
|
|
3786
4027
|
return;
|
|
3787
4028
|
}
|
|
3788
4029
|
try {
|
|
@@ -3796,13 +4037,13 @@ function useRoleController() {
|
|
|
3796
4037
|
async function updatePermissionsById(req, res, next) {
|
|
3797
4038
|
const _id = req.params.id;
|
|
3798
4039
|
const permissions = req.body.permissions ?? [];
|
|
3799
|
-
const validation =
|
|
3800
|
-
_id:
|
|
3801
|
-
permissions:
|
|
4040
|
+
const validation = Joi8.object({
|
|
4041
|
+
_id: Joi8.string().required(),
|
|
4042
|
+
permissions: Joi8.array().items(Joi8.string()).required()
|
|
3802
4043
|
});
|
|
3803
4044
|
const { error } = validation.validate({ _id, permissions });
|
|
3804
4045
|
if (error) {
|
|
3805
|
-
next(new
|
|
4046
|
+
next(new BadRequestError18(error.message));
|
|
3806
4047
|
return;
|
|
3807
4048
|
}
|
|
3808
4049
|
try {
|
|
@@ -3813,18 +4054,19 @@ function useRoleController() {
|
|
|
3813
4054
|
next(error2);
|
|
3814
4055
|
}
|
|
3815
4056
|
}
|
|
4057
|
+
const { deleteById } = useRoleService();
|
|
3816
4058
|
async function deleteRole(req, res, next) {
|
|
3817
4059
|
const _id = req.params.id;
|
|
3818
|
-
const validation =
|
|
3819
|
-
_id:
|
|
4060
|
+
const validation = Joi8.object({
|
|
4061
|
+
_id: Joi8.string().required()
|
|
3820
4062
|
});
|
|
3821
4063
|
const { error } = validation.validate({ _id });
|
|
3822
4064
|
if (error) {
|
|
3823
|
-
next(new
|
|
4065
|
+
next(new BadRequestError18(error.message));
|
|
3824
4066
|
return;
|
|
3825
4067
|
}
|
|
3826
4068
|
try {
|
|
3827
|
-
const message = await
|
|
4069
|
+
const message = await deleteById(_id);
|
|
3828
4070
|
res.json({ message });
|
|
3829
4071
|
return;
|
|
3830
4072
|
} catch (error2) {
|
|
@@ -3939,11 +4181,11 @@ function useFileService() {
|
|
|
3939
4181
|
|
|
3940
4182
|
// src/resources/file/file.controller.ts
|
|
3941
4183
|
import {
|
|
3942
|
-
AppError as
|
|
3943
|
-
BadRequestError as
|
|
3944
|
-
InternalServerError as
|
|
4184
|
+
AppError as AppError7,
|
|
4185
|
+
BadRequestError as BadRequestError19,
|
|
4186
|
+
InternalServerError as InternalServerError15
|
|
3945
4187
|
} from "@eeplatform/nodejs-utils";
|
|
3946
|
-
import
|
|
4188
|
+
import Joi9 from "joi";
|
|
3947
4189
|
function useFileController() {
|
|
3948
4190
|
const { createFile, deleteFile: _deleteFile } = useFileService();
|
|
3949
4191
|
async function upload(req, res, next) {
|
|
@@ -3956,29 +4198,29 @@ function useFileController() {
|
|
|
3956
4198
|
res.json({ message: "Successfully uploaded file", id });
|
|
3957
4199
|
return;
|
|
3958
4200
|
} catch (error) {
|
|
3959
|
-
if (error instanceof
|
|
4201
|
+
if (error instanceof AppError7) {
|
|
3960
4202
|
next(error);
|
|
3961
4203
|
} else {
|
|
3962
|
-
next(new
|
|
4204
|
+
next(new InternalServerError15(error));
|
|
3963
4205
|
}
|
|
3964
4206
|
}
|
|
3965
4207
|
}
|
|
3966
4208
|
async function deleteFile(req, res, next) {
|
|
3967
4209
|
const id = req.params.id;
|
|
3968
|
-
const validation =
|
|
4210
|
+
const validation = Joi9.string().required();
|
|
3969
4211
|
const { error } = validation.validate(id);
|
|
3970
4212
|
if (error) {
|
|
3971
|
-
next(new
|
|
4213
|
+
next(new BadRequestError19(error.message));
|
|
3972
4214
|
}
|
|
3973
4215
|
try {
|
|
3974
4216
|
const message = await _deleteFile(id);
|
|
3975
4217
|
res.json({ message });
|
|
3976
4218
|
return;
|
|
3977
4219
|
} catch (error2) {
|
|
3978
|
-
if (error2 instanceof
|
|
4220
|
+
if (error2 instanceof AppError7) {
|
|
3979
4221
|
next(error2);
|
|
3980
4222
|
} else {
|
|
3981
|
-
next(new
|
|
4223
|
+
next(new InternalServerError15(error2));
|
|
3982
4224
|
}
|
|
3983
4225
|
}
|
|
3984
4226
|
}
|
|
@@ -3990,11 +4232,11 @@ function useFileController() {
|
|
|
3990
4232
|
|
|
3991
4233
|
// src/resources/verification/verification.controller.ts
|
|
3992
4234
|
import {
|
|
3993
|
-
AppError as
|
|
3994
|
-
BadRequestError as
|
|
3995
|
-
InternalServerError as
|
|
4235
|
+
AppError as AppError8,
|
|
4236
|
+
BadRequestError as BadRequestError20,
|
|
4237
|
+
InternalServerError as InternalServerError16
|
|
3996
4238
|
} from "@eeplatform/nodejs-utils";
|
|
3997
|
-
import
|
|
4239
|
+
import Joi10 from "joi";
|
|
3998
4240
|
function useVerificationController() {
|
|
3999
4241
|
const {
|
|
4000
4242
|
createUserInvite: _createUserInvite,
|
|
@@ -4004,17 +4246,17 @@ function useVerificationController() {
|
|
|
4004
4246
|
} = useVerificationService();
|
|
4005
4247
|
const { getVerifications: _getVerifications } = useVerificationRepo();
|
|
4006
4248
|
async function createUserInvite(req, res, next) {
|
|
4007
|
-
const validation =
|
|
4008
|
-
email:
|
|
4009
|
-
app:
|
|
4010
|
-
role:
|
|
4011
|
-
roleName:
|
|
4012
|
-
org:
|
|
4013
|
-
orgName:
|
|
4249
|
+
const validation = Joi10.object({
|
|
4250
|
+
email: Joi10.string().email().required(),
|
|
4251
|
+
app: Joi10.string().required(),
|
|
4252
|
+
role: Joi10.string().hex().required(),
|
|
4253
|
+
roleName: Joi10.string().required(),
|
|
4254
|
+
org: Joi10.string().hex().optional().optional().allow("", null),
|
|
4255
|
+
orgName: Joi10.string().optional().optional().allow("", null)
|
|
4014
4256
|
});
|
|
4015
4257
|
const { error } = validation.validate(req.body);
|
|
4016
4258
|
if (error) {
|
|
4017
|
-
next(new
|
|
4259
|
+
next(new BadRequestError20(error.message));
|
|
4018
4260
|
return;
|
|
4019
4261
|
}
|
|
4020
4262
|
const email = req.body.email ?? "";
|
|
@@ -4042,10 +4284,10 @@ function useVerificationController() {
|
|
|
4042
4284
|
}
|
|
4043
4285
|
async function createForgetPassword(req, res, next) {
|
|
4044
4286
|
const email = req.body.email || "";
|
|
4045
|
-
const validation =
|
|
4287
|
+
const validation = Joi10.string().email().required();
|
|
4046
4288
|
const { error } = validation.validate(email);
|
|
4047
4289
|
if (error) {
|
|
4048
|
-
next(new
|
|
4290
|
+
next(new BadRequestError20(error.message));
|
|
4049
4291
|
return;
|
|
4050
4292
|
}
|
|
4051
4293
|
try {
|
|
@@ -4055,25 +4297,25 @@ function useVerificationController() {
|
|
|
4055
4297
|
});
|
|
4056
4298
|
return;
|
|
4057
4299
|
} catch (error2) {
|
|
4058
|
-
if (error2 instanceof
|
|
4300
|
+
if (error2 instanceof AppError8) {
|
|
4059
4301
|
next(error2);
|
|
4060
4302
|
} else {
|
|
4061
|
-
next(new
|
|
4303
|
+
next(new InternalServerError16("An unexpected error occurred"));
|
|
4062
4304
|
}
|
|
4063
4305
|
}
|
|
4064
4306
|
}
|
|
4065
4307
|
async function getVerifications(req, res, next) {
|
|
4066
|
-
const validation =
|
|
4067
|
-
status:
|
|
4068
|
-
search:
|
|
4069
|
-
page:
|
|
4070
|
-
type:
|
|
4071
|
-
email:
|
|
4072
|
-
app:
|
|
4308
|
+
const validation = Joi10.object({
|
|
4309
|
+
status: Joi10.string().required(),
|
|
4310
|
+
search: Joi10.string().optional().allow("", null),
|
|
4311
|
+
page: Joi10.number().required(),
|
|
4312
|
+
type: Joi10.string().optional().allow("", null),
|
|
4313
|
+
email: Joi10.string().optional().allow("", null),
|
|
4314
|
+
app: Joi10.string().optional().allow("", null)
|
|
4073
4315
|
});
|
|
4074
4316
|
const { error } = validation.validate(req.query);
|
|
4075
4317
|
if (error) {
|
|
4076
|
-
next(new
|
|
4318
|
+
next(new BadRequestError20(error.message));
|
|
4077
4319
|
return;
|
|
4078
4320
|
}
|
|
4079
4321
|
const status = req.query.status ?? "";
|
|
@@ -4104,10 +4346,10 @@ function useVerificationController() {
|
|
|
4104
4346
|
}
|
|
4105
4347
|
async function verify(req, res, next) {
|
|
4106
4348
|
const id = req.params.id || "";
|
|
4107
|
-
const validation =
|
|
4349
|
+
const validation = Joi10.string().hex().required();
|
|
4108
4350
|
const { error } = validation.validate(id);
|
|
4109
4351
|
if (error) {
|
|
4110
|
-
next(new
|
|
4352
|
+
next(new BadRequestError20(error.message));
|
|
4111
4353
|
return;
|
|
4112
4354
|
}
|
|
4113
4355
|
try {
|
|
@@ -4120,10 +4362,10 @@ function useVerificationController() {
|
|
|
4120
4362
|
}
|
|
4121
4363
|
async function cancelUserInvitation(req, res, next) {
|
|
4122
4364
|
const otpId = req.params.id || "";
|
|
4123
|
-
const validation =
|
|
4365
|
+
const validation = Joi10.string().hex().required();
|
|
4124
4366
|
const { error } = validation.validate(otpId);
|
|
4125
4367
|
if (error) {
|
|
4126
|
-
next(new
|
|
4368
|
+
next(new BadRequestError20(error.message));
|
|
4127
4369
|
return;
|
|
4128
4370
|
}
|
|
4129
4371
|
try {
|
|
@@ -4145,34 +4387,34 @@ function useVerificationController() {
|
|
|
4145
4387
|
}
|
|
4146
4388
|
|
|
4147
4389
|
// src/resources/address/address.model.ts
|
|
4148
|
-
import { BadRequestError as
|
|
4149
|
-
import
|
|
4390
|
+
import { BadRequestError as BadRequestError21 } from "@eeplatform/nodejs-utils";
|
|
4391
|
+
import Joi11 from "joi";
|
|
4150
4392
|
import { ObjectId as ObjectId14 } from "mongodb";
|
|
4151
|
-
var addressSchema =
|
|
4152
|
-
type:
|
|
4153
|
-
user:
|
|
4154
|
-
org:
|
|
4155
|
-
country:
|
|
4156
|
-
address:
|
|
4157
|
-
continuedAddress:
|
|
4158
|
-
city:
|
|
4159
|
-
province:
|
|
4160
|
-
postalCode:
|
|
4161
|
-
taxId:
|
|
4393
|
+
var addressSchema = Joi11.object({
|
|
4394
|
+
type: Joi11.string().required(),
|
|
4395
|
+
user: Joi11.string().hex().optional().allow("", null),
|
|
4396
|
+
org: Joi11.string().hex().optional().allow("", null),
|
|
4397
|
+
country: Joi11.string().required(),
|
|
4398
|
+
address: Joi11.string().required(),
|
|
4399
|
+
continuedAddress: Joi11.string().optional().allow("", null),
|
|
4400
|
+
city: Joi11.string().required(),
|
|
4401
|
+
province: Joi11.string().required(),
|
|
4402
|
+
postalCode: Joi11.string().required(),
|
|
4403
|
+
taxId: Joi11.string().optional().allow("", null)
|
|
4162
4404
|
});
|
|
4163
4405
|
function MAddress(value) {
|
|
4164
4406
|
if (value.user) {
|
|
4165
4407
|
try {
|
|
4166
4408
|
value.user = new ObjectId14(value.user);
|
|
4167
4409
|
} catch (error) {
|
|
4168
|
-
throw new
|
|
4410
|
+
throw new BadRequestError21("Invalid user ID.");
|
|
4169
4411
|
}
|
|
4170
4412
|
}
|
|
4171
4413
|
if (value.org) {
|
|
4172
4414
|
try {
|
|
4173
4415
|
value.org = new ObjectId14(value.org);
|
|
4174
4416
|
} catch (error) {
|
|
4175
|
-
throw new
|
|
4417
|
+
throw new BadRequestError21("Invalid org ID.");
|
|
4176
4418
|
}
|
|
4177
4419
|
}
|
|
4178
4420
|
return {
|
|
@@ -4191,7 +4433,7 @@ function MAddress(value) {
|
|
|
4191
4433
|
|
|
4192
4434
|
// src/resources/address/address.repository.ts
|
|
4193
4435
|
import {
|
|
4194
|
-
BadRequestError as
|
|
4436
|
+
BadRequestError as BadRequestError22,
|
|
4195
4437
|
useAtlas as useAtlas12,
|
|
4196
4438
|
useCache as useCache10,
|
|
4197
4439
|
makeCacheKey as makeCacheKey9,
|
|
@@ -4201,7 +4443,7 @@ import { ObjectId as ObjectId15 } from "mongodb";
|
|
|
4201
4443
|
function useAddressRepo() {
|
|
4202
4444
|
const db = useAtlas12.getDb();
|
|
4203
4445
|
if (!db) {
|
|
4204
|
-
throw new
|
|
4446
|
+
throw new BadRequestError22("Unable to connect to server.");
|
|
4205
4447
|
}
|
|
4206
4448
|
const namespace_collection = "addresses";
|
|
4207
4449
|
const collection = db.collection(namespace_collection);
|
|
@@ -4227,7 +4469,7 @@ function useAddressRepo() {
|
|
|
4227
4469
|
{ key: { orgId: 1 } }
|
|
4228
4470
|
]);
|
|
4229
4471
|
} catch (error) {
|
|
4230
|
-
throw new
|
|
4472
|
+
throw new BadRequestError22("Failed to create index on address.");
|
|
4231
4473
|
}
|
|
4232
4474
|
}
|
|
4233
4475
|
async function add(value, session) {
|
|
@@ -4237,1519 +4479,210 @@ function useAddressRepo() {
|
|
|
4237
4479
|
delCachedData();
|
|
4238
4480
|
return res.insertedId;
|
|
4239
4481
|
} catch (error) {
|
|
4240
|
-
throw new
|
|
4482
|
+
throw new BadRequestError22("Failed to create address.");
|
|
4241
4483
|
}
|
|
4242
4484
|
}
|
|
4243
4485
|
async function updateById(_id, value, session) {
|
|
4244
4486
|
try {
|
|
4245
|
-
_id = new ObjectId15(_id);
|
|
4246
|
-
} catch (error) {
|
|
4247
|
-
throw new
|
|
4248
|
-
}
|
|
4249
|
-
if (value.org) {
|
|
4250
|
-
try {
|
|
4251
|
-
value.org = new ObjectId15(value.org);
|
|
4252
|
-
} catch (error) {
|
|
4253
|
-
throw new
|
|
4254
|
-
}
|
|
4255
|
-
}
|
|
4256
|
-
try {
|
|
4257
|
-
await collection.updateOne(
|
|
4258
|
-
{ _id },
|
|
4259
|
-
{ $set: value },
|
|
4260
|
-
{ session, upsert: true }
|
|
4261
|
-
);
|
|
4262
|
-
delCachedData();
|
|
4263
|
-
return "Successfully updated address.";
|
|
4264
|
-
} catch (error) {
|
|
4265
|
-
throw new BadRequestError20("Failed to update address.");
|
|
4266
|
-
}
|
|
4267
|
-
}
|
|
4268
|
-
async function getByUserId(user) {
|
|
4269
|
-
try {
|
|
4270
|
-
user = new ObjectId15(user);
|
|
4271
|
-
} catch (error) {
|
|
4272
|
-
throw new BadRequestError20("Invalid user ID.");
|
|
4273
|
-
}
|
|
4274
|
-
const cacheKey = makeCacheKey9(namespace_collection, { user: String(user) });
|
|
4275
|
-
try {
|
|
4276
|
-
const cached = await getCache(cacheKey);
|
|
4277
|
-
if (cached) {
|
|
4278
|
-
logger12.log({
|
|
4279
|
-
level: "info",
|
|
4280
|
-
message: `Cache hit for getByUserId address: ${cacheKey}`
|
|
4281
|
-
});
|
|
4282
|
-
return cached;
|
|
4283
|
-
}
|
|
4284
|
-
const data = await collection.findOne({ user });
|
|
4285
|
-
if (data) {
|
|
4286
|
-
setCache(cacheKey, data, 300).then(() => {
|
|
4287
|
-
logger12.log({
|
|
4288
|
-
level: "info",
|
|
4289
|
-
message: `Cache set for address by user ID: ${cacheKey}`
|
|
4290
|
-
});
|
|
4291
|
-
}).catch((err) => {
|
|
4292
|
-
logger12.log({
|
|
4293
|
-
level: "error",
|
|
4294
|
-
message: `Failed to set cache for address by user ID: ${err.message}`
|
|
4295
|
-
});
|
|
4296
|
-
});
|
|
4297
|
-
}
|
|
4298
|
-
return data;
|
|
4299
|
-
} catch (error) {
|
|
4300
|
-
throw new BadRequestError20("Failed to get address by ID.");
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
async function getByOrgId(org) {
|
|
4304
|
-
try {
|
|
4305
|
-
org = new ObjectId15(org);
|
|
4306
|
-
} catch (error) {
|
|
4307
|
-
throw new BadRequestError20("Invalid orgId.");
|
|
4308
|
-
}
|
|
4309
|
-
const cacheKey = makeCacheKey9(namespace_collection, { org: String(org) });
|
|
4310
|
-
try {
|
|
4311
|
-
const cached = await getCache(cacheKey);
|
|
4312
|
-
if (cached) {
|
|
4313
|
-
logger12.log({
|
|
4314
|
-
level: "info",
|
|
4315
|
-
message: `Cache hit for getByOrgId address: ${cacheKey}`
|
|
4316
|
-
});
|
|
4317
|
-
return cached;
|
|
4318
|
-
}
|
|
4319
|
-
const data = await collection.findOne({ org });
|
|
4320
|
-
if (data) {
|
|
4321
|
-
setCache(cacheKey, data, 300).then(() => {
|
|
4322
|
-
logger12.log({
|
|
4323
|
-
level: "info",
|
|
4324
|
-
message: `Cache set for address by org ID: ${cacheKey}`
|
|
4325
|
-
});
|
|
4326
|
-
}).catch((err) => {
|
|
4327
|
-
logger12.log({
|
|
4328
|
-
level: "error",
|
|
4329
|
-
message: `Failed to set cache for address by org ID: ${err.message}`
|
|
4330
|
-
});
|
|
4331
|
-
});
|
|
4332
|
-
}
|
|
4333
|
-
return data;
|
|
4334
|
-
} catch (error) {
|
|
4335
|
-
throw new BadRequestError20("Failed to get address by orgId.");
|
|
4336
|
-
}
|
|
4337
|
-
}
|
|
4338
|
-
return {
|
|
4339
|
-
createIndex,
|
|
4340
|
-
add,
|
|
4341
|
-
getByUserId,
|
|
4342
|
-
getByOrgId,
|
|
4343
|
-
updateById
|
|
4344
|
-
};
|
|
4345
|
-
}
|
|
4346
|
-
|
|
4347
|
-
// src/resources/address/address.controller.ts
|
|
4348
|
-
import { BadRequestError as BadRequestError21, NotFoundError as NotFoundError4 } from "@eeplatform/nodejs-utils";
|
|
4349
|
-
import Joi10 from "joi";
|
|
4350
|
-
function useAddressController() {
|
|
4351
|
-
const {
|
|
4352
|
-
add: _add,
|
|
4353
|
-
getByUserId: _getByUserId,
|
|
4354
|
-
getByOrgId: _getByOrgId,
|
|
4355
|
-
updateById: _updateById
|
|
4356
|
-
} = useAddressRepo();
|
|
4357
|
-
async function add(req, res, next) {
|
|
4358
|
-
const value = req.body;
|
|
4359
|
-
const validation = Joi10.object({
|
|
4360
|
-
type: Joi10.string().required(),
|
|
4361
|
-
user: Joi10.string().hex().optional().allow("", null),
|
|
4362
|
-
org: Joi10.string().hex().optional().allow("", null),
|
|
4363
|
-
country: Joi10.string().required(),
|
|
4364
|
-
address: Joi10.string().required(),
|
|
4365
|
-
continuedAddress: Joi10.string().optional().allow("", null),
|
|
4366
|
-
city: Joi10.string().required(),
|
|
4367
|
-
province: Joi10.string().required(),
|
|
4368
|
-
postalCode: Joi10.string().required(),
|
|
4369
|
-
taxId: Joi10.string().optional().allow("", null)
|
|
4370
|
-
});
|
|
4371
|
-
const { error } = validation.validate(value);
|
|
4372
|
-
if (error) {
|
|
4373
|
-
next(new BadRequestError21(error.message));
|
|
4374
|
-
}
|
|
4375
|
-
try {
|
|
4376
|
-
const value2 = req.body;
|
|
4377
|
-
const id = await _add(value2);
|
|
4378
|
-
res.json({ message: "Successfully added subscription.", id });
|
|
4379
|
-
return;
|
|
4380
|
-
} catch (error2) {
|
|
4381
|
-
next(error2);
|
|
4382
|
-
}
|
|
4383
|
-
}
|
|
4384
|
-
async function updateById(req, res, next) {
|
|
4385
|
-
const id = req.params.id ?? "";
|
|
4386
|
-
const value = req.body;
|
|
4387
|
-
const validation = Joi10.object({
|
|
4388
|
-
id: Joi10.string().hex().required(),
|
|
4389
|
-
country: Joi10.string().required(),
|
|
4390
|
-
address: Joi10.string().required(),
|
|
4391
|
-
continuedAddress: Joi10.string().optional().allow("", null),
|
|
4392
|
-
city: Joi10.string().required(),
|
|
4393
|
-
province: Joi10.string().required(),
|
|
4394
|
-
postalCode: Joi10.string().required(),
|
|
4395
|
-
taxId: Joi10.string().optional().allow("", null),
|
|
4396
|
-
org: Joi10.string().hex().optional().allow("", null)
|
|
4397
|
-
});
|
|
4398
|
-
const { error } = validation.validate({ id, ...value });
|
|
4399
|
-
if (error) {
|
|
4400
|
-
next(new BadRequestError21(error.message));
|
|
4401
|
-
return;
|
|
4402
|
-
}
|
|
4403
|
-
try {
|
|
4404
|
-
const message = await _updateById(id, value);
|
|
4405
|
-
res.json({ message });
|
|
4406
|
-
return;
|
|
4407
|
-
} catch (error2) {
|
|
4408
|
-
next(error2);
|
|
4409
|
-
}
|
|
4410
|
-
}
|
|
4411
|
-
async function getByUserId(req, res, next) {
|
|
4412
|
-
const user = req.params.user;
|
|
4413
|
-
const validation = Joi10.string().hex().required();
|
|
4414
|
-
const { error } = validation.validate(user);
|
|
4415
|
-
if (error) {
|
|
4416
|
-
next(new BadRequestError21(error.message));
|
|
4417
|
-
}
|
|
4418
|
-
try {
|
|
4419
|
-
const address = await _getByUserId(user);
|
|
4420
|
-
if (!address) {
|
|
4421
|
-
next(new NotFoundError4("Address not found."));
|
|
4422
|
-
return;
|
|
4423
|
-
}
|
|
4424
|
-
res.json(address);
|
|
4425
|
-
return;
|
|
4426
|
-
} catch (error2) {
|
|
4427
|
-
next(error2);
|
|
4428
|
-
}
|
|
4429
|
-
}
|
|
4430
|
-
async function getByOrgId(req, res, next) {
|
|
4431
|
-
const id = req.params.id;
|
|
4432
|
-
const validation = Joi10.string().hex().required();
|
|
4433
|
-
const { error } = validation.validate(id);
|
|
4434
|
-
if (error) {
|
|
4435
|
-
next(new BadRequestError21(error.message));
|
|
4436
|
-
}
|
|
4437
|
-
try {
|
|
4438
|
-
const address = await _getByOrgId(id);
|
|
4439
|
-
if (!address) {
|
|
4440
|
-
next(new NotFoundError4("Address not found."));
|
|
4441
|
-
return;
|
|
4442
|
-
}
|
|
4443
|
-
res.json(address);
|
|
4444
|
-
return;
|
|
4445
|
-
} catch (error2) {
|
|
4446
|
-
next(error2);
|
|
4447
|
-
}
|
|
4448
|
-
}
|
|
4449
|
-
return {
|
|
4450
|
-
add,
|
|
4451
|
-
getByUserId,
|
|
4452
|
-
getByOrgId,
|
|
4453
|
-
updateById
|
|
4454
|
-
};
|
|
4455
|
-
}
|
|
4456
|
-
|
|
4457
|
-
// src/resources/member/member.controller.ts
|
|
4458
|
-
import Joi11 from "joi";
|
|
4459
|
-
import { BadRequestError as BadRequestError22 } from "@eeplatform/nodejs-utils";
|
|
4460
|
-
function useMemberController() {
|
|
4461
|
-
const {
|
|
4462
|
-
getByUserId: _getByUserId,
|
|
4463
|
-
getAll: _getAll,
|
|
4464
|
-
getOrgsByMembership: _getOrgsByMembership,
|
|
4465
|
-
updateStatusByUserId: _updateStatusByUserId,
|
|
4466
|
-
getByUserType: _getByUserType
|
|
4467
|
-
} = useMemberRepo();
|
|
4468
|
-
async function getByUserId(req, res, next) {
|
|
4469
|
-
const userId = req.params.id;
|
|
4470
|
-
const validation = Joi11.object({
|
|
4471
|
-
id: Joi11.string().hex().required()
|
|
4472
|
-
});
|
|
4473
|
-
const { error } = validation.validate({ id: userId });
|
|
4474
|
-
if (error) {
|
|
4475
|
-
next(new BadRequestError22(error.message));
|
|
4476
|
-
return;
|
|
4477
|
-
}
|
|
4478
|
-
try {
|
|
4479
|
-
const member = await _getByUserId(userId);
|
|
4480
|
-
if (!member) {
|
|
4481
|
-
res.status(404).json({ message: "Member not found." });
|
|
4482
|
-
return;
|
|
4483
|
-
}
|
|
4484
|
-
res.json(member);
|
|
4485
|
-
} catch (error2) {
|
|
4486
|
-
next(error2);
|
|
4487
|
-
}
|
|
4488
|
-
}
|
|
4489
|
-
async function getByUserType(req, res, next) {
|
|
4490
|
-
const validation = Joi11.object({
|
|
4491
|
-
org: Joi11.string().hex().optional().allow("", null),
|
|
4492
|
-
user: Joi11.string().hex().required(),
|
|
4493
|
-
type: Joi11.string().required()
|
|
4494
|
-
});
|
|
4495
|
-
const { error } = validation.validate({ ...req.params, ...req.query });
|
|
4496
|
-
if (error) {
|
|
4497
|
-
next(new BadRequestError22(error.message));
|
|
4498
|
-
return;
|
|
4499
|
-
}
|
|
4500
|
-
const orgId = req.query.org;
|
|
4501
|
-
const userId = req.params.user;
|
|
4502
|
-
const type = req.params.type;
|
|
4503
|
-
try {
|
|
4504
|
-
const member = await _getByUserType(userId, type, orgId);
|
|
4505
|
-
if (!member) {
|
|
4506
|
-
res.status(404).json({ message: "Member not found." });
|
|
4507
|
-
return;
|
|
4508
|
-
}
|
|
4509
|
-
res.json(member);
|
|
4510
|
-
} catch (error2) {
|
|
4511
|
-
next(error2);
|
|
4512
|
-
}
|
|
4513
|
-
}
|
|
4514
|
-
async function getAll(req, res, next) {
|
|
4515
|
-
const limit = Number(req.query.limit) ?? 10;
|
|
4516
|
-
const search = req.query.search ?? "";
|
|
4517
|
-
const page = Number(req.query.page) ?? 1;
|
|
4518
|
-
const user = req.query.user ?? "";
|
|
4519
|
-
const org = req.query.org ?? "";
|
|
4520
|
-
const type = req.query.type ?? "main";
|
|
4521
|
-
const status = req.query.status ?? "active";
|
|
4522
|
-
const validation = Joi11.object({
|
|
4523
|
-
limit: Joi11.number().min(10).max(50).required(),
|
|
4524
|
-
search: Joi11.string().optional().allow("", null),
|
|
4525
|
-
page: Joi11.number().required(),
|
|
4526
|
-
user: Joi11.string().hex().optional().allow("", null),
|
|
4527
|
-
org: Joi11.string().hex().optional().allow("", null),
|
|
4528
|
-
type: Joi11.string().required(),
|
|
4529
|
-
status: Joi11.string().required()
|
|
4530
|
-
});
|
|
4531
|
-
const { error } = validation.validate({
|
|
4532
|
-
search,
|
|
4533
|
-
page,
|
|
4534
|
-
user,
|
|
4535
|
-
org,
|
|
4536
|
-
type,
|
|
4537
|
-
limit,
|
|
4538
|
-
status
|
|
4539
|
-
});
|
|
4540
|
-
if (error) {
|
|
4541
|
-
next(new BadRequestError22(error.message));
|
|
4542
|
-
return;
|
|
4543
|
-
}
|
|
4544
|
-
try {
|
|
4545
|
-
const items = await _getAll({
|
|
4546
|
-
search,
|
|
4547
|
-
page,
|
|
4548
|
-
user,
|
|
4549
|
-
org,
|
|
4550
|
-
type,
|
|
4551
|
-
limit,
|
|
4552
|
-
status
|
|
4553
|
-
});
|
|
4554
|
-
res.json(items);
|
|
4555
|
-
return;
|
|
4556
|
-
} catch (error2) {
|
|
4557
|
-
next(error2);
|
|
4558
|
-
}
|
|
4559
|
-
}
|
|
4560
|
-
async function getOrgsByMembership(req, res, next) {
|
|
4561
|
-
const limit = Number(req.query.limit) ?? 10;
|
|
4562
|
-
const search = req.query.search ?? "";
|
|
4563
|
-
const page = Number(req.query.page) ?? 1;
|
|
4564
|
-
const user = req.query.user ?? "";
|
|
4565
|
-
const validation = Joi11.object({
|
|
4566
|
-
limit: Joi11.number().min(10).max(50).required(),
|
|
4567
|
-
search: Joi11.string().optional().allow("", null),
|
|
4568
|
-
page: Joi11.number().required(),
|
|
4569
|
-
user: Joi11.string().hex().optional().allow("", null)
|
|
4570
|
-
});
|
|
4571
|
-
const { error } = validation.validate({
|
|
4572
|
-
search,
|
|
4573
|
-
page,
|
|
4574
|
-
user,
|
|
4575
|
-
limit
|
|
4576
|
-
});
|
|
4577
|
-
if (error) {
|
|
4578
|
-
next(new BadRequestError22(error.message));
|
|
4579
|
-
}
|
|
4580
|
-
try {
|
|
4581
|
-
const items = await _getOrgsByMembership({
|
|
4582
|
-
search,
|
|
4583
|
-
page,
|
|
4584
|
-
user,
|
|
4585
|
-
limit
|
|
4586
|
-
});
|
|
4587
|
-
res.json(items);
|
|
4588
|
-
return;
|
|
4589
|
-
} catch (error2) {
|
|
4590
|
-
next(error2);
|
|
4591
|
-
}
|
|
4592
|
-
}
|
|
4593
|
-
async function updateStatusByUserId(req, res, next) {
|
|
4594
|
-
const validation = Joi11.object({
|
|
4595
|
-
id: Joi11.string().hex().required(),
|
|
4596
|
-
status: Joi11.string().valid("active", "suspended", "deleted").required()
|
|
4597
|
-
});
|
|
4598
|
-
const { error } = validation.validate(req.params);
|
|
4599
|
-
if (error) {
|
|
4600
|
-
next(new BadRequestError22(error.message));
|
|
4601
|
-
return;
|
|
4602
|
-
}
|
|
4603
|
-
const id = req.params.id;
|
|
4604
|
-
const status = req.params.status;
|
|
4605
|
-
try {
|
|
4606
|
-
const message = await _updateStatusByUserId(id, status);
|
|
4607
|
-
res.json({ message });
|
|
4608
|
-
} catch (error2) {
|
|
4609
|
-
next(error2);
|
|
4610
|
-
}
|
|
4611
|
-
}
|
|
4612
|
-
return {
|
|
4613
|
-
getByUserId,
|
|
4614
|
-
getAll,
|
|
4615
|
-
getOrgsByMembership,
|
|
4616
|
-
updateStatusByUserId,
|
|
4617
|
-
getByUserType
|
|
4618
|
-
};
|
|
4619
|
-
}
|
|
4620
|
-
|
|
4621
|
-
// src/resources/building/building.model.ts
|
|
4622
|
-
import { BadRequestError as BadRequestError23, logger as logger13 } from "@eeplatform/nodejs-utils";
|
|
4623
|
-
import Joi12 from "joi";
|
|
4624
|
-
import { ObjectId as ObjectId16 } from "mongodb";
|
|
4625
|
-
var schemaBuilding = Joi12.object({
|
|
4626
|
-
_id: Joi12.string().hex().optional(),
|
|
4627
|
-
school: Joi12.string().hex().required(),
|
|
4628
|
-
serial: Joi12.string().optional().allow("", null),
|
|
4629
|
-
name: Joi12.string().required(),
|
|
4630
|
-
levels: Joi12.number().integer().min(1).required(),
|
|
4631
|
-
createdAt: Joi12.date().optional().allow("", null),
|
|
4632
|
-
updatedAt: Joi12.date().optional().allow("", null),
|
|
4633
|
-
deletedAt: Joi12.date().optional().allow("", null),
|
|
4634
|
-
status: Joi12.string().optional().allow("", null)
|
|
4635
|
-
});
|
|
4636
|
-
var schemaBuildingUnit = Joi12.object({
|
|
4637
|
-
_id: Joi12.string().hex().optional(),
|
|
4638
|
-
school: Joi12.string().hex().required(),
|
|
4639
|
-
name: Joi12.string().optional().allow("", null),
|
|
4640
|
-
building: Joi12.string().hex().required(),
|
|
4641
|
-
buildingName: Joi12.string().optional().allow("", null),
|
|
4642
|
-
level: Joi12.number().integer().min(1).required(),
|
|
4643
|
-
category: Joi12.string().required(),
|
|
4644
|
-
type: Joi12.string().required(),
|
|
4645
|
-
seating_capacity: Joi12.number().integer().min(0).required(),
|
|
4646
|
-
standing_capacity: Joi12.number().integer().min(0).required(),
|
|
4647
|
-
description: Joi12.string().optional().allow("", null),
|
|
4648
|
-
unit_of_measurement: Joi12.string().valid("sqm").required(),
|
|
4649
|
-
area: Joi12.number().positive().required(),
|
|
4650
|
-
status: Joi12.string().optional().allow("", null)
|
|
4651
|
-
});
|
|
4652
|
-
var schemaUpdateOptions = Joi12.object({
|
|
4653
|
-
name: Joi12.string().optional().allow("", null),
|
|
4654
|
-
building: Joi12.string().hex().optional().allow("", null),
|
|
4655
|
-
buildingName: Joi12.string().optional().allow("", null),
|
|
4656
|
-
level: Joi12.number().integer().min(1).optional().allow("", null),
|
|
4657
|
-
category: Joi12.string().optional().allow("", null),
|
|
4658
|
-
type: Joi12.string().optional().allow("", null),
|
|
4659
|
-
seating_capacity: Joi12.number().integer().min(0).optional().allow("", null),
|
|
4660
|
-
standing_capacity: Joi12.number().integer().min(0).optional().allow("", null),
|
|
4661
|
-
area: Joi12.number().positive().optional().allow("", null)
|
|
4662
|
-
});
|
|
4663
|
-
function MBuilding(value) {
|
|
4664
|
-
const { error } = schemaBuilding.validate(value);
|
|
4665
|
-
if (error) {
|
|
4666
|
-
logger13.info(`Building Model: ${error.message}`);
|
|
4667
|
-
throw new BadRequestError23(error.message);
|
|
4668
|
-
}
|
|
4669
|
-
if (value._id && typeof value._id === "string") {
|
|
4670
|
-
try {
|
|
4671
|
-
value._id = new ObjectId16(value._id);
|
|
4672
|
-
} catch (error2) {
|
|
4673
|
-
throw new BadRequestError23("Invalid _id format");
|
|
4674
|
-
}
|
|
4675
|
-
}
|
|
4676
|
-
try {
|
|
4677
|
-
value.school = new ObjectId16(value.school);
|
|
4678
|
-
} catch (error2) {
|
|
4679
|
-
throw new BadRequestError23("Invalid school format");
|
|
4680
|
-
}
|
|
4681
|
-
return {
|
|
4682
|
-
_id: value._id ?? void 0,
|
|
4683
|
-
school: value.school,
|
|
4684
|
-
serial: value.serial ?? "",
|
|
4685
|
-
name: value.name ?? "",
|
|
4686
|
-
levels: value.levels ?? 0,
|
|
4687
|
-
status: value.status ?? "active",
|
|
4688
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
4689
|
-
updatedAt: value.updatedAt ?? "",
|
|
4690
|
-
deletedAt: value.deletedAt ?? ""
|
|
4691
|
-
};
|
|
4692
|
-
}
|
|
4693
|
-
function MBuildingUnit(value) {
|
|
4694
|
-
const { error } = schemaBuildingUnit.validate(value);
|
|
4695
|
-
if (error) {
|
|
4696
|
-
logger13.info(`Building Unit Model: ${error.message}`);
|
|
4697
|
-
throw new BadRequestError23(error.message);
|
|
4698
|
-
}
|
|
4699
|
-
if (value._id && typeof value._id === "string") {
|
|
4700
|
-
try {
|
|
4701
|
-
value._id = new ObjectId16(value._id);
|
|
4702
|
-
} catch (error2) {
|
|
4703
|
-
throw new BadRequestError23("Invalid ID");
|
|
4704
|
-
}
|
|
4705
|
-
}
|
|
4706
|
-
try {
|
|
4707
|
-
value.school = new ObjectId16(value.school);
|
|
4708
|
-
} catch (error2) {
|
|
4709
|
-
throw new BadRequestError23("Invalid school ID");
|
|
4710
|
-
}
|
|
4711
|
-
try {
|
|
4712
|
-
value.building = new ObjectId16(value.building);
|
|
4713
|
-
} catch (error2) {
|
|
4714
|
-
throw new BadRequestError23("Invalid building ID");
|
|
4715
|
-
}
|
|
4716
|
-
return {
|
|
4717
|
-
_id: value._id ?? void 0,
|
|
4718
|
-
school: value.school,
|
|
4719
|
-
name: value.name ?? "",
|
|
4720
|
-
building: value.building,
|
|
4721
|
-
buildingName: value.buildingName ?? "",
|
|
4722
|
-
level: value.level ?? 0,
|
|
4723
|
-
category: value.category ?? "",
|
|
4724
|
-
type: value.type ?? "",
|
|
4725
|
-
seating_capacity: value.seating_capacity ?? 0,
|
|
4726
|
-
standing_capacity: value.standing_capacity ?? 0,
|
|
4727
|
-
description: value.description ?? "",
|
|
4728
|
-
unit_of_measurement: value.unit_of_measurement ?? "sqm",
|
|
4729
|
-
area: value.area ?? 0,
|
|
4730
|
-
status: value.status ?? "active",
|
|
4731
|
-
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
4732
|
-
updatedAt: value.updatedAt ?? "",
|
|
4733
|
-
deletedAt: value.deletedAt ?? ""
|
|
4734
|
-
};
|
|
4735
|
-
}
|
|
4736
|
-
|
|
4737
|
-
// src/resources/building/building.repository.ts
|
|
4738
|
-
import {
|
|
4739
|
-
AppError as AppError8,
|
|
4740
|
-
BadRequestError as BadRequestError24,
|
|
4741
|
-
InternalServerError as InternalServerError16,
|
|
4742
|
-
logger as logger14,
|
|
4743
|
-
makeCacheKey as makeCacheKey10,
|
|
4744
|
-
paginate as paginate6,
|
|
4745
|
-
useAtlas as useAtlas13,
|
|
4746
|
-
useCache as useCache11
|
|
4747
|
-
} from "@eeplatform/nodejs-utils";
|
|
4748
|
-
import { ObjectId as ObjectId17 } from "mongodb";
|
|
4749
|
-
function useBuildingRepo() {
|
|
4750
|
-
const db = useAtlas13.getDb();
|
|
4751
|
-
if (!db) {
|
|
4752
|
-
throw new Error("Unable to connect to server.");
|
|
4753
|
-
}
|
|
4754
|
-
const namespace_collection = "school.buildings";
|
|
4755
|
-
const collection = db.collection(namespace_collection);
|
|
4756
|
-
const { getCache, setCache, delNamespace } = useCache11(namespace_collection);
|
|
4757
|
-
async function createIndexes() {
|
|
4758
|
-
try {
|
|
4759
|
-
await collection.createIndexes([
|
|
4760
|
-
{ key: { name: 1 }, unique: true, name: "unique_name_index" },
|
|
4761
|
-
{ key: { school: 1 } },
|
|
4762
|
-
{ key: { status: 1 } }
|
|
4763
|
-
]);
|
|
4764
|
-
} catch (error) {
|
|
4765
|
-
throw new Error("Failed to create index on buildings.");
|
|
4766
|
-
}
|
|
4767
|
-
}
|
|
4768
|
-
async function add(value, session) {
|
|
4769
|
-
try {
|
|
4770
|
-
value = MBuilding(value);
|
|
4771
|
-
const res = await collection.insertOne(value, { session });
|
|
4772
|
-
delCachedData();
|
|
4773
|
-
return res.insertedId;
|
|
4774
|
-
} catch (error) {
|
|
4775
|
-
logger14.log({
|
|
4776
|
-
level: "error",
|
|
4777
|
-
message: error.message
|
|
4778
|
-
});
|
|
4779
|
-
if (error instanceof AppError8) {
|
|
4780
|
-
throw error;
|
|
4781
|
-
} else {
|
|
4782
|
-
const isDuplicated = error.message.includes("duplicate");
|
|
4783
|
-
if (isDuplicated) {
|
|
4784
|
-
throw new BadRequestError24("Building already exists.");
|
|
4785
|
-
}
|
|
4786
|
-
throw new Error("Failed to create building.");
|
|
4787
|
-
}
|
|
4788
|
-
}
|
|
4789
|
-
}
|
|
4790
|
-
async function updateById(_id, value, session) {
|
|
4791
|
-
try {
|
|
4792
|
-
_id = new ObjectId17(_id);
|
|
4793
|
-
} catch (error) {
|
|
4794
|
-
throw new BadRequestError24("Invalid ID.");
|
|
4795
|
-
}
|
|
4796
|
-
try {
|
|
4797
|
-
const res = await collection.updateOne(
|
|
4798
|
-
{ _id },
|
|
4799
|
-
{ $set: value },
|
|
4800
|
-
{ session }
|
|
4801
|
-
);
|
|
4802
|
-
delCachedData();
|
|
4803
|
-
return res;
|
|
4804
|
-
} catch (error) {
|
|
4805
|
-
logger14.log({
|
|
4806
|
-
level: "error",
|
|
4807
|
-
message: error.message
|
|
4808
|
-
});
|
|
4809
|
-
if (error instanceof AppError8) {
|
|
4810
|
-
throw error;
|
|
4811
|
-
} else {
|
|
4812
|
-
throw new Error("Failed to update building.");
|
|
4813
|
-
}
|
|
4814
|
-
}
|
|
4815
|
-
}
|
|
4816
|
-
async function getAll({
|
|
4817
|
-
search = "",
|
|
4818
|
-
page = 1,
|
|
4819
|
-
limit = 10,
|
|
4820
|
-
sort = {},
|
|
4821
|
-
school = "",
|
|
4822
|
-
status = "active"
|
|
4823
|
-
} = {}) {
|
|
4824
|
-
page = page > 0 ? page - 1 : 0;
|
|
4825
|
-
const query = {
|
|
4826
|
-
status
|
|
4827
|
-
};
|
|
4828
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
4829
|
-
if (search) {
|
|
4830
|
-
query.$text = { $search: search };
|
|
4831
|
-
}
|
|
4832
|
-
if (school) {
|
|
4833
|
-
try {
|
|
4834
|
-
query.school = new ObjectId17(school);
|
|
4835
|
-
} catch (error) {
|
|
4836
|
-
throw new BadRequestError24("Invalid school ID.");
|
|
4837
|
-
}
|
|
4838
|
-
}
|
|
4839
|
-
const cacheParams = {
|
|
4840
|
-
page,
|
|
4841
|
-
limit,
|
|
4842
|
-
sort: JSON.stringify(sort)
|
|
4843
|
-
};
|
|
4844
|
-
if (search)
|
|
4845
|
-
cacheParams.search = search;
|
|
4846
|
-
if (school)
|
|
4847
|
-
cacheParams.school = school;
|
|
4848
|
-
if (status !== "active")
|
|
4849
|
-
cacheParams.status = status;
|
|
4850
|
-
const cacheKey = makeCacheKey10(namespace_collection, cacheParams);
|
|
4851
|
-
logger14.log({
|
|
4852
|
-
level: "info",
|
|
4853
|
-
message: `Cache key for getAll buildings: ${cacheKey}`
|
|
4854
|
-
});
|
|
4855
|
-
try {
|
|
4856
|
-
const cached = await getCache(cacheKey);
|
|
4857
|
-
if (cached) {
|
|
4858
|
-
logger14.log({
|
|
4859
|
-
level: "info",
|
|
4860
|
-
message: `Cache hit for getAll buildings: ${cacheKey}`
|
|
4861
|
-
});
|
|
4862
|
-
return cached;
|
|
4863
|
-
}
|
|
4864
|
-
const items = await collection.aggregate([
|
|
4865
|
-
{ $match: query },
|
|
4866
|
-
{ $sort: sort },
|
|
4867
|
-
{ $skip: page * limit },
|
|
4868
|
-
{ $limit: limit }
|
|
4869
|
-
]).toArray();
|
|
4870
|
-
const length = await collection.countDocuments(query);
|
|
4871
|
-
const data = paginate6(items, page, limit, length);
|
|
4872
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
4873
|
-
logger14.log({
|
|
4874
|
-
level: "info",
|
|
4875
|
-
message: `Cache set for getAll buildings: ${cacheKey}`
|
|
4876
|
-
});
|
|
4877
|
-
}).catch((err) => {
|
|
4878
|
-
logger14.log({
|
|
4879
|
-
level: "error",
|
|
4880
|
-
message: `Failed to set cache for getAll buildings: ${err.message}`
|
|
4881
|
-
});
|
|
4882
|
-
});
|
|
4883
|
-
return data;
|
|
4884
|
-
} catch (error) {
|
|
4885
|
-
logger14.log({ level: "error", message: `${error}` });
|
|
4886
|
-
throw error;
|
|
4887
|
-
}
|
|
4888
|
-
}
|
|
4889
|
-
async function getById(_id) {
|
|
4890
|
-
try {
|
|
4891
|
-
_id = new ObjectId17(_id);
|
|
4892
|
-
} catch (error) {
|
|
4893
|
-
throw new BadRequestError24("Invalid ID.");
|
|
4894
|
-
}
|
|
4895
|
-
const cacheKey = makeCacheKey10(namespace_collection, { _id: String(_id) });
|
|
4896
|
-
try {
|
|
4897
|
-
const cached = await getCache(cacheKey);
|
|
4898
|
-
if (cached) {
|
|
4899
|
-
logger14.log({
|
|
4900
|
-
level: "info",
|
|
4901
|
-
message: `Cache hit for getById building: ${cacheKey}`
|
|
4902
|
-
});
|
|
4903
|
-
return cached;
|
|
4904
|
-
}
|
|
4905
|
-
const result = await collection.findOne({
|
|
4906
|
-
_id
|
|
4907
|
-
});
|
|
4908
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
4909
|
-
logger14.log({
|
|
4910
|
-
level: "info",
|
|
4911
|
-
message: `Cache set for building by id: ${cacheKey}`
|
|
4912
|
-
});
|
|
4913
|
-
}).catch((err) => {
|
|
4914
|
-
logger14.log({
|
|
4915
|
-
level: "error",
|
|
4916
|
-
message: `Failed to set cache for building by id: ${err.message}`
|
|
4917
|
-
});
|
|
4918
|
-
});
|
|
4919
|
-
return result;
|
|
4920
|
-
} catch (error) {
|
|
4921
|
-
if (error instanceof AppError8) {
|
|
4922
|
-
throw error;
|
|
4923
|
-
} else {
|
|
4924
|
-
throw new InternalServerError16("Failed to get building.");
|
|
4925
|
-
}
|
|
4926
|
-
}
|
|
4927
|
-
}
|
|
4928
|
-
async function deleteById(_id, session) {
|
|
4929
|
-
try {
|
|
4930
|
-
_id = new ObjectId17(_id);
|
|
4931
|
-
} catch (error) {
|
|
4932
|
-
throw new BadRequestError24("Invalid ID.");
|
|
4933
|
-
}
|
|
4934
|
-
try {
|
|
4935
|
-
const res = await collection.updateOne(
|
|
4936
|
-
{ _id },
|
|
4937
|
-
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
|
|
4938
|
-
);
|
|
4939
|
-
delCachedData();
|
|
4940
|
-
return res;
|
|
4941
|
-
} catch (error) {
|
|
4942
|
-
logger14.log({
|
|
4943
|
-
level: "error",
|
|
4944
|
-
message: error.message
|
|
4945
|
-
});
|
|
4946
|
-
if (error instanceof AppError8) {
|
|
4947
|
-
throw error;
|
|
4948
|
-
} else {
|
|
4949
|
-
throw new InternalServerError16("Failed to delete building.");
|
|
4950
|
-
}
|
|
4951
|
-
}
|
|
4952
|
-
}
|
|
4953
|
-
function delCachedData() {
|
|
4954
|
-
delNamespace().then(() => {
|
|
4955
|
-
logger14.log({
|
|
4956
|
-
level: "info",
|
|
4957
|
-
message: `Cache namespace cleared for ${namespace_collection}`
|
|
4958
|
-
});
|
|
4959
|
-
}).catch((err) => {
|
|
4960
|
-
logger14.log({
|
|
4961
|
-
level: "error",
|
|
4962
|
-
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
4963
|
-
});
|
|
4964
|
-
});
|
|
4965
|
-
}
|
|
4966
|
-
return {
|
|
4967
|
-
createIndexes,
|
|
4968
|
-
add,
|
|
4969
|
-
getAll,
|
|
4970
|
-
getById,
|
|
4971
|
-
updateById,
|
|
4972
|
-
deleteById
|
|
4973
|
-
};
|
|
4974
|
-
}
|
|
4975
|
-
|
|
4976
|
-
// src/resources/building/building.service.ts
|
|
4977
|
-
import {
|
|
4978
|
-
BadRequestError as BadRequestError26,
|
|
4979
|
-
NotFoundError as NotFoundError5,
|
|
4980
|
-
useAtlas as useAtlas15
|
|
4981
|
-
} from "@eeplatform/nodejs-utils";
|
|
4982
|
-
|
|
4983
|
-
// src/resources/building/building-unit.repository.ts
|
|
4984
|
-
import {
|
|
4985
|
-
AppError as AppError9,
|
|
4986
|
-
BadRequestError as BadRequestError25,
|
|
4987
|
-
InternalServerError as InternalServerError17,
|
|
4988
|
-
logger as logger15,
|
|
4989
|
-
makeCacheKey as makeCacheKey11,
|
|
4990
|
-
paginate as paginate7,
|
|
4991
|
-
useAtlas as useAtlas14,
|
|
4992
|
-
useCache as useCache12
|
|
4993
|
-
} from "@eeplatform/nodejs-utils";
|
|
4994
|
-
import { ObjectId as ObjectId18 } from "mongodb";
|
|
4995
|
-
function useBuildingUnitRepo() {
|
|
4996
|
-
const db = useAtlas14.getDb();
|
|
4997
|
-
if (!db) {
|
|
4998
|
-
throw new Error("Unable to connect to server.");
|
|
4999
|
-
}
|
|
5000
|
-
const namespace_collection = "school.building-units";
|
|
5001
|
-
const collection = db.collection(namespace_collection);
|
|
5002
|
-
const { getCache, setCache, delNamespace } = useCache12(namespace_collection);
|
|
5003
|
-
async function createIndexes() {
|
|
5004
|
-
try {
|
|
5005
|
-
await collection.createIndexes([
|
|
5006
|
-
{
|
|
5007
|
-
key: { name: 1, building: 1, level: 1 },
|
|
5008
|
-
unique: true,
|
|
5009
|
-
name: "unique_name_index"
|
|
5010
|
-
},
|
|
5011
|
-
{ key: { school: 1 } },
|
|
5012
|
-
{ key: { building: 1 } },
|
|
5013
|
-
{ key: { status: 1 } },
|
|
5014
|
-
{ key: { createdAt: 1 } },
|
|
5015
|
-
{
|
|
5016
|
-
key: {
|
|
5017
|
-
name: "text",
|
|
5018
|
-
buildingName: "text",
|
|
5019
|
-
category: "text",
|
|
5020
|
-
type: "text"
|
|
5021
|
-
}
|
|
5022
|
-
}
|
|
5023
|
-
]);
|
|
5024
|
-
} catch (error) {
|
|
5025
|
-
throw new Error("Failed to create index on building units.");
|
|
5026
|
-
}
|
|
5027
|
-
}
|
|
5028
|
-
function delCachedData() {
|
|
5029
|
-
delNamespace().then(() => {
|
|
5030
|
-
logger15.log({
|
|
5031
|
-
level: "info",
|
|
5032
|
-
message: `Cache namespace cleared for ${namespace_collection}`
|
|
5033
|
-
});
|
|
5034
|
-
}).catch((err) => {
|
|
5035
|
-
logger15.log({
|
|
5036
|
-
level: "error",
|
|
5037
|
-
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
5038
|
-
});
|
|
5039
|
-
});
|
|
5040
|
-
}
|
|
5041
|
-
async function add(value, session) {
|
|
5042
|
-
try {
|
|
5043
|
-
value = MBuildingUnit(value);
|
|
5044
|
-
const res = await collection.insertOne(value, { session });
|
|
5045
|
-
delCachedData();
|
|
5046
|
-
return res.insertedId;
|
|
5047
|
-
} catch (error) {
|
|
5048
|
-
logger15.log({
|
|
5049
|
-
level: "error",
|
|
5050
|
-
message: error.message
|
|
5051
|
-
});
|
|
5052
|
-
if (error instanceof AppError9) {
|
|
5053
|
-
throw error;
|
|
5054
|
-
} else {
|
|
5055
|
-
throw new Error("Failed to create building unit.");
|
|
5056
|
-
}
|
|
5057
|
-
}
|
|
5058
|
-
}
|
|
5059
|
-
async function updateById(_id, value, session) {
|
|
5060
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
5061
|
-
if (error) {
|
|
5062
|
-
throw new BadRequestError25(error.message);
|
|
5063
|
-
}
|
|
5064
|
-
try {
|
|
5065
|
-
_id = new ObjectId18(_id);
|
|
5066
|
-
} catch (error2) {
|
|
5067
|
-
throw new BadRequestError25("Invalid ID.");
|
|
5068
|
-
}
|
|
5069
|
-
try {
|
|
5070
|
-
const res = await collection.updateOne(
|
|
5071
|
-
{ _id },
|
|
5072
|
-
{ $set: value },
|
|
5073
|
-
{ session }
|
|
5074
|
-
);
|
|
5075
|
-
delCachedData();
|
|
5076
|
-
return res;
|
|
5077
|
-
} catch (error2) {
|
|
5078
|
-
logger15.log({
|
|
5079
|
-
level: "error",
|
|
5080
|
-
message: error2.message
|
|
5081
|
-
});
|
|
5082
|
-
if (error2 instanceof AppError9) {
|
|
5083
|
-
throw error2;
|
|
5084
|
-
} else {
|
|
5085
|
-
throw new Error("Failed to create building unit.");
|
|
5086
|
-
}
|
|
5087
|
-
}
|
|
5088
|
-
}
|
|
5089
|
-
async function updateByBuildingId(building, value, session) {
|
|
5090
|
-
const { error } = schemaUpdateOptions.validate(value);
|
|
5091
|
-
if (error) {
|
|
5092
|
-
throw new BadRequestError25(error.message);
|
|
5093
|
-
}
|
|
5094
|
-
try {
|
|
5095
|
-
building = new ObjectId18(building);
|
|
5096
|
-
} catch (error2) {
|
|
5097
|
-
throw new BadRequestError25("Invalid building ID.");
|
|
5098
|
-
}
|
|
5099
|
-
try {
|
|
5100
|
-
const res = await collection.updateMany(
|
|
5101
|
-
{ building },
|
|
5102
|
-
{ $set: value },
|
|
5103
|
-
{ session }
|
|
5104
|
-
);
|
|
5105
|
-
delCachedData();
|
|
5106
|
-
return res;
|
|
5107
|
-
} catch (error2) {
|
|
5108
|
-
logger15.log({
|
|
5109
|
-
level: "error",
|
|
5110
|
-
message: error2.message
|
|
5111
|
-
});
|
|
5112
|
-
if (error2 instanceof AppError9) {
|
|
5113
|
-
throw error2;
|
|
5114
|
-
} else {
|
|
5115
|
-
throw new Error("Failed to update building unit.");
|
|
5116
|
-
}
|
|
5117
|
-
}
|
|
5118
|
-
}
|
|
5119
|
-
async function getAll({
|
|
5120
|
-
search = "",
|
|
5121
|
-
page = 1,
|
|
5122
|
-
limit = 10,
|
|
5123
|
-
sort = {},
|
|
5124
|
-
school = "",
|
|
5125
|
-
building = "",
|
|
5126
|
-
status = "active"
|
|
5127
|
-
} = {}) {
|
|
5128
|
-
page = page > 0 ? page - 1 : 0;
|
|
5129
|
-
const query = {
|
|
5130
|
-
deletedAt: { $in: ["", null] },
|
|
5131
|
-
status: { $in: [status, "", null] }
|
|
5132
|
-
};
|
|
5133
|
-
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
5134
|
-
if (search) {
|
|
5135
|
-
query.$text = { $search: search };
|
|
5136
|
-
}
|
|
5137
|
-
if (school) {
|
|
5138
|
-
try {
|
|
5139
|
-
query.school = new ObjectId18(school);
|
|
5140
|
-
} catch (error) {
|
|
5141
|
-
throw new BadRequestError25("Invalid school ID.");
|
|
5142
|
-
}
|
|
5143
|
-
}
|
|
5144
|
-
if (building) {
|
|
5145
|
-
try {
|
|
5146
|
-
query.building = new ObjectId18(building);
|
|
5147
|
-
} catch (error) {
|
|
5148
|
-
throw new BadRequestError25("Invalid building ID.");
|
|
5149
|
-
}
|
|
5150
|
-
}
|
|
5151
|
-
const cacheParams = {
|
|
5152
|
-
page,
|
|
5153
|
-
limit,
|
|
5154
|
-
sort: JSON.stringify(sort)
|
|
5155
|
-
};
|
|
5156
|
-
if (search)
|
|
5157
|
-
cacheParams.search = search;
|
|
5158
|
-
if (school)
|
|
5159
|
-
cacheParams.school = school;
|
|
5160
|
-
if (building)
|
|
5161
|
-
cacheParams.building = building;
|
|
5162
|
-
if (status !== "active")
|
|
5163
|
-
cacheParams.status = status;
|
|
5164
|
-
const cacheKey = makeCacheKey11(namespace_collection, cacheParams);
|
|
5165
|
-
logger15.log({
|
|
5166
|
-
level: "info",
|
|
5167
|
-
message: `Cache key for getAll building units: ${cacheKey}`
|
|
5168
|
-
});
|
|
5169
|
-
try {
|
|
5170
|
-
const cached = await getCache(cacheKey);
|
|
5171
|
-
if (cached) {
|
|
5172
|
-
logger15.log({
|
|
5173
|
-
level: "info",
|
|
5174
|
-
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
5175
|
-
});
|
|
5176
|
-
return cached;
|
|
5177
|
-
}
|
|
5178
|
-
const items = await collection.aggregate([
|
|
5179
|
-
{ $match: query },
|
|
5180
|
-
{ $sort: sort },
|
|
5181
|
-
{ $skip: page * limit },
|
|
5182
|
-
{ $limit: limit }
|
|
5183
|
-
]).toArray();
|
|
5184
|
-
const length = await collection.countDocuments(query);
|
|
5185
|
-
const data = paginate7(items, page, limit, length);
|
|
5186
|
-
setCache(cacheKey, data, 600).then(() => {
|
|
5187
|
-
logger15.log({
|
|
5188
|
-
level: "info",
|
|
5189
|
-
message: `Cache set for getAll building units: ${cacheKey}`
|
|
5190
|
-
});
|
|
5191
|
-
}).catch((err) => {
|
|
5192
|
-
logger15.log({
|
|
5193
|
-
level: "error",
|
|
5194
|
-
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
5195
|
-
});
|
|
5196
|
-
});
|
|
5197
|
-
return data;
|
|
5198
|
-
} catch (error) {
|
|
5199
|
-
logger15.log({ level: "error", message: `${error}` });
|
|
5200
|
-
throw error;
|
|
5201
|
-
}
|
|
5202
|
-
}
|
|
5203
|
-
async function getById(_id) {
|
|
5204
|
-
try {
|
|
5205
|
-
_id = new ObjectId18(_id);
|
|
5206
|
-
} catch (error) {
|
|
5207
|
-
throw new BadRequestError25("Invalid ID.");
|
|
5208
|
-
}
|
|
5209
|
-
const cacheKey = makeCacheKey11(namespace_collection, { _id: String(_id) });
|
|
5210
|
-
try {
|
|
5211
|
-
const cached = await getCache(cacheKey);
|
|
5212
|
-
if (cached) {
|
|
5213
|
-
logger15.log({
|
|
5214
|
-
level: "info",
|
|
5215
|
-
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
5216
|
-
});
|
|
5217
|
-
return cached;
|
|
5218
|
-
}
|
|
5219
|
-
const result = await collection.findOne({
|
|
5220
|
-
_id,
|
|
5221
|
-
deletedAt: { $in: ["", null] }
|
|
5222
|
-
});
|
|
5223
|
-
if (!result) {
|
|
5224
|
-
throw new BadRequestError25("Building unit not found.");
|
|
5225
|
-
}
|
|
5226
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
5227
|
-
logger15.log({
|
|
5228
|
-
level: "info",
|
|
5229
|
-
message: `Cache set for building unit by id: ${cacheKey}`
|
|
5230
|
-
});
|
|
5231
|
-
}).catch((err) => {
|
|
5232
|
-
logger15.log({
|
|
5233
|
-
level: "error",
|
|
5234
|
-
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
5235
|
-
});
|
|
5236
|
-
});
|
|
5237
|
-
return result;
|
|
5238
|
-
} catch (error) {
|
|
5239
|
-
if (error instanceof AppError9) {
|
|
5240
|
-
throw error;
|
|
5241
|
-
} else {
|
|
5242
|
-
throw new InternalServerError17("Failed to get building unit.");
|
|
5243
|
-
}
|
|
5244
|
-
}
|
|
5245
|
-
}
|
|
5246
|
-
async function getByBuildingLevel(building, level) {
|
|
5247
|
-
try {
|
|
5248
|
-
building = new ObjectId18(building);
|
|
5249
|
-
} catch (error) {
|
|
5250
|
-
throw new BadRequestError25("Invalid building ID.");
|
|
5251
|
-
}
|
|
5252
|
-
const cacheKey = makeCacheKey11(namespace_collection, {
|
|
5253
|
-
building: String(building),
|
|
5254
|
-
level
|
|
5255
|
-
});
|
|
5256
|
-
try {
|
|
5257
|
-
const cached = await getCache(cacheKey);
|
|
5258
|
-
if (cached) {
|
|
5259
|
-
logger15.log({
|
|
5260
|
-
level: "info",
|
|
5261
|
-
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
5262
|
-
});
|
|
5263
|
-
return cached;
|
|
5264
|
-
}
|
|
5265
|
-
const result = await collection.findOne({
|
|
5266
|
-
building,
|
|
5267
|
-
level,
|
|
5268
|
-
status: "active"
|
|
5269
|
-
});
|
|
5270
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
5271
|
-
logger15.log({
|
|
5272
|
-
level: "info",
|
|
5273
|
-
message: `Cache set for building unit by id: ${cacheKey}`
|
|
5274
|
-
});
|
|
5275
|
-
}).catch((err) => {
|
|
5276
|
-
logger15.log({
|
|
5277
|
-
level: "error",
|
|
5278
|
-
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
5279
|
-
});
|
|
5280
|
-
});
|
|
5281
|
-
return result;
|
|
5282
|
-
} catch (error) {
|
|
5283
|
-
if (error instanceof AppError9) {
|
|
5284
|
-
throw error;
|
|
5285
|
-
} else {
|
|
5286
|
-
throw new InternalServerError17("Failed to get building unit.");
|
|
5287
|
-
}
|
|
5288
|
-
}
|
|
5289
|
-
}
|
|
5290
|
-
async function getByBuilding(building) {
|
|
5291
|
-
try {
|
|
5292
|
-
building = new ObjectId18(building);
|
|
5293
|
-
} catch (error) {
|
|
5294
|
-
throw new BadRequestError25("Invalid building ID.");
|
|
5295
|
-
}
|
|
5296
|
-
const cacheKey = makeCacheKey11(namespace_collection, {
|
|
5297
|
-
building: String(building)
|
|
5298
|
-
});
|
|
5299
|
-
try {
|
|
5300
|
-
const cached = await getCache(cacheKey);
|
|
5301
|
-
if (cached) {
|
|
5302
|
-
logger15.log({
|
|
5303
|
-
level: "info",
|
|
5304
|
-
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
5305
|
-
});
|
|
5306
|
-
return cached;
|
|
5307
|
-
}
|
|
5308
|
-
const result = await collection.findOne({
|
|
5309
|
-
building,
|
|
5310
|
-
status: "active"
|
|
5311
|
-
});
|
|
5312
|
-
setCache(cacheKey, result, 300).then(() => {
|
|
5313
|
-
logger15.log({
|
|
5314
|
-
level: "info",
|
|
5315
|
-
message: `Cache set for building unit by id: ${cacheKey}`
|
|
5316
|
-
});
|
|
5317
|
-
}).catch((err) => {
|
|
5318
|
-
logger15.log({
|
|
5319
|
-
level: "error",
|
|
5320
|
-
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
5321
|
-
});
|
|
5322
|
-
});
|
|
5323
|
-
return result;
|
|
5324
|
-
} catch (error) {
|
|
5325
|
-
if (error instanceof AppError9) {
|
|
5326
|
-
throw error;
|
|
5327
|
-
} else {
|
|
5328
|
-
throw new InternalServerError17("Failed to get building unit.");
|
|
5329
|
-
}
|
|
5330
|
-
}
|
|
5331
|
-
}
|
|
5332
|
-
async function deleteById(_id, session) {
|
|
5333
|
-
try {
|
|
5334
|
-
_id = new ObjectId18(_id);
|
|
5335
|
-
} catch (error) {
|
|
5336
|
-
throw new BadRequestError25("Invalid ID.");
|
|
5337
|
-
}
|
|
5338
|
-
try {
|
|
5339
|
-
const res = await collection.updateOne(
|
|
5340
|
-
{ _id },
|
|
5341
|
-
{ $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } },
|
|
5342
|
-
{ session }
|
|
5343
|
-
);
|
|
5344
|
-
delCachedData();
|
|
5345
|
-
return "Room/Facility deleted successfully.";
|
|
5346
|
-
} catch (error) {
|
|
5347
|
-
logger15.log({
|
|
5348
|
-
level: "error",
|
|
5349
|
-
message: error.message
|
|
5350
|
-
});
|
|
5351
|
-
if (error instanceof AppError9) {
|
|
5352
|
-
throw error;
|
|
5353
|
-
} else {
|
|
5354
|
-
throw new Error("Failed to deleted room/facility.");
|
|
5355
|
-
}
|
|
5356
|
-
}
|
|
5357
|
-
}
|
|
5358
|
-
return {
|
|
5359
|
-
createIndexes,
|
|
5360
|
-
add,
|
|
5361
|
-
getAll,
|
|
5362
|
-
getById,
|
|
5363
|
-
getByBuildingLevel,
|
|
5364
|
-
updateById,
|
|
5365
|
-
getByBuilding,
|
|
5366
|
-
deleteById,
|
|
5367
|
-
updateByBuildingId
|
|
5368
|
-
};
|
|
5369
|
-
}
|
|
5370
|
-
|
|
5371
|
-
// src/resources/building/building.service.ts
|
|
5372
|
-
function useBuildingService() {
|
|
5373
|
-
const {
|
|
5374
|
-
updateById: _updateById,
|
|
5375
|
-
getById: _getById,
|
|
5376
|
-
deleteById: _deleteById
|
|
5377
|
-
} = useBuildingRepo();
|
|
5378
|
-
const { getByBuildingLevel, getByBuilding, updateByBuildingId } = useBuildingUnitRepo();
|
|
5379
|
-
async function updateById(id, data) {
|
|
5380
|
-
data.levels = Number(data.levels);
|
|
5381
|
-
const session = useAtlas15.getClient()?.startSession();
|
|
5382
|
-
try {
|
|
5383
|
-
const building = await _getById(id);
|
|
5384
|
-
if (!building) {
|
|
5385
|
-
throw new NotFoundError5("Building not found.");
|
|
5386
|
-
}
|
|
5387
|
-
if (data.levels < building.levels) {
|
|
5388
|
-
const unit = await getByBuildingLevel(id, building.levels);
|
|
5389
|
-
if (unit) {
|
|
5390
|
-
throw new BadRequestError26(
|
|
5391
|
-
"Cannot reduce floors, there are existing building units at higher floors."
|
|
5392
|
-
);
|
|
5393
|
-
}
|
|
5394
|
-
}
|
|
5395
|
-
session?.startTransaction();
|
|
5396
|
-
if (building.name !== data.name) {
|
|
5397
|
-
await updateByBuildingId(id, { buildingName: data.name }, session);
|
|
5398
|
-
}
|
|
5399
|
-
const result = await _updateById(id, data, session);
|
|
5400
|
-
await session?.commitTransaction();
|
|
5401
|
-
return result;
|
|
5402
|
-
} catch (error) {
|
|
5403
|
-
await session?.abortTransaction();
|
|
5404
|
-
throw error;
|
|
5405
|
-
} finally {
|
|
5406
|
-
session?.endSession();
|
|
5407
|
-
}
|
|
5408
|
-
}
|
|
5409
|
-
async function deleteById(id) {
|
|
5410
|
-
const building = await getByBuilding(id);
|
|
5411
|
-
if (building) {
|
|
5412
|
-
throw new BadRequestError26(
|
|
5413
|
-
"Cannot delete building with existing room/facility. Please delete room/facility first."
|
|
5414
|
-
);
|
|
5415
|
-
}
|
|
5416
|
-
try {
|
|
5417
|
-
await _deleteById(id);
|
|
5418
|
-
return "Building deleted successfully.";
|
|
5419
|
-
} catch (error) {
|
|
5420
|
-
throw error;
|
|
5421
|
-
}
|
|
5422
|
-
}
|
|
5423
|
-
return {
|
|
5424
|
-
updateById,
|
|
5425
|
-
deleteById
|
|
5426
|
-
};
|
|
5427
|
-
}
|
|
5428
|
-
|
|
5429
|
-
// src/resources/building/building.controller.ts
|
|
5430
|
-
import { BadRequestError as BadRequestError27, logger as logger16 } from "@eeplatform/nodejs-utils";
|
|
5431
|
-
import Joi13 from "joi";
|
|
5432
|
-
function useBuildingController() {
|
|
5433
|
-
const { getAll: _getAll, getById: _getById, add: _add } = useBuildingRepo();
|
|
5434
|
-
const { updateById: _updateById, deleteById: _deleteById } = useBuildingService();
|
|
5435
|
-
async function createBuilding(req, res, next) {
|
|
5436
|
-
const value = req.body;
|
|
5437
|
-
const validation = Joi13.object({
|
|
5438
|
-
name: Joi13.string().required(),
|
|
5439
|
-
school: Joi13.string().hex().required(),
|
|
5440
|
-
levels: Joi13.number().integer().min(1).required(),
|
|
5441
|
-
serial: Joi13.string().optional().allow("", null),
|
|
5442
|
-
status: Joi13.string().optional().allow("", null)
|
|
5443
|
-
});
|
|
5444
|
-
const { error } = validation.validate(value);
|
|
5445
|
-
if (error) {
|
|
5446
|
-
next(new BadRequestError27(error.message));
|
|
5447
|
-
logger16.info(`Controller: ${error.message}`);
|
|
5448
|
-
return;
|
|
5449
|
-
}
|
|
5450
|
-
try {
|
|
5451
|
-
const result = await _add(value);
|
|
5452
|
-
res.json(result);
|
|
5453
|
-
return;
|
|
5454
|
-
} catch (error2) {
|
|
5455
|
-
next(error2);
|
|
5456
|
-
}
|
|
5457
|
-
}
|
|
5458
|
-
async function updateById(req, res, next) {
|
|
5459
|
-
const value = req.body;
|
|
5460
|
-
const id = req.params.id ?? "";
|
|
5461
|
-
const validation = Joi13.object({
|
|
5462
|
-
id: Joi13.string().hex().required(),
|
|
5463
|
-
value: Joi13.object({
|
|
5464
|
-
name: Joi13.string().required(),
|
|
5465
|
-
serial: Joi13.string().optional().allow("", null),
|
|
5466
|
-
levels: Joi13.number().integer().min(1).required()
|
|
5467
|
-
})
|
|
5468
|
-
});
|
|
5469
|
-
const { error } = validation.validate({ id, value });
|
|
5470
|
-
if (error) {
|
|
5471
|
-
next(new BadRequestError27(error.message));
|
|
5472
|
-
logger16.info(`Controller: ${error.message}`);
|
|
5473
|
-
return;
|
|
5474
|
-
}
|
|
5475
|
-
try {
|
|
5476
|
-
const result = await _updateById(id, value);
|
|
5477
|
-
res.json(result);
|
|
5478
|
-
return;
|
|
5479
|
-
} catch (error2) {
|
|
5480
|
-
next(error2);
|
|
5481
|
-
}
|
|
5482
|
-
}
|
|
5483
|
-
async function getAll(req, res, next) {
|
|
5484
|
-
const query = req.query;
|
|
5485
|
-
const validation = Joi13.object({
|
|
5486
|
-
page: Joi13.number().min(1).optional().allow("", null),
|
|
5487
|
-
limit: Joi13.number().min(1).optional().allow("", null),
|
|
5488
|
-
search: Joi13.string().optional().allow("", null),
|
|
5489
|
-
school: Joi13.string().hex().optional().allow("", null),
|
|
5490
|
-
status: Joi13.string().optional().allow("", null)
|
|
5491
|
-
});
|
|
5492
|
-
const { error } = validation.validate(query);
|
|
5493
|
-
if (error) {
|
|
5494
|
-
next(new BadRequestError27(error.message));
|
|
5495
|
-
return;
|
|
5496
|
-
}
|
|
5497
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
5498
|
-
let limit = parseInt(req.query.limit) ?? 20;
|
|
5499
|
-
limit = isNaN(limit) ? 20 : limit;
|
|
5500
|
-
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
5501
|
-
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
5502
|
-
const sortObj = {};
|
|
5503
|
-
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
5504
|
-
sort.forEach((field, index) => {
|
|
5505
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
5506
|
-
});
|
|
5507
|
-
}
|
|
5508
|
-
const status = req.query.status ?? "active";
|
|
5509
|
-
const school = req.query.school ?? "";
|
|
5510
|
-
const search = req.query.search ?? "";
|
|
5511
|
-
try {
|
|
5512
|
-
const buildings = await _getAll({
|
|
5513
|
-
page,
|
|
5514
|
-
limit,
|
|
5515
|
-
sort: sortObj,
|
|
5516
|
-
status,
|
|
5517
|
-
school,
|
|
5518
|
-
search
|
|
5519
|
-
});
|
|
5520
|
-
res.json(buildings);
|
|
5521
|
-
return;
|
|
5522
|
-
} catch (error2) {
|
|
5523
|
-
next(error2);
|
|
5524
|
-
}
|
|
5525
|
-
}
|
|
5526
|
-
async function getById(req, res, next) {
|
|
5527
|
-
const id = req.params.id;
|
|
5528
|
-
const validation = Joi13.object({
|
|
5529
|
-
id: Joi13.string().hex().required()
|
|
5530
|
-
});
|
|
5531
|
-
const { error } = validation.validate({ id });
|
|
5532
|
-
if (error) {
|
|
5533
|
-
next(new BadRequestError27(error.message));
|
|
5534
|
-
return;
|
|
4487
|
+
_id = new ObjectId15(_id);
|
|
4488
|
+
} catch (error) {
|
|
4489
|
+
throw new BadRequestError22("Invalid address ID.");
|
|
4490
|
+
}
|
|
4491
|
+
if (value.org) {
|
|
4492
|
+
try {
|
|
4493
|
+
value.org = new ObjectId15(value.org);
|
|
4494
|
+
} catch (error) {
|
|
4495
|
+
throw new BadRequestError22("Invalid org ID.");
|
|
4496
|
+
}
|
|
5535
4497
|
}
|
|
5536
4498
|
try {
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
4499
|
+
await collection.updateOne(
|
|
4500
|
+
{ _id },
|
|
4501
|
+
{ $set: value },
|
|
4502
|
+
{ session, upsert: true }
|
|
4503
|
+
);
|
|
4504
|
+
delCachedData();
|
|
4505
|
+
return "Successfully updated address.";
|
|
4506
|
+
} catch (error) {
|
|
4507
|
+
throw new BadRequestError22("Failed to update address.");
|
|
5545
4508
|
}
|
|
5546
4509
|
}
|
|
5547
|
-
async function
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
const { error } = validation.validate({ id });
|
|
5553
|
-
if (error) {
|
|
5554
|
-
next(new BadRequestError27(error.message));
|
|
5555
|
-
return;
|
|
4510
|
+
async function getByUserId(user) {
|
|
4511
|
+
try {
|
|
4512
|
+
user = new ObjectId15(user);
|
|
4513
|
+
} catch (error) {
|
|
4514
|
+
throw new BadRequestError22("Invalid user ID.");
|
|
5556
4515
|
}
|
|
4516
|
+
const cacheKey = makeCacheKey9(namespace_collection, { user: String(user) });
|
|
5557
4517
|
try {
|
|
5558
|
-
const
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
4518
|
+
const cached = await getCache(cacheKey);
|
|
4519
|
+
if (cached) {
|
|
4520
|
+
logger12.log({
|
|
4521
|
+
level: "info",
|
|
4522
|
+
message: `Cache hit for getByUserId address: ${cacheKey}`
|
|
4523
|
+
});
|
|
4524
|
+
return cached;
|
|
4525
|
+
}
|
|
4526
|
+
const data = await collection.findOne({ user });
|
|
4527
|
+
if (data) {
|
|
4528
|
+
setCache(cacheKey, data, 300).then(() => {
|
|
4529
|
+
logger12.log({
|
|
4530
|
+
level: "info",
|
|
4531
|
+
message: `Cache set for address by user ID: ${cacheKey}`
|
|
4532
|
+
});
|
|
4533
|
+
}).catch((err) => {
|
|
4534
|
+
logger12.log({
|
|
4535
|
+
level: "error",
|
|
4536
|
+
message: `Failed to set cache for address by user ID: ${err.message}`
|
|
4537
|
+
});
|
|
4538
|
+
});
|
|
4539
|
+
}
|
|
4540
|
+
return data;
|
|
4541
|
+
} catch (error) {
|
|
4542
|
+
throw new BadRequestError22("Failed to get address by ID.");
|
|
5563
4543
|
}
|
|
5564
4544
|
}
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
deleteById
|
|
5571
|
-
};
|
|
5572
|
-
}
|
|
5573
|
-
|
|
5574
|
-
// src/resources/building/building-unit.service.ts
|
|
5575
|
-
import { useAtlas as useAtlas16 } from "@eeplatform/nodejs-utils";
|
|
5576
|
-
function useBuildingUnitService() {
|
|
5577
|
-
const { add: _add } = useBuildingUnitRepo();
|
|
5578
|
-
async function add(value) {
|
|
5579
|
-
const session = useAtlas16.getClient()?.startSession();
|
|
5580
|
-
if (!session) {
|
|
5581
|
-
throw new Error("Unable to start session for building unit service.");
|
|
4545
|
+
async function getByOrgId(org) {
|
|
4546
|
+
try {
|
|
4547
|
+
org = new ObjectId15(org);
|
|
4548
|
+
} catch (error) {
|
|
4549
|
+
throw new BadRequestError22("Invalid orgId.");
|
|
5582
4550
|
}
|
|
4551
|
+
const cacheKey = makeCacheKey9(namespace_collection, { org: String(org) });
|
|
5583
4552
|
try {
|
|
5584
|
-
await
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
);
|
|
4553
|
+
const cached = await getCache(cacheKey);
|
|
4554
|
+
if (cached) {
|
|
4555
|
+
logger12.log({
|
|
4556
|
+
level: "info",
|
|
4557
|
+
message: `Cache hit for getByOrgId address: ${cacheKey}`
|
|
4558
|
+
});
|
|
4559
|
+
return cached;
|
|
4560
|
+
}
|
|
4561
|
+
const data = await collection.findOne({ org });
|
|
4562
|
+
if (data) {
|
|
4563
|
+
setCache(cacheKey, data, 300).then(() => {
|
|
4564
|
+
logger12.log({
|
|
4565
|
+
level: "info",
|
|
4566
|
+
message: `Cache set for address by org ID: ${cacheKey}`
|
|
4567
|
+
});
|
|
4568
|
+
}).catch((err) => {
|
|
4569
|
+
logger12.log({
|
|
4570
|
+
level: "error",
|
|
4571
|
+
message: `Failed to set cache for address by org ID: ${err.message}`
|
|
4572
|
+
});
|
|
4573
|
+
});
|
|
5590
4574
|
}
|
|
5591
|
-
|
|
5592
|
-
return "Building unit added successfully.";
|
|
4575
|
+
return data;
|
|
5593
4576
|
} catch (error) {
|
|
5594
|
-
|
|
5595
|
-
throw error;
|
|
5596
|
-
} finally {
|
|
5597
|
-
session.endSession();
|
|
4577
|
+
throw new BadRequestError22("Failed to get address by orgId.");
|
|
5598
4578
|
}
|
|
5599
4579
|
}
|
|
5600
4580
|
return {
|
|
5601
|
-
|
|
4581
|
+
createIndex,
|
|
4582
|
+
add,
|
|
4583
|
+
getByUserId,
|
|
4584
|
+
getByOrgId,
|
|
4585
|
+
updateById
|
|
5602
4586
|
};
|
|
5603
4587
|
}
|
|
5604
4588
|
|
|
5605
|
-
// src/resources/
|
|
5606
|
-
import { BadRequestError as
|
|
5607
|
-
import
|
|
5608
|
-
function
|
|
4589
|
+
// src/resources/address/address.controller.ts
|
|
4590
|
+
import { BadRequestError as BadRequestError23, NotFoundError as NotFoundError4 } from "@eeplatform/nodejs-utils";
|
|
4591
|
+
import Joi12 from "joi";
|
|
4592
|
+
function useAddressController() {
|
|
5609
4593
|
const {
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
} =
|
|
5615
|
-
const { add: _add } = useBuildingUnitService();
|
|
4594
|
+
add: _add,
|
|
4595
|
+
getByUserId: _getByUserId,
|
|
4596
|
+
getByOrgId: _getByOrgId,
|
|
4597
|
+
updateById: _updateById
|
|
4598
|
+
} = useAddressRepo();
|
|
5616
4599
|
async function add(req, res, next) {
|
|
5617
|
-
const
|
|
5618
|
-
const validation =
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
description: Joi14.string().optional().allow("", null),
|
|
5630
|
-
unit_of_measurement: Joi14.string().valid("sqm").required(),
|
|
5631
|
-
area: Joi14.number().positive().required(),
|
|
5632
|
-
status: Joi14.string().optional().allow("", null)
|
|
5633
|
-
}),
|
|
5634
|
-
qty: Joi14.number().integer().min(1).max(20).optional().default(1)
|
|
4600
|
+
const value = req.body;
|
|
4601
|
+
const validation = Joi12.object({
|
|
4602
|
+
type: Joi12.string().required(),
|
|
4603
|
+
user: Joi12.string().hex().optional().allow("", null),
|
|
4604
|
+
org: Joi12.string().hex().optional().allow("", null),
|
|
4605
|
+
country: Joi12.string().required(),
|
|
4606
|
+
address: Joi12.string().required(),
|
|
4607
|
+
continuedAddress: Joi12.string().optional().allow("", null),
|
|
4608
|
+
city: Joi12.string().required(),
|
|
4609
|
+
province: Joi12.string().required(),
|
|
4610
|
+
postalCode: Joi12.string().required(),
|
|
4611
|
+
taxId: Joi12.string().optional().allow("", null)
|
|
5635
4612
|
});
|
|
5636
|
-
const { error } = validation.validate(
|
|
4613
|
+
const { error } = validation.validate(value);
|
|
5637
4614
|
if (error) {
|
|
5638
|
-
next(new
|
|
5639
|
-
return;
|
|
4615
|
+
next(new BadRequestError23(error.message));
|
|
5640
4616
|
}
|
|
5641
4617
|
try {
|
|
5642
|
-
const
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
});
|
|
4618
|
+
const value2 = req.body;
|
|
4619
|
+
const id = await _add(value2);
|
|
4620
|
+
res.json({ message: "Successfully added subscription.", id });
|
|
4621
|
+
return;
|
|
5647
4622
|
} catch (error2) {
|
|
5648
4623
|
next(error2);
|
|
5649
4624
|
}
|
|
5650
4625
|
}
|
|
5651
4626
|
async function updateById(req, res, next) {
|
|
5652
|
-
const data = req.body;
|
|
5653
4627
|
const id = req.params.id ?? "";
|
|
5654
|
-
const
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
res.json({
|
|
5666
|
-
message: "Building unit updated successfully.",
|
|
5667
|
-
data: { buildingUnit }
|
|
5668
|
-
});
|
|
5669
|
-
} catch (error2) {
|
|
5670
|
-
next(error2);
|
|
5671
|
-
}
|
|
5672
|
-
}
|
|
5673
|
-
async function getAll(req, res, next) {
|
|
5674
|
-
const query = req.query;
|
|
5675
|
-
const validation = Joi14.object({
|
|
5676
|
-
page: Joi14.number().min(1).optional().allow("", null),
|
|
5677
|
-
limit: Joi14.number().min(1).optional().allow("", null),
|
|
5678
|
-
search: Joi14.string().optional().allow("", null),
|
|
5679
|
-
school: Joi14.string().hex().optional().allow("", null),
|
|
5680
|
-
building: Joi14.string().hex().optional().allow("", null),
|
|
5681
|
-
status: Joi14.string().optional().allow("", null)
|
|
4628
|
+
const value = req.body;
|
|
4629
|
+
const validation = Joi12.object({
|
|
4630
|
+
id: Joi12.string().hex().required(),
|
|
4631
|
+
country: Joi12.string().required(),
|
|
4632
|
+
address: Joi12.string().required(),
|
|
4633
|
+
continuedAddress: Joi12.string().optional().allow("", null),
|
|
4634
|
+
city: Joi12.string().required(),
|
|
4635
|
+
province: Joi12.string().required(),
|
|
4636
|
+
postalCode: Joi12.string().required(),
|
|
4637
|
+
taxId: Joi12.string().optional().allow("", null),
|
|
4638
|
+
org: Joi12.string().hex().optional().allow("", null)
|
|
5682
4639
|
});
|
|
5683
|
-
const { error } = validation.validate(
|
|
4640
|
+
const { error } = validation.validate({ id, ...value });
|
|
5684
4641
|
if (error) {
|
|
5685
|
-
next(new
|
|
4642
|
+
next(new BadRequestError23(error.message));
|
|
5686
4643
|
return;
|
|
5687
4644
|
}
|
|
5688
|
-
const page = parseInt(req.query.page) ?? 1;
|
|
5689
|
-
let limit = parseInt(req.query.limit) ?? 20;
|
|
5690
|
-
limit = isNaN(limit) ? 20 : limit;
|
|
5691
|
-
const sort = req.query.sort ? String(req.query.sort).split(",") : "";
|
|
5692
|
-
const sortOrder = req.query.sortOrder ? String(req.query.sortOrder).split(",") : "";
|
|
5693
|
-
const sortObj = {};
|
|
5694
|
-
if (sort && Array.isArray(sort) && sort.length && sortOrder && Array.isArray(sortOrder) && sortOrder.length) {
|
|
5695
|
-
sort.forEach((field, index) => {
|
|
5696
|
-
sortObj[field] = sortOrder[index] === "desc" ? -1 : 1;
|
|
5697
|
-
});
|
|
5698
|
-
}
|
|
5699
|
-
const status = req.query.status ?? "active";
|
|
5700
|
-
const school = req.query.school ?? "";
|
|
5701
|
-
const building = req.query.building ?? "";
|
|
5702
|
-
const search = req.query.search ?? "";
|
|
5703
4645
|
try {
|
|
5704
|
-
const
|
|
5705
|
-
|
|
5706
|
-
limit,
|
|
5707
|
-
sort: sortObj,
|
|
5708
|
-
status,
|
|
5709
|
-
school,
|
|
5710
|
-
search,
|
|
5711
|
-
building
|
|
5712
|
-
});
|
|
5713
|
-
res.json(buildings);
|
|
4646
|
+
const message = await _updateById(id, value);
|
|
4647
|
+
res.json({ message });
|
|
5714
4648
|
return;
|
|
5715
4649
|
} catch (error2) {
|
|
5716
4650
|
next(error2);
|
|
5717
4651
|
}
|
|
5718
4652
|
}
|
|
5719
|
-
async function
|
|
5720
|
-
const
|
|
5721
|
-
const validation =
|
|
5722
|
-
|
|
5723
|
-
});
|
|
5724
|
-
const { error } = validation.validate({ id });
|
|
4653
|
+
async function getByUserId(req, res, next) {
|
|
4654
|
+
const user = req.params.user;
|
|
4655
|
+
const validation = Joi12.string().hex().required();
|
|
4656
|
+
const { error } = validation.validate(user);
|
|
5725
4657
|
if (error) {
|
|
5726
|
-
next(new
|
|
5727
|
-
return;
|
|
4658
|
+
next(new BadRequestError23(error.message));
|
|
5728
4659
|
}
|
|
5729
4660
|
try {
|
|
5730
|
-
const
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
}
|
|
4661
|
+
const address = await _getByUserId(user);
|
|
4662
|
+
if (!address) {
|
|
4663
|
+
next(new NotFoundError4("Address not found."));
|
|
4664
|
+
return;
|
|
4665
|
+
}
|
|
4666
|
+
res.json(address);
|
|
5735
4667
|
return;
|
|
5736
4668
|
} catch (error2) {
|
|
5737
4669
|
next(error2);
|
|
5738
4670
|
}
|
|
5739
4671
|
}
|
|
5740
|
-
async function
|
|
4672
|
+
async function getByOrgId(req, res, next) {
|
|
5741
4673
|
const id = req.params.id;
|
|
5742
|
-
const validation =
|
|
5743
|
-
|
|
5744
|
-
});
|
|
5745
|
-
const { error } = validation.validate({ id });
|
|
4674
|
+
const validation = Joi12.string().hex().required();
|
|
4675
|
+
const { error } = validation.validate(id);
|
|
5746
4676
|
if (error) {
|
|
5747
|
-
next(new
|
|
5748
|
-
return;
|
|
4677
|
+
next(new BadRequestError23(error.message));
|
|
5749
4678
|
}
|
|
5750
4679
|
try {
|
|
5751
|
-
const
|
|
5752
|
-
|
|
4680
|
+
const address = await _getByOrgId(id);
|
|
4681
|
+
if (!address) {
|
|
4682
|
+
next(new NotFoundError4("Address not found."));
|
|
4683
|
+
return;
|
|
4684
|
+
}
|
|
4685
|
+
res.json(address);
|
|
5753
4686
|
return;
|
|
5754
4687
|
} catch (error2) {
|
|
5755
4688
|
next(error2);
|
|
@@ -5757,32 +4690,31 @@ function useBuildingUnitController() {
|
|
|
5757
4690
|
}
|
|
5758
4691
|
return {
|
|
5759
4692
|
add,
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
updateById
|
|
5763
|
-
deleteById
|
|
4693
|
+
getByUserId,
|
|
4694
|
+
getByOrgId,
|
|
4695
|
+
updateById
|
|
5764
4696
|
};
|
|
5765
4697
|
}
|
|
5766
4698
|
|
|
5767
4699
|
// src/resources/token/token.model.ts
|
|
5768
|
-
import { ObjectId as
|
|
4700
|
+
import { ObjectId as ObjectId16 } from "mongodb";
|
|
5769
4701
|
var MToken = class {
|
|
5770
4702
|
constructor(value) {
|
|
5771
4703
|
this.token = value.token ?? "";
|
|
5772
|
-
this.user = value.user ?? new
|
|
4704
|
+
this.user = value.user ?? new ObjectId16();
|
|
5773
4705
|
this.createdAt = value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
5774
4706
|
}
|
|
5775
4707
|
};
|
|
5776
4708
|
|
|
5777
4709
|
// src/resources/counter/counter.model.ts
|
|
5778
|
-
import { BadRequestError as
|
|
5779
|
-
import { ObjectId as
|
|
4710
|
+
import { BadRequestError as BadRequestError24 } from "@eeplatform/nodejs-utils";
|
|
4711
|
+
import { ObjectId as ObjectId17 } from "mongodb";
|
|
5780
4712
|
import { z } from "zod";
|
|
5781
4713
|
var TCounter = z.object({
|
|
5782
4714
|
_id: z.union([
|
|
5783
4715
|
z.string().length(24, "Invalid ObjectId hex string"),
|
|
5784
|
-
z.instanceof(
|
|
5785
|
-
]).transform((val) => typeof val === "string" ? new
|
|
4716
|
+
z.instanceof(ObjectId17)
|
|
4717
|
+
]).transform((val) => typeof val === "string" ? new ObjectId17(val) : val).optional(),
|
|
5786
4718
|
count: z.number().int().min(0).default(0),
|
|
5787
4719
|
type: z.string(),
|
|
5788
4720
|
createdAt: z.date().optional().default(() => /* @__PURE__ */ new Date()),
|
|
@@ -5795,7 +4727,7 @@ function useCounterModel(db) {
|
|
|
5795
4727
|
try {
|
|
5796
4728
|
return TCounter.parse(value);
|
|
5797
4729
|
} catch (error) {
|
|
5798
|
-
throw new
|
|
4730
|
+
throw new BadRequestError24(error.issues[0].message);
|
|
5799
4731
|
}
|
|
5800
4732
|
}
|
|
5801
4733
|
function validateCounter(data) {
|
|
@@ -5810,27 +4742,27 @@ function useCounterModel(db) {
|
|
|
5810
4742
|
|
|
5811
4743
|
// src/resources/counter/counter.repository.ts
|
|
5812
4744
|
import {
|
|
5813
|
-
useAtlas as
|
|
5814
|
-
useCache as
|
|
5815
|
-
makeCacheKey as
|
|
5816
|
-
logger as
|
|
4745
|
+
useAtlas as useAtlas13,
|
|
4746
|
+
useCache as useCache11,
|
|
4747
|
+
makeCacheKey as makeCacheKey10,
|
|
4748
|
+
logger as logger13
|
|
5817
4749
|
} from "@eeplatform/nodejs-utils";
|
|
5818
4750
|
function useCounterRepo() {
|
|
5819
|
-
const db =
|
|
4751
|
+
const db = useAtlas13.getDb();
|
|
5820
4752
|
if (!db) {
|
|
5821
4753
|
throw new Error("Unable to connect to server.");
|
|
5822
4754
|
}
|
|
5823
4755
|
const namespace_collection = "counters";
|
|
5824
4756
|
const { collection, createCounter } = useCounterModel(db);
|
|
5825
|
-
const { getCache, setCache, delNamespace } =
|
|
4757
|
+
const { getCache, setCache, delNamespace } = useCache11(namespace_collection);
|
|
5826
4758
|
function delCachedData() {
|
|
5827
4759
|
delNamespace().then(() => {
|
|
5828
|
-
|
|
4760
|
+
logger13.log({
|
|
5829
4761
|
level: "info",
|
|
5830
4762
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
5831
4763
|
});
|
|
5832
4764
|
}).catch((err) => {
|
|
5833
|
-
|
|
4765
|
+
logger13.log({
|
|
5834
4766
|
level: "error",
|
|
5835
4767
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
5836
4768
|
});
|
|
@@ -5882,11 +4814,11 @@ function useCounterRepo() {
|
|
|
5882
4814
|
}
|
|
5883
4815
|
}
|
|
5884
4816
|
async function getByType(type) {
|
|
5885
|
-
const cacheKey =
|
|
4817
|
+
const cacheKey = makeCacheKey10(namespace_collection, { type });
|
|
5886
4818
|
try {
|
|
5887
4819
|
const cached = await getCache(cacheKey);
|
|
5888
4820
|
if (cached) {
|
|
5889
|
-
|
|
4821
|
+
logger13.log({
|
|
5890
4822
|
level: "info",
|
|
5891
4823
|
message: `Cache hit for getByType counter: ${cacheKey}`
|
|
5892
4824
|
});
|
|
@@ -5895,12 +4827,12 @@ function useCounterRepo() {
|
|
|
5895
4827
|
const data = await collection.findOne({ type });
|
|
5896
4828
|
if (data) {
|
|
5897
4829
|
setCache(cacheKey, data, 300).then(() => {
|
|
5898
|
-
|
|
4830
|
+
logger13.log({
|
|
5899
4831
|
level: "info",
|
|
5900
4832
|
message: `Cache set for counter by type: ${cacheKey}`
|
|
5901
4833
|
});
|
|
5902
4834
|
}).catch((err) => {
|
|
5903
|
-
|
|
4835
|
+
logger13.log({
|
|
5904
4836
|
level: "error",
|
|
5905
4837
|
message: `Failed to set cache for counter by type: ${err.message}`
|
|
5906
4838
|
});
|
|
@@ -6238,7 +5170,7 @@ IMPORTANT: Only consider it a match if the target phoneme is the FIRST sound pro
|
|
|
6238
5170
|
}
|
|
6239
5171
|
|
|
6240
5172
|
// src/resources/utils/github.service.ts
|
|
6241
|
-
import { AppError as
|
|
5173
|
+
import { AppError as AppError9, BadRequestError as BadRequestError25 } from "@eeplatform/nodejs-utils";
|
|
6242
5174
|
import { Octokit } from "@octokit/rest";
|
|
6243
5175
|
import _sodium from "libsodium-wrappers";
|
|
6244
5176
|
function useGitHubService() {
|
|
@@ -6252,23 +5184,23 @@ function useGitHubService() {
|
|
|
6252
5184
|
try {
|
|
6253
5185
|
const { data: repoData } = await octokit.repos.get({ owner, repo });
|
|
6254
5186
|
if (!repoData.permissions?.admin) {
|
|
6255
|
-
throw new
|
|
5187
|
+
throw new BadRequestError25(
|
|
6256
5188
|
"You do not have admin access to this repository."
|
|
6257
5189
|
);
|
|
6258
5190
|
}
|
|
6259
5191
|
} catch (error) {
|
|
6260
5192
|
if (error.status === 404) {
|
|
6261
|
-
throw new
|
|
5193
|
+
throw new BadRequestError25(
|
|
6262
5194
|
"Repository not found or you don't have access to it."
|
|
6263
5195
|
);
|
|
6264
5196
|
} else if (error.status === 401) {
|
|
6265
|
-
throw new
|
|
5197
|
+
throw new BadRequestError25(
|
|
6266
5198
|
"Invalid GitHub token or insufficient permissions."
|
|
6267
5199
|
);
|
|
6268
5200
|
} else if (error.message.includes("admin access")) {
|
|
6269
5201
|
throw error;
|
|
6270
5202
|
} else {
|
|
6271
|
-
throw new
|
|
5203
|
+
throw new BadRequestError25(
|
|
6272
5204
|
`Failed to check repository permissions: ${error.message}`
|
|
6273
5205
|
);
|
|
6274
5206
|
}
|
|
@@ -6317,7 +5249,7 @@ function useGitHubService() {
|
|
|
6317
5249
|
key_id: publicKeyRes.key_id
|
|
6318
5250
|
});
|
|
6319
5251
|
} catch (encryptionError) {
|
|
6320
|
-
throw new
|
|
5252
|
+
throw new BadRequestError25(
|
|
6321
5253
|
`Failed to encrypt secret '${key}': ${encryptionError.message}`
|
|
6322
5254
|
);
|
|
6323
5255
|
}
|
|
@@ -6333,22 +5265,22 @@ function useGitHubService() {
|
|
|
6333
5265
|
}
|
|
6334
5266
|
return `Successfully set ${lines.length} ${type} variables/secrets in environment '${environment}'`;
|
|
6335
5267
|
} catch (error) {
|
|
6336
|
-
if (error instanceof
|
|
5268
|
+
if (error instanceof AppError9)
|
|
6337
5269
|
throw error;
|
|
6338
5270
|
if (error.status === 422) {
|
|
6339
|
-
throw new
|
|
5271
|
+
throw new BadRequestError25(
|
|
6340
5272
|
`GitHub API validation error: ${error.message}`
|
|
6341
5273
|
);
|
|
6342
5274
|
} else if (error.status === 404) {
|
|
6343
|
-
throw new
|
|
5275
|
+
throw new BadRequestError25("Environment or repository not found.");
|
|
6344
5276
|
} else if (error.status === 403) {
|
|
6345
|
-
throw new
|
|
5277
|
+
throw new BadRequestError25(
|
|
6346
5278
|
"Forbidden: Insufficient permissions or rate limit exceeded."
|
|
6347
5279
|
);
|
|
6348
5280
|
} else if (error.message.includes("admin access") || error.message.includes("permissions")) {
|
|
6349
5281
|
throw error;
|
|
6350
5282
|
} else {
|
|
6351
|
-
throw new
|
|
5283
|
+
throw new BadRequestError25(
|
|
6352
5284
|
`Failed to set GitHub variables: ${error.message}`
|
|
6353
5285
|
);
|
|
6354
5286
|
}
|
|
@@ -6360,7 +5292,7 @@ function useGitHubService() {
|
|
|
6360
5292
|
}
|
|
6361
5293
|
|
|
6362
5294
|
// src/resources/utils/transcribe.service.ts
|
|
6363
|
-
import { AppError as
|
|
5295
|
+
import { AppError as AppError10, BadRequestError as BadRequestError26, useRedis } from "@eeplatform/nodejs-utils";
|
|
6364
5296
|
function useTranscribeService() {
|
|
6365
5297
|
const { createFile } = useFileService();
|
|
6366
5298
|
const { getClient } = useRedis();
|
|
@@ -6369,10 +5301,10 @@ function useTranscribeService() {
|
|
|
6369
5301
|
try {
|
|
6370
5302
|
const fileId = await createFile(file);
|
|
6371
5303
|
} catch (error) {
|
|
6372
|
-
if (error instanceof
|
|
5304
|
+
if (error instanceof AppError10) {
|
|
6373
5305
|
throw error;
|
|
6374
5306
|
} else {
|
|
6375
|
-
throw new
|
|
5307
|
+
throw new BadRequestError26("Failed to transcribe audio file");
|
|
6376
5308
|
}
|
|
6377
5309
|
}
|
|
6378
5310
|
}
|
|
@@ -6383,31 +5315,31 @@ function useTranscribeService() {
|
|
|
6383
5315
|
|
|
6384
5316
|
// src/resources/utils/audio-transcription.controller.ts
|
|
6385
5317
|
import {
|
|
6386
|
-
AppError as
|
|
6387
|
-
BadRequestError as
|
|
6388
|
-
InternalServerError as
|
|
5318
|
+
AppError as AppError11,
|
|
5319
|
+
BadRequestError as BadRequestError27,
|
|
5320
|
+
InternalServerError as InternalServerError17
|
|
6389
5321
|
} from "@eeplatform/nodejs-utils";
|
|
6390
|
-
import
|
|
5322
|
+
import Joi13 from "joi";
|
|
6391
5323
|
function useAudioTranscriptionController() {
|
|
6392
5324
|
const geminiService = useGeminiAiService();
|
|
6393
|
-
const transcriptionOptionsSchema =
|
|
6394
|
-
language:
|
|
6395
|
-
enableTimestamps:
|
|
6396
|
-
prompt:
|
|
6397
|
-
maxTokens:
|
|
5325
|
+
const transcriptionOptionsSchema = Joi13.object({
|
|
5326
|
+
language: Joi13.string().optional().max(50),
|
|
5327
|
+
enableTimestamps: Joi13.boolean().optional(),
|
|
5328
|
+
prompt: Joi13.string().optional().max(1e3),
|
|
5329
|
+
maxTokens: Joi13.number().integer().min(1).max(8192).optional()
|
|
6398
5330
|
});
|
|
6399
|
-
const phonemeOptionsSchema =
|
|
6400
|
-
language:
|
|
6401
|
-
caseSensitive:
|
|
6402
|
-
partialMatch:
|
|
5331
|
+
const phonemeOptionsSchema = Joi13.object({
|
|
5332
|
+
language: Joi13.string().optional().max(50),
|
|
5333
|
+
caseSensitive: Joi13.boolean().optional(),
|
|
5334
|
+
partialMatch: Joi13.boolean().optional()
|
|
6403
5335
|
});
|
|
6404
|
-
const phonemeMatchSchema =
|
|
6405
|
-
targetPhoneme:
|
|
5336
|
+
const phonemeMatchSchema = Joi13.object({
|
|
5337
|
+
targetPhoneme: Joi13.string().required().min(1).max(10),
|
|
6406
5338
|
options: phonemeOptionsSchema.optional()
|
|
6407
5339
|
});
|
|
6408
5340
|
async function transcribeFromFile(req, res, next) {
|
|
6409
5341
|
if (!req.file) {
|
|
6410
|
-
next(new
|
|
5342
|
+
next(new BadRequestError27("Audio file is required"));
|
|
6411
5343
|
return;
|
|
6412
5344
|
}
|
|
6413
5345
|
try {
|
|
@@ -6415,14 +5347,14 @@ function useAudioTranscriptionController() {
|
|
|
6415
5347
|
req.body
|
|
6416
5348
|
);
|
|
6417
5349
|
if (error) {
|
|
6418
|
-
next(new
|
|
5350
|
+
next(new BadRequestError27(error.message));
|
|
6419
5351
|
return;
|
|
6420
5352
|
}
|
|
6421
5353
|
const { buffer, mimetype, originalname, size } = req.file;
|
|
6422
5354
|
if (!geminiService.validateAudioFormat(mimetype)) {
|
|
6423
5355
|
const supportedFormats = geminiService.getSupportedAudioFormats();
|
|
6424
5356
|
next(
|
|
6425
|
-
new
|
|
5357
|
+
new BadRequestError27(
|
|
6426
5358
|
`Unsupported audio format: ${mimetype}. Supported formats: ${supportedFormats.join(
|
|
6427
5359
|
", "
|
|
6428
5360
|
)}`
|
|
@@ -6433,7 +5365,7 @@ function useAudioTranscriptionController() {
|
|
|
6433
5365
|
const maxSizeBytes = 25 * 1024 * 1024;
|
|
6434
5366
|
if (size > maxSizeBytes) {
|
|
6435
5367
|
next(
|
|
6436
|
-
new
|
|
5368
|
+
new BadRequestError27(
|
|
6437
5369
|
`File size too large. Maximum allowed size is ${maxSizeBytes / (1024 * 1024)}MB`
|
|
6438
5370
|
)
|
|
6439
5371
|
);
|
|
@@ -6463,11 +5395,11 @@ function useAudioTranscriptionController() {
|
|
|
6463
5395
|
}
|
|
6464
5396
|
});
|
|
6465
5397
|
} catch (error) {
|
|
6466
|
-
if (error instanceof
|
|
5398
|
+
if (error instanceof AppError11) {
|
|
6467
5399
|
next(error);
|
|
6468
5400
|
} else {
|
|
6469
5401
|
next(
|
|
6470
|
-
new
|
|
5402
|
+
new InternalServerError17(
|
|
6471
5403
|
`Audio transcription failed: ${error.message}`
|
|
6472
5404
|
)
|
|
6473
5405
|
);
|
|
@@ -6476,21 +5408,21 @@ function useAudioTranscriptionController() {
|
|
|
6476
5408
|
}
|
|
6477
5409
|
async function transcribeFromBase64(req, res, next) {
|
|
6478
5410
|
try {
|
|
6479
|
-
const bodySchema =
|
|
6480
|
-
audioData:
|
|
6481
|
-
mimeType:
|
|
5411
|
+
const bodySchema = Joi13.object({
|
|
5412
|
+
audioData: Joi13.string().required(),
|
|
5413
|
+
mimeType: Joi13.string().required(),
|
|
6482
5414
|
options: transcriptionOptionsSchema.optional()
|
|
6483
5415
|
});
|
|
6484
5416
|
const { error, value } = bodySchema.validate(req.body);
|
|
6485
5417
|
if (error) {
|
|
6486
|
-
next(new
|
|
5418
|
+
next(new BadRequestError27(error.message));
|
|
6487
5419
|
return;
|
|
6488
5420
|
}
|
|
6489
5421
|
const { audioData, mimeType, options = {} } = value;
|
|
6490
5422
|
if (!geminiService.validateAudioFormat(mimeType)) {
|
|
6491
5423
|
const supportedFormats = geminiService.getSupportedAudioFormats();
|
|
6492
5424
|
next(
|
|
6493
|
-
new
|
|
5425
|
+
new BadRequestError27(
|
|
6494
5426
|
`Unsupported audio format: ${mimeType}. Supported formats: ${supportedFormats.join(
|
|
6495
5427
|
", "
|
|
6496
5428
|
)}`
|
|
@@ -6502,13 +5434,13 @@ function useAudioTranscriptionController() {
|
|
|
6502
5434
|
try {
|
|
6503
5435
|
audioBuffer = Buffer.from(audioData, "base64");
|
|
6504
5436
|
} catch (conversionError) {
|
|
6505
|
-
next(new
|
|
5437
|
+
next(new BadRequestError27("Invalid base64 audio data"));
|
|
6506
5438
|
return;
|
|
6507
5439
|
}
|
|
6508
5440
|
const maxSizeBytes = 25 * 1024 * 1024;
|
|
6509
5441
|
if (audioBuffer.length > maxSizeBytes) {
|
|
6510
5442
|
next(
|
|
6511
|
-
new
|
|
5443
|
+
new BadRequestError27(
|
|
6512
5444
|
`Audio data too large. Maximum allowed size is ${maxSizeBytes / (1024 * 1024)}MB`
|
|
6513
5445
|
)
|
|
6514
5446
|
);
|
|
@@ -6537,11 +5469,11 @@ function useAudioTranscriptionController() {
|
|
|
6537
5469
|
}
|
|
6538
5470
|
});
|
|
6539
5471
|
} catch (error) {
|
|
6540
|
-
if (error instanceof
|
|
5472
|
+
if (error instanceof AppError11) {
|
|
6541
5473
|
next(error);
|
|
6542
5474
|
} else {
|
|
6543
5475
|
next(
|
|
6544
|
-
new
|
|
5476
|
+
new InternalServerError17(
|
|
6545
5477
|
`Audio transcription failed: ${error.message}`
|
|
6546
5478
|
)
|
|
6547
5479
|
);
|
|
@@ -6561,7 +5493,7 @@ function useAudioTranscriptionController() {
|
|
|
6561
5493
|
});
|
|
6562
5494
|
} catch (error) {
|
|
6563
5495
|
next(
|
|
6564
|
-
new
|
|
5496
|
+
new InternalServerError17(
|
|
6565
5497
|
`Failed to get supported formats: ${error.message}`
|
|
6566
5498
|
)
|
|
6567
5499
|
);
|
|
@@ -6569,12 +5501,12 @@ function useAudioTranscriptionController() {
|
|
|
6569
5501
|
}
|
|
6570
5502
|
async function validateFormat(req, res, next) {
|
|
6571
5503
|
try {
|
|
6572
|
-
const schema =
|
|
6573
|
-
mimeType:
|
|
5504
|
+
const schema = Joi13.object({
|
|
5505
|
+
mimeType: Joi13.string().required()
|
|
6574
5506
|
});
|
|
6575
5507
|
const { error, value } = schema.validate(req.body);
|
|
6576
5508
|
if (error) {
|
|
6577
|
-
next(new
|
|
5509
|
+
next(new BadRequestError27(error.message));
|
|
6578
5510
|
return;
|
|
6579
5511
|
}
|
|
6580
5512
|
const { mimeType } = value;
|
|
@@ -6590,19 +5522,19 @@ function useAudioTranscriptionController() {
|
|
|
6590
5522
|
});
|
|
6591
5523
|
} catch (error) {
|
|
6592
5524
|
next(
|
|
6593
|
-
new
|
|
5525
|
+
new InternalServerError17(`Format validation failed: ${error.message}`)
|
|
6594
5526
|
);
|
|
6595
5527
|
}
|
|
6596
5528
|
}
|
|
6597
5529
|
async function checkPhonemeFromFile(req, res, next) {
|
|
6598
5530
|
if (!req.file) {
|
|
6599
|
-
next(new
|
|
5531
|
+
next(new BadRequestError27("Audio file is required"));
|
|
6600
5532
|
return;
|
|
6601
5533
|
}
|
|
6602
5534
|
try {
|
|
6603
5535
|
const { error, value } = phonemeMatchSchema.validate(req.body);
|
|
6604
5536
|
if (error) {
|
|
6605
|
-
next(new
|
|
5537
|
+
next(new BadRequestError27(error.message));
|
|
6606
5538
|
return;
|
|
6607
5539
|
}
|
|
6608
5540
|
const { targetPhoneme, options = {} } = value;
|
|
@@ -6610,7 +5542,7 @@ function useAudioTranscriptionController() {
|
|
|
6610
5542
|
if (!geminiService.validateAudioFormat(mimetype)) {
|
|
6611
5543
|
const supportedFormats = geminiService.getSupportedAudioFormats();
|
|
6612
5544
|
next(
|
|
6613
|
-
new
|
|
5545
|
+
new BadRequestError27(
|
|
6614
5546
|
`Unsupported audio format: ${mimetype}. Supported formats: ${supportedFormats.join(
|
|
6615
5547
|
", "
|
|
6616
5548
|
)}`
|
|
@@ -6621,7 +5553,7 @@ function useAudioTranscriptionController() {
|
|
|
6621
5553
|
const maxSizeBytes = 25 * 1024 * 1024;
|
|
6622
5554
|
if (size > maxSizeBytes) {
|
|
6623
5555
|
next(
|
|
6624
|
-
new
|
|
5556
|
+
new BadRequestError27(
|
|
6625
5557
|
`File size too large. Maximum allowed size is ${maxSizeBytes / (1024 * 1024)}MB`
|
|
6626
5558
|
)
|
|
6627
5559
|
);
|
|
@@ -6636,7 +5568,7 @@ function useAudioTranscriptionController() {
|
|
|
6636
5568
|
);
|
|
6637
5569
|
const processingTime = Date.now() - startTime;
|
|
6638
5570
|
if (!result.isMatch) {
|
|
6639
|
-
throw new
|
|
5571
|
+
throw new BadRequestError27(
|
|
6640
5572
|
`Phoneme "${targetPhoneme}" not found in the provided audio. Transcription: "${result.transcription}"`
|
|
6641
5573
|
);
|
|
6642
5574
|
}
|
|
@@ -6664,33 +5596,33 @@ function useAudioTranscriptionController() {
|
|
|
6664
5596
|
}
|
|
6665
5597
|
});
|
|
6666
5598
|
} catch (error) {
|
|
6667
|
-
if (error instanceof
|
|
5599
|
+
if (error instanceof AppError11) {
|
|
6668
5600
|
next(error);
|
|
6669
5601
|
} else {
|
|
6670
5602
|
next(
|
|
6671
|
-
new
|
|
5603
|
+
new InternalServerError17(`Phoneme analysis failed: ${error.message}`)
|
|
6672
5604
|
);
|
|
6673
5605
|
}
|
|
6674
5606
|
}
|
|
6675
5607
|
}
|
|
6676
5608
|
async function checkPhonemeFromBase64(req, res, next) {
|
|
6677
5609
|
try {
|
|
6678
|
-
const bodySchema =
|
|
6679
|
-
audioData:
|
|
6680
|
-
mimeType:
|
|
6681
|
-
targetPhoneme:
|
|
5610
|
+
const bodySchema = Joi13.object({
|
|
5611
|
+
audioData: Joi13.string().required(),
|
|
5612
|
+
mimeType: Joi13.string().required(),
|
|
5613
|
+
targetPhoneme: Joi13.string().required().min(1).max(10),
|
|
6682
5614
|
options: phonemeOptionsSchema.optional()
|
|
6683
5615
|
});
|
|
6684
5616
|
const { error, value } = bodySchema.validate(req.body);
|
|
6685
5617
|
if (error) {
|
|
6686
|
-
next(new
|
|
5618
|
+
next(new BadRequestError27(error.message));
|
|
6687
5619
|
return;
|
|
6688
5620
|
}
|
|
6689
5621
|
const { audioData, mimeType, targetPhoneme, options = {} } = value;
|
|
6690
5622
|
if (!geminiService.validateAudioFormat(mimeType)) {
|
|
6691
5623
|
const supportedFormats = geminiService.getSupportedAudioFormats();
|
|
6692
5624
|
next(
|
|
6693
|
-
new
|
|
5625
|
+
new BadRequestError27(
|
|
6694
5626
|
`Unsupported audio format: ${mimeType}. Supported formats: ${supportedFormats.join(
|
|
6695
5627
|
", "
|
|
6696
5628
|
)}`
|
|
@@ -6702,13 +5634,13 @@ function useAudioTranscriptionController() {
|
|
|
6702
5634
|
try {
|
|
6703
5635
|
audioBuffer = Buffer.from(audioData, "base64");
|
|
6704
5636
|
} catch (conversionError) {
|
|
6705
|
-
next(new
|
|
5637
|
+
next(new BadRequestError27("Invalid base64 audio data"));
|
|
6706
5638
|
return;
|
|
6707
5639
|
}
|
|
6708
5640
|
const maxSizeBytes = 25 * 1024 * 1024;
|
|
6709
5641
|
if (audioBuffer.length > maxSizeBytes) {
|
|
6710
5642
|
next(
|
|
6711
|
-
new
|
|
5643
|
+
new BadRequestError27(
|
|
6712
5644
|
`Audio data too large. Maximum allowed size is ${maxSizeBytes / (1024 * 1024)}MB`
|
|
6713
5645
|
)
|
|
6714
5646
|
);
|
|
@@ -6723,7 +5655,7 @@ function useAudioTranscriptionController() {
|
|
|
6723
5655
|
);
|
|
6724
5656
|
const processingTime = Date.now() - startTime;
|
|
6725
5657
|
if (!result.isMatch) {
|
|
6726
|
-
throw new
|
|
5658
|
+
throw new BadRequestError27(
|
|
6727
5659
|
`Phoneme "${targetPhoneme}" not found in the provided audio. Transcription: "${result.transcription}"`
|
|
6728
5660
|
);
|
|
6729
5661
|
}
|
|
@@ -6750,28 +5682,28 @@ function useAudioTranscriptionController() {
|
|
|
6750
5682
|
}
|
|
6751
5683
|
});
|
|
6752
5684
|
} catch (error) {
|
|
6753
|
-
if (error instanceof
|
|
5685
|
+
if (error instanceof AppError11) {
|
|
6754
5686
|
next(error);
|
|
6755
5687
|
} else {
|
|
6756
5688
|
next(
|
|
6757
|
-
new
|
|
5689
|
+
new InternalServerError17(`Phoneme analysis failed: ${error.message}`)
|
|
6758
5690
|
);
|
|
6759
5691
|
}
|
|
6760
5692
|
}
|
|
6761
5693
|
}
|
|
6762
5694
|
async function batchPhonemeCheck(req, res, next) {
|
|
6763
5695
|
if (!req.file) {
|
|
6764
|
-
next(new
|
|
5696
|
+
next(new BadRequestError27("Audio file is required"));
|
|
6765
5697
|
return;
|
|
6766
5698
|
}
|
|
6767
5699
|
try {
|
|
6768
|
-
const batchSchema =
|
|
6769
|
-
targetPhonemes:
|
|
5700
|
+
const batchSchema = Joi13.object({
|
|
5701
|
+
targetPhonemes: Joi13.array().items(Joi13.string().min(1).max(10)).min(1).max(20).required(),
|
|
6770
5702
|
options: phonemeOptionsSchema.optional()
|
|
6771
5703
|
});
|
|
6772
5704
|
const { error, value } = batchSchema.validate(req.body);
|
|
6773
5705
|
if (error) {
|
|
6774
|
-
next(new
|
|
5706
|
+
next(new BadRequestError27(error.message));
|
|
6775
5707
|
return;
|
|
6776
5708
|
}
|
|
6777
5709
|
const { targetPhonemes, options = {} } = value;
|
|
@@ -6779,7 +5711,7 @@ function useAudioTranscriptionController() {
|
|
|
6779
5711
|
if (!geminiService.validateAudioFormat(mimetype)) {
|
|
6780
5712
|
const supportedFormats = geminiService.getSupportedAudioFormats();
|
|
6781
5713
|
next(
|
|
6782
|
-
new
|
|
5714
|
+
new BadRequestError27(
|
|
6783
5715
|
`Unsupported audio format: ${mimetype}. Supported formats: ${supportedFormats.join(
|
|
6784
5716
|
", "
|
|
6785
5717
|
)}`
|
|
@@ -6790,7 +5722,7 @@ function useAudioTranscriptionController() {
|
|
|
6790
5722
|
const maxSizeBytes = 25 * 1024 * 1024;
|
|
6791
5723
|
if (size > maxSizeBytes) {
|
|
6792
5724
|
next(
|
|
6793
|
-
new
|
|
5725
|
+
new BadRequestError27(
|
|
6794
5726
|
`File size too large. Maximum allowed size is ${maxSizeBytes / (1024 * 1024)}MB`
|
|
6795
5727
|
)
|
|
6796
5728
|
);
|
|
@@ -6846,11 +5778,11 @@ function useAudioTranscriptionController() {
|
|
|
6846
5778
|
}
|
|
6847
5779
|
});
|
|
6848
5780
|
} catch (error) {
|
|
6849
|
-
if (error instanceof
|
|
5781
|
+
if (error instanceof AppError11) {
|
|
6850
5782
|
next(error);
|
|
6851
5783
|
} else {
|
|
6852
5784
|
next(
|
|
6853
|
-
new
|
|
5785
|
+
new InternalServerError17(
|
|
6854
5786
|
`Batch phoneme analysis failed: ${error.message}`
|
|
6855
5787
|
)
|
|
6856
5788
|
);
|
|
@@ -6871,7 +5803,7 @@ function useAudioTranscriptionController() {
|
|
|
6871
5803
|
}
|
|
6872
5804
|
});
|
|
6873
5805
|
} catch (error) {
|
|
6874
|
-
next(new
|
|
5806
|
+
next(new InternalServerError17(`Health check failed: ${error.message}`));
|
|
6875
5807
|
}
|
|
6876
5808
|
}
|
|
6877
5809
|
return {
|
|
@@ -6887,12 +5819,12 @@ function useAudioTranscriptionController() {
|
|
|
6887
5819
|
}
|
|
6888
5820
|
|
|
6889
5821
|
// src/resources/utils/util.controller.ts
|
|
6890
|
-
import
|
|
5822
|
+
import Joi14 from "joi";
|
|
6891
5823
|
import {
|
|
6892
|
-
AppError as
|
|
6893
|
-
BadRequestError as
|
|
6894
|
-
InternalServerError as
|
|
6895
|
-
logger as
|
|
5824
|
+
AppError as AppError12,
|
|
5825
|
+
BadRequestError as BadRequestError28,
|
|
5826
|
+
InternalServerError as InternalServerError18,
|
|
5827
|
+
logger as logger14
|
|
6896
5828
|
} from "@eeplatform/nodejs-utils";
|
|
6897
5829
|
function useUtilController() {
|
|
6898
5830
|
async function healthCheck(req, res, next) {
|
|
@@ -6909,32 +5841,32 @@ function useUtilController() {
|
|
|
6909
5841
|
}
|
|
6910
5842
|
});
|
|
6911
5843
|
} catch (error) {
|
|
6912
|
-
|
|
6913
|
-
next(new
|
|
5844
|
+
logger14.error("Health check failed", { error: error.message });
|
|
5845
|
+
next(new InternalServerError18("Health check failed"));
|
|
6914
5846
|
}
|
|
6915
5847
|
}
|
|
6916
5848
|
async function setGitHubVariables(req, res, next) {
|
|
6917
5849
|
try {
|
|
6918
5850
|
const { githubToken, repoUrl, environment, type, keyValues } = req.body;
|
|
6919
|
-
const validation =
|
|
6920
|
-
githubToken:
|
|
5851
|
+
const validation = Joi14.object({
|
|
5852
|
+
githubToken: Joi14.string().required().messages({
|
|
6921
5853
|
"string.empty": "GitHub token is required",
|
|
6922
5854
|
"any.required": "GitHub token is required"
|
|
6923
5855
|
}),
|
|
6924
|
-
repoUrl:
|
|
5856
|
+
repoUrl: Joi14.string().uri().required().messages({
|
|
6925
5857
|
"string.empty": "Repository URL is required",
|
|
6926
5858
|
"string.uri": "Repository URL must be a valid URL",
|
|
6927
5859
|
"any.required": "Repository URL is required"
|
|
6928
5860
|
}),
|
|
6929
|
-
environment:
|
|
5861
|
+
environment: Joi14.string().required().messages({
|
|
6930
5862
|
"string.empty": "Environment name is required",
|
|
6931
5863
|
"any.required": "Environment name is required"
|
|
6932
5864
|
}),
|
|
6933
|
-
type:
|
|
5865
|
+
type: Joi14.string().valid("env", "secret").required().messages({
|
|
6934
5866
|
"any.only": 'Type must be either "env" or "secret"',
|
|
6935
5867
|
"any.required": "Type is required"
|
|
6936
5868
|
}),
|
|
6937
|
-
keyValues:
|
|
5869
|
+
keyValues: Joi14.string().required().messages({
|
|
6938
5870
|
"string.empty": "Key-value pairs are required",
|
|
6939
5871
|
"any.required": "Key-value pairs are required"
|
|
6940
5872
|
})
|
|
@@ -6947,13 +5879,13 @@ function useUtilController() {
|
|
|
6947
5879
|
keyValues
|
|
6948
5880
|
});
|
|
6949
5881
|
if (error) {
|
|
6950
|
-
next(new
|
|
5882
|
+
next(new BadRequestError28(error.message));
|
|
6951
5883
|
return;
|
|
6952
5884
|
}
|
|
6953
5885
|
const repoUrlPattern = /github\.com[:\/]([^\/]+)\/(.+)\.git$/;
|
|
6954
5886
|
if (!repoUrlPattern.test(repoUrl)) {
|
|
6955
5887
|
next(
|
|
6956
|
-
new
|
|
5888
|
+
new BadRequestError28(
|
|
6957
5889
|
"Invalid GitHub repository URL format. Expected format: https://github.com/owner/repo.git"
|
|
6958
5890
|
)
|
|
6959
5891
|
);
|
|
@@ -6965,7 +5897,7 @@ function useUtilController() {
|
|
|
6965
5897
|
);
|
|
6966
5898
|
if (invalidLines.length > 0) {
|
|
6967
5899
|
next(
|
|
6968
|
-
new
|
|
5900
|
+
new BadRequestError28(
|
|
6969
5901
|
"Invalid key-value format. Each pair should be in format: KEY=value. Pairs should be separated by semicolons."
|
|
6970
5902
|
)
|
|
6971
5903
|
);
|
|
@@ -6979,7 +5911,7 @@ function useUtilController() {
|
|
|
6979
5911
|
type,
|
|
6980
5912
|
keyValues
|
|
6981
5913
|
});
|
|
6982
|
-
|
|
5914
|
+
logger14.info(`GitHub variables set successfully`, {
|
|
6983
5915
|
repoUrl,
|
|
6984
5916
|
environment,
|
|
6985
5917
|
type,
|
|
@@ -6996,15 +5928,15 @@ function useUtilController() {
|
|
|
6996
5928
|
}
|
|
6997
5929
|
});
|
|
6998
5930
|
} catch (error) {
|
|
6999
|
-
|
|
5931
|
+
logger14.error("Failed to set GitHub variables", {
|
|
7000
5932
|
error: error.message,
|
|
7001
5933
|
stack: error.stack
|
|
7002
5934
|
});
|
|
7003
|
-
if (error instanceof
|
|
5935
|
+
if (error instanceof AppError12) {
|
|
7004
5936
|
next(error);
|
|
7005
5937
|
} else {
|
|
7006
5938
|
next(
|
|
7007
|
-
new
|
|
5939
|
+
new InternalServerError18(
|
|
7008
5940
|
`Failed to set GitHub variables: ${error.message}`
|
|
7009
5941
|
)
|
|
7010
5942
|
);
|
|
@@ -7018,34 +5950,34 @@ function useUtilController() {
|
|
|
7018
5950
|
}
|
|
7019
5951
|
|
|
7020
5952
|
// src/resources/utils/transaction.schema.ts
|
|
7021
|
-
import
|
|
7022
|
-
var transactionSchema =
|
|
7023
|
-
_id:
|
|
7024
|
-
payment:
|
|
7025
|
-
user:
|
|
7026
|
-
org:
|
|
7027
|
-
type:
|
|
7028
|
-
amount:
|
|
7029
|
-
currency:
|
|
7030
|
-
description:
|
|
7031
|
-
metadata:
|
|
7032
|
-
subscriptionId:
|
|
7033
|
-
cycle:
|
|
7034
|
-
seats:
|
|
7035
|
-
promoCode:
|
|
5953
|
+
import Joi15 from "joi";
|
|
5954
|
+
var transactionSchema = Joi15.object({
|
|
5955
|
+
_id: Joi15.string().hex().optional().allow("", null),
|
|
5956
|
+
payment: Joi15.string().required(),
|
|
5957
|
+
user: Joi15.string().hex().optional().allow("", null),
|
|
5958
|
+
org: Joi15.string().hex().optional().allow("", null),
|
|
5959
|
+
type: Joi15.string().required(),
|
|
5960
|
+
amount: Joi15.number().positive().min(0).required(),
|
|
5961
|
+
currency: Joi15.string().required(),
|
|
5962
|
+
description: Joi15.string().optional().allow("", null),
|
|
5963
|
+
metadata: Joi15.object({
|
|
5964
|
+
subscriptionId: Joi15.string().hex().optional().allow("", null),
|
|
5965
|
+
cycle: Joi15.number().optional().allow("", null),
|
|
5966
|
+
seats: Joi15.number().optional().allow("", null),
|
|
5967
|
+
promoCode: Joi15.string().optional().allow("", null)
|
|
7036
5968
|
}).optional().allow("", null),
|
|
7037
|
-
status:
|
|
7038
|
-
createdAt:
|
|
7039
|
-
updatedAt:
|
|
7040
|
-
deletedAt:
|
|
5969
|
+
status: Joi15.string().optional().allow("", null),
|
|
5970
|
+
createdAt: Joi15.string().optional().allow("", null),
|
|
5971
|
+
updatedAt: Joi15.string().optional().allow("", null),
|
|
5972
|
+
deletedAt: Joi15.string().optional().allow("", null)
|
|
7041
5973
|
});
|
|
7042
5974
|
|
|
7043
5975
|
// src/resources/psgc/psgc.model.ts
|
|
7044
|
-
import
|
|
7045
|
-
var schemaPSGC =
|
|
7046
|
-
code:
|
|
7047
|
-
name:
|
|
7048
|
-
type:
|
|
5976
|
+
import Joi16 from "joi";
|
|
5977
|
+
var schemaPSGC = Joi16.object({
|
|
5978
|
+
code: Joi16.string().length(10).required(),
|
|
5979
|
+
name: Joi16.string().required(),
|
|
5980
|
+
type: Joi16.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required()
|
|
7049
5981
|
});
|
|
7050
5982
|
function modelPSGC(data) {
|
|
7051
5983
|
const { error } = schemaPSGC.validate(data);
|
|
@@ -7061,24 +5993,24 @@ function modelPSGC(data) {
|
|
|
7061
5993
|
|
|
7062
5994
|
// src/resources/psgc/psgc.repository.ts
|
|
7063
5995
|
import {
|
|
7064
|
-
AppError as
|
|
7065
|
-
BadRequestError as
|
|
7066
|
-
InternalServerError as
|
|
7067
|
-
logger as
|
|
7068
|
-
makeCacheKey as
|
|
7069
|
-
paginate as
|
|
7070
|
-
useAtlas as
|
|
7071
|
-
useCache as
|
|
5996
|
+
AppError as AppError13,
|
|
5997
|
+
BadRequestError as BadRequestError29,
|
|
5998
|
+
InternalServerError as InternalServerError19,
|
|
5999
|
+
logger as logger15,
|
|
6000
|
+
makeCacheKey as makeCacheKey11,
|
|
6001
|
+
paginate as paginate6,
|
|
6002
|
+
useAtlas as useAtlas14,
|
|
6003
|
+
useCache as useCache12
|
|
7072
6004
|
} from "@eeplatform/nodejs-utils";
|
|
7073
|
-
import { ObjectId as
|
|
6005
|
+
import { ObjectId as ObjectId18 } from "mongodb";
|
|
7074
6006
|
function usePSGCRepo() {
|
|
7075
|
-
const db =
|
|
6007
|
+
const db = useAtlas14.getDb();
|
|
7076
6008
|
if (!db) {
|
|
7077
6009
|
throw new Error("Unable to connect to server.");
|
|
7078
6010
|
}
|
|
7079
6011
|
const namespace_collection = "psgc";
|
|
7080
6012
|
const collection = db.collection(namespace_collection);
|
|
7081
|
-
const { getCache, setCache, delNamespace } =
|
|
6013
|
+
const { getCache, setCache, delNamespace } = useCache12(namespace_collection);
|
|
7082
6014
|
async function createIndexes() {
|
|
7083
6015
|
try {
|
|
7084
6016
|
await collection.createIndexes([
|
|
@@ -7092,12 +6024,12 @@ function usePSGCRepo() {
|
|
|
7092
6024
|
}
|
|
7093
6025
|
function delCachedData() {
|
|
7094
6026
|
delNamespace().then(() => {
|
|
7095
|
-
|
|
6027
|
+
logger15.log({
|
|
7096
6028
|
level: "info",
|
|
7097
6029
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
7098
6030
|
});
|
|
7099
6031
|
}).catch((err) => {
|
|
7100
|
-
|
|
6032
|
+
logger15.log({
|
|
7101
6033
|
level: "error",
|
|
7102
6034
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
7103
6035
|
});
|
|
@@ -7110,16 +6042,16 @@ function usePSGCRepo() {
|
|
|
7110
6042
|
delCachedData();
|
|
7111
6043
|
return res.insertedId;
|
|
7112
6044
|
} catch (error) {
|
|
7113
|
-
|
|
6045
|
+
logger15.log({
|
|
7114
6046
|
level: "error",
|
|
7115
6047
|
message: error.message
|
|
7116
6048
|
});
|
|
7117
|
-
if (error instanceof
|
|
6049
|
+
if (error instanceof AppError13) {
|
|
7118
6050
|
throw error;
|
|
7119
6051
|
} else {
|
|
7120
6052
|
const isDuplicated = error.message.includes("duplicate");
|
|
7121
6053
|
if (isDuplicated) {
|
|
7122
|
-
throw new
|
|
6054
|
+
throw new BadRequestError29("Region already exists.");
|
|
7123
6055
|
}
|
|
7124
6056
|
throw new Error("Failed to create PSGC.");
|
|
7125
6057
|
}
|
|
@@ -7155,15 +6087,15 @@ function usePSGCRepo() {
|
|
|
7155
6087
|
query.$text = { $search: search };
|
|
7156
6088
|
cacheKeyOptions.search = search;
|
|
7157
6089
|
}
|
|
7158
|
-
const cacheKey =
|
|
7159
|
-
|
|
6090
|
+
const cacheKey = makeCacheKey11(namespace_collection, cacheKeyOptions);
|
|
6091
|
+
logger15.log({
|
|
7160
6092
|
level: "info",
|
|
7161
6093
|
message: `Cache key for getAll PSGC: ${cacheKey}`
|
|
7162
6094
|
});
|
|
7163
6095
|
try {
|
|
7164
6096
|
const cached = await getCache(cacheKey);
|
|
7165
6097
|
if (cached) {
|
|
7166
|
-
|
|
6098
|
+
logger15.log({
|
|
7167
6099
|
level: "info",
|
|
7168
6100
|
message: `Cache hit for getAll PSGC: ${cacheKey}`
|
|
7169
6101
|
});
|
|
@@ -7176,35 +6108,35 @@ function usePSGCRepo() {
|
|
|
7176
6108
|
{ $limit: limit }
|
|
7177
6109
|
]).toArray();
|
|
7178
6110
|
const length = await collection.countDocuments(query);
|
|
7179
|
-
const data =
|
|
6111
|
+
const data = paginate6(items, page, limit, length);
|
|
7180
6112
|
setCache(cacheKey, data, 600).then(() => {
|
|
7181
|
-
|
|
6113
|
+
logger15.log({
|
|
7182
6114
|
level: "info",
|
|
7183
6115
|
message: `Cache set for getAll PSGC: ${cacheKey}`
|
|
7184
6116
|
});
|
|
7185
6117
|
}).catch((err) => {
|
|
7186
|
-
|
|
6118
|
+
logger15.log({
|
|
7187
6119
|
level: "error",
|
|
7188
6120
|
message: `Failed to set cache for getAll PSGC: ${err.message}`
|
|
7189
6121
|
});
|
|
7190
6122
|
});
|
|
7191
6123
|
return data;
|
|
7192
6124
|
} catch (error) {
|
|
7193
|
-
|
|
6125
|
+
logger15.log({ level: "error", message: `${error}` });
|
|
7194
6126
|
throw error;
|
|
7195
6127
|
}
|
|
7196
6128
|
}
|
|
7197
6129
|
async function getById(_id) {
|
|
7198
6130
|
try {
|
|
7199
|
-
_id = new
|
|
6131
|
+
_id = new ObjectId18(_id);
|
|
7200
6132
|
} catch (error) {
|
|
7201
|
-
throw new
|
|
6133
|
+
throw new BadRequestError29("Invalid ID.");
|
|
7202
6134
|
}
|
|
7203
|
-
const cacheKey =
|
|
6135
|
+
const cacheKey = makeCacheKey11(namespace_collection, { _id: String(_id) });
|
|
7204
6136
|
try {
|
|
7205
6137
|
const cached = await getCache(cacheKey);
|
|
7206
6138
|
if (cached) {
|
|
7207
|
-
|
|
6139
|
+
logger15.log({
|
|
7208
6140
|
level: "info",
|
|
7209
6141
|
message: `Cache hit for getById PSGC: ${cacheKey}`
|
|
7210
6142
|
});
|
|
@@ -7215,25 +6147,25 @@ function usePSGCRepo() {
|
|
|
7215
6147
|
deletedAt: { $in: ["", null] }
|
|
7216
6148
|
});
|
|
7217
6149
|
if (!result) {
|
|
7218
|
-
throw new
|
|
6150
|
+
throw new BadRequestError29("Region not found.");
|
|
7219
6151
|
}
|
|
7220
6152
|
setCache(cacheKey, result, 300).then(() => {
|
|
7221
|
-
|
|
6153
|
+
logger15.log({
|
|
7222
6154
|
level: "info",
|
|
7223
6155
|
message: `Cache set for PSGC by id: ${cacheKey}`
|
|
7224
6156
|
});
|
|
7225
6157
|
}).catch((err) => {
|
|
7226
|
-
|
|
6158
|
+
logger15.log({
|
|
7227
6159
|
level: "error",
|
|
7228
6160
|
message: `Failed to set cache for PSGC by id: ${err.message}`
|
|
7229
6161
|
});
|
|
7230
6162
|
});
|
|
7231
6163
|
return result;
|
|
7232
6164
|
} catch (error) {
|
|
7233
|
-
if (error instanceof
|
|
6165
|
+
if (error instanceof AppError13) {
|
|
7234
6166
|
throw error;
|
|
7235
6167
|
} else {
|
|
7236
|
-
throw new
|
|
6168
|
+
throw new InternalServerError19("Failed to get PSGC.");
|
|
7237
6169
|
}
|
|
7238
6170
|
}
|
|
7239
6171
|
}
|
|
@@ -7257,15 +6189,15 @@ function usePSGCRepo() {
|
|
|
7257
6189
|
query.code = { $regex: `^${prefix}` };
|
|
7258
6190
|
cacheKeyOptions.prefix = prefix;
|
|
7259
6191
|
}
|
|
7260
|
-
const cacheKey =
|
|
7261
|
-
|
|
6192
|
+
const cacheKey = makeCacheKey11(namespace_collection, { name });
|
|
6193
|
+
logger15.log({
|
|
7262
6194
|
level: "info",
|
|
7263
6195
|
message: `Query for getByName PSGC: ${JSON.stringify(query)}`
|
|
7264
6196
|
});
|
|
7265
6197
|
try {
|
|
7266
6198
|
const cached = await getCache(cacheKey);
|
|
7267
6199
|
if (cached) {
|
|
7268
|
-
|
|
6200
|
+
logger15.log({
|
|
7269
6201
|
level: "info",
|
|
7270
6202
|
message: `Cache hit for getByName PSGC: ${cacheKey}`
|
|
7271
6203
|
});
|
|
@@ -7273,36 +6205,36 @@ function usePSGCRepo() {
|
|
|
7273
6205
|
}
|
|
7274
6206
|
const result = await collection.findOne(query);
|
|
7275
6207
|
setCache(cacheKey, result, 300).then(() => {
|
|
7276
|
-
|
|
6208
|
+
logger15.log({
|
|
7277
6209
|
level: "info",
|
|
7278
6210
|
message: `Cache set for PSGC by name: ${cacheKey}`
|
|
7279
6211
|
});
|
|
7280
6212
|
}).catch((err) => {
|
|
7281
|
-
|
|
6213
|
+
logger15.log({
|
|
7282
6214
|
level: "error",
|
|
7283
6215
|
message: `Failed to set cache for PSGC by name: ${err.message}`
|
|
7284
6216
|
});
|
|
7285
6217
|
});
|
|
7286
6218
|
return result;
|
|
7287
6219
|
} catch (error) {
|
|
7288
|
-
if (error instanceof
|
|
6220
|
+
if (error instanceof AppError13) {
|
|
7289
6221
|
throw error;
|
|
7290
6222
|
} else {
|
|
7291
|
-
throw new
|
|
6223
|
+
throw new InternalServerError19("Failed to get PSGC.");
|
|
7292
6224
|
}
|
|
7293
6225
|
}
|
|
7294
6226
|
}
|
|
7295
6227
|
async function updateFieldById({ _id, field, value } = {}, session) {
|
|
7296
6228
|
const allowedFields = ["name"];
|
|
7297
6229
|
if (!allowedFields.includes(field)) {
|
|
7298
|
-
throw new
|
|
6230
|
+
throw new BadRequestError29(
|
|
7299
6231
|
`Field "${field}" is not allowed to be updated.`
|
|
7300
6232
|
);
|
|
7301
6233
|
}
|
|
7302
6234
|
try {
|
|
7303
|
-
_id = new
|
|
6235
|
+
_id = new ObjectId18(_id);
|
|
7304
6236
|
} catch (error) {
|
|
7305
|
-
throw new
|
|
6237
|
+
throw new BadRequestError29("Invalid ID.");
|
|
7306
6238
|
}
|
|
7307
6239
|
try {
|
|
7308
6240
|
await collection.updateOne(
|
|
@@ -7313,14 +6245,14 @@ function usePSGCRepo() {
|
|
|
7313
6245
|
delCachedData();
|
|
7314
6246
|
return `Successfully updated PSGC ${field}.`;
|
|
7315
6247
|
} catch (error) {
|
|
7316
|
-
throw new
|
|
6248
|
+
throw new InternalServerError19(`Failed to update PSGC ${field}.`);
|
|
7317
6249
|
}
|
|
7318
6250
|
}
|
|
7319
6251
|
async function deleteById(_id) {
|
|
7320
6252
|
try {
|
|
7321
|
-
_id = new
|
|
6253
|
+
_id = new ObjectId18(_id);
|
|
7322
6254
|
} catch (error) {
|
|
7323
|
-
throw new
|
|
6255
|
+
throw new BadRequestError29("Invalid ID.");
|
|
7324
6256
|
}
|
|
7325
6257
|
try {
|
|
7326
6258
|
await collection.updateOne(
|
|
@@ -7330,7 +6262,7 @@ function usePSGCRepo() {
|
|
|
7330
6262
|
delCachedData();
|
|
7331
6263
|
return "Successfully deleted PSGC.";
|
|
7332
6264
|
} catch (error) {
|
|
7333
|
-
throw new
|
|
6265
|
+
throw new InternalServerError19("Failed to delete PSGC.");
|
|
7334
6266
|
}
|
|
7335
6267
|
}
|
|
7336
6268
|
return {
|
|
@@ -7345,8 +6277,8 @@ function usePSGCRepo() {
|
|
|
7345
6277
|
}
|
|
7346
6278
|
|
|
7347
6279
|
// src/resources/psgc/psgc.controller.ts
|
|
7348
|
-
import { BadRequestError as
|
|
7349
|
-
import
|
|
6280
|
+
import { BadRequestError as BadRequestError30 } from "@eeplatform/nodejs-utils";
|
|
6281
|
+
import Joi17 from "joi";
|
|
7350
6282
|
function usePSGCController() {
|
|
7351
6283
|
const {
|
|
7352
6284
|
add: _add,
|
|
@@ -7360,7 +6292,7 @@ function usePSGCController() {
|
|
|
7360
6292
|
const value = req.body;
|
|
7361
6293
|
const { error } = schemaPSGC.validate(value);
|
|
7362
6294
|
if (error) {
|
|
7363
|
-
next(new
|
|
6295
|
+
next(new BadRequestError30(error.message));
|
|
7364
6296
|
return;
|
|
7365
6297
|
}
|
|
7366
6298
|
try {
|
|
@@ -7376,12 +6308,12 @@ function usePSGCController() {
|
|
|
7376
6308
|
}
|
|
7377
6309
|
async function getAll(req, res, next) {
|
|
7378
6310
|
const query = req.query;
|
|
7379
|
-
const validation =
|
|
7380
|
-
page:
|
|
7381
|
-
limit:
|
|
7382
|
-
search:
|
|
7383
|
-
type:
|
|
7384
|
-
prefix:
|
|
6311
|
+
const validation = Joi17.object({
|
|
6312
|
+
page: Joi17.number().min(1).optional().allow("", null),
|
|
6313
|
+
limit: Joi17.number().min(1).optional().allow("", null),
|
|
6314
|
+
search: Joi17.string().optional().allow("", null),
|
|
6315
|
+
type: Joi17.string().valid("Reg", "Prov", "City", "Mun", "Bgy").required(),
|
|
6316
|
+
prefix: Joi17.string().optional().allow("", null)
|
|
7385
6317
|
});
|
|
7386
6318
|
const { error } = validation.validate(query);
|
|
7387
6319
|
const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
|
|
@@ -7391,16 +6323,16 @@ function usePSGCController() {
|
|
|
7391
6323
|
const prefix = req.query.prefix ? String(req.query.prefix) : "";
|
|
7392
6324
|
const isPageNumber = isFinite(page);
|
|
7393
6325
|
if (!isPageNumber) {
|
|
7394
|
-
next(new
|
|
6326
|
+
next(new BadRequestError30("Invalid page number."));
|
|
7395
6327
|
return;
|
|
7396
6328
|
}
|
|
7397
6329
|
const isLimitNumber = isFinite(limit);
|
|
7398
6330
|
if (!isLimitNumber) {
|
|
7399
|
-
next(new
|
|
6331
|
+
next(new BadRequestError30("Invalid limit number."));
|
|
7400
6332
|
return;
|
|
7401
6333
|
}
|
|
7402
6334
|
if (error) {
|
|
7403
|
-
next(new
|
|
6335
|
+
next(new BadRequestError30(error.message));
|
|
7404
6336
|
return;
|
|
7405
6337
|
}
|
|
7406
6338
|
try {
|
|
@@ -7419,12 +6351,12 @@ function usePSGCController() {
|
|
|
7419
6351
|
}
|
|
7420
6352
|
async function getById(req, res, next) {
|
|
7421
6353
|
const id = req.params.id;
|
|
7422
|
-
const validation =
|
|
7423
|
-
id:
|
|
6354
|
+
const validation = Joi17.object({
|
|
6355
|
+
id: Joi17.string().hex().required()
|
|
7424
6356
|
});
|
|
7425
6357
|
const { error } = validation.validate({ id });
|
|
7426
6358
|
if (error) {
|
|
7427
|
-
next(new
|
|
6359
|
+
next(new BadRequestError30(error.message));
|
|
7428
6360
|
return;
|
|
7429
6361
|
}
|
|
7430
6362
|
try {
|
|
@@ -7440,12 +6372,12 @@ function usePSGCController() {
|
|
|
7440
6372
|
}
|
|
7441
6373
|
async function getByName(req, res, next) {
|
|
7442
6374
|
const name = req.params.name;
|
|
7443
|
-
const validation =
|
|
7444
|
-
name:
|
|
6375
|
+
const validation = Joi17.object({
|
|
6376
|
+
name: Joi17.string().required()
|
|
7445
6377
|
});
|
|
7446
6378
|
const { error } = validation.validate({ name });
|
|
7447
6379
|
if (error) {
|
|
7448
|
-
next(new
|
|
6380
|
+
next(new BadRequestError30(error.message));
|
|
7449
6381
|
return;
|
|
7450
6382
|
}
|
|
7451
6383
|
try {
|
|
@@ -7462,14 +6394,14 @@ function usePSGCController() {
|
|
|
7462
6394
|
async function updateField(req, res, next) {
|
|
7463
6395
|
const _id = req.params.id;
|
|
7464
6396
|
const { field, value } = req.body;
|
|
7465
|
-
const validation =
|
|
7466
|
-
_id:
|
|
7467
|
-
field:
|
|
7468
|
-
value:
|
|
6397
|
+
const validation = Joi17.object({
|
|
6398
|
+
_id: Joi17.string().hex().required(),
|
|
6399
|
+
field: Joi17.string().valid("name", "director", "directorName").required(),
|
|
6400
|
+
value: Joi17.string().required()
|
|
7469
6401
|
});
|
|
7470
6402
|
const { error } = validation.validate({ _id, field, value });
|
|
7471
6403
|
if (error) {
|
|
7472
|
-
next(new
|
|
6404
|
+
next(new BadRequestError30(error.message));
|
|
7473
6405
|
return;
|
|
7474
6406
|
}
|
|
7475
6407
|
try {
|
|
@@ -7482,12 +6414,12 @@ function usePSGCController() {
|
|
|
7482
6414
|
}
|
|
7483
6415
|
async function deleteById(req, res, next) {
|
|
7484
6416
|
const _id = req.params.id;
|
|
7485
|
-
const validation =
|
|
7486
|
-
_id:
|
|
6417
|
+
const validation = Joi17.object({
|
|
6418
|
+
_id: Joi17.string().hex().required()
|
|
7487
6419
|
});
|
|
7488
6420
|
const { error } = validation.validate({ _id });
|
|
7489
6421
|
if (error) {
|
|
7490
|
-
next(new
|
|
6422
|
+
next(new BadRequestError30(error.message));
|
|
7491
6423
|
return;
|
|
7492
6424
|
}
|
|
7493
6425
|
try {
|
|
@@ -7525,8 +6457,6 @@ export {
|
|
|
7525
6457
|
MAILER_TRANSPORT_PORT,
|
|
7526
6458
|
MAILER_TRANSPORT_SECURE,
|
|
7527
6459
|
MAddress,
|
|
7528
|
-
MBuilding,
|
|
7529
|
-
MBuildingUnit,
|
|
7530
6460
|
MFile,
|
|
7531
6461
|
MMember,
|
|
7532
6462
|
MONGO_DB,
|
|
@@ -7559,23 +6489,14 @@ export {
|
|
|
7559
6489
|
addressSchema,
|
|
7560
6490
|
isDev,
|
|
7561
6491
|
modelPSGC,
|
|
7562
|
-
schemaBuilding,
|
|
7563
|
-
schemaBuildingUnit,
|
|
7564
6492
|
schemaOrg,
|
|
7565
6493
|
schemaPSGC,
|
|
7566
|
-
schemaUpdateOptions,
|
|
7567
6494
|
transactionSchema,
|
|
7568
6495
|
useAddressController,
|
|
7569
6496
|
useAddressRepo,
|
|
7570
6497
|
useAudioTranscriptionController,
|
|
7571
6498
|
useAuthController,
|
|
7572
6499
|
useAuthService,
|
|
7573
|
-
useBuildingController,
|
|
7574
|
-
useBuildingRepo,
|
|
7575
|
-
useBuildingService,
|
|
7576
|
-
useBuildingUnitController,
|
|
7577
|
-
useBuildingUnitRepo,
|
|
7578
|
-
useBuildingUnitService,
|
|
7579
6500
|
useCounterModel,
|
|
7580
6501
|
useCounterRepo,
|
|
7581
6502
|
useFileController,
|