@goweekdays/core 2.11.15 → 2.11.17

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @goweekdays/core
2
2
 
3
+ ## 2.11.17
4
+
5
+ ### Patch Changes
6
+
7
+ - 029e07e: Add getByUserOrg to member repo and update verification logic
8
+
9
+ ## 2.11.16
10
+
11
+ ### Patch Changes
12
+
13
+ - c764e95: Add pilot org invite flow and email template
14
+
3
15
  ## 2.11.15
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -345,6 +345,7 @@ declare function useMemberRepo(): {
345
345
  deleteById: (_id: string | ObjectId, session?: ClientSession) => Promise<string>;
346
346
  updateStatusByOrg: (org: string | ObjectId, status: string, session?: ClientSession) => Promise<string>;
347
347
  countUserByOrg: (org: string | ObjectId) => Promise<any>;
348
+ getByUserOrg: (user: string | ObjectId, org: string | ObjectId) => Promise<TMember | null>;
348
349
  };
349
350
 
350
351
  declare function useMemberController(): {
@@ -374,6 +375,7 @@ type TOrg = {
374
375
  deletedAt?: string | Date;
375
376
  };
376
377
  declare const schemaOrg: Joi.ObjectSchema<any>;
378
+ declare const schemaOrgPilot: Joi.ObjectSchema<any>;
377
379
  declare const schemaOrgAdd: Joi.ObjectSchema<any>;
378
380
  declare const schemaOrgUpdate: Joi.ObjectSchema<any>;
379
381
  declare function modelOrg(value: TOrg): TOrg;
@@ -410,6 +412,13 @@ declare function useOrgService(): {
410
412
  paypalOrderLink: any;
411
413
  }>;
412
414
  addWithVerification: (id: string) => Promise<string>;
415
+ addPilot: (value: {
416
+ email: string;
417
+ name: string;
418
+ contact: string;
419
+ createdBy: string;
420
+ verificationCode: string;
421
+ }) => Promise<string>;
413
422
  };
414
423
 
