@7365admin1/core 3.18.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -12092,7 +12092,8 @@ function useVerificationService() {
12092
12092
  email,
12093
12093
  orgId,
12094
12094
  siteId,
12095
- siteName
12095
+ siteName,
12096
+ inviteType
12096
12097
  }) {
12097
12098
  const schema2 = Joi11.object({
12098
12099
  email: Joi11.string().email().lowercase().required(),
@@ -12129,11 +12130,11 @@ function useVerificationService() {
12129
12130
  };
12130
12131
  try {
12131
12132
  const org = await getOrgById(orgId);
12132
- if (org) {
12133
- value.type = "service-provider-create-org" /* SERVICE_PROVIDER_CREATE_ORG */;
12133
+ if (inviteType === "organization-invite") {
12134
+ value.type = "service-provider-invite" /* SERVICE_PROVIDER_INVITE */;
12134
12135
  subject = "Service Provider Organization Invite" /* _SERVICE_PROVIDER_ORGANIZATION_INVITE */;
12135
12136
  } else {
12136
- value.type = "service-provider-invite" /* SERVICE_PROVIDER_INVITE */;
12137
+ value.type = "service-provider-create-org" /* SERVICE_PROVIDER_CREATE_ORG */;
12137
12138
  subject = "Service Provider Invite" /* _SERVICE_PROVIDER_INVITE */;
12138
12139
  }
12139
12140
  const res = await _add(value);
@@ -14728,25 +14729,47 @@ function useVerificationController() {
14728
14729
  email: Joi16.string().email().required(),
14729
14730
  orgId: Joi16.string().hex().required(),
14730
14731
  siteId: Joi16.string().hex().required(),
14731
- siteName: Joi16.string().required()
14732
+ siteName: Joi16.string().required(),
14733
+ inviteType: Joi16.string().valid("create-org", "organization-invite").required()
14732
14734
  });
14733
14735
  const { error } = validation.validate(payload);
14734
14736
  if (error) {
14735
- logger22.log({ level: "error", message: `controller - ${error.message}` });
14737
+ logger22.log({
14738
+ level: "error",
14739
+ message: `controller - ${error.message}`
14740
+ });
14736
14741
  next(new BadRequestError31(`Invalid input: ${error.message}`));
14737
14742
  return;
14738
14743
  }
14744
+ const {
14745
+ email,
14746
+ orgId,
14747
+ siteId,
14748
+ siteName,
14749
+ inviteType
14750
+ } = payload;
14739
14751
  try {
14740
- await _createServiceProviderInvite(payload);
14752
+ await _createServiceProviderInvite({
14753
+ email,
14754
+ orgId,
14755
+ siteId,
14756
+ siteName,
14757
+ inviteType
14758
+ });
14741
14759
  const cookieOptions = {
14742
14760
  domain: DOMAIN,
14743
14761
  secure: true,
14744
14762
  maxAge: 4 * 60 * 60 * 1e3
14745
14763
  };
14746
- res.cookie("service-provider-email", payload.email, cookieOptions).json({ message: "Successfully invited service provider." });
14764
+ res.cookie("service-provider-email", email, cookieOptions).json({
14765
+ message: "Successfully invited service provider."
14766
+ });
14747
14767
  return;
14748
14768
  } catch (error2) {
14749
- logger22.log({ level: "error", message: `controller - ${error2.message}` });
14769
+ logger22.log({
14770
+ level: "error",
14771
+ message: `controller - ${error2.message}`
14772
+ });
14750
14773
  next(error2);
14751
14774
  return;
14752
14775
  }
@@ -15106,421 +15129,77 @@ function useFileController() {
15106
15129
 
15107
15130
  // src/controllers/organization.controller.ts
15108
15131
  import {
15109
- BadRequestError as BadRequestError33,
15110
- logger as logger25,
15132
+ BadRequestError as BadRequestError35,
15133
+ logger as logger26,
15111
15134
  NotFoundError as NotFoundError11
15112
15135
  } from "@7365admin1/node-server-utils";
15113
- import Joi18 from "joi";
15114
- function useOrgController() {
15115
- const { getOrgsByMembership } = useMemberRepo();
15116
- const {
15117
- getByName: _getByName,
15118
- getById: _getById,
15119
- getByEmail: _getByEmail,
15120
- getAll: _getAll,
15121
- add: _add,
15122
- update: _update,
15123
- getOrgsByEmail: _getOrgsByEmail,
15124
- getAdminOrgForResident: _getAdminOrgForResident,
15125
- completeOnboardingById: _completeOnboardingById
15126
- } = useOrgRepo();
15127
- async function add(req, res, next) {
15128
- const validation = Joi18.object({
15129
- name: Joi18.string().required(),
15130
- type: Joi18.string().required(),
15131
- nature: Joi18.string().valid(...allowedNatures).required(),
15132
- email: Joi18.string().email().optional().allow("", null),
15133
- contact: Joi18.string().optional().allow("", null),
15134
- terms: Joi18.string().optional().allow("", null),
15135
- policies: Joi18.string().optional().allow("", null)
15136
- });
15137
- const { error } = validation.validate(req.body);
15138
- if (error) {
15139
- logger25.log({ level: "error", message: error.message });
15140
- next(new BadRequestError33(error.message));
15141
- return;
15142
- }
15143
- try {
15144
- await _add(req.body);
15145
- res.status(201).json({ message: "Successfully created organization." });
15146
- return;
15147
- } catch (error2) {
15148
- logger25.log({ level: "error", message: error2.message });
15149
- next(error2);
15150
- return;
15151
- }
15152
- }
15153
- async function getAll(req, res, next) {
15154
- const validation = Joi18.object({
15155
- search: Joi18.string().optional().allow("", null),
15156
- page: Joi18.number().integer().min(1).allow("", null).default(1),
15157
- limit: Joi18.number().integer().min(1).max(100).allow("", null).default(10),
15158
- nature: Joi18.string().valid(...allowedNatures).optional().allow("", null),
15159
- sort: Joi18.string().optional().allow("", null)
15160
- });
15161
- const query = { ...req.query };
15162
- const { error } = validation.validate(query);
15163
- if (error) {
15164
- logger25.log({ level: "error", message: error.message });
15165
- next(new BadRequestError33(error.message));
15166
- return;
15167
- }
15168
- const search = req.query.search ?? "";
15169
- const page = parseInt(req.query.page ?? "1");
15170
- const limit = parseInt(req.query.limit ?? "10");
15171
- const nature = req.query.nature ?? "";
15172
- try {
15173
- const data = await _getAll({
15174
- search,
15175
- page,
15176
- limit,
15177
- nature
15178
- });
15179
- res.json(data);
15180
- return;
15181
- } catch (error2) {
15182
- logger25.log({ level: "error", message: error2.message });
15183
- next(error2);
15184
- return;
15185
- }
15186
- }
15187
- async function addOnboardingOrg(req, res, next) {
15188
- const validation = Joi18.object({
15189
- name: Joi18.string().required(),
15190
- type: Joi18.string().required(),
15191
- nature: Joi18.string().valid(...allowedNatures).required(),
15192
- email: Joi18.string().email().optional().allow("", null),
15193
- contact: Joi18.string().optional().allow("", null)
15194
- });
15195
- const { error } = validation.validate(req.body);
15196
- if (error) {
15197
- logger25.log({ level: "error", message: error.message });
15198
- next(new BadRequestError33(error.message));
15199
- return;
15200
- }
15201
- try {
15202
- const _id = await _add(req.body);
15203
- const data = await _getById(_id);
15204
- res.status(201).json({
15205
- message: "Successfully created organization.",
15206
- data
15207
- });
15208
- return;
15209
- } catch (error2) {
15210
- logger25.log({ level: "error", message: error2.message });
15211
- next(error2);
15212
- return;
15213
- }
15214
- }
15215
- async function getOrgsByUserId(req, res, next) {
15216
- const validation = Joi18.object({
15217
- search: Joi18.string().optional().allow("", null),
15218
- page: Joi18.number().integer().min(1).allow("", null).default(1),
15219
- limit: Joi18.number().integer().min(1).max(100).allow("", null).default(10),
15220
- user: Joi18.string().hex().required(),
15221
- type: Joi18.string().optional().allow("", null)
15222
- });
15223
- const query = { ...req.query };
15224
- query.user = req.params.user;
15225
- const { error } = validation.validate(query);
15226
- if (error) {
15227
- logger25.log({ level: "error", message: error.message });
15228
- next(new BadRequestError33(error.message));
15229
- return;
15230
- }
15231
- const search = req.query.search ?? "";
15232
- const page = parseInt(req.query.page ?? "1");
15233
- const limit = parseInt(req.query.limit ?? "10");
15234
- const user = req.params.user;
15235
- const type = req.query.type ?? "";
15236
- try {
15237
- const data = await getOrgsByMembership({
15238
- search,
15239
- page,
15240
- limit,
15241
- user,
15242
- type
15243
- });
15244
- res.json(data);
15245
- return;
15246
- } catch (error2) {
15247
- logger25.log({ level: "error", message: error2.message });
15248
- next(error2);
15249
- return;
15250
- }
15251
- }
15252
- async function getByName(req, res, next) {
15253
- const validation = Joi18.string().required();
15254
- const name = req.params.name;
15255
- const { error } = validation.validate(name);
15256
- if (error) {
15257
- logger25.log({ level: "error", message: error.message });
15258
- next(new BadRequestError33(error.message));
15259
- return;
15260
- }
15261
- try {
15262
- const data = await _getByName(name);
15263
- res.json(data);
15264
- return;
15265
- } catch (error2) {
15266
- next(error2);
15267
- return;
15268
- }
15269
- }
15270
- async function getById(req, res, next) {
15271
- const validation = Joi18.string().hex().required();
15272
- const _id = req.params.id;
15273
- const { error } = validation.validate(_id);
15274
- if (error) {
15275
- logger25.log({ level: "error", message: error.message });
15276
- next(new BadRequestError33(error.message));
15277
- return;
15278
- }
15279
- try {
15280
- const data = await _getById(_id);
15281
- res.json(data);
15282
- return;
15283
- } catch (error2) {
15284
- logger25.log({ level: "error", message: error2.message });
15285
- next(error2);
15286
- return;
15287
- }
15288
- }
15289
- async function getByEmail(req, res, next) {
15290
- const validation = Joi18.string().required();
15291
- const email = req.params.email;
15292
- const { error } = validation.validate(email);
15293
- if (error) {
15294
- logger25.log({ level: "error", message: error.message });
15295
- next(new BadRequestError33(error.message));
15296
- return;
15297
- }
15298
- try {
15299
- const data = await _getByEmail(email);
15300
- if (!data) {
15301
- next(new NotFoundError11("Organization not found."));
15302
- return;
15303
- }
15304
- res.json(data);
15305
- return;
15306
- } catch (error2) {
15307
- next(error2);
15308
- return;
15309
- }
15310
- }
15311
- async function getOrgsByEmail(req, res, next) {
15312
- const validation = Joi18.object({
15313
- email: Joi18.string().email().required()
15314
- });
15315
- const query = {
15316
- email: req.params.email
15317
- };
15318
- const { error } = validation.validate(query);
15319
- if (error) {
15320
- logger25.log({ level: "error", message: error.message });
15321
- next(new BadRequestError33(error.message));
15322
- return;
15323
- }
15324
- const email = req.params.email;
15325
- try {
15326
- const data = await _getOrgsByEmail(email);
15327
- res.json(data);
15328
- return;
15329
- } catch (error2) {
15330
- logger25.log({ level: "error", message: error2.message });
15331
- next(error2);
15332
- return;
15333
- }
15334
- }
15335
- async function update(req, res, next) {
15336
- const validation = Joi18.object({
15337
- name: Joi18.string().optional(),
15338
- type: Joi18.string().optional(),
15339
- nature: Joi18.string().valid(...allowedNatures).optional(),
15340
- email: Joi18.string().email().allow("", null).optional(),
15341
- contact: Joi18.string().allow("", null).optional(),
15342
- terms: Joi18.string().optional().allow("", null),
15343
- policies: Joi18.string().optional().allow("", null)
15344
- });
15345
- const { error } = validation.validate(req.body);
15346
- if (error) {
15347
- next(new BadRequestError33(error.message));
15348
- return;
15349
- }
15350
- const id = req.params.id;
15351
- try {
15352
- await _update(id, req.body);
15353
- const data = await _getById(id);
15354
- res.json({
15355
- message: "Organization updated successfully",
15356
- data
15357
- });
15358
- } catch (err) {
15359
- next(err);
15360
- }
15361
- }
15362
- async function getAdminOrgForResident(_req, res, next) {
15363
- try {
15364
- const data = await _getAdminOrgForResident();
15365
- res.status(200).json(data);
15366
- } catch (error) {
15367
- logger25.log({ level: "error", message: error.message });
15368
- next(error);
15369
- }
15370
- }
15371
- return {
15372
- add,
15373
- addOnboardingOrg,
15374
- getAll,
15375
- getOrgsByUserId,
15376
- getByName,
15377
- getById,
15378
- getByEmail,
15379
- update,
15380
- getOrgsByEmail,
15381
- getAdminOrgForResident
15382
- };
15383
- }
15136
+ import Joi20 from "joi";
15384
15137
 
15385
- // src/controllers/organization-v2.controller.ts
15386
- import Joi19 from "joi";
15387
- import { BadRequestError as BadRequestError34, logger as logger26 } from "@7365admin1/node-server-utils";
15388
- function useOrgControllerV2() {
15389
- const { getAll: _getAll, getOrganizationsWithSubscription: _getOrganizationsWithSubscription } = useOrgRepo();
15390
- async function getAll(req, res, next) {
15391
- const validation = Joi19.object({
15392
- search: Joi19.string().optional().allow("", null),
15393
- page: Joi19.number().integer().min(1).allow("", null).default(1),
15394
- limit: Joi19.number().integer().min(1).max(100).allow("", null).default(10),
15395
- nature: Joi19.string().valid(...allowedNatures).optional().allow("", null),
15396
- status: Joi19.string().trim().valid("active", "suspended", "deleted").optional().empty("").default("active")
15397
- });
15398
- const query = { ...req.query };
15399
- const { error, value } = validation.validate(query, {
15400
- convert: true,
15401
- stripUnknown: true
15402
- });
15403
- if (error) {
15404
- logger26.log({ level: "error", message: error.message });
15405
- next(new BadRequestError34(error.message));
15406
- return;
15407
- }
15408
- const search = value.search ?? "";
15409
- const page = typeof value.page === "number" ? value.page : parseInt(String(value.page ?? "1"), 10);
15410
- const limit = typeof value.limit === "number" ? value.limit : parseInt(String(value.limit ?? "10"), 10);
15411
- const nature = value.nature ?? "";
15412
- const status = value.status;
15413
- try {
15414
- const data = await _getAll({
15415
- search,
15416
- page,
15417
- limit,
15418
- nature,
15419
- status
15420
- });
15421
- res.json(data);
15422
- return;
15423
- } catch (error2) {
15424
- logger26.log({ level: "error", message: error2.message });
15425
- next(error2);
15426
- return;
15427
- }
15428
- }
15429
- async function getOrganizationsWithSubscription(req, res, next) {
15430
- const validation = Joi19.object({
15431
- search: Joi19.string().optional().allow("", null),
15432
- page: Joi19.number().integer().min(1).default(1),
15433
- limit: Joi19.number().integer().min(1).max(100).default(10),
15434
- status: Joi19.string().trim().valid("active", "suspended", "deleted").default("active"),
15435
- type: Joi19.string().optional().allow("", null),
15436
- billingCycle: Joi19.string().optional().allow("", null)
15437
- });
15438
- const { error, value } = validation.validate(
15439
- req.query,
15440
- {
15441
- convert: true,
15442
- stripUnknown: true
15443
- }
15444
- );
15445
- if (error) {
15446
- next(new BadRequestError34(error.message));
15447
- return;
15448
- }
15449
- try {
15450
- const data = await _getOrganizationsWithSubscription({
15451
- search: value.search ?? "",
15452
- page: value.page ?? 1,
15453
- limit: value.limit ?? 10,
15454
- status: value.status ?? "active",
15455
- type: value.type ?? "",
15456
- billingCycle: value.billingCycle ?? ""
15457
- });
15458
- res.json(data);
15459
- } catch (error2) {
15460
- next(error2);
15461
- }
15462
- }
15463
- return {
15464
- getAll,
15465
- getOrganizationsWithSubscription
15466
- };
15467
- }
15138
+ // src/repositories/subscription.repo.ts
15139
+ import {
15140
+ BadRequestError as BadRequestError34,
15141
+ logger as logger25,
15142
+ makeCacheKey as makeCacheKey13,
15143
+ paginate as paginate11,
15144
+ useAtlas as useAtlas17,
15145
+ useCache as useCache14
15146
+ } from "@7365admin1/node-server-utils";
15468
15147
 
15469
15148
  // src/models/subscription.model.ts
15470
- import { BadRequestError as BadRequestError35 } from "@7365admin1/node-server-utils";
15471
- import Joi20 from "joi";
15149
+ import { BadRequestError as BadRequestError33 } from "@7365admin1/node-server-utils";
15150
+ import Joi18 from "joi";
15472
15151
  import { ObjectId as ObjectId22 } from "mongodb";
15473
15152
  var SubscriptionType = /* @__PURE__ */ ((SubscriptionType2) => {
15474
15153
  SubscriptionType2["ORGANIZATION"] = "organization";
15475
15154
  SubscriptionType2["AFFILIATE"] = "affiliate";
15476
15155
  return SubscriptionType2;
15477
15156
  })(SubscriptionType || {});
15478
- var schema = Joi20.object({
15479
- user: Joi20.string().hex().required(),
15480
- amount: Joi20.number().min(0).required(),
15481
- payment_method_card_number: Joi20.string().optional().allow("", null),
15482
- payment_method_cardholder_name: Joi20.string().optional().allow("", null),
15483
- payment_method_expiry_month: Joi20.string().optional().allow("", null),
15484
- payment_method_expiry_year: Joi20.string().optional().allow("", null),
15485
- payment_method_cvv: Joi20.string().optional().allow("", null),
15486
- payment_method_type: Joi20.string().optional().allow("", null),
15487
- currency: Joi20.string().optional().allow("", null),
15488
- seats: Joi20.number().optional().min(0).allow(null),
15157
+ var schema = Joi18.object({
15158
+ user: Joi18.string().hex().required(),
15159
+ amount: Joi18.number().min(0).required(),
15160
+ payment_method_card_number: Joi18.string().optional().allow("", null),
15161
+ payment_method_cardholder_name: Joi18.string().optional().allow("", null),
15162
+ payment_method_expiry_month: Joi18.string().optional().allow("", null),
15163
+ payment_method_expiry_year: Joi18.string().optional().allow("", null),
15164
+ payment_method_cvv: Joi18.string().optional().allow("", null),
15165
+ payment_method_type: Joi18.string().optional().allow("", null),
15166
+ currency: Joi18.string().optional().allow("", null),
15167
+ seats: Joi18.number().optional().min(0).allow(null),
15489
15168
  organization: orgSchema.optional().allow({}),
15490
- billingAddress: Joi20.object({
15491
- type: Joi20.string().required(),
15492
- country: Joi20.string().required(),
15493
- address: Joi20.string().required(),
15494
- continuedAddress: Joi20.string().optional().allow("", null),
15495
- city: Joi20.string().required(),
15496
- province: Joi20.string().optional().allow("", null),
15497
- postalCode: Joi20.string().required(),
15498
- taxId: Joi20.string().optional().allow("", null)
15169
+ billingAddress: Joi18.object({
15170
+ type: Joi18.string().required(),
15171
+ country: Joi18.string().required(),
15172
+ address: Joi18.string().required(),
15173
+ continuedAddress: Joi18.string().optional().allow("", null),
15174
+ city: Joi18.string().required(),
15175
+ province: Joi18.string().optional().allow("", null),
15176
+ postalCode: Joi18.string().required(),
15177
+ taxId: Joi18.string().optional().allow("", null)
15499
15178
  }).required(),
15500
- promoCode: Joi20.string().optional().allow("", null)
15179
+ promoCode: Joi18.string().optional().allow("", null)
15501
15180
  });
15502
15181
  function MSubscription(value) {
15503
- const schema2 = Joi20.object({
15504
- _id: Joi20.string().hex().optional().allow("", null),
15505
- user: Joi20.string().hex().optional().allow("", null),
15506
- org: Joi20.string().hex().optional().allow("", null),
15507
- amount: Joi20.number().min(0).required(),
15508
- currency: Joi20.string().required(),
15509
- description: Joi20.string().optional().allow("", null),
15510
- promoCode: Joi20.string().optional().allow("", null),
15511
- type: Joi20.string().valid(...Object.values(SubscriptionType)).optional().allow(null, ""),
15512
- paidSeats: Joi20.number().optional().min(0).allow("", null),
15513
- currentSeats: Joi20.number().optional().min(0).allow("", null),
15514
- maxSeats: Joi20.number().optional().min(0).allow("", null),
15515
- status: Joi20.string().optional().allow("", null),
15516
- billingCycle: Joi20.string().valid("monthly", "yearly").required(),
15182
+ const schema2 = Joi18.object({
15183
+ _id: Joi18.string().hex().optional().allow("", null),
15184
+ user: Joi18.string().hex().optional().allow("", null),
15185
+ org: Joi18.string().hex().optional().allow("", null),
15186
+ amount: Joi18.number().min(0).required(),
15187
+ currency: Joi18.string().required(),
15188
+ description: Joi18.string().optional().allow("", null),
15189
+ promoCode: Joi18.string().optional().allow("", null),
15190
+ type: Joi18.string().valid(...Object.values(SubscriptionType)).optional().allow(null, ""),
15191
+ paidSeats: Joi18.number().optional().min(0).allow("", null),
15192
+ currentSeats: Joi18.number().optional().min(0).allow("", null),
15193
+ maxSeats: Joi18.number().optional().min(0).allow("", null),
15194
+ status: Joi18.string().optional().allow("", null),
15195
+ billingCycle: Joi18.string().valid("monthly", "yearly").required(),
15517
15196
  // Ensure valid values
15518
- nextBillingDate: Joi20.date().optional(),
15519
- lastPaymentStatus: Joi20.string().optional().allow("", null),
15520
- failedAttempts: Joi20.number().optional().allow("", null),
15521
- createdAt: Joi20.date().optional(),
15522
- updatedAt: Joi20.string().optional().allow("", null),
15523
- deletedAt: Joi20.string().optional().allow("", null)
15197
+ nextBillingDate: Joi18.date().optional(),
15198
+ lastPaymentStatus: Joi18.string().optional().allow("", null),
15199
+ failedAttempts: Joi18.number().optional().allow("", null),
15200
+ createdAt: Joi18.date().optional(),
15201
+ updatedAt: Joi18.string().optional().allow("", null),
15202
+ deletedAt: Joi18.string().optional().allow("", null)
15524
15203
  }).custom((value2, helpers) => {
15525
15204
  if (!value2.user && !value2.org) {
15526
15205
  return helpers.error("any.invalid", {
@@ -15531,7 +15210,7 @@ function MSubscription(value) {
15531
15210
  });
15532
15211
  const { error } = schema2.validate(value);
15533
15212
  if (error) {
15534
- throw new BadRequestError35(error.details[0].message);
15213
+ throw new BadRequestError33(error.details[0].message);
15535
15214
  }
15536
15215
  if (value._id)
15537
15216
  value._id = new ObjectId22(value._id);
@@ -15571,20 +15250,12 @@ function MSubscription(value) {
15571
15250
  }
15572
15251
 
15573
15252
  // src/repositories/subscription.repo.ts
15574
- import {
15575
- BadRequestError as BadRequestError36,
15576
- logger as logger27,
15577
- makeCacheKey as makeCacheKey13,
15578
- paginate as paginate11,
15579
- useAtlas as useAtlas17,
15580
- useCache as useCache14
15581
- } from "@7365admin1/node-server-utils";
15582
15253
  import { ObjectId as ObjectId23 } from "mongodb";
15583
- import Joi21 from "joi";
15254
+ import Joi19 from "joi";
15584
15255
  function useSubscriptionRepo() {
15585
15256
  const db = useAtlas17.getDb();
15586
15257
  if (!db) {
15587
- throw new BadRequestError36("Unable to connect to server.");
15258
+ throw new BadRequestError34("Unable to connect to server.");
15588
15259
  }
15589
15260
  const namespace_collection = "subscriptions";
15590
15261
  const collection = db.collection(namespace_collection);
@@ -15599,7 +15270,7 @@ function useSubscriptionRepo() {
15599
15270
  { key: { failedAttempts: 1 } }
15600
15271
  ]);
15601
15272
  } catch (error) {
15602
- throw new BadRequestError36("Failed to create index on subscription.");
15273
+ throw new BadRequestError34("Failed to create index on subscription.");
15603
15274
  }
15604
15275
  }
15605
15276
  async function createUniqueIndex() {
@@ -15609,7 +15280,7 @@ function useSubscriptionRepo() {
15609
15280
  { unique: true }
15610
15281
  );
15611
15282
  } catch (error) {
15612
- throw new BadRequestError36(
15283
+ throw new BadRequestError34(
15613
15284
  "Failed to create unique index on subscription."
15614
15285
  );
15615
15286
  }
@@ -15620,76 +15291,76 @@ function useSubscriptionRepo() {
15620
15291
  value = MSubscription(value);
15621
15292
  const res = await collection.insertOne(value, { session });
15622
15293
  delNamespace().then(() => {
15623
- logger27.info(`Cache cleared for namespace: ${namespace_collection}`);
15294
+ logger25.info(`Cache cleared for namespace: ${namespace_collection}`);
15624
15295
  }).catch((err) => {
15625
- logger27.error(
15296
+ logger25.error(
15626
15297
  `Failed to clear cache for namespace: ${namespace_collection}`,
15627
15298
  err
15628
15299
  );
15629
15300
  });
15630
15301
  return res.insertedId;
15631
15302
  } catch (error) {
15632
- logger27.log({ level: "error", message: `${error}` });
15303
+ logger25.log({ level: "error", message: `${error}` });
15633
15304
  const isDuplicated = error.message.includes("duplicate");
15634
15305
  if (isDuplicated) {
15635
- throw new BadRequestError36("Subscription already exists.");
15306
+ throw new BadRequestError34("Subscription already exists.");
15636
15307
  }
15637
- throw new BadRequestError36("Failed to create subscription.");
15308
+ throw new BadRequestError34("Failed to create subscription.");
15638
15309
  }
15639
15310
  }
15640
15311
  async function getById(_id) {
15641
15312
  try {
15642
15313
  _id = new ObjectId23(_id);
15643
15314
  } catch (error) {
15644
- throw new BadRequestError36("Invalid subscription ID format.");
15315
+ throw new BadRequestError34("Invalid subscription ID format.");
15645
15316
  }
15646
15317
  try {
15647
15318
  const cacheKey = makeCacheKey13(namespace_collection, { _id });
15648
15319
  const cachedData = await getCache(cacheKey);
15649
15320
  if (cachedData) {
15650
- logger27.info(`Cache hit for key: ${cacheKey}`);
15321
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15651
15322
  return cachedData;
15652
15323
  }
15653
15324
  const data = await collection.findOne({ _id });
15654
15325
  setCache(cacheKey, data, 15 * 60).then(() => {
15655
- logger27.info(`Cache set for key: ${cacheKey}`);
15326
+ logger25.info(`Cache set for key: ${cacheKey}`);
15656
15327
  }).catch((err) => {
15657
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15328
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15658
15329
  });
15659
15330
  return data;
15660
15331
  } catch (error) {
15661
- throw new BadRequestError36("Failed to get subscription by ID.");
15332
+ throw new BadRequestError34("Failed to get subscription by ID.");
15662
15333
  }
15663
15334
  }
15664
15335
  async function getByUserId(user) {
15665
15336
  try {
15666
15337
  user = new ObjectId23(user);
15667
15338
  } catch (error) {
15668
- throw new BadRequestError36("Invalid user ID format.");
15339
+ throw new BadRequestError34("Invalid user ID format.");
15669
15340
  }
15670
15341
  try {
15671
15342
  const cacheKey = makeCacheKey13(namespace_collection, { user });
15672
15343
  const cachedData = await getCache(cacheKey);
15673
15344
  if (cachedData) {
15674
- logger27.info(`Cache hit for key: ${cacheKey}`);
15345
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15675
15346
  return cachedData;
15676
15347
  }
15677
15348
  const data = await collection.findOne({ user });
15678
15349
  setCache(cacheKey, data, 15 * 60).then(() => {
15679
- logger27.info(`Cache set for key: ${cacheKey}`);
15350
+ logger25.info(`Cache set for key: ${cacheKey}`);
15680
15351
  }).catch((err) => {
15681
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15352
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15682
15353
  });
15683
15354
  return data;
15684
15355
  } catch (error) {
15685
- throw new BadRequestError36("Failed to get subscription by ID.");
15356
+ throw new BadRequestError34("Failed to get subscription by ID.");
15686
15357
  }
15687
15358
  }
15688
15359
  async function getByAffiliateUserId(user) {
15689
15360
  try {
15690
15361
  user = new ObjectId23(user);
15691
15362
  } catch (error) {
15692
- throw new BadRequestError36("Invalid user ID format.");
15363
+ throw new BadRequestError34("Invalid user ID format.");
15693
15364
  }
15694
15365
  try {
15695
15366
  const cacheKey = makeCacheKey13(namespace_collection, {
@@ -15698,7 +15369,7 @@ function useSubscriptionRepo() {
15698
15369
  });
15699
15370
  const cachedData = await getCache(cacheKey);
15700
15371
  if (cachedData) {
15701
- logger27.info(`Cache hit for key: ${cacheKey}`);
15372
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15702
15373
  return cachedData;
15703
15374
  }
15704
15375
  const data = await collection.findOne({
@@ -15706,20 +15377,20 @@ function useSubscriptionRepo() {
15706
15377
  type: "affiliate"
15707
15378
  });
15708
15379
  setCache(cacheKey, data, 15 * 60).then(() => {
15709
- logger27.info(`Cache set for key: ${cacheKey}`);
15380
+ logger25.info(`Cache set for key: ${cacheKey}`);
15710
15381
  }).catch((err) => {
15711
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15382
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15712
15383
  });
15713
15384
  return data;
15714
15385
  } catch (error) {
15715
- throw new BadRequestError36("Failed to get subscription by ID.");
15386
+ throw new BadRequestError34("Failed to get subscription by ID.");
15716
15387
  }
15717
15388
  }
15718
15389
  async function getByOrgId(org) {
15719
15390
  try {
15720
15391
  org = new ObjectId23(org);
15721
15392
  } catch (error) {
15722
- throw new BadRequestError36("Invalid org ID format.");
15393
+ throw new BadRequestError34("Invalid org ID format.");
15723
15394
  }
15724
15395
  try {
15725
15396
  const cacheKey = makeCacheKey13(namespace_collection, {
@@ -15728,7 +15399,7 @@ function useSubscriptionRepo() {
15728
15399
  });
15729
15400
  const cachedData = await getCache(cacheKey);
15730
15401
  if (cachedData) {
15731
- logger27.info(`Cache hit for key: ${cacheKey}`);
15402
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15732
15403
  return cachedData;
15733
15404
  }
15734
15405
  const data = await collection.findOne({
@@ -15736,13 +15407,13 @@ function useSubscriptionRepo() {
15736
15407
  type: "organization"
15737
15408
  });
15738
15409
  setCache(cacheKey, data, 15 * 60).then(() => {
15739
- logger27.info(`Cache set for key: ${cacheKey}`);
15410
+ logger25.info(`Cache set for key: ${cacheKey}`);
15740
15411
  }).catch((err) => {
15741
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15412
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15742
15413
  });
15743
15414
  return data;
15744
15415
  } catch (error) {
15745
- throw new BadRequestError36("Failed to get subscription by ID.");
15416
+ throw new BadRequestError34("Failed to get subscription by ID.");
15746
15417
  }
15747
15418
  }
15748
15419
  async function getBySubscriptionId(subscriptionId) {
@@ -15750,18 +15421,18 @@ function useSubscriptionRepo() {
15750
15421
  const cacheKey = makeCacheKey13(namespace_collection, { subscriptionId });
15751
15422
  const cachedData = await getCache(cacheKey);
15752
15423
  if (cachedData) {
15753
- logger27.info(`Cache hit for key: ${cacheKey}`);
15424
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15754
15425
  return cachedData;
15755
15426
  }
15756
15427
  const data = await collection.findOne({ subscriptionId });
15757
15428
  setCache(cacheKey, data, 15 * 60).then(() => {
15758
- logger27.info(`Cache set for key: ${cacheKey}`);
15429
+ logger25.info(`Cache set for key: ${cacheKey}`);
15759
15430
  }).catch((err) => {
15760
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15431
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15761
15432
  });
15762
15433
  return data;
15763
15434
  } catch (error) {
15764
- throw new BadRequestError36(
15435
+ throw new BadRequestError34(
15765
15436
  "Failed to get subscription by subscription ID."
15766
15437
  );
15767
15438
  }
@@ -15785,7 +15456,7 @@ function useSubscriptionRepo() {
15785
15456
  const cacheKey = makeCacheKey13(namespace_collection, cacheOptions);
15786
15457
  const cachedData = await getCache(cacheKey);
15787
15458
  if (cachedData) {
15788
- logger27.info(`Cache hit for key: ${cacheKey}`);
15459
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15789
15460
  return cachedData;
15790
15461
  }
15791
15462
  try {
@@ -15798,13 +15469,13 @@ function useSubscriptionRepo() {
15798
15469
  const length = await collection.countDocuments(query);
15799
15470
  const data = paginate11(items, page, limit, length);
15800
15471
  setCache(cacheKey, data, 15 * 60).then(() => {
15801
- logger27.info(`Cache set for key: ${cacheKey}`);
15472
+ logger25.info(`Cache set for key: ${cacheKey}`);
15802
15473
  }).catch((err) => {
15803
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15474
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15804
15475
  });
15805
15476
  return data;
15806
15477
  } catch (error) {
15807
- logger27.log({ level: "error", message: `${error}` });
15478
+ logger25.log({ level: "error", message: `${error}` });
15808
15479
  throw error;
15809
15480
  }
15810
15481
  }
@@ -15812,19 +15483,19 @@ function useSubscriptionRepo() {
15812
15483
  try {
15813
15484
  _id = new ObjectId23(_id);
15814
15485
  } catch (error) {
15815
- throw new BadRequestError36("Invalid subscription ID format.");
15486
+ throw new BadRequestError34("Invalid subscription ID format.");
15816
15487
  }
15817
15488
  try {
15818
15489
  await collection.updateOne({ _id }, { $set: { status } });
15819
15490
  const cacheKey = makeCacheKey13(namespace_collection, { _id });
15820
15491
  delCache(cacheKey).then(() => {
15821
- logger27.info(`Cache deleted for key: ${cacheKey}`);
15492
+ logger25.info(`Cache deleted for key: ${cacheKey}`);
15822
15493
  }).catch((err) => {
15823
- logger27.error(`Failed to delete cache for key: ${cacheKey}`, err);
15494
+ logger25.error(`Failed to delete cache for key: ${cacheKey}`, err);
15824
15495
  });
15825
15496
  return "Successfully updated subscription status.";
15826
15497
  } catch (error) {
15827
- throw new BadRequestError36("Failed to update subscription status.");
15498
+ throw new BadRequestError34("Failed to update subscription status.");
15828
15499
  }
15829
15500
  }
15830
15501
  async function getDueSubscriptions(BATCH_SIZE = 100) {
@@ -15851,7 +15522,7 @@ function useSubscriptionRepo() {
15851
15522
  const cacheKey = makeCacheKey13(namespace_collection, cacheOptions);
15852
15523
  const cachedData = await getCache(cacheKey);
15853
15524
  if (cachedData) {
15854
- logger27.info(`Cache hit for key: ${cacheKey}`);
15525
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15855
15526
  return cachedData;
15856
15527
  }
15857
15528
  try {
@@ -15873,13 +15544,13 @@ function useSubscriptionRepo() {
15873
15544
  ]
15874
15545
  }).sort({ nextBillingDate: 1 }).limit(BATCH_SIZE).toArray();
15875
15546
  setCache(cacheKey, data, 15 * 60).then(() => {
15876
- logger27.info(`Cache set for key: ${cacheKey}`);
15547
+ logger25.info(`Cache set for key: ${cacheKey}`);
15877
15548
  }).catch((err) => {
15878
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15549
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15879
15550
  });
15880
15551
  return data;
15881
15552
  } catch (error) {
15882
- throw new BadRequestError36("Failed to get due subscriptions.");
15553
+ throw new BadRequestError34("Failed to get due subscriptions.");
15883
15554
  }
15884
15555
  }
15885
15556
  async function getFailedSubscriptions(BATCH_SIZE = 100) {
@@ -15890,7 +15561,7 @@ function useSubscriptionRepo() {
15890
15561
  const cacheKey = makeCacheKey13(namespace_collection, cacheOptions);
15891
15562
  const cachedData = await getCache(cacheKey);
15892
15563
  if (cachedData) {
15893
- logger27.info(`Cache hit for key: ${cacheKey}`);
15564
+ logger25.info(`Cache hit for key: ${cacheKey}`);
15894
15565
  return cachedData;
15895
15566
  }
15896
15567
  try {
@@ -15899,13 +15570,13 @@ function useSubscriptionRepo() {
15899
15570
  status: "active"
15900
15571
  }).limit(BATCH_SIZE).toArray();
15901
15572
  setCache(cacheKey, data, 15 * 60).then(() => {
15902
- logger27.info(`Cache set for key: ${cacheKey}`);
15573
+ logger25.info(`Cache set for key: ${cacheKey}`);
15903
15574
  }).catch((err) => {
15904
- logger27.error(`Failed to set cache for key: ${cacheKey}`, err);
15575
+ logger25.error(`Failed to set cache for key: ${cacheKey}`, err);
15905
15576
  });
15906
15577
  return data;
15907
15578
  } catch (error) {
15908
- throw new BadRequestError36("Failed to get failed subscriptions.");
15579
+ throw new BadRequestError34("Failed to get failed subscriptions.");
15909
15580
  }
15910
15581
  }
15911
15582
  async function findOrgSubscriptionsForStatusSync() {
@@ -15919,7 +15590,7 @@ function useSubscriptionRepo() {
15919
15590
  ).toArray();
15920
15591
  return data;
15921
15592
  } catch (error) {
15922
- throw new BadRequestError36(
15593
+ throw new BadRequestError34(
15923
15594
  "Failed to list organization subscriptions for status sync."
15924
15595
  );
15925
15596
  }
@@ -15938,24 +15609,24 @@ function useSubscriptionRepo() {
15938
15609
  ).toArray();
15939
15610
  return data;
15940
15611
  } catch (error) {
15941
- throw new BadRequestError36(
15612
+ throw new BadRequestError34(
15942
15613
  "Failed to list organization subscriptions with overdue next billing date."
15943
15614
  );
15944
15615
  }
15945
15616
  }
15946
15617
  async function processSuccessfulPayment(value, session) {
15947
- const schema2 = Joi21.object({
15948
- _id: Joi21.string().hex().required(),
15949
- nextBillingDate: Joi21.date().required()
15618
+ const schema2 = Joi19.object({
15619
+ _id: Joi19.string().hex().required(),
15620
+ nextBillingDate: Joi19.date().required()
15950
15621
  });
15951
15622
  const { error } = schema2.validate(value);
15952
15623
  if (error) {
15953
- throw new BadRequestError36(error.message);
15624
+ throw new BadRequestError34(error.message);
15954
15625
  }
15955
15626
  try {
15956
15627
  value._id = new ObjectId23(value._id);
15957
15628
  } catch (error2) {
15958
- throw new BadRequestError36("Invalid subscription ID format.");
15629
+ throw new BadRequestError34("Invalid subscription ID format.");
15959
15630
  }
15960
15631
  const date = value.nextBillingDate;
15961
15632
  try {
@@ -15973,31 +15644,31 @@ function useSubscriptionRepo() {
15973
15644
  },
15974
15645
  { session }
15975
15646
  );
15976
- logger27.info(`${res.modifiedCount} subscription updated.`);
15647
+ logger25.info(`${res.modifiedCount} subscription updated.`);
15977
15648
  const cacheKey = makeCacheKey13(namespace_collection, { _id: value._id });
15978
15649
  delCache(cacheKey).then(() => {
15979
- logger27.info(`Cache deleted for key: ${cacheKey}`);
15650
+ logger25.info(`Cache deleted for key: ${cacheKey}`);
15980
15651
  }).catch((err) => {
15981
- logger27.error(`Failed to delete cache for key: ${cacheKey}`, err);
15652
+ logger25.error(`Failed to delete cache for key: ${cacheKey}`, err);
15982
15653
  });
15983
15654
  return "Successfully updated subscription.";
15984
15655
  } catch (error2) {
15985
- logger27.error(`${error2}`);
15986
- throw new BadRequestError36("Failed to update subscription.");
15656
+ logger25.error(`${error2}`);
15657
+ throw new BadRequestError34("Failed to update subscription.");
15987
15658
  }
15988
15659
  }
15989
15660
  async function markSubscriptionAsFailed({ _id, failed }, session) {
15990
- const schema2 = Joi21.object({
15991
- _id: Joi21.string().hex().required()
15661
+ const schema2 = Joi19.object({
15662
+ _id: Joi19.string().hex().required()
15992
15663
  });
15993
15664
  const { error } = schema2.validate({ _id });
15994
15665
  if (error) {
15995
- throw new BadRequestError36(error.message);
15666
+ throw new BadRequestError34(error.message);
15996
15667
  }
15997
15668
  try {
15998
15669
  _id = new ObjectId23(_id);
15999
15670
  } catch (error2) {
16000
- throw new BadRequestError36("Invalid subscription ID format.");
15671
+ throw new BadRequestError34("Invalid subscription ID format.");
16001
15672
  }
16002
15673
  const updateOptions = {
16003
15674
  $inc: { failedAttempts: 1 }
@@ -16011,27 +15682,27 @@ function useSubscriptionRepo() {
16011
15682
  });
16012
15683
  const cacheKey = makeCacheKey13(namespace_collection, { _id });
16013
15684
  delCache(cacheKey).then(() => {
16014
- logger27.info(`Cache deleted for key: ${cacheKey}`);
15685
+ logger25.info(`Cache deleted for key: ${cacheKey}`);
16015
15686
  }).catch((err) => {
16016
- logger27.error(`Failed to delete cache for key: ${cacheKey}`, err);
15687
+ logger25.error(`Failed to delete cache for key: ${cacheKey}`, err);
16017
15688
  });
16018
15689
  return result;
16019
15690
  } catch (error2) {
16020
- throw new BadRequestError36("Failed to update subscription.");
15691
+ throw new BadRequestError34("Failed to update subscription.");
16021
15692
  }
16022
15693
  }
16023
15694
  async function markSubscriptionAsCanceled(_id, session) {
16024
- const schema2 = Joi21.object({
16025
- _id: Joi21.string().hex().required()
15695
+ const schema2 = Joi19.object({
15696
+ _id: Joi19.string().hex().required()
16026
15697
  });
16027
15698
  const { error } = schema2.validate({ _id });
16028
15699
  if (error) {
16029
- throw new BadRequestError36(error.message);
15700
+ throw new BadRequestError34(error.message);
16030
15701
  }
16031
15702
  try {
16032
15703
  _id = new ObjectId23(_id);
16033
15704
  } catch (error2) {
16034
- throw new BadRequestError36("Invalid subscription ID format.");
15705
+ throw new BadRequestError34("Invalid subscription ID format.");
16035
15706
  }
16036
15707
  try {
16037
15708
  const result = await collection.updateOne(
@@ -16041,27 +15712,27 @@ function useSubscriptionRepo() {
16041
15712
  );
16042
15713
  const cacheKey = makeCacheKey13(namespace_collection, { _id });
16043
15714
  delCache(cacheKey).then(() => {
16044
- logger27.info(`Cache deleted for key: ${cacheKey}`);
15715
+ logger25.info(`Cache deleted for key: ${cacheKey}`);
16045
15716
  }).catch((err) => {
16046
- logger27.error(`Failed to delete cache for key: ${cacheKey}`, err);
15717
+ logger25.error(`Failed to delete cache for key: ${cacheKey}`, err);
16047
15718
  });
16048
15719
  return result;
16049
15720
  } catch (error2) {
16050
- throw new BadRequestError36("Failed to update subscription.");
15721
+ throw new BadRequestError34("Failed to update subscription.");
16051
15722
  }
16052
15723
  }
16053
15724
  async function updateStatusById(_id, status, session) {
16054
- const schema2 = Joi21.object({
16055
- _id: Joi21.string().hex().required()
15725
+ const schema2 = Joi19.object({
15726
+ _id: Joi19.string().hex().required()
16056
15727
  });
16057
15728
  const { error } = schema2.validate({ _id });
16058
15729
  if (error) {
16059
- throw new BadRequestError36(error.message);
15730
+ throw new BadRequestError34(error.message);
16060
15731
  }
16061
15732
  try {
16062
15733
  _id = new ObjectId23(_id);
16063
15734
  } catch (error2) {
16064
- throw new BadRequestError36("Invalid subscription ID format.");
15735
+ throw new BadRequestError34("Invalid subscription ID format.");
16065
15736
  }
16066
15737
  try {
16067
15738
  const result = await collection.updateOne(
@@ -16071,13 +15742,13 @@ function useSubscriptionRepo() {
16071
15742
  );
16072
15743
  const cacheKey = makeCacheKey13(namespace_collection, { _id });
16073
15744
  delCache(cacheKey).then(() => {
16074
- logger27.info(`Cache deleted for key: ${cacheKey}`);
15745
+ logger25.info(`Cache deleted for key: ${cacheKey}`);
16075
15746
  }).catch((err) => {
16076
- logger27.error(`Failed to delete cache for key: ${cacheKey}`, err);
15747
+ logger25.error(`Failed to delete cache for key: ${cacheKey}`, err);
16077
15748
  });
16078
15749
  return result;
16079
15750
  } catch (error2) {
16080
- throw new BadRequestError36("Failed to update subscription status.");
15751
+ throw new BadRequestError34("Failed to update subscription status.");
16081
15752
  }
16082
15753
  }
16083
15754
  async function updateSeatsById({
@@ -16088,13 +15759,13 @@ function useSubscriptionRepo() {
16088
15759
  amount,
16089
15760
  promoCode
16090
15761
  }, session) {
16091
- const schema2 = Joi21.object({
16092
- _id: Joi21.string().hex().required(),
16093
- currentSeats: Joi21.number().required().min(1),
16094
- maxSeats: Joi21.number().required().min(0),
16095
- paidSeats: Joi21.number().optional().min(0),
16096
- amount: Joi21.number().required().min(0),
16097
- promoCode: Joi21.string().optional().allow("", null)
15762
+ const schema2 = Joi19.object({
15763
+ _id: Joi19.string().hex().required(),
15764
+ currentSeats: Joi19.number().required().min(1),
15765
+ maxSeats: Joi19.number().required().min(0),
15766
+ paidSeats: Joi19.number().optional().min(0),
15767
+ amount: Joi19.number().required().min(0),
15768
+ promoCode: Joi19.string().optional().allow("", null)
16098
15769
  });
16099
15770
  const { error } = schema2.validate({
16100
15771
  _id,
@@ -16105,12 +15776,12 @@ function useSubscriptionRepo() {
16105
15776
  promoCode
16106
15777
  });
16107
15778
  if (error) {
16108
- throw new BadRequestError36(error.message);
15779
+ throw new BadRequestError34(error.message);
16109
15780
  }
16110
15781
  try {
16111
15782
  _id = new ObjectId23(_id);
16112
15783
  } catch (error2) {
16113
- throw new BadRequestError36("Invalid subscription ID format.");
15784
+ throw new BadRequestError34("Invalid subscription ID format.");
16114
15785
  }
16115
15786
  const data = {
16116
15787
  currentSeats,
@@ -16131,31 +15802,31 @@ function useSubscriptionRepo() {
16131
15802
  );
16132
15803
  const cacheKey = makeCacheKey13(namespace_collection, { _id });
16133
15804
  delCache(cacheKey).then(() => {
16134
- logger27.info(`Cache deleted for key: ${cacheKey}`);
15805
+ logger25.info(`Cache deleted for key: ${cacheKey}`);
16135
15806
  }).catch((err) => {
16136
- logger27.error(`Failed to delete cache for key: ${cacheKey}`, err);
15807
+ logger25.error(`Failed to delete cache for key: ${cacheKey}`, err);
16137
15808
  });
16138
15809
  return result;
16139
15810
  } catch (error2) {
16140
- throw new BadRequestError36("Failed to update subscription seats.");
15811
+ throw new BadRequestError34("Failed to update subscription seats.");
16141
15812
  }
16142
15813
  }
16143
15814
  async function updateMaxSeatsById({
16144
15815
  _id,
16145
15816
  seats
16146
15817
  }, session) {
16147
- const schema2 = Joi21.object({
16148
- _id: Joi21.string().hex().required(),
16149
- seats: Joi21.number().required().min(1)
15818
+ const schema2 = Joi19.object({
15819
+ _id: Joi19.string().hex().required(),
15820
+ seats: Joi19.number().required().min(1)
16150
15821
  });
16151
15822
  const { error } = schema2.validate({ _id, seats });
16152
15823
  if (error) {
16153
- throw new BadRequestError36(error.message);
15824
+ throw new BadRequestError34(error.message);
16154
15825
  }
16155
15826
  try {
16156
15827
  _id = new ObjectId23(_id);
16157
15828
  } catch (error2) {
16158
- throw new BadRequestError36("Invalid subscription ID format.");
15829
+ throw new BadRequestError34("Invalid subscription ID format.");
16159
15830
  }
16160
15831
  try {
16161
15832
  const result = await collection.updateOne(
@@ -16165,13 +15836,13 @@ function useSubscriptionRepo() {
16165
15836
  );
16166
15837
  const cacheKey = makeCacheKey13(namespace_collection, { _id });
16167
15838
  delCache(cacheKey).then(() => {
16168
- logger27.info(`Cache deleted for key: ${cacheKey}`);
15839
+ logger25.info(`Cache deleted for key: ${cacheKey}`);
16169
15840
  }).catch((err) => {
16170
- logger27.error(`Failed to delete cache for key: ${cacheKey}`, err);
15841
+ logger25.error(`Failed to delete cache for key: ${cacheKey}`, err);
16171
15842
  });
16172
15843
  return result;
16173
15844
  } catch (error2) {
16174
- throw new BadRequestError36("Failed to update subscription paid seats.");
15845
+ throw new BadRequestError34("Failed to update subscription paid seats.");
16175
15846
  }
16176
15847
  }
16177
15848
  return {
@@ -16198,6 +15869,397 @@ function useSubscriptionRepo() {
16198
15869
  };
16199
15870
  }
16200
15871
 
15872
+ // src/controllers/organization.controller.ts
15873
+ function useOrgController() {
15874
+ const { getOrgsByMembership } = useMemberRepo();
15875
+ const {
15876
+ getByName: _getByName,
15877
+ getById: _getById,
15878
+ getByEmail: _getByEmail,
15879
+ getAll: _getAll,
15880
+ add: _add,
15881
+ update: _update,
15882
+ getOrgsByEmail: _getOrgsByEmail,
15883
+ getAdminOrgForResident: _getAdminOrgForResident,
15884
+ completeOnboardingById: _completeOnboardingById,
15885
+ updateStatusById: _updateStatusById
15886
+ } = useOrgRepo();
15887
+ const {
15888
+ getByOrgId: _getSubscriptionByOrgId,
15889
+ updateStatusById: _updateSubscriptionStatusById
15890
+ } = useSubscriptionRepo();
15891
+ async function add(req, res, next) {
15892
+ const validation = Joi20.object({
15893
+ name: Joi20.string().required(),
15894
+ type: Joi20.string().required(),
15895
+ nature: Joi20.string().valid(...allowedNatures).required(),
15896
+ email: Joi20.string().email().optional().allow("", null),
15897
+ contact: Joi20.string().optional().allow("", null),
15898
+ terms: Joi20.string().optional().allow("", null),
15899
+ policies: Joi20.string().optional().allow("", null)
15900
+ });
15901
+ const { error } = validation.validate(req.body);
15902
+ if (error) {
15903
+ logger26.log({ level: "error", message: error.message });
15904
+ next(new BadRequestError35(error.message));
15905
+ return;
15906
+ }
15907
+ try {
15908
+ await _add(req.body);
15909
+ res.status(201).json({ message: "Successfully created organization." });
15910
+ return;
15911
+ } catch (error2) {
15912
+ logger26.log({ level: "error", message: error2.message });
15913
+ next(error2);
15914
+ return;
15915
+ }
15916
+ }
15917
+ async function getAll(req, res, next) {
15918
+ const validation = Joi20.object({
15919
+ search: Joi20.string().optional().allow("", null),
15920
+ page: Joi20.number().integer().min(1).allow("", null).default(1),
15921
+ limit: Joi20.number().integer().min(1).max(100).allow("", null).default(10),
15922
+ nature: Joi20.string().valid(...allowedNatures).optional().allow("", null),
15923
+ sort: Joi20.string().optional().allow("", null)
15924
+ });
15925
+ const query = { ...req.query };
15926
+ const { error } = validation.validate(query);
15927
+ if (error) {
15928
+ logger26.log({ level: "error", message: error.message });
15929
+ next(new BadRequestError35(error.message));
15930
+ return;
15931
+ }
15932
+ const search = req.query.search ?? "";
15933
+ const page = parseInt(req.query.page ?? "1");
15934
+ const limit = parseInt(req.query.limit ?? "10");
15935
+ const nature = req.query.nature ?? "";
15936
+ try {
15937
+ const data = await _getAll({
15938
+ search,
15939
+ page,
15940
+ limit,
15941
+ nature
15942
+ });
15943
+ res.json(data);
15944
+ return;
15945
+ } catch (error2) {
15946
+ logger26.log({ level: "error", message: error2.message });
15947
+ next(error2);
15948
+ return;
15949
+ }
15950
+ }
15951
+ async function addOnboardingOrg(req, res, next) {
15952
+ const validation = Joi20.object({
15953
+ name: Joi20.string().required(),
15954
+ type: Joi20.string().required(),
15955
+ nature: Joi20.string().valid(...allowedNatures).required(),
15956
+ email: Joi20.string().email().optional().allow("", null),
15957
+ contact: Joi20.string().optional().allow("", null)
15958
+ });
15959
+ const { error } = validation.validate(req.body);
15960
+ if (error) {
15961
+ logger26.log({ level: "error", message: error.message });
15962
+ next(new BadRequestError35(error.message));
15963
+ return;
15964
+ }
15965
+ try {
15966
+ const _id = await _add(req.body);
15967
+ const data = await _getById(_id);
15968
+ res.status(201).json({
15969
+ message: "Successfully created organization.",
15970
+ data
15971
+ });
15972
+ return;
15973
+ } catch (error2) {
15974
+ logger26.log({ level: "error", message: error2.message });
15975
+ next(error2);
15976
+ return;
15977
+ }
15978
+ }
15979
+ async function getOrgsByUserId(req, res, next) {
15980
+ const validation = Joi20.object({
15981
+ search: Joi20.string().optional().allow("", null),
15982
+ page: Joi20.number().integer().min(1).allow("", null).default(1),
15983
+ limit: Joi20.number().integer().min(1).max(100).allow("", null).default(10),
15984
+ user: Joi20.string().hex().required(),
15985
+ type: Joi20.string().optional().allow("", null)
15986
+ });
15987
+ const query = { ...req.query };
15988
+ query.user = req.params.user;
15989
+ const { error } = validation.validate(query);
15990
+ if (error) {
15991
+ logger26.log({ level: "error", message: error.message });
15992
+ next(new BadRequestError35(error.message));
15993
+ return;
15994
+ }
15995
+ const search = req.query.search ?? "";
15996
+ const page = parseInt(req.query.page ?? "1");
15997
+ const limit = parseInt(req.query.limit ?? "10");
15998
+ const user = req.params.user;
15999
+ const type = req.query.type ?? "";
16000
+ try {
16001
+ const data = await getOrgsByMembership({
16002
+ search,
16003
+ page,
16004
+ limit,
16005
+ user,
16006
+ type
16007
+ });
16008
+ res.json(data);
16009
+ return;
16010
+ } catch (error2) {
16011
+ logger26.log({ level: "error", message: error2.message });
16012
+ next(error2);
16013
+ return;
16014
+ }
16015
+ }
16016
+ async function getByName(req, res, next) {
16017
+ const validation = Joi20.string().required();
16018
+ const name = req.params.name;
16019
+ const { error } = validation.validate(name);
16020
+ if (error) {
16021
+ logger26.log({ level: "error", message: error.message });
16022
+ next(new BadRequestError35(error.message));
16023
+ return;
16024
+ }
16025
+ try {
16026
+ const data = await _getByName(name);
16027
+ res.json(data);
16028
+ return;
16029
+ } catch (error2) {
16030
+ next(error2);
16031
+ return;
16032
+ }
16033
+ }
16034
+ async function getById(req, res, next) {
16035
+ const validation = Joi20.string().hex().required();
16036
+ const _id = req.params.id;
16037
+ const { error } = validation.validate(_id);
16038
+ if (error) {
16039
+ logger26.log({ level: "error", message: error.message });
16040
+ next(new BadRequestError35(error.message));
16041
+ return;
16042
+ }
16043
+ try {
16044
+ const data = await _getById(_id);
16045
+ res.json(data);
16046
+ return;
16047
+ } catch (error2) {
16048
+ logger26.log({ level: "error", message: error2.message });
16049
+ next(error2);
16050
+ return;
16051
+ }
16052
+ }
16053
+ async function getByEmail(req, res, next) {
16054
+ const validation = Joi20.string().required();
16055
+ const email = req.params.email;
16056
+ const { error } = validation.validate(email);
16057
+ if (error) {
16058
+ logger26.log({ level: "error", message: error.message });
16059
+ next(new BadRequestError35(error.message));
16060
+ return;
16061
+ }
16062
+ try {
16063
+ const data = await _getByEmail(email);
16064
+ if (!data) {
16065
+ next(new NotFoundError11("Organization not found."));
16066
+ return;
16067
+ }
16068
+ res.json(data);
16069
+ return;
16070
+ } catch (error2) {
16071
+ next(error2);
16072
+ return;
16073
+ }
16074
+ }
16075
+ async function getOrgsByEmail(req, res, next) {
16076
+ const validation = Joi20.object({
16077
+ email: Joi20.string().email().required()
16078
+ });
16079
+ const query = {
16080
+ email: req.params.email
16081
+ };
16082
+ const { error } = validation.validate(query);
16083
+ if (error) {
16084
+ logger26.log({ level: "error", message: error.message });
16085
+ next(new BadRequestError35(error.message));
16086
+ return;
16087
+ }
16088
+ const email = req.params.email;
16089
+ try {
16090
+ const data = await _getOrgsByEmail(email);
16091
+ res.json(data);
16092
+ return;
16093
+ } catch (error2) {
16094
+ logger26.log({ level: "error", message: error2.message });
16095
+ next(error2);
16096
+ return;
16097
+ }
16098
+ }
16099
+ async function update(req, res, next) {
16100
+ const validation = Joi20.object({
16101
+ name: Joi20.string().optional(),
16102
+ type: Joi20.string().optional(),
16103
+ nature: Joi20.string().valid(...allowedNatures).optional(),
16104
+ email: Joi20.string().email().allow("", null).optional(),
16105
+ contact: Joi20.string().allow("", null).optional(),
16106
+ terms: Joi20.string().optional().allow("", null),
16107
+ policies: Joi20.string().optional().allow("", null)
16108
+ });
16109
+ const { error } = validation.validate(req.body);
16110
+ if (error) {
16111
+ next(new BadRequestError35(error.message));
16112
+ return;
16113
+ }
16114
+ const id = req.params.id;
16115
+ try {
16116
+ await _update(id, req.body);
16117
+ const data = await _getById(id);
16118
+ res.json({
16119
+ message: "Organization updated successfully",
16120
+ data
16121
+ });
16122
+ } catch (err) {
16123
+ next(err);
16124
+ }
16125
+ }
16126
+ async function getAdminOrgForResident(_req, res, next) {
16127
+ try {
16128
+ const data = await _getAdminOrgForResident();
16129
+ res.status(200).json(data);
16130
+ } catch (error) {
16131
+ logger26.log({ level: "error", message: error.message });
16132
+ next(error);
16133
+ }
16134
+ }
16135
+ async function updateStatus(req, res, next) {
16136
+ const validation = Joi20.object({
16137
+ status: Joi20.string().valid("active", "suspended").required()
16138
+ });
16139
+ const { error } = validation.validate(req.body);
16140
+ if (error) {
16141
+ next(new BadRequestError35(error.message));
16142
+ return;
16143
+ }
16144
+ const orgId = req.params.id;
16145
+ const { status } = req.body;
16146
+ try {
16147
+ await _updateStatusById(orgId, status);
16148
+ const subscription = await _getSubscriptionByOrgId(orgId);
16149
+ if (subscription) {
16150
+ await _updateSubscriptionStatusById(
16151
+ subscription._id,
16152
+ status
16153
+ );
16154
+ }
16155
+ const data = await _getById(orgId);
16156
+ res.json({
16157
+ message: "Organization status updated successfully.",
16158
+ data
16159
+ });
16160
+ } catch (err) {
16161
+ next(err);
16162
+ }
16163
+ }
16164
+ return {
16165
+ add,
16166
+ addOnboardingOrg,
16167
+ getAll,
16168
+ getOrgsByUserId,
16169
+ getByName,
16170
+ getById,
16171
+ getByEmail,
16172
+ update,
16173
+ getOrgsByEmail,
16174
+ getAdminOrgForResident,
16175
+ updateStatus
16176
+ };
16177
+ }
16178
+
16179
+ // src/controllers/organization-v2.controller.ts
16180
+ import Joi21 from "joi";
16181
+ import { BadRequestError as BadRequestError36, logger as logger27 } from "@7365admin1/node-server-utils";
16182
+ function useOrgControllerV2() {
16183
+ const { getAll: _getAll, getOrganizationsWithSubscription: _getOrganizationsWithSubscription } = useOrgRepo();
16184
+ async function getAll(req, res, next) {
16185
+ const validation = Joi21.object({
16186
+ search: Joi21.string().optional().allow("", null),
16187
+ page: Joi21.number().integer().min(1).allow("", null).default(1),
16188
+ limit: Joi21.number().integer().min(1).max(100).allow("", null).default(10),
16189
+ nature: Joi21.string().valid(...allowedNatures).optional().allow("", null),
16190
+ status: Joi21.string().trim().valid("active", "suspended", "deleted").optional().empty("").default("active")
16191
+ });
16192
+ const query = { ...req.query };
16193
+ const { error, value } = validation.validate(query, {
16194
+ convert: true,
16195
+ stripUnknown: true
16196
+ });
16197
+ if (error) {
16198
+ logger27.log({ level: "error", message: error.message });
16199
+ next(new BadRequestError36(error.message));
16200
+ return;
16201
+ }
16202
+ const search = value.search ?? "";
16203
+ const page = typeof value.page === "number" ? value.page : parseInt(String(value.page ?? "1"), 10);
16204
+ const limit = typeof value.limit === "number" ? value.limit : parseInt(String(value.limit ?? "10"), 10);
16205
+ const nature = value.nature ?? "";
16206
+ const status = value.status;
16207
+ try {
16208
+ const data = await _getAll({
16209
+ search,
16210
+ page,
16211
+ limit,
16212
+ nature,
16213
+ status
16214
+ });
16215
+ res.json(data);
16216
+ return;
16217
+ } catch (error2) {
16218
+ logger27.log({ level: "error", message: error2.message });
16219
+ next(error2);
16220
+ return;
16221
+ }
16222
+ }
16223
+ async function getOrganizationsWithSubscription(req, res, next) {
16224
+ const validation = Joi21.object({
16225
+ search: Joi21.string().optional().allow("", null),
16226
+ page: Joi21.number().integer().min(1).default(1),
16227
+ limit: Joi21.number().integer().min(1).max(100).default(10),
16228
+ status: Joi21.string().trim().valid("active", "suspended", "deleted").default("active"),
16229
+ type: Joi21.string().optional().allow("", null),
16230
+ billingCycle: Joi21.string().optional().allow("", null)
16231
+ });
16232
+ const { error, value } = validation.validate(
16233
+ req.query,
16234
+ {
16235
+ convert: true,
16236
+ stripUnknown: true
16237
+ }
16238
+ );
16239
+ if (error) {
16240
+ next(new BadRequestError36(error.message));
16241
+ return;
16242
+ }
16243
+ try {
16244
+ const data = await _getOrganizationsWithSubscription({
16245
+ search: value.search ?? "",
16246
+ page: value.page ?? 1,
16247
+ limit: value.limit ?? 10,
16248
+ status: value.status ?? "active",
16249
+ type: value.type ?? "",
16250
+ billingCycle: value.billingCycle ?? ""
16251
+ });
16252
+ res.json(data);
16253
+ } catch (error2) {
16254
+ next(error2);
16255
+ }
16256
+ }
16257
+ return {
16258
+ getAll,
16259
+ getOrganizationsWithSubscription
16260
+ };
16261
+ }
16262
+
16201
16263
  // src/services/subscription.service.ts
16202
16264
  import {
16203
16265
  AppError as AppError7,
@@ -25378,6 +25440,7 @@ var SortOrder = /* @__PURE__ */ ((SortOrder2) => {
25378
25440
  var BuildingStatus = /* @__PURE__ */ ((BuildingStatus2) => {
25379
25441
  BuildingStatus2["ACTIVE"] = "active";
25380
25442
  BuildingStatus2["PENDING"] = "pending";
25443
+ BuildingStatus2["DELETED"] = "deleted";
25381
25444
  return BuildingStatus2;
25382
25445
  })(BuildingStatus || {});
25383
25446
  var objectIdSchema = Joi41.alternatives().try(
@@ -26738,12 +26801,6 @@ function useVehicleService() {
26738
26801
  const org = await _getById(orgId);
26739
26802
  if (!org)
26740
26803
  throw new BadRequestError75("Org not found");
26741
- const allowedNatures2 = "property_management_agency" /* PROPERTY_MANAGEMENT_AGENCY */;
26742
- if (!allowedNatures2.includes(org.nature)) {
26743
- throw new BadRequestError75(
26744
- "Only property management can approve vehicles."
26745
- );
26746
- }
26747
26804
  const vehicle = await _getVehicleById(id);
26748
26805
  const plate = vehicle.plates.find((p) => p._id.toString() === id);
26749
26806
  const _plateNumber = plate?.plateNumber;
@@ -27966,6 +28023,21 @@ function useBuildingRepo() {
27966
28023
  );
27967
28024
  async function createIndexes() {
27968
28025
  try {
28026
+ const indexes = await collection.indexes();
28027
+ const legacyUniqueIndexKeys = [
28028
+ JSON.stringify({ name: 1 }),
28029
+ JSON.stringify({ site: 1, name: 1 }),
28030
+ JSON.stringify({ site: 1, block: 1 })
28031
+ ];
28032
+ await Promise.all(
28033
+ indexes.map(async (index) => {
28034
+ const key = JSON.stringify(index.key);
28035
+ const isLegacyUniqueIndex = index.unique && legacyUniqueIndexKeys.includes(key) && index.partialFilterExpression?.status !== "active" /* ACTIVE */;
28036
+ if (index.name && isLegacyUniqueIndex) {
28037
+ await collection.dropIndex(index.name);
28038
+ }
28039
+ })
28040
+ );
27969
28041
  await collection.createIndexes([
27970
28042
  { key: { name: "text" }, name: "text-index" },
27971
28043
  // { key: { name: 1 }, unique: true, name: "unique-name-index" },
@@ -27979,6 +28051,14 @@ function useBuildingRepo() {
27979
28051
  partialFilterExpression: {
27980
28052
  status: "active" /* ACTIVE */
27981
28053
  }
28054
+ },
28055
+ {
28056
+ key: { site: 1, name: 1 },
28057
+ unique: true,
28058
+ name: "unique-site-name-active",
28059
+ partialFilterExpression: {
28060
+ status: "active" /* ACTIVE */
28061
+ }
27982
28062
  }
27983
28063
  ]);
27984
28064
  } catch (error) {
@@ -27986,9 +28066,45 @@ function useBuildingRepo() {
27986
28066
  }
27987
28067
  }
27988
28068
  const { getBySiteBuildingLevel: _getBySiteBuildingLevel } = useBuildingUnitRepo();
28069
+ async function assertBuildingDoesNotExist({
28070
+ site,
28071
+ name,
28072
+ block,
28073
+ excludeId,
28074
+ session
28075
+ }) {
28076
+ const duplicates = [];
28077
+ if (name) {
28078
+ duplicates.push({ name });
28079
+ }
28080
+ if (block) {
28081
+ duplicates.push({ block });
28082
+ }
28083
+ if (!duplicates.length) {
28084
+ return;
28085
+ }
28086
+ const existing = await collection.findOne(
28087
+ {
28088
+ site,
28089
+ status: "active" /* ACTIVE */,
28090
+ ...excludeId && { _id: { $ne: excludeId } },
28091
+ $or: duplicates
28092
+ },
28093
+ { session }
28094
+ );
28095
+ if (existing) {
28096
+ throw new BadRequestError80("Building already exists.");
28097
+ }
28098
+ }
27989
28099
  async function add(value, session) {
27990
28100
  try {
27991
28101
  value = MBuilding(value);
28102
+ await assertBuildingDoesNotExist({
28103
+ site: value.site,
28104
+ name: value.name,
28105
+ block: value.block,
28106
+ session
28107
+ });
27992
28108
  const res = await collection.insertOne(value, { session });
27993
28109
  delCachedData();
27994
28110
  return res.insertedId;
@@ -28027,6 +28143,21 @@ function useBuildingRepo() {
28027
28143
  throw new BadRequestError80("Invalid level ID format.");
28028
28144
  }
28029
28145
  }
28146
+ if (value.name || value.block) {
28147
+ const currentBuilding = await collection.findOne(
28148
+ { _id },
28149
+ { session }
28150
+ );
28151
+ if (currentBuilding) {
28152
+ await assertBuildingDoesNotExist({
28153
+ site: currentBuilding.site,
28154
+ name: value.name,
28155
+ block: value.block,
28156
+ excludeId: _id,
28157
+ session
28158
+ });
28159
+ }
28160
+ }
28030
28161
  if (value.name)
28031
28162
  await buildingUnitCollection.updateMany(
28032
28163
  { building: _id, status: "active" /* ACTIVE */ },
@@ -28256,7 +28387,8 @@ function useBuildingRepo() {
28256
28387
  try {
28257
28388
  const res = await collection.updateOne(
28258
28389
  { _id },
28259
- { $set: { status: "deleted", deletedAt: /* @__PURE__ */ new Date() } }
28390
+ { $set: { status: "deleted" /* DELETED */, deletedAt: /* @__PURE__ */ new Date() } },
28391
+ { session }
28260
28392
  );
28261
28393
  delCachedData();
28262
28394
  return res;
@@ -29165,18 +29297,19 @@ function useBuildingService() {
29165
29297
  }
29166
29298
  }
29167
29299
  const buildingUnitData = {};
29168
- if (building.name !== data.name) {
29300
+ if (data.name && building.name !== data.name) {
29169
29301
  buildingUnitData.buildingName = data.name;
29170
29302
  }
29171
- if (building.block !== data.block) {
29303
+ if (data.block && building.block !== data.block) {
29172
29304
  buildingUnitData.block = data.block;
29173
29305
  }
29174
- await updateByBuildingId(id, buildingUnitData, session);
29175
29306
  if (building.name === data.name) {
29176
29307
  delete data.name;
29177
29308
  }
29178
- console.log("data", data);
29179
29309
  const result = await _updateById(id, data, session);
29310
+ if (Object.keys(buildingUnitData).length) {
29311
+ await updateByBuildingId(id, buildingUnitData, session);
29312
+ }
29180
29313
  await session.commitTransaction();
29181
29314
  return result;
29182
29315
  } catch (error) {
@@ -57331,7 +57464,7 @@ function useNewDashboardRepo() {
57331
57464
  const periodRange = getDateRange(period);
57332
57465
  const incidentCollection = db.collection(incidents_namespace_collection);
57333
57466
  const visitorCollection = db.collection(visitors_namespace_collection);
57334
- const nfcPatrolLogCollection = db.collection("nfc-patrol-logs");
57467
+ const patrolLogCollection = db.collection("patrol.logs");
57335
57468
  const [
57336
57469
  workOrderReport,
57337
57470
  yesterdayWorkOrderReport,
@@ -57458,7 +57591,7 @@ function useNewDashboardRepo() {
57458
57591
  checkOut: null,
57459
57592
  status: { $ne: "deleted" }
57460
57593
  }),
57461
- nfcPatrolLogCollection.aggregate([
57594
+ patrolLogCollection.aggregate([
57462
57595
  {
57463
57596
  $match: {
57464
57597
  site: { $in: [siteIdObj, siteId] },
@@ -57466,23 +57599,23 @@ function useNewDashboardRepo() {
57466
57599
  }
57467
57600
  },
57468
57601
  {
57469
- $unwind: "$checkPoints"
57602
+ $unwind: "$cameras"
57470
57603
  },
57471
57604
  {
57472
57605
  $facet: {
57473
57606
  total: [{ $count: "count" }],
57474
57607
  completed: [
57475
- { $match: { "checkPoints.status": "Completed" } },
57608
+ { $match: { "cameras.status": "Completed" } },
57476
57609
  { $count: "count" }
57477
57610
  ],
57478
57611
  skipped: [
57479
- { $match: { "checkPoints.status": "Skipped" } },
57612
+ { $match: { "cameras.status": "Skipped" } },
57480
57613
  { $count: "count" }
57481
57614
  ]
57482
57615
  }
57483
57616
  }
57484
57617
  ]).toArray(),
57485
- nfcPatrolLogCollection.aggregate([
57618
+ patrolLogCollection.aggregate([
57486
57619
  {
57487
57620
  $match: {
57488
57621
  site: { $in: [siteIdObj, siteId] },
@@ -57490,23 +57623,23 @@ function useNewDashboardRepo() {
57490
57623
  }
57491
57624
  },
57492
57625
  {
57493
- $unwind: "$checkPoints"
57626
+ $unwind: "$cameras"
57494
57627
  },
57495
57628
  {
57496
57629
  $facet: {
57497
57630
  total: [{ $count: "count" }],
57498
57631
  completed: [
57499
- { $match: { "checkPoints.status": "Completed" } },
57632
+ { $match: { "cameras.status": "Completed" } },
57500
57633
  { $count: "count" }
57501
57634
  ],
57502
57635
  skipped: [
57503
- { $match: { "checkPoints.status": "Skipped" } },
57636
+ { $match: { "cameras.status": "Skipped" } },
57504
57637
  { $count: "count" }
57505
57638
  ]
57506
57639
  }
57507
57640
  }
57508
57641
  ]).toArray(),
57509
- nfcPatrolLogCollection.aggregate([
57642
+ patrolLogCollection.aggregate([
57510
57643
  {
57511
57644
  $match: {
57512
57645
  site: { $in: [siteIdObj, siteId] },
@@ -57514,17 +57647,17 @@ function useNewDashboardRepo() {
57514
57647
  }
57515
57648
  },
57516
57649
  {
57517
- $unwind: "$checkPoints"
57650
+ $unwind: "$cameras"
57518
57651
  },
57519
57652
  {
57520
57653
  $facet: {
57521
57654
  total: [{ $count: "count" }],
57522
57655
  completed: [
57523
- { $match: { "checkPoints.status": "Completed" } },
57656
+ { $match: { "cameras.status": "Completed" } },
57524
57657
  { $count: "count" }
57525
57658
  ],
57526
57659
  skipped: [
57527
- { $match: { "checkPoints.status": "Skipped" } },
57660
+ { $match: { "cameras.status": "Skipped" } },
57528
57661
  { $count: "count" }
57529
57662
  ]
57530
57663
  }
@@ -57555,78 +57688,127 @@ function useNewDashboardRepo() {
57555
57688
  const tTotal = tPatrolFacet.total[0]?.count ?? 0;
57556
57689
  const tCompleted = tPatrolFacet.completed[0]?.count ?? 0;
57557
57690
  const todayCompliance = tTotal > 0 ? tCompleted / tTotal * 100 : 0;
57558
- const todayString = moment2.tz("Asia/Singapore").format("YYYY-MM-DD");
57559
- const dayIndex = moment2.tz("Asia/Singapore").day();
57560
- const routes = await db.collection("nfc-patrol-routes").find({
57561
- site: { $in: [siteIdObj, siteId] },
57562
- days: { $in: [dayIndex] },
57563
- status: { $ne: "Inactive" }
57564
- }).toArray();
57565
- const expandedRoutes = [];
57566
- for (const route of routes) {
57567
- if (route.startTimes && Array.isArray(route.startTimes)) {
57568
- for (const startTime of route.startTimes) {
57691
+ let activePatrolItems = [];
57692
+ if (period === "today" /* TODAY */) {
57693
+ const todayString = moment2.tz("Asia/Singapore").format("YYYY-MM-DD");
57694
+ const dayIndex = moment2.tz("Asia/Singapore").day();
57695
+ const repeatDay = dayIndex === 0 ? 7 : dayIndex;
57696
+ const routes = await db.collection("patrol.route").find({
57697
+ site: { $in: [siteIdObj, siteId] },
57698
+ repeat: { $in: [repeatDay, String(repeatDay)] },
57699
+ status: { $ne: "deleted" }
57700
+ }).toArray();
57701
+ const expandedRoutes = [];
57702
+ for (const route of routes) {
57703
+ if (route.start) {
57569
57704
  expandedRoutes.push({
57570
57705
  route,
57571
- startTime,
57706
+ startTime: route.start,
57572
57707
  itemIndex: 0
57573
57708
  });
57574
57709
  }
57575
57710
  }
57576
- }
57577
- expandedRoutes.sort((a, b) => a.startTime.localeCompare(b.startTime));
57578
- const limitedRoutes = expandedRoutes.slice(0, 4);
57579
- limitedRoutes.forEach((item, idx) => {
57580
- item.itemIndex = idx + 1;
57581
- });
57582
- const activePatrolItems = await Promise.all(
57583
- limitedRoutes.map(async ({ route, startTime, itemIndex }) => {
57584
- const log = await db.collection("nfc-patrol-logs").findOne({
57585
- site: { $in: [siteIdObj, siteId] },
57586
- date: todayString,
57587
- "route._id": { $in: [route._id, route._id.toString()] },
57588
- "route.startTime": startTime
57589
- });
57590
- let person = "Unassigned";
57591
- if (log && log.createdBy) {
57592
- const userDoc = await db.collection("users").findOne({
57593
- _id: toObjectId16(log.createdBy)
57711
+ expandedRoutes.sort((a, b) => a.startTime.localeCompare(b.startTime));
57712
+ const limitedRoutes = expandedRoutes.slice(0, 4);
57713
+ limitedRoutes.forEach((item, idx) => {
57714
+ item.itemIndex = idx + 1;
57715
+ });
57716
+ activePatrolItems = await Promise.all(
57717
+ limitedRoutes.map(async ({ route, startTime, itemIndex }) => {
57718
+ const log = await db.collection("patrol.logs").findOne({
57719
+ site: { $in: [siteIdObj, siteId] },
57720
+ route: { $in: [route._id, route._id.toString()] },
57721
+ createdAt: { $gte: today, $lte: todayEnd }
57594
57722
  });
57595
- if (userDoc && userDoc.name) {
57596
- person = userDoc.name;
57723
+ let person = "Unassigned";
57724
+ if (log && log.assignee && log.assignee.length > 0) {
57725
+ const userIds = log.assignee.map((id) => toObjectId16(id));
57726
+ const userDocs = await db.collection("members").find({ _id: { $in: userIds } }).toArray();
57727
+ if (userDocs && userDocs.length > 0) {
57728
+ person = userDocs.map((u) => u.name || u.email || "").filter(Boolean).join(", ");
57729
+ }
57730
+ } else if (log && log.createdBy) {
57731
+ const userDoc = await db.collection("members").findOne({
57732
+ _id: toObjectId16(log.createdBy)
57733
+ });
57734
+ if (userDoc && userDoc.name) {
57735
+ person = userDoc.name;
57736
+ }
57597
57737
  }
57598
- }
57599
- let status = "pending";
57600
- if (log) {
57601
- status = "completed";
57602
- } else {
57603
- const routeTime = moment2.tz(
57604
- `${todayString} ${startTime}`,
57605
- "YYYY-MM-DD HH:mm",
57606
- "Asia/Singapore"
57607
- );
57608
- const nowSg = moment2.tz("Asia/Singapore");
57609
- const diffMinutes = nowSg.diff(routeTime, "minutes");
57610
- if (diffMinutes >= 0) {
57611
- if (diffMinutes <= 120) {
57612
- status = "on paused";
57738
+ let status = "pending";
57739
+ if (log) {
57740
+ if (log.status) {
57741
+ status = Array.isArray(log.status) ? log.status.join(", ") : log.status;
57613
57742
  } else {
57614
- status = "incomplete";
57743
+ status = "completed";
57615
57744
  }
57616
57745
  } else {
57617
- status = "pending";
57746
+ const routeTime = moment2.tz(
57747
+ `${todayString} ${startTime}`,
57748
+ "YYYY-MM-DD HH:mm",
57749
+ "Asia/Singapore"
57750
+ );
57751
+ const nowSg = moment2.tz("Asia/Singapore");
57752
+ const diffMinutes = nowSg.diff(routeTime, "minutes");
57753
+ if (diffMinutes >= 0) {
57754
+ if (diffMinutes <= 120) {
57755
+ status = "on paused";
57756
+ } else {
57757
+ status = "incomplete";
57758
+ }
57759
+ } else {
57760
+ status = "pending";
57761
+ }
57618
57762
  }
57619
- }
57620
- return {
57621
- id: `${route._id.toString()}_${startTime}`,
57622
- title: route.name,
57623
- subtitle: `ID${String(itemIndex).padStart(3, "0")}`,
57624
- person,
57625
- status,
57626
- time: startTime
57627
- };
57628
- })
57629
- );
57763
+ return {
57764
+ id: `${route._id.toString()}_${startTime}`,
57765
+ title: route.name,
57766
+ subtitle: `ID${String(itemIndex).padStart(3, "0")}`,
57767
+ person,
57768
+ status,
57769
+ time: startTime
57770
+ };
57771
+ })
57772
+ );
57773
+ } else {
57774
+ const logs = await db.collection("patrol.logs").find({
57775
+ site: { $in: [siteIdObj, siteId] },
57776
+ createdAt: periodRange
57777
+ }).sort({ createdAt: -1 }).limit(4).toArray();
57778
+ activePatrolItems = await Promise.all(
57779
+ logs.map(async (log) => {
57780
+ let person = "Unassigned";
57781
+ if (log.assignee && log.assignee.length > 0) {
57782
+ const userIds = log.assignee.map((id) => toObjectId16(id));
57783
+ const userDocs = await db.collection("members").find({ _id: { $in: userIds } }).toArray();
57784
+ if (userDocs && userDocs.length > 0) {
57785
+ person = userDocs.map((u) => u.name || u.email || "").filter(Boolean).join(", ");
57786
+ }
57787
+ } else if (log.createdBy) {
57788
+ const userDoc = await db.collection("members").findOne({
57789
+ _id: toObjectId16(log.createdBy)
57790
+ });
57791
+ if (userDoc && userDoc.name) {
57792
+ person = userDoc.name;
57793
+ }
57794
+ }
57795
+ let status = "completed";
57796
+ if (log.status) {
57797
+ status = Array.isArray(log.status) ? log.status.join(", ") : log.status;
57798
+ }
57799
+ const logTime = moment2(log.createdAt).tz("Asia/Singapore").format("HH:mm");
57800
+ const logDate = moment2(log.createdAt).tz("Asia/Singapore").format("DD/MM/YYYY");
57801
+ return {
57802
+ id: log._id.toString(),
57803
+ title: log.name,
57804
+ subtitle: logDate,
57805
+ person,
57806
+ status,
57807
+ time: logTime
57808
+ };
57809
+ })
57810
+ );
57811
+ }
57630
57812
  const data = {
57631
57813
  openWorkOrder: {
57632
57814
  count: wFacet.total[0]?.count ?? 0,