@7365admin1/core 3.53.9 → 3.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/index.d.ts +246 -12
- package/dist/index.js +275 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +269 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/test/e2e/harness.mjs +9 -0
- package/test/e2e/notification-matrix.e2e.test.mjs +420 -0
- package/test/e2e/notification-preference.e2e.test.mjs +21 -8
- package/test/e2e/personal-emergency-chain-scope.e2e.test.mjs +373 -0
- package/test/e2e/safety-notification.e2e.test.mjs +1 -1
- package/test/notification-category.util.test.mjs +29 -11
- package/test/personal-emergency-chain.test.mjs +261 -0
package/dist/index.js
CHANGED
|
@@ -536,13 +536,13 @@ var require_logger = __commonJS({
|
|
|
536
536
|
"use strict";
|
|
537
537
|
exports.__esModule = true;
|
|
538
538
|
var _utils = require_utils();
|
|
539
|
-
var
|
|
539
|
+
var logger222 = {
|
|
540
540
|
methodMap: ["debug", "info", "warn", "error"],
|
|
541
541
|
level: "info",
|
|
542
542
|
// Maps a given level value to the `methodMap` indexes above.
|
|
543
543
|
lookupLevel: function lookupLevel(level) {
|
|
544
544
|
if (typeof level === "string") {
|
|
545
|
-
var levelMap = _utils.indexOf(
|
|
545
|
+
var levelMap = _utils.indexOf(logger222.methodMap, level.toLowerCase());
|
|
546
546
|
if (levelMap >= 0) {
|
|
547
547
|
level = levelMap;
|
|
548
548
|
} else {
|
|
@@ -553,9 +553,9 @@ var require_logger = __commonJS({
|
|
|
553
553
|
},
|
|
554
554
|
// Can be overridden in the host environment
|
|
555
555
|
log: function log(level) {
|
|
556
|
-
level =
|
|
557
|
-
if (typeof console !== "undefined" &&
|
|
558
|
-
var method =
|
|
556
|
+
level = logger222.lookupLevel(level);
|
|
557
|
+
if (typeof console !== "undefined" && logger222.lookupLevel(logger222.level) <= level) {
|
|
558
|
+
var method = logger222.methodMap[level];
|
|
559
559
|
if (!console[method]) {
|
|
560
560
|
method = "log";
|
|
561
561
|
}
|
|
@@ -566,7 +566,7 @@ var require_logger = __commonJS({
|
|
|
566
566
|
}
|
|
567
567
|
}
|
|
568
568
|
};
|
|
569
|
-
exports["default"] =
|
|
569
|
+
exports["default"] = logger222;
|
|
570
570
|
module2.exports = exports["default"];
|
|
571
571
|
}
|
|
572
572
|
});
|
|
@@ -5933,11 +5933,13 @@ __export(src_exports, {
|
|
|
5933
5933
|
CameraType: () => CameraType,
|
|
5934
5934
|
ConsoleAuditAction: () => ConsoleAuditAction,
|
|
5935
5935
|
ConsoleAuditTarget: () => ConsoleAuditTarget,
|
|
5936
|
+
DEFAULT_RING_SECONDS: () => DEFAULT_RING_SECONDS,
|
|
5936
5937
|
DEFAULT_SITE_TIMEZONE: () => DEFAULT_SITE_TIMEZONE,
|
|
5937
5938
|
DEVICE_STATUS: () => DEVICE_STATUS,
|
|
5938
5939
|
DOBStatus: () => DOBStatus,
|
|
5939
5940
|
DUPLICATE_TERMS_VERSION_MESSAGE: () => DUPLICATE_TERMS_VERSION_MESSAGE,
|
|
5940
5941
|
DayOfWeek: () => DayOfWeek,
|
|
5942
|
+
E164: () => E164,
|
|
5941
5943
|
EAccessCardTypes: () => EAccessCardTypes,
|
|
5942
5944
|
EAccessCardUserTypes: () => EAccessCardUserTypes,
|
|
5943
5945
|
EmailSender: () => EmailSender,
|
|
@@ -5960,6 +5962,8 @@ __export(src_exports, {
|
|
|
5960
5962
|
MAX_BULK_CAMERA_ROWS: () => MAX_BULK_CAMERA_ROWS,
|
|
5961
5963
|
MAX_CAMERA_CHANNEL: () => MAX_CAMERA_CHANNEL,
|
|
5962
5964
|
MAX_CAMERA_NAME_LENGTH: () => MAX_CAMERA_NAME_LENGTH,
|
|
5965
|
+
MAX_PERSONAL_EMERGENCY_CONTACTS: () => MAX_PERSONAL_EMERGENCY_CONTACTS,
|
|
5966
|
+
MAX_RING_SECONDS: () => MAX_RING_SECONDS,
|
|
5963
5967
|
MAccessCard: () => MAccessCard,
|
|
5964
5968
|
MAccessCardTransaction: () => MAccessCardTransaction,
|
|
5965
5969
|
MAddress: () => MAddress,
|
|
@@ -5993,6 +5997,7 @@ __export(src_exports, {
|
|
|
5993
5997
|
MHidAmicoReader: () => MHidAmicoReader,
|
|
5994
5998
|
MHidSipAccount: () => MHidSipAccount,
|
|
5995
5999
|
MHidSitePermissions: () => MHidSitePermissions,
|
|
6000
|
+
MIN_RING_SECONDS: () => MIN_RING_SECONDS,
|
|
5996
6001
|
MIncidentReport: () => MIncidentReport,
|
|
5997
6002
|
MManpowerDesignations: () => MManpowerDesignations,
|
|
5998
6003
|
MManpowerMonitoring: () => MManpowerMonitoring,
|
|
@@ -6018,6 +6023,7 @@ __export(src_exports, {
|
|
|
6018
6023
|
MPatrolQuestion: () => MPatrolQuestion,
|
|
6019
6024
|
MPatrolRoute: () => MPatrolRoute,
|
|
6020
6025
|
MPerson: () => MPerson,
|
|
6026
|
+
MPersonalEmergencyChain: () => MPersonalEmergencyChain,
|
|
6021
6027
|
MPlatformTerms: () => MPlatformTerms,
|
|
6022
6028
|
MPost: () => MPost,
|
|
6023
6029
|
MPostFavorite: () => MPostFavorite,
|
|
@@ -6160,6 +6166,7 @@ __export(src_exports, {
|
|
|
6160
6166
|
deviceHttpTimeoutMs: () => deviceHttpTimeoutMs,
|
|
6161
6167
|
deviceProbeTtlSeconds: () => deviceProbeTtlSeconds,
|
|
6162
6168
|
emitNotificationCreated: () => emitNotificationCreated,
|
|
6169
|
+
emptyPersonalEmergencyChain: () => emptyPersonalEmergencyChain,
|
|
6163
6170
|
encodeHidPacsCard: () => encodeHidPacsCard,
|
|
6164
6171
|
entitledSiteScope: () => entitledSiteScope,
|
|
6165
6172
|
events_namespace_collection: () => events_namespace_collection,
|
|
@@ -6342,6 +6349,7 @@ __export(src_exports, {
|
|
|
6342
6349
|
schemaPatrolQuestion: () => schemaPatrolQuestion,
|
|
6343
6350
|
schemaPatrolRoute: () => schemaPatrolRoute,
|
|
6344
6351
|
schemaPerson: () => schemaPerson,
|
|
6352
|
+
schemaPersonalEmergencyContact: () => schemaPersonalEmergencyContact,
|
|
6345
6353
|
schemaPlate: () => schemaPlate,
|
|
6346
6354
|
schemaPlatformTerms: () => schemaPlatformTerms,
|
|
6347
6355
|
schemaPost: () => schemaPost,
|
|
@@ -6387,6 +6395,7 @@ __export(src_exports, {
|
|
|
6387
6395
|
schemaUpdatePatrolQuestion: () => schemaUpdatePatrolQuestion,
|
|
6388
6396
|
schemaUpdatePatrolRoute: () => schemaUpdatePatrolRoute,
|
|
6389
6397
|
schemaUpdatePerson: () => schemaUpdatePerson,
|
|
6398
|
+
schemaUpdatePersonalEmergencyChain: () => schemaUpdatePersonalEmergencyChain,
|
|
6390
6399
|
schemaUpdatePost: () => schemaUpdatePost,
|
|
6391
6400
|
schemaUpdatePostFavorite: () => schemaUpdatePostFavorite,
|
|
6392
6401
|
schemaUpdateServiceProviderBilling: () => schemaUpdateServiceProviderBilling,
|
|
@@ -6567,6 +6576,9 @@ __export(src_exports, {
|
|
|
6567
6576
|
usePatrolRouteRepo: () => usePatrolRouteRepo,
|
|
6568
6577
|
usePersonController: () => usePersonController,
|
|
6569
6578
|
usePersonRepo: () => usePersonRepo,
|
|
6579
|
+
usePersonalEmergencyChainController: () => usePersonalEmergencyChainController,
|
|
6580
|
+
usePersonalEmergencyChainRepo: () => usePersonalEmergencyChainRepo,
|
|
6581
|
+
usePersonalEmergencyChainService: () => usePersonalEmergencyChainService,
|
|
6570
6582
|
usePlatformTermsController: () => usePlatformTermsController,
|
|
6571
6583
|
usePlatformTermsRepo: () => usePlatformTermsRepo,
|
|
6572
6584
|
usePlatformTermsService: () => usePlatformTermsService,
|
|
@@ -14304,6 +14316,8 @@ var NotificationModule = /* @__PURE__ */ ((NotificationModule2) => {
|
|
|
14304
14316
|
NotificationModule2["FACILITY_BOOKING"] = "facilityBooking";
|
|
14305
14317
|
NotificationModule2["ONLINE_FORM"] = "onlineForm";
|
|
14306
14318
|
NotificationModule2["PRELOVED_MARKETPLACE"] = "prelovedMarketplace";
|
|
14319
|
+
NotificationModule2["MARKETPLACE_ORDER"] = "marketplace-order";
|
|
14320
|
+
NotificationModule2["MARKETPLACE_VENDOR_ORDER"] = "marketplace-vendor-order";
|
|
14307
14321
|
NotificationModule2["INCIDENT_REPORT"] = "incidentReport";
|
|
14308
14322
|
NotificationModule2["EMERGENCY_CONTACT"] = "emergencyContact";
|
|
14309
14323
|
NotificationModule2["VIRTUAL_PATROL"] = "virtualPatrol";
|
|
@@ -14758,7 +14772,7 @@ var NOTIFICATION_CATEGORIES = [
|
|
|
14758
14772
|
{
|
|
14759
14773
|
key: "facilityBooking",
|
|
14760
14774
|
label: "Facility Bookings",
|
|
14761
|
-
description: "When a facility booking is made or its status changes.",
|
|
14775
|
+
description: "When a facility booking is made or its status changes. The confirmation email goes to the address entered on the booking form itself.",
|
|
14762
14776
|
channels: { inApp: true, push: true, email: false },
|
|
14763
14777
|
channelNote: {
|
|
14764
14778
|
email: "Booking confirmations go to the email address entered on the booking form itself. To change where a confirmation lands, change that address when the booking is made."
|
|
@@ -14770,7 +14784,7 @@ var NOTIFICATION_CATEGORIES = [
|
|
|
14770
14784
|
{
|
|
14771
14785
|
key: "visitors",
|
|
14772
14786
|
label: "Visitors",
|
|
14773
|
-
description: "When a visitor you invited checks in or checks out.",
|
|
14787
|
+
description: "When a visitor you invited checks in or checks out. The invitation email goes to the address entered for the visitor.",
|
|
14774
14788
|
channels: { inApp: true, push: true, email: false },
|
|
14775
14789
|
channelNote: {
|
|
14776
14790
|
email: "Visitor invitations go to the email address entered for the visitor when they are invited. To change where one lands, change that address on the invitation."
|
|
@@ -14844,7 +14858,7 @@ var NOTIFICATION_CATEGORIES = [
|
|
|
14844
14858
|
{
|
|
14845
14859
|
key: "serviceProviderInvite",
|
|
14846
14860
|
label: "Service Provider Invitations",
|
|
14847
|
-
description: "When a property manager invites your company to provide services at a site.",
|
|
14861
|
+
description: "When a property manager invites your company to provide services at a site. The invitation email is the invitation itself and is always sent to the address it was addressed to; these settings control the copy that reaches you inside the app.",
|
|
14848
14862
|
channels: { inApp: true, push: true, email: false },
|
|
14849
14863
|
channelNote: {
|
|
14850
14864
|
email: "The invitation email is the invitation itself \u2014 for a company that has no account here yet it is the only copy, so it is always sent to the address the invitation was addressed to. The switches above control the copy that reaches you inside the app."
|
|
@@ -14875,12 +14889,15 @@ var NOTIFICATION_CATEGORIES = [
|
|
|
14875
14889
|
channelNote: { email: NO_EMAIL_RECIPIENT },
|
|
14876
14890
|
permissionResources: ["emergency-contact"],
|
|
14877
14891
|
safety: true,
|
|
14878
|
-
//
|
|
14879
|
-
// contacts are written
|
|
14880
|
-
//
|
|
14881
|
-
//
|
|
14882
|
-
//
|
|
14883
|
-
|
|
14892
|
+
// A caller exists again. `iservice365-API-core` is still the only place a
|
|
14893
|
+
// site's emergency contacts are written, and its `emergency.service.ts`
|
|
14894
|
+
// now calls the sender below on each of the three writes. That caller
|
|
14895
|
+
// reads THIS flag before it sends (`notificationCategory("emergencyContact")
|
|
14896
|
+
// ?.rendered`), so the two halves cannot land out of order and leave a
|
|
14897
|
+
// safety alert arriving with no switch to turn it off: whichever repository
|
|
14898
|
+
// merges first, the alert only starts once a published core carrying this
|
|
14899
|
+
// line is installed there.
|
|
14900
|
+
rendered: true
|
|
14884
14901
|
},
|
|
14885
14902
|
{
|
|
14886
14903
|
key: "virtualPatrol",
|
|
@@ -29898,7 +29915,7 @@ function usePromoCodeRepo() {
|
|
|
29898
29915
|
}
|
|
29899
29916
|
}
|
|
29900
29917
|
async function updateById(_id, value) {
|
|
29901
|
-
const objectId2 =
|
|
29918
|
+
const objectId2 = toObjectId26(_id);
|
|
29902
29919
|
const changes = promoCodeUpdate(value);
|
|
29903
29920
|
const res = await collection.updateOne(
|
|
29904
29921
|
{ _id: objectId2, deletedAt: null },
|
|
@@ -29911,7 +29928,7 @@ function usePromoCodeRepo() {
|
|
|
29911
29928
|
return res;
|
|
29912
29929
|
}
|
|
29913
29930
|
async function updateStatusById(_id, status) {
|
|
29914
|
-
const objectId2 =
|
|
29931
|
+
const objectId2 = toObjectId26(_id);
|
|
29915
29932
|
const res = await collection.updateOne(
|
|
29916
29933
|
{ _id: objectId2, deletedAt: null },
|
|
29917
29934
|
{ $set: { status } }
|
|
@@ -29923,7 +29940,7 @@ function usePromoCodeRepo() {
|
|
|
29923
29940
|
return res;
|
|
29924
29941
|
}
|
|
29925
29942
|
async function softDeleteById(_id, deletedBy) {
|
|
29926
|
-
const objectId2 =
|
|
29943
|
+
const objectId2 = toObjectId26(_id);
|
|
29927
29944
|
const res = await collection.updateOne(
|
|
29928
29945
|
{ _id: objectId2, deletedAt: null },
|
|
29929
29946
|
{
|
|
@@ -29940,7 +29957,7 @@ function usePromoCodeRepo() {
|
|
|
29940
29957
|
await invalidate(`delete ${objectId2}`);
|
|
29941
29958
|
return res;
|
|
29942
29959
|
}
|
|
29943
|
-
function
|
|
29960
|
+
function toObjectId26(_id) {
|
|
29944
29961
|
const { error } = import_joi34.default.object({
|
|
29945
29962
|
_id: import_joi34.default.string().hex().length(24).required()
|
|
29946
29963
|
}).validate({ _id: String(_id) });
|
|
@@ -91988,8 +92005,10 @@ function useNotificationPreferenceService() {
|
|
|
91988
92005
|
categoriesForUser(id)
|
|
91989
92006
|
]);
|
|
91990
92007
|
const isOff = (category, channel) => off.some((o) => o.category === category && o.channel === channel);
|
|
92008
|
+
const supportedIn = (category) => NOTIFICATION_CHANNELS.filter((channel) => category.channels[channel]);
|
|
92009
|
+
const offered = new Set(categories.flatMap((c) => supportedIn(c)));
|
|
91991
92010
|
return {
|
|
91992
|
-
channels: NOTIFICATION_CHANNELS.map((c) => ({
|
|
92011
|
+
channels: NOTIFICATION_CHANNELS.filter((c) => offered.has(c)).map((c) => ({
|
|
91993
92012
|
key: c,
|
|
91994
92013
|
label: NOTIFICATION_CHANNEL_LABELS[c]
|
|
91995
92014
|
})),
|
|
@@ -91998,16 +92017,14 @@ function useNotificationPreferenceService() {
|
|
|
91998
92017
|
label: category.label,
|
|
91999
92018
|
description: category.description,
|
|
92000
92019
|
safety: Boolean(category.safety),
|
|
92001
|
-
channels:
|
|
92002
|
-
|
|
92003
|
-
|
|
92004
|
-
|
|
92005
|
-
|
|
92006
|
-
|
|
92007
|
-
|
|
92008
|
-
|
|
92009
|
-
};
|
|
92010
|
-
})
|
|
92020
|
+
channels: supportedIn(category).map((channel) => ({
|
|
92021
|
+
key: channel,
|
|
92022
|
+
label: NOTIFICATION_CHANNEL_LABELS[channel],
|
|
92023
|
+
// kept so a client written against the old shape still filters
|
|
92024
|
+
// correctly; every channel sent is now a supported one.
|
|
92025
|
+
supported: true,
|
|
92026
|
+
enabled: !isOff(category.key, channel)
|
|
92027
|
+
}))
|
|
92011
92028
|
}))
|
|
92012
92029
|
};
|
|
92013
92030
|
}
|
|
@@ -92070,6 +92087,222 @@ function useNotificationPreferenceController() {
|
|
|
92070
92087
|
}
|
|
92071
92088
|
return { get, update };
|
|
92072
92089
|
}
|
|
92090
|
+
|
|
92091
|
+
// src/models/personal-emergency-chain.model.ts
|
|
92092
|
+
var import_node_server_utils303 = require("@7365admin1/node-server-utils");
|
|
92093
|
+
var import_mongodb184 = require("mongodb");
|
|
92094
|
+
var import_joi167 = __toESM(require("joi"));
|
|
92095
|
+
var MAX_PERSONAL_EMERGENCY_CONTACTS = 10;
|
|
92096
|
+
var MIN_RING_SECONDS = 5;
|
|
92097
|
+
var MAX_RING_SECONDS = 120;
|
|
92098
|
+
var DEFAULT_RING_SECONDS = 20;
|
|
92099
|
+
var E164 = /^\+[1-9]\d{1,14}$/;
|
|
92100
|
+
var schemaPersonalEmergencyContact = import_joi167.default.object({
|
|
92101
|
+
name: import_joi167.default.string().trim().min(1).max(120).required(),
|
|
92102
|
+
phone: import_joi167.default.string().trim().pattern(E164).required().messages({
|
|
92103
|
+
"string.pattern.base": "Phone number must be in international format, e.g. +6591234567."
|
|
92104
|
+
}),
|
|
92105
|
+
relationship: import_joi167.default.string().trim().max(60).allow("", null).default(""),
|
|
92106
|
+
order: import_joi167.default.number().integer().min(1).max(MAX_PERSONAL_EMERGENCY_CONTACTS).required(),
|
|
92107
|
+
active: import_joi167.default.boolean().default(true)
|
|
92108
|
+
});
|
|
92109
|
+
var schemaUpdatePersonalEmergencyChain = import_joi167.default.object({
|
|
92110
|
+
contacts: import_joi167.default.array().items(schemaPersonalEmergencyContact).unique("order").max(MAX_PERSONAL_EMERGENCY_CONTACTS).required().messages({
|
|
92111
|
+
"array.unique": "Two contacts cannot share the same position in the chain."
|
|
92112
|
+
}),
|
|
92113
|
+
ringSeconds: import_joi167.default.number().integer().min(MIN_RING_SECONDS).max(MAX_RING_SECONDS).default(DEFAULT_RING_SECONDS),
|
|
92114
|
+
siteDirectoryFallback: import_joi167.default.boolean().default(true),
|
|
92115
|
+
org: import_joi167.default.string().hex().length(24).allow("", null).default(null),
|
|
92116
|
+
site: import_joi167.default.string().hex().length(24).allow("", null).default(null)
|
|
92117
|
+
});
|
|
92118
|
+
var toObjectId25 = (value, what) => {
|
|
92119
|
+
if (value === null || value === void 0 || value === "")
|
|
92120
|
+
return null;
|
|
92121
|
+
const id = value.toString();
|
|
92122
|
+
if (!import_mongodb184.ObjectId.isValid(id))
|
|
92123
|
+
throw new import_node_server_utils303.BadRequestError(`Invalid ${what}.`);
|
|
92124
|
+
return new import_mongodb184.ObjectId(id);
|
|
92125
|
+
};
|
|
92126
|
+
function MPersonalEmergencyChain(value) {
|
|
92127
|
+
const user = toObjectId25(value.user, "user ID");
|
|
92128
|
+
if (!user)
|
|
92129
|
+
throw new import_node_server_utils303.BadRequestError("Invalid user ID.");
|
|
92130
|
+
const contacts = [...value.contacts ?? []].map((c) => ({
|
|
92131
|
+
name: c.name.trim(),
|
|
92132
|
+
phone: c.phone.trim(),
|
|
92133
|
+
relationship: (c.relationship ?? "").trim(),
|
|
92134
|
+
order: c.order,
|
|
92135
|
+
active: c.active ?? true
|
|
92136
|
+
})).sort((a, b) => a.order - b.order);
|
|
92137
|
+
const seen = /* @__PURE__ */ new Set();
|
|
92138
|
+
for (const contact of contacts) {
|
|
92139
|
+
if (seen.has(contact.order)) {
|
|
92140
|
+
throw new import_node_server_utils303.BadRequestError(
|
|
92141
|
+
"Two contacts cannot share the same position in the chain."
|
|
92142
|
+
);
|
|
92143
|
+
}
|
|
92144
|
+
seen.add(contact.order);
|
|
92145
|
+
}
|
|
92146
|
+
const now = /* @__PURE__ */ new Date();
|
|
92147
|
+
return {
|
|
92148
|
+
user,
|
|
92149
|
+
org: toObjectId25(value.org, "organization ID"),
|
|
92150
|
+
site: toObjectId25(value.site, "site ID"),
|
|
92151
|
+
contacts,
|
|
92152
|
+
ringSeconds: value.ringSeconds ?? DEFAULT_RING_SECONDS,
|
|
92153
|
+
siteDirectoryFallback: value.siteDirectoryFallback ?? true,
|
|
92154
|
+
createdAt: value.createdAt ?? now,
|
|
92155
|
+
updatedAt: now
|
|
92156
|
+
};
|
|
92157
|
+
}
|
|
92158
|
+
function emptyPersonalEmergencyChain(user) {
|
|
92159
|
+
return {
|
|
92160
|
+
user,
|
|
92161
|
+
org: null,
|
|
92162
|
+
site: null,
|
|
92163
|
+
contacts: [],
|
|
92164
|
+
ringSeconds: DEFAULT_RING_SECONDS,
|
|
92165
|
+
siteDirectoryFallback: true
|
|
92166
|
+
};
|
|
92167
|
+
}
|
|
92168
|
+
|
|
92169
|
+
// src/repositories/personal-emergency-chain.repo.ts
|
|
92170
|
+
var import_mongodb185 = require("mongodb");
|
|
92171
|
+
var import_node_server_utils304 = require("@7365admin1/node-server-utils");
|
|
92172
|
+
function usePersonalEmergencyChainRepo() {
|
|
92173
|
+
const namespace_collection = "personal-emergency-contacts";
|
|
92174
|
+
const getDB2 = () => {
|
|
92175
|
+
const db2 = import_node_server_utils304.useAtlas.getDb();
|
|
92176
|
+
if (!db2) {
|
|
92177
|
+
throw new import_node_server_utils304.InternalServerError("Unable to connect to server.");
|
|
92178
|
+
}
|
|
92179
|
+
return db2;
|
|
92180
|
+
};
|
|
92181
|
+
const collection = () => getDB2().collection(namespace_collection);
|
|
92182
|
+
async function createIndexes() {
|
|
92183
|
+
try {
|
|
92184
|
+
await collection().createIndexes([
|
|
92185
|
+
{ key: { user: 1 }, name: "one_chain_per_user", unique: true }
|
|
92186
|
+
]);
|
|
92187
|
+
return `Successfully created indexes for ${namespace_collection}.`;
|
|
92188
|
+
} catch (error) {
|
|
92189
|
+
import_node_server_utils304.logger.log({ level: "error", message: error.message });
|
|
92190
|
+
throw new import_node_server_utils304.InternalServerError(
|
|
92191
|
+
`Failed to create indexes for ${namespace_collection}.`
|
|
92192
|
+
);
|
|
92193
|
+
}
|
|
92194
|
+
}
|
|
92195
|
+
async function getByUser(user) {
|
|
92196
|
+
if (!import_mongodb185.ObjectId.isValid(user)) {
|
|
92197
|
+
throw new import_node_server_utils304.BadRequestError("Invalid user ID format.");
|
|
92198
|
+
}
|
|
92199
|
+
try {
|
|
92200
|
+
const doc = await collection().findOne({ user: new import_mongodb185.ObjectId(user) });
|
|
92201
|
+
return doc ?? emptyPersonalEmergencyChain(user);
|
|
92202
|
+
} catch (error) {
|
|
92203
|
+
if (error instanceof import_node_server_utils304.AppError)
|
|
92204
|
+
throw error;
|
|
92205
|
+
import_node_server_utils304.logger.log({ level: "error", message: error.message });
|
|
92206
|
+
throw new import_node_server_utils304.InternalServerError("Failed to retrieve emergency contacts.");
|
|
92207
|
+
}
|
|
92208
|
+
}
|
|
92209
|
+
async function replaceForUser(user, value) {
|
|
92210
|
+
const doc = MPersonalEmergencyChain({ ...value, user });
|
|
92211
|
+
try {
|
|
92212
|
+
await collection().updateOne(
|
|
92213
|
+
{ user: doc.user },
|
|
92214
|
+
{
|
|
92215
|
+
$set: {
|
|
92216
|
+
contacts: doc.contacts,
|
|
92217
|
+
ringSeconds: doc.ringSeconds,
|
|
92218
|
+
siteDirectoryFallback: doc.siteDirectoryFallback,
|
|
92219
|
+
org: doc.org,
|
|
92220
|
+
site: doc.site,
|
|
92221
|
+
updatedAt: doc.updatedAt
|
|
92222
|
+
},
|
|
92223
|
+
$setOnInsert: { user: doc.user, createdAt: doc.createdAt }
|
|
92224
|
+
},
|
|
92225
|
+
{ upsert: true }
|
|
92226
|
+
);
|
|
92227
|
+
return doc;
|
|
92228
|
+
} catch (error) {
|
|
92229
|
+
if (error instanceof import_node_server_utils304.AppError)
|
|
92230
|
+
throw error;
|
|
92231
|
+
import_node_server_utils304.logger.log({ level: "error", message: error.message });
|
|
92232
|
+
throw new import_node_server_utils304.InternalServerError("Failed to save emergency contacts.");
|
|
92233
|
+
}
|
|
92234
|
+
}
|
|
92235
|
+
return { createIndexes, getByUser, replaceForUser };
|
|
92236
|
+
}
|
|
92237
|
+
|
|
92238
|
+
// src/services/personal-emergency-chain.service.ts
|
|
92239
|
+
var import_node_server_utils305 = require("@7365admin1/node-server-utils");
|
|
92240
|
+
function usePersonalEmergencyChainService() {
|
|
92241
|
+
async function getForUser(user) {
|
|
92242
|
+
if (!user)
|
|
92243
|
+
throw new import_node_server_utils305.BadRequestError("No user in session.");
|
|
92244
|
+
return await usePersonalEmergencyChainRepo().getByUser(user);
|
|
92245
|
+
}
|
|
92246
|
+
async function updateForUser(user, value) {
|
|
92247
|
+
if (!user)
|
|
92248
|
+
throw new import_node_server_utils305.BadRequestError("No user in session.");
|
|
92249
|
+
return await usePersonalEmergencyChainRepo().replaceForUser(
|
|
92250
|
+
user,
|
|
92251
|
+
value
|
|
92252
|
+
);
|
|
92253
|
+
}
|
|
92254
|
+
return { getForUser, updateForUser };
|
|
92255
|
+
}
|
|
92256
|
+
|
|
92257
|
+
// src/controllers/personal-emergency-chain.controller.ts
|
|
92258
|
+
var import_node_server_utils306 = require("@7365admin1/node-server-utils");
|
|
92259
|
+
function usePersonalEmergencyChainController() {
|
|
92260
|
+
const { getForUser, updateForUser } = usePersonalEmergencyChainService();
|
|
92261
|
+
async function get(req, res, next) {
|
|
92262
|
+
const userId = req.params.userId;
|
|
92263
|
+
try {
|
|
92264
|
+
await requireSelfOrPlatformStaff(req, userId, {
|
|
92265
|
+
resource: "users",
|
|
92266
|
+
action: "see-user-details"
|
|
92267
|
+
});
|
|
92268
|
+
res.status(200).json({ data: await getForUser(userId) });
|
|
92269
|
+
} catch (error) {
|
|
92270
|
+
import_node_server_utils306.logger.log({ level: "error", message: error.message });
|
|
92271
|
+
next(error);
|
|
92272
|
+
}
|
|
92273
|
+
}
|
|
92274
|
+
async function update(req, res, next) {
|
|
92275
|
+
const userId = req.params.userId;
|
|
92276
|
+
try {
|
|
92277
|
+
await requireSelfOrPlatformStaff(req, userId, {
|
|
92278
|
+
resource: "users",
|
|
92279
|
+
action: "see-user-details"
|
|
92280
|
+
});
|
|
92281
|
+
} catch (error2) {
|
|
92282
|
+
import_node_server_utils306.logger.log({ level: "error", message: error2.message });
|
|
92283
|
+
next(error2);
|
|
92284
|
+
return;
|
|
92285
|
+
}
|
|
92286
|
+
const { error, value } = schemaUpdatePersonalEmergencyChain.validate(
|
|
92287
|
+
req.body,
|
|
92288
|
+
{ convert: true }
|
|
92289
|
+
);
|
|
92290
|
+
if (error) {
|
|
92291
|
+
next(new import_node_server_utils306.BadRequestError(error.details[0].message));
|
|
92292
|
+
return;
|
|
92293
|
+
}
|
|
92294
|
+
try {
|
|
92295
|
+
res.status(200).json({
|
|
92296
|
+
message: "success",
|
|
92297
|
+
data: await updateForUser(userId, value)
|
|
92298
|
+
});
|
|
92299
|
+
} catch (err) {
|
|
92300
|
+
import_node_server_utils306.logger.log({ level: "error", message: err.message });
|
|
92301
|
+
next(err);
|
|
92302
|
+
}
|
|
92303
|
+
}
|
|
92304
|
+
return { get, update };
|
|
92305
|
+
}
|
|
92073
92306
|
// Annotate the CommonJS export names for ESM import in node:
|
|
92074
92307
|
0 && (module.exports = {
|
|
92075
92308
|
ANPRMode,
|
|
@@ -92116,11 +92349,13 @@ function useNotificationPreferenceController() {
|
|
|
92116
92349
|
CameraType,
|
|
92117
92350
|
ConsoleAuditAction,
|
|
92118
92351
|
ConsoleAuditTarget,
|
|
92352
|
+
DEFAULT_RING_SECONDS,
|
|
92119
92353
|
DEFAULT_SITE_TIMEZONE,
|
|
92120
92354
|
DEVICE_STATUS,
|
|
92121
92355
|
DOBStatus,
|
|
92122
92356
|
DUPLICATE_TERMS_VERSION_MESSAGE,
|
|
92123
92357
|
DayOfWeek,
|
|
92358
|
+
E164,
|
|
92124
92359
|
EAccessCardTypes,
|
|
92125
92360
|
EAccessCardUserTypes,
|
|
92126
92361
|
EmailSender,
|
|
@@ -92143,6 +92378,8 @@ function useNotificationPreferenceController() {
|
|
|
92143
92378
|
MAX_BULK_CAMERA_ROWS,
|
|
92144
92379
|
MAX_CAMERA_CHANNEL,
|
|
92145
92380
|
MAX_CAMERA_NAME_LENGTH,
|
|
92381
|
+
MAX_PERSONAL_EMERGENCY_CONTACTS,
|
|
92382
|
+
MAX_RING_SECONDS,
|
|
92146
92383
|
MAccessCard,
|
|
92147
92384
|
MAccessCardTransaction,
|
|
92148
92385
|
MAddress,
|
|
@@ -92176,6 +92413,7 @@ function useNotificationPreferenceController() {
|
|
|
92176
92413
|
MHidAmicoReader,
|
|
92177
92414
|
MHidSipAccount,
|
|
92178
92415
|
MHidSitePermissions,
|
|
92416
|
+
MIN_RING_SECONDS,
|
|
92179
92417
|
MIncidentReport,
|
|
92180
92418
|
MManpowerDesignations,
|
|
92181
92419
|
MManpowerMonitoring,
|
|
@@ -92201,6 +92439,7 @@ function useNotificationPreferenceController() {
|
|
|
92201
92439
|
MPatrolQuestion,
|
|
92202
92440
|
MPatrolRoute,
|
|
92203
92441
|
MPerson,
|
|
92442
|
+
MPersonalEmergencyChain,
|
|
92204
92443
|
MPlatformTerms,
|
|
92205
92444
|
MPost,
|
|
92206
92445
|
MPostFavorite,
|
|
@@ -92343,6 +92582,7 @@ function useNotificationPreferenceController() {
|
|
|
92343
92582
|
deviceHttpTimeoutMs,
|
|
92344
92583
|
deviceProbeTtlSeconds,
|
|
92345
92584
|
emitNotificationCreated,
|
|
92585
|
+
emptyPersonalEmergencyChain,
|
|
92346
92586
|
encodeHidPacsCard,
|
|
92347
92587
|
entitledSiteScope,
|
|
92348
92588
|
events_namespace_collection,
|
|
@@ -92525,6 +92765,7 @@ function useNotificationPreferenceController() {
|
|
|
92525
92765
|
schemaPatrolQuestion,
|
|
92526
92766
|
schemaPatrolRoute,
|
|
92527
92767
|
schemaPerson,
|
|
92768
|
+
schemaPersonalEmergencyContact,
|
|
92528
92769
|
schemaPlate,
|
|
92529
92770
|
schemaPlatformTerms,
|
|
92530
92771
|
schemaPost,
|
|
@@ -92570,6 +92811,7 @@ function useNotificationPreferenceController() {
|
|
|
92570
92811
|
schemaUpdatePatrolQuestion,
|
|
92571
92812
|
schemaUpdatePatrolRoute,
|
|
92572
92813
|
schemaUpdatePerson,
|
|
92814
|
+
schemaUpdatePersonalEmergencyChain,
|
|
92573
92815
|
schemaUpdatePost,
|
|
92574
92816
|
schemaUpdatePostFavorite,
|
|
92575
92817
|
schemaUpdateServiceProviderBilling,
|
|
@@ -92750,6 +92992,9 @@ function useNotificationPreferenceController() {
|
|
|
92750
92992
|
usePatrolRouteRepo,
|
|
92751
92993
|
usePersonController,
|
|
92752
92994
|
usePersonRepo,
|
|
92995
|
+
usePersonalEmergencyChainController,
|
|
92996
|
+
usePersonalEmergencyChainRepo,
|
|
92997
|
+
usePersonalEmergencyChainService,
|
|
92753
92998
|
usePlatformTermsController,
|
|
92754
92999
|
usePlatformTermsRepo,
|
|
92755
93000
|
usePlatformTermsService,
|