415
424
  declare function useOrgController(): {
@@ -420,6 +429,7 @@ declare function useOrgController(): {
420
429
  getById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
421
430
  updateById: (req: Request, res: Response, next: NextFunction) => Promise<void>;
422
431
  companySearch: (req: Request, res: Response, next: NextFunction) => Promise<void>;
432
+ addPilot: (req: Request, res: Response, next: NextFunction) => Promise<void>;
423
433
  };
424
434
 
425
435
  type TPromo = {
@@ -722,6 +732,7 @@ type TVerificationMetadata = {
722
732
  seats?: number;
723
733
  createdBy?: string | ObjectId;
724
734
  amount?: number;
735
+ pilot?: boolean;
725
736
  };
726
737
  type TVerification = {
727
738
  _id?: ObjectId;
@@ -734,6 +745,7 @@ type TVerification = {
734
745
  expireAt?: string | Date;
735
746
  };
736
747
  declare const schemaInviteMember: Joi.ObjectSchema<any>;
748
+ declare const schemaVerificationOrgInvite: Joi.ObjectSchema<any>;
737
749
  declare const schemaVerification: Joi.ObjectSchema<any>;
738
750
  declare function modelVerification(value: TVerification): TVerification;
739
751
 
@@ -798,6 +810,10 @@ declare function useVerificationService(): {
798
810
  orgSetupFee: (value: TOrg) => Promise<{
799
811
  paypalOrderLink: any;
800
812
  }>;
813
+ inviteOrg: (value: {
814
+ email: string;
815
+ pilot?: boolean;
816
+ }) => Promise<string>;
801
817
  };
802
818
 
803
819
  declare function useVerificationController(): {
@@ -811,6 +827,7 @@ declare function useVerificationController(): {
811
827
  cancelInviteMember: (req: Request, res: Response, next: NextFunction) => Promise<void>;
812
828
  forgetPassword: (req: Request, res: Response, next: NextFunction) => Promise<void>;
813
829
  orgSetupFee: (req: Request, res: Response, next: NextFunction) => Promise<void>;
830
+ inviteOrg: (req: Request, res: Response, next: NextFunction) => Promise<void>;
814
831
  };
815
832
 
816
833
  type TPlan = {
@@ -1298,4 +1315,4 @@ declare const XENDIT_BASE_URL: string;
1298
1315
  declare const DOMAIN: string;
1299
1316
  declare const APP_ORG: string;
1300
1317
 
1301
- export { ACCESS_TOKEN_EXPIRY, ACCESS_TOKEN_SECRET, APP_ACCOUNT, APP_MAIN, APP_ORG, DEFAULT_USER_EMAIL, DEFAULT_USER_FIRST_NAME, DEFAULT_USER_LAST_NAME, DEFAULT_USER_PASSWORD, DOMAIN, MAILER_EMAIL, MAILER_PASSWORD, MAILER_TRANSPORT_HOST, MAILER_TRANSPORT_PORT, MAILER_TRANSPORT_SECURE, MBuilding, MBuildingUnit, MFile, MONGO_DB, MONGO_URI, PAYPAL_API_URL, PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET, PAYPAL_WEBHOOK_ID, PORT, PaypalWebhookHeaders, REDIS_HOST, REDIS_PASSWORD, REDIS_PORT, REFRESH_TOKEN_EXPIRY, REFRESH_TOKEN_SECRET, SECRET_KEY, SPACES_ACCESS_KEY, SPACES_BUCKET, SPACES_ENDPOINT, SPACES_REGION, SPACES_SECRET_KEY, TApp, TBuilding, TBuildingUnit, TCounter, TFile, TJobPost, TLedgerBill, TMember, TOrg, TPermission, TPermissionGroup, TPlan, TPromo, TRole, TSubscribe, TSubscription, TSubscriptionTransaction, TUser, TVerification, TVerificationMetadata, VERIFICATION_FORGET_PASSWORD_DURATION, VERIFICATION_USER_INVITE_DURATION, XENDIT_BASE_URL, XENDIT_SECRET_KEY, currencies, isDev, ledgerBillStatuses, ledgerBillTypes, modelApp, modelJobPost, modelLedgerBill, modelMember, modelOrg, modelPermission, modelPermissionGroup, modelPlan, modelPromo, modelRole, modelSubscription, modelSubscriptionTransaction, modelUser, modelVerification, schemaApp, schemaAppUpdate, schemaBuilding, schemaBuildingUnit, schemaInviteMember, schemaJobPost, schemaJobPostUpdate, schemaLedgerBill, schemaLedgerBillingSummary, schemaMember, schemaMemberRole, schemaMemberStatus, schemaOrg, schemaOrgAdd, schemaOrgUpdate, schemaPermission, schemaPermissionGroup, schemaPermissionGroupUpdate, schemaPermissionUpdate, schemaPlan, schemaPromo, schemaRole, schemaRoleUpdate, schemaSubscribe, schemaSubscription, schemaSubscriptionCompute, schemaSubscriptionPromoCode, schemaSubscriptionSeats, schemaSubscriptionTransaction, schemaSubscriptionUpdate, schemaUpdateOptions, schemaUser, schemaVerification, transactionSchema, useAppController, useAppRepo, useAppService, useAuthController, useAuthService, useBuildingController, useBuildingRepo, useBuildingService, useBuildingUnitController, useBuildingUnitRepo, useBuildingUnitService, useCounterModel, useCounterRepo, useFileController, useFileRepo, useFileService, useGitHubService, useJobPostController, useJobPostRepo, useJobPostService, useLedgerBillingController, useLedgerBillingRepo, useMemberController, useMemberRepo, useOrgController, useOrgRepo, useOrgService, usePaypalService, usePermissionController, usePermissionGroupController, usePermissionGroupRepo, usePermissionGroupService, usePermissionRepo, usePermissionService, usePlanController, usePlanRepo, usePlanService, usePromoController, usePromoRepo, usePromoUsageRepo, useRoleController, useRoleRepo, useRoleService, useSubscriptionController, useSubscriptionRepo, useSubscriptionService, useSubscriptionTransactionController, useSubscriptionTransactionRepo, useUserController, useUserRepo, useUserService, useUtilController, useVerificationController, useVerificationRepo, useVerificationService };
1318
+ export { ACCESS_TOKEN_EXPIRY, ACCESS_TOKEN_SECRET, APP_ACCOUNT, APP_MAIN, APP_ORG, DEFAULT_USER_EMAIL, DEFAULT_USER_FIRST_NAME, DEFAULT_USER_LAST_NAME, DEFAULT_USER_PASSWORD, DOMAIN, MAILER_EMAIL, MAILER_PASSWORD, MAILER_TRANSPORT_HOST, MAILER_TRANSPORT_PORT, MAILER_TRANSPORT_SECURE, MBuilding, MBuildingUnit, MFile, MONGO_DB, MONGO_URI, PAYPAL_API_URL, PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET, PAYPAL_WEBHOOK_ID, PORT, PaypalWebhookHeaders, REDIS_HOST, REDIS_PASSWORD, REDIS_PORT, REFRESH_TOKEN_EXPIRY, REFRESH_TOKEN_SECRET, SECRET_KEY, SPACES_ACCESS_KEY, SPACES_BUCKET, SPACES_ENDPOINT, SPACES_REGION, SPACES_SECRET_KEY, TApp, TBuilding, TBuildingUnit, TCounter, TFile, TJobPost, TLedgerBill, TMember, TOrg, TPermission, TPermissionGroup, TPlan, TPromo, TRole, TSubscribe, TSubscription, TSubscriptionTransaction, TUser, TVerification, TVerificationMetadata, VERIFICATION_FORGET_PASSWORD_DURATION, VERIFICATION_USER_INVITE_DURATION, XENDIT_BASE_URL, XENDIT_SECRET_KEY, currencies, isDev, ledgerBillStatuses, ledgerBillTypes, modelApp, modelJobPost, modelLedgerBill, modelMember, modelOrg, modelPermission, modelPermissionGroup, modelPlan, modelPromo, modelRole, modelSubscription, modelSubscriptionTransaction, modelUser, modelVerification, schemaApp, schemaAppUpdate, schemaBuilding, schemaBuildingUnit, schemaInviteMember, schemaJobPost, schemaJobPostUpdate, schemaLedgerBill, schemaLedgerBillingSummary, schemaMember, schemaMemberRole, schemaMemberStatus, schemaOrg, schemaOrgAdd, schemaOrgPilot, schemaOrgUpdate, schemaPermission, schemaPermissionGroup, schemaPermissionGroupUpdate, schemaPermissionUpdate, schemaPlan, schemaPromo, schemaRole, schemaRoleUpdate, schemaSubscribe, schemaSubscription, schemaSubscriptionCompute, schemaSubscriptionPromoCode, schemaSubscriptionSeats, schemaSubscriptionTransaction, schemaSubscriptionUpdate, schemaUpdateOptions, schemaUser, schemaVerification, schemaVerificationOrgInvite, transactionSchema, useAppController, useAppRepo, useAppService, useAuthController, useAuthService, useBuildingController, useBuildingRepo, useBuildingService, useBuildingUnitController, useBuildingUnitRepo, useBuildingUnitService, useCounterModel, useCounterRepo, useFileController, useFileRepo, useFileService, useGitHubService, useJobPostController, useJobPostRepo, useJobPostService, useLedgerBillingController, useLedgerBillingRepo, useMemberController, useMemberRepo, useOrgController, useOrgRepo, useOrgService, usePaypalService, usePermissionController, usePermissionGroupController, usePermissionGroupRepo, usePermissionGroupService, usePermissionRepo, usePermissionService, usePlanController, usePlanRepo, usePlanService, usePromoController, usePromoRepo, usePromoUsageRepo, useRoleController, useRoleRepo, useRoleService, useSubscriptionController, useSubscriptionRepo, useSubscriptionService, useSubscriptionTransactionController, useSubscriptionTransactionRepo, useUserController, useUserRepo, useUserService, useUtilController, useVerificationController, useVerificationRepo, useVerificationService };
package/dist/index.js CHANGED
@@ -102,6 +102,7 @@ __export(src_exports, {
102
102
  schemaMemberStatus: () => schemaMemberStatus,
103
103
  schemaOrg: () => schemaOrg,
104
104
  schemaOrgAdd: () => schemaOrgAdd,
105
+ schemaOrgPilot: () => schemaOrgPilot,
105
106
  schemaOrgUpdate: () => schemaOrgUpdate,
106
107
  schemaPermission: () => schemaPermission,
107
108
  schemaPermissionGroup: () => schemaPermissionGroup,
@@ -121,6 +122,7 @@ __export(src_exports, {
121
122
  schemaUpdateOptions: () => schemaUpdateOptions,
122
123
  schemaUser: () => schemaUser,
123
124
  schemaVerification: () => schemaVerification,
125
+ schemaVerificationOrgInvite: () => schemaVerificationOrgInvite,
124
126
  transactionSchema: () => transactionSchema,
125
127
  useAppController: () => useAppController,
126
128
  useAppRepo: () => useAppRepo,
@@ -674,6 +676,10 @@ var schemaInviteMember = import_joi2.default.object({
674
676
  app: import_joi2.default.string().required(),
675
677
  org: import_joi2.default.string().hex().optional().allow("", null)
676
678
  });
679
+ var schemaVerificationOrgInvite = import_joi2.default.object({
680
+ email: import_joi2.default.string().email().required(),
681
+ pilot: import_joi2.default.boolean().optional()
682
+ });
677
683
  var schemaVerification = import_joi2.default.object({
678
684
  type: import_joi2.default.string().required(),
679
685
  email: import_joi2.default.string().email().required(),
@@ -688,7 +694,8 @@ var schemaVerification = import_joi2.default.object({
688
694
  contact: import_joi2.default.string().optional().allow("", null),
689
695
  seats: import_joi2.default.number().optional().allow("", null),
690
696
  createdBy: import_joi2.default.string().optional().allow("", null),
691
- amount: import_joi2.default.number().optional().allow("", null)
697
+ amount: import_joi2.default.number().optional().allow("", null),
698
+ pilot: import_joi2.default.boolean().optional().allow("", null)
692
699
  }).optional(),
693
700
  expireAt: import_joi2.default.date().optional().allow("", null)
694
701
  });
@@ -2059,6 +2066,49 @@ function useMemberRepo() {
2059
2066
  );
2060
2067
  }
2061
2068
  }
2069
+ async function getByUserOrg(user, org) {
2070
+ try {
2071
+ org = new import_mongodb7.ObjectId(org);
2072
+ } catch (error) {
2073
+ throw new import_utils7.BadRequestError("Invalid organization ID.");
2074
+ }
2075
+ try {
2076
+ user = new import_mongodb7.ObjectId(user);
2077
+ } catch (error) {
2078
+ throw new import_utils7.BadRequestError("Invalid user ID.");
2079
+ }
2080
+ try {
2081
+ const cacheKey = (0, import_utils7.makeCacheKey)(namespace_collection, {
2082
+ user: String(user),
2083
+ org: String(org)
2084
+ });
2085
+ const cached = await getCache(cacheKey);
2086
+ if (cached) {
2087
+ import_utils7.logger.log({
2088
+ level: "info",
2089
+ message: `Cache hit for getByUserOrg member: ${cacheKey}`
2090
+ });
2091
+ return cached;
2092
+ }
2093
+ const data = await collection.findOne({ user, org });
2094
+ setCache(cacheKey, data, 300).then(() => {
2095
+ import_utils7.logger.log({
2096
+ level: "info",
2097
+ message: `Cache set for member by user and org: ${cacheKey}`
2098
+ });
2099
+ }).catch((err) => {
2100
+ import_utils7.logger.log({
2101
+ level: "error",
2102
+ message: `Failed to set cache for member by user and org: ${err.message}`
2103
+ });
2104
+ });
2105
+ return data;
2106
+ } catch (error) {
2107
+ throw new import_utils7.InternalServerError(
2108
+ "Internal server error, failed to retrieve member."
2109
+ );
2110
+ }
2111
+ }
2062
2112
  return {
2063
2113
  createIndexes,
2064
2114
  add,
@@ -2078,7 +2128,8 @@ function useMemberRepo() {
2078
2128
  updateStatusById,
2079
2129
  deleteById,
2080
2130
  updateStatusByOrg,
2081
- countUserByOrg
2131
+ countUserByOrg,
2132
+ getByUserOrg
2082
2133
  };
2083
2134
  }
2084
2135
 
@@ -4492,13 +4543,17 @@ var schema = {
4492
4543
  name: import_joi15.default.string().max(255).required(),
4493
4544
  description: import_joi15.default.string().max(1024).optional().allow("", null),
4494
4545
  email: import_joi15.default.string().email().max(255).required(),
4495
- contact: import_joi15.default.string().max(50).optional().allow("", null),
4496
- promoCode: import_joi15.default.string().max(50).optional().allow("", null)
4546
+ contact: import_joi15.default.string().max(50).optional().allow("", null)
4497
4547
  };
4498
4548
  var schemaOrg = import_joi15.default.object({
4499
4549
  ...schema,
4500
4550
  createdBy: import_joi15.default.string().hex().required()
4501
4551
  });
4552
+ var schemaOrgPilot = import_joi15.default.object({
4553
+ ...schema,
4554
+ createdBy: import_joi15.default.string().hex().required(),
4555
+ verificationCode: import_joi15.default.string().hex().required()
4556
+ });
4502
4557
  var schemaOrgAdd = import_joi15.default.object({
4503
4558
  ...schema,
4504
4559
  createdBy: import_joi15.default.string().hex().required()
@@ -9305,7 +9360,8 @@ function useVerificationController() {
9305
9360
  signUp: _signUp,
9306
9361
  cancelInviteMember: _cancelInviteMember,
9307
9362
  forgetPassword: _forgetPassword,
9308
- orgSetupFee: _orgSetupFee
9363
+ orgSetupFee: _orgSetupFee,
9364
+ inviteOrg: _inviteOrg
9309
9365
  } = useVerificationService();
9310
9366
  const { getVerifications: _getVerifications } = useVerificationRepo();
9311
9367
  async function createUserInvite(req, res, next) {
@@ -9526,6 +9582,20 @@ function useVerificationController() {
9526
9582
  next(error2);
9527
9583
  }
9528
9584
  }
9585
+ async function inviteOrg(req, res, next) {
9586
+ const value = req.body;
9587
+ const { error } = schemaVerificationOrgInvite.validate(value);
9588
+ if (error) {
9589
+ next(new import_utils48.BadRequestError(error.message));
9590
+ }
9591
+ try {
9592
+ const message = await _inviteOrg(value);
9593
+ res.json({ message });
9594
+ return;
9595
+ } catch (error2) {
9596
+ next(error2);
9597
+ }
9598
+ }
9529
9599
  return {
9530
9600
  getVerifications,
9531
9601
  createUserInvite,
@@ -9536,7 +9606,8 @@ function useVerificationController() {
9536
9606
  signUp,
9537
9607
  cancelInviteMember,
9538
9608
  forgetPassword,
9539
- orgSetupFee
9609
+ orgSetupFee,
9610
+ inviteOrg
9540
9611
  };
9541
9612
  }
9542
9613
 
@@ -9691,7 +9762,6 @@ function useOrgService() {
9691
9762
  try {
9692
9763
  session?.startTransaction();
9693
9764
  const verification = await getById(id);
9694
- await updateVerificationStatus(id, "complete", session);
9695
9765
  if (!verification) {
9696
9766
  throw new import_utils49.BadRequestError("Verification not found.");
9697
9767
  }
@@ -9704,6 +9774,10 @@ function useOrgService() {
9704
9774
  if (!verification.metadata?.contact) {
9705
9775
  throw new import_utils49.BadRequestError("Contact is required.");
9706
9776
  }
9777
+ if (verification.type !== "org-setup-fee") {
9778
+ throw new import_utils49.BadRequestError("Invalid verification type.");
9779
+ }
9780
+ await updateVerificationStatus(id, "complete", session);
9707
9781
  const org = await addOrg(
9708
9782
  {
9709
9783
  email: verification.email,
@@ -9805,9 +9879,125 @@ function useOrgService() {
9805
9879
  await session?.endSession();
9806
9880
  }
9807
9881
  }
9882
+ async function addPilot(value) {
9883
+ const { error } = schemaOrgPilot.validate(value);
9884
+ if (error) {
9885
+ throw new import_utils49.BadRequestError(error.message);
9886
+ }
9887
+ const session = import_utils49.useAtlas.getClient()?.startSession();
9888
+ if (!session) {
9889
+ throw new import_utils49.BadRequestError("Unable to start database session.");
9890
+ }
9891
+ try {
9892
+ session?.startTransaction();
9893
+ const verification = await getById(value.verificationCode);
9894
+ if (!verification) {
9895
+ throw new import_utils49.BadRequestError("Verification not found.");
9896
+ }
9897
+ if (verification.type !== "org-invite") {
9898
+ throw new import_utils49.BadRequestError("Invalid verification type.");
9899
+ }
9900
+ if (verification.metadata && !verification.metadata.pilot) {
9901
+ throw new import_utils49.BadRequestError("Not a pilot invitation.");
9902
+ }
9903
+ await updateVerificationStatus(
9904
+ value.verificationCode,
9905
+ "complete",
9906
+ session
9907
+ );
9908
+ const org = await addOrg(
9909
+ {
9910
+ email: value.email,
9911
+ name: value.name,
9912
+ contact: value.contact,
9913
+ createdBy: value.createdBy
9914
+ },
9915
+ session
9916
+ );
9917
+ const plan = await getDefault();
9918
+ if (!plan) {
9919
+ throw new import_utils49.BadRequestError(
9920
+ "Failed to create organization, plan not found."
9921
+ );
9922
+ }
9923
+ const currentDate = /* @__PURE__ */ new Date();
9924
+ const nextBillingDate = new Date(currentDate);
9925
+ nextBillingDate.setMonth(currentDate.getMonth() + 1);
9926
+ const createdBy = String(value.createdBy);
9927
+ const user = await getUserById(createdBy);
9928
+ if (!user) {
9929
+ throw new import_utils49.BadRequestError("User is required to create org member.");
9930
+ }
9931
+ const allPermissions = await getAllPermission({
9932
+ app: "org",
9933
+ limit: 100
9934
+ });
9935
+ let permissions = [];
9936
+ if (allPermissions && allPermissions.items && allPermissions.items.length) {
9937
+ permissions = allPermissions.items.map((perm) => perm.key);
9938
+ }
9939
+ if (permissions.length === 0) {
9940
+ throw new Error("No permissions found for the organization type.");
9941
+ }
9942
+ const roleData = {
9943
+ org: String(org),
9944
+ name: "Owner",
9945
+ description: "Owner of the organization",
9946
+ permissions,
9947
+ createdBy,
9948
+ app: "org"
9949
+ };
9950
+ const role = await addRole(roleData, session);
9951
+ if (!role) {
9952
+ throw new import_utils49.BadRequestError("Role is required to create org member.");
9953
+ }
9954
+ await addMember(
9955
+ {
9956
+ role: String(role),
9957
+ roleName: roleData.name,
9958
+ org: String(org),
9959
+ orgName: value.name,
9960
+ name: `${user.firstName} ${user.lastName}`,
9961
+ user: createdBy,
9962
+ app: "org"
9963
+ },
9964
+ session
9965
+ );
9966
+ const filePath = (0, import_utils49.getDirectory)(
9967
+ __dirname,
9968
+ "./public/handlebars/org-created"
9969
+ );
9970
+ const emailContent = (0, import_utils49.compileHandlebar)({
9971
+ context: {
9972
+ app: APP_ORG,
9973
+ organization_name: value.name
9974
+ },
9975
+ filePath
9976
+ });
9977
+ mailer.sendMail({
9978
+ to: verification.email,
9979
+ subject: "Welcome to GoWeekdays - Your Organization is Ready",
9980
+ html: emailContent,
9981
+ from: "GoWeekdays"
9982
+ }).catch((error2) => {
9983
+ import_utils49.logger.log({
9984
+ level: "error",
9985
+ message: `Error sending user invite email: ${error2}`
9986
+ });
9987
+ });
9988
+ await session?.commitTransaction();
9989
+ return "Successfully created organization with verification.";
9990
+ } catch (error2) {
9991
+ await session?.abortTransaction();
9992
+ throw error2;
9993
+ } finally {
9994
+ await session?.endSession();
9995
+ }
9996
+ }
9808
9997
  return {
9809
9998
  add,
9810
- addWithVerification
9999
+ addWithVerification,
10000
+ addPilot
9811
10001
  };
9812
10002
  }
9813
10003
 
@@ -9824,6 +10014,7 @@ function useOrgController() {
9824
10014
  updateById: _updateById,
9825
10015
  companySearch: _companySearch
9826
10016
  } = useOrgRepo();
10017
+ const { addPilot: _addPilot } = useOrgService();
9827
10018
  async function add(req, res, next) {
9828
10019
  const value = req.body;
9829
10020
  const { error } = schemaOrgAdd.validate(value);
@@ -9842,6 +10033,24 @@ function useOrgController() {
9842
10033
  next(error2);
9843
10034
  }
9844
10035
  }
10036
+ async function addPilot(req, res, next) {
10037
+ const value = req.body;
10038
+ const { error } = schemaOrgPilot.validate(value);
10039
+ if (error) {
10040
+ next(new import_utils50.BadRequestError(error.message));
10041
+ return;
10042
+ }
10043
+ try {
10044
+ const data = await _addPilot(value);
10045
+ res.json({
10046
+ message: "Organization created successfully.",
10047
+ data
10048
+ });
10049
+ return;
10050
+ } catch (error2) {
10051
+ next(error2);
10052
+ }
10053
+ }
9845
10054
  async function getOrgsByUserId(req, res, next) {
9846
10055
  const page = typeof req.query.page === "string" ? Number(req.query.page) : 1;
9847
10056
  const limit = typeof req.query.limit === "string" ? Number(req.query.limit) : 10;
@@ -9985,7 +10194,8 @@ function useOrgController() {
9985
10194
  getAll,
9986
10195
  getById,
9987
10196
  updateById,
9988
- companySearch
10197
+ companySearch,
10198
+ addPilot
9989
10199
  };
9990
10200
  }
9991
10201
 
@@ -10410,7 +10620,8 @@ function useUserController() {
10410
10620
  const id = req.params.id || "";
10411
10621
  const validation = import_joi43.default.string().hex().validate(id);
10412
10622
  if (validation.error) {
10413
- throw new import_utils52.BadRequestError("Invalid id.");
10623
+ next(new import_utils52.BadRequestError("Invalid user ID."));
10624
+ return;
10414
10625
  }
10415
10626
  try {
10416
10627
  const user = await _getUserById(id);
@@ -10614,7 +10825,11 @@ function useVerificationService() {
10614
10825
  getVerifications: _getVerifications
10615
10826
  } = useVerificationRepo();
10616
10827
  const { getUserByEmail } = useUserRepo();
10617
- const { add: addMember, countUserByOrg } = useMemberRepo();
10828
+ const {
10829
+ add: addMember,
10830
+ countUserByOrg,
10831
+ getByUserOrg: getMemberByUserOrg
10832
+ } = useMemberRepo();
10618
10833
  const { getById: getOrgById } = useOrgRepo();
10619
10834
  const { getById: getRoleById } = useRoleRepo();
10620
10835
  async function createUserInvite({
@@ -10946,8 +11161,17 @@ function useVerificationService() {
10946
11161
  );
10947
11162
  }
10948
11163
  }
11164
+ const user = await getUserByEmail(value.email);
11165
+ let userId = "";
11166
+ if (user) {
11167
+ userId = String(user._id);
11168
+ }
10949
11169
  const memberCount = await countUserByOrg(String(value.org));
10950
- if (subscription.seats <= memberCount) {
11170
+ const existingMember = await getMemberByUserOrg(
11171
+ userId,
11172
+ String(value.org)
11173
+ );
11174
+ if (subscription.seats <= memberCount && !existingMember) {
10951
11175
  throw new import_utils53.BadRequestError(
10952
11176
  "Organization has reached the maximum number of members for its subscription plan."
10953
11177
  );
@@ -11142,12 +11366,79 @@ function useVerificationService() {
11142
11366
  paypalOrderLink: paypalOrderLink ? paypalOrderLink.href : ""
11143
11367
  };
11144
11368
  } catch (error) {
11369
+ import_utils53.logger.log({
11370
+ level: "error",
11371
+ message: `Error processing organization setup fee: ${error}`
11372
+ });
11373
+ await session?.abortTransaction();
11145
11374
  if (error instanceof import_utils53.AppError) {
11146
11375
  throw error;
11147
11376
  }
11148
11377
  throw new import_utils53.InternalServerError(
11149
11378
  "Failed to process organization setup fee."
11150
11379
  );
11380
+ } finally {
11381
+ session?.endSession();
11382
+ }
11383
+ }
11384
+ async function inviteOrg(value) {
11385
+ const { error } = schemaVerificationOrgInvite.validate(value);
11386
+ if (error) {
11387
+ throw new import_utils53.BadRequestError(error.message);
11388
+ }
11389
+ const session = import_utils53.useAtlas.getClient()?.startSession();
11390
+ if (!session) {
11391
+ throw new import_utils53.BadRequestError("Unable to start database session.");
11392
+ }
11393
+ try {
11394
+ session.startTransaction();
11395
+ const orgExistingByEmail = await getOrgByEmail(value.email);
11396
+ if (orgExistingByEmail) {
11397
+ throw new import_utils53.BadRequestError(`Email ${value.email} is already taken.`);
11398
+ }
11399
+ const verificationId = await add(
11400
+ {
11401
+ type: "org-invite",
11402
+ email: value.email,
11403
+ metadata: {
11404
+ pilot: value.pilot
11405
+ }
11406
+ },
11407
+ session
11408
+ );
11409
+ const filePath = (0, import_utils53.getDirectory)(
11410
+ __dirname,
11411
+ "./public/handlebars/org-invite"
11412
+ );
11413
+ const emailContent = (0, import_utils53.compileHandlebar)({
11414
+ context: {
11415
+ validity: VERIFICATION_USER_INVITE_DURATION,
11416
+ link: `${APP_ORG}/organizations/create?invite=${verificationId}`
11417
+ },
11418
+ filePath
11419
+ });
11420
+ await mailer.sendMail({
11421
+ to: value.email,
11422
+ subject: value.pilot ? "Pilot Organization Invitation" : "Organization Invitation",
11423
+ html: emailContent,
11424
+ from: "GoWeekdays"
11425
+ });
11426
+ await session?.commitTransaction();
11427
+ return "Successfully created organization invite.";
11428
+ } catch (error2) {
11429
+ import_utils53.logger.log({
11430
+ level: "error",
11431
+ message: `Error inviting organization: ${error2}`
11432
+ });
11433
+ await session?.abortTransaction();
11434
+ if (error2 instanceof import_utils53.AppError) {
11435
+ throw error2;
11436
+ }
11437
+ throw new import_utils53.InternalServerError(
11438
+ "Failed to process organization setup fee."
11439
+ );
11440
+ } finally {
11441
+ session?.endSession();
11151
11442
  }
11152
11443
  }
11153
11444
  return {
@@ -11162,7 +11453,8 @@ function useVerificationService() {
11162
11453
  inviteMember,
11163
11454
  cancelInviteMember,
11164
11455
  forgetPassword,
11165
- orgSetupFee
11456
+ orgSetupFee,
11457
+ inviteOrg
11166
11458
  };
11167
11459
  }
11168
11460
 
@@ -13678,6 +13970,7 @@ function useJobPostController() {
13678
13970
  schemaMemberStatus,
13679
13971
  schemaOrg,
13680
13972
  schemaOrgAdd,
13973
+ schemaOrgPilot,
13681
13974
  schemaOrgUpdate,
13682
13975
  schemaPermission,
13683
13976
  schemaPermissionGroup,
@@ -13697,6 +13990,7 @@ function useJobPostController() {
13697
13990
  schemaUpdateOptions,
13698
13991
  schemaUser,
13699
13992
  schemaVerification,
13993
+ schemaVerificationOrgInvite,
13700
13994
  transactionSchema,
13701
13995
  useAppController,
13702
13996
  useAppRepo,