@7365admin1/core 3.78.0 → 3.79.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 +6 -0
- package/dist/index.d.ts +46 -1
- package/dist/index.js +98 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +97 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/test/notification-category.util.test.mjs +10 -1
- package/test/staff-platform-notifications.test.mjs +95 -0
package/dist/index.mjs
CHANGED
|
@@ -4401,6 +4401,20 @@ async function resolveStaffRole(userId) {
|
|
|
4401
4401
|
const role = await db2.collection("roles").findOne({ _id: new ObjectId14(member.role.toString()), ...LIVE_ROLE });
|
|
4402
4402
|
return role?.type === "admin" ? role : null;
|
|
4403
4403
|
}
|
|
4404
|
+
async function listStaffUserIds() {
|
|
4405
|
+
const db2 = useAtlas8.getDb();
|
|
4406
|
+
if (!db2)
|
|
4407
|
+
return [];
|
|
4408
|
+
const members = await db2.collection("members").find({ type: "admin", status: { $ne: "deleted" } }, { projection: { user: 1, role: 1 } }).toArray();
|
|
4409
|
+
const roleIds = members.map((m) => m.role?.toString?.() ?? "").filter((r) => r && ObjectId14.isValid(r)).map((r) => new ObjectId14(r));
|
|
4410
|
+
if (!roleIds.length)
|
|
4411
|
+
return [];
|
|
4412
|
+
const staffRoles = new Set(
|
|
4413
|
+
(await db2.collection("roles").find({ _id: { $in: roleIds }, type: "admin", ...LIVE_ROLE }, { projection: { _id: 1 } }).toArray()).map((r) => r._id.toString())
|
|
4414
|
+
);
|
|
4415
|
+
const ids2 = members.filter((m) => staffRoles.has(m.role?.toString?.() ?? "")).map((m) => m.user?.toString?.() ?? "").filter((id) => id && ObjectId14.isValid(id));
|
|
4416
|
+
return Array.from(new Set(ids2));
|
|
4417
|
+
}
|
|
4404
4418
|
async function isSuperAdmin(userId) {
|
|
4405
4419
|
return await resolveStaffRole(userId) !== null;
|
|
4406
4420
|
}
|
|
@@ -8396,6 +8410,7 @@ var NotificationModule = /* @__PURE__ */ ((NotificationModule2) => {
|
|
|
8396
8410
|
NotificationModule2["EMERGENCY_CONTACT"] = "emergencyContact";
|
|
8397
8411
|
NotificationModule2["VIRTUAL_PATROL"] = "virtualPatrol";
|
|
8398
8412
|
NotificationModule2["CAMERA_FAULT"] = "cameraFault";
|
|
8413
|
+
NotificationModule2["PLATFORM"] = "platform";
|
|
8399
8414
|
NotificationModule2["OTHER"] = "other";
|
|
8400
8415
|
return NotificationModule2;
|
|
8401
8416
|
})(NotificationModule || {});
|
|
@@ -8818,6 +8833,17 @@ var NOTIFICATION_CHANNEL_LABELS = {
|
|
|
8818
8833
|
var ORG_MARKETPLACE_VENDOR_FIELD = "isMarketplaceVendor";
|
|
8819
8834
|
var NO_EMAIL_RECIPIENT = "This system does not email anyone about this \u2014 the alert only reaches you in the app and on your phone.";
|
|
8820
8835
|
var NOTIFICATION_CATEGORIES = [
|
|
8836
|
+
{
|
|
8837
|
+
key: "platform",
|
|
8838
|
+
label: "Seven365 platform",
|
|
8839
|
+
description: "When a new client is created, or an invited client owner accepts and their account goes live. Seven365 staff only.",
|
|
8840
|
+
channels: { inApp: true, push: true, email: false },
|
|
8841
|
+
channelNote: { email: NO_EMAIL_RECIPIENT },
|
|
8842
|
+
// Staff hold `*`; the flag below is what decides, not a resource.
|
|
8843
|
+
permissionResources: [],
|
|
8844
|
+
staffOnly: true,
|
|
8845
|
+
rendered: true
|
|
8846
|
+
},
|
|
8821
8847
|
{
|
|
8822
8848
|
key: "feedback",
|
|
8823
8849
|
label: "Feedback",
|
|
@@ -9039,6 +9065,8 @@ function categoriesForPermissions(params) {
|
|
|
9039
9065
|
return NOTIFICATION_CATEGORIES.filter((category) => {
|
|
9040
9066
|
if (!category.rendered)
|
|
9041
9067
|
return false;
|
|
9068
|
+
if (category.staffOnly)
|
|
9069
|
+
return params.isStaff === true;
|
|
9042
9070
|
if (wildcard)
|
|
9043
9071
|
return true;
|
|
9044
9072
|
if (params.isResident && category.residentDefault)
|
|
@@ -10258,7 +10286,61 @@ async function sendSafetyAlert(params) {
|
|
|
10258
10286
|
);
|
|
10259
10287
|
return userIds.length;
|
|
10260
10288
|
}
|
|
10289
|
+
async function staffRecipients() {
|
|
10290
|
+
try {
|
|
10291
|
+
return await listStaffUserIds();
|
|
10292
|
+
} catch (error) {
|
|
10293
|
+
console.warn("[NotificationService] staff lookup", error);
|
|
10294
|
+
return [];
|
|
10295
|
+
}
|
|
10296
|
+
}
|
|
10261
10297
|
var NotificationService = class {
|
|
10298
|
+
/**
|
|
10299
|
+
* Seven365's own staff, told about the platform's client lifecycle.
|
|
10300
|
+
*
|
|
10301
|
+
* Nothing in the estate addressed Seven365 staff before this: their bell was
|
|
10302
|
+
* empty by construction (owner, 2026-09-21). Both senders resolve the staff
|
|
10303
|
+
* list themselves — a caller cannot address the platform by accident — and
|
|
10304
|
+
* both are quiet when there are no staff accounts.
|
|
10305
|
+
*
|
|
10306
|
+
* No `appSlug`: staff work on the web, and the web feed asks for everything
|
|
10307
|
+
* addressed to the person. The category is `platform`, whose switch only
|
|
10308
|
+
* staff are shown.
|
|
10309
|
+
*/
|
|
10310
|
+
static async clientCreated(payload) {
|
|
10311
|
+
const staff = await staffRecipients();
|
|
10312
|
+
if (!staff.length)
|
|
10313
|
+
return;
|
|
10314
|
+
const what = [payload.orgName, payload.nature].filter(Boolean).join(" \u2014 ");
|
|
10315
|
+
await send(
|
|
10316
|
+
staff,
|
|
10317
|
+
"New client created",
|
|
10318
|
+
`${what} is now on iService365.`,
|
|
10319
|
+
{
|
|
10320
|
+
module: "platform",
|
|
10321
|
+
screen: "",
|
|
10322
|
+
params: { id: payload.orgId.toString() }
|
|
10323
|
+
},
|
|
10324
|
+
false,
|
|
10325
|
+
void 0,
|
|
10326
|
+
"platform"
|
|
10327
|
+
);
|
|
10328
|
+
}
|
|
10329
|
+
static async clientInvitationAccepted(payload) {
|
|
10330
|
+
const staff = await staffRecipients();
|
|
10331
|
+
if (!staff.length)
|
|
10332
|
+
return;
|
|
10333
|
+
const who = payload.orgName ? `${payload.email} (${payload.orgName})` : payload.email;
|
|
10334
|
+
await send(
|
|
10335
|
+
staff,
|
|
10336
|
+
"Invitation accepted",
|
|
10337
|
+
`${who} accepted their invitation and can sign in.`,
|
|
10338
|
+
{ module: "platform", screen: "" },
|
|
10339
|
+
false,
|
|
10340
|
+
void 0,
|
|
10341
|
+
"platform"
|
|
10342
|
+
);
|
|
10343
|
+
}
|
|
10262
10344
|
static async bulletinBoardCreated(payload) {
|
|
10263
10345
|
await send(
|
|
10264
10346
|
toStringArray(payload.to),
|
|
@@ -24186,6 +24268,11 @@ function useVerificationController() {
|
|
|
24186
24268
|
return;
|
|
24187
24269
|
}
|
|
24188
24270
|
const result = await _updateStatusById(id, status);
|
|
24271
|
+
void NotificationService.clientInvitationAccepted({
|
|
24272
|
+
email: verification.email,
|
|
24273
|
+
invitationType: verification.type,
|
|
24274
|
+
orgName: verification?.metadata?.organizationName
|
|
24275
|
+
});
|
|
24189
24276
|
res.json({ message: result });
|
|
24190
24277
|
return;
|
|
24191
24278
|
} catch (error2) {
|
|
@@ -25587,6 +25674,12 @@ function useOrgController() {
|
|
|
25587
25674
|
const createdBy = await requireConsolePermission(req, "organizations");
|
|
25588
25675
|
const org = await _add({ ...req.body, createdBy });
|
|
25589
25676
|
await seedDefaultRoles(org, req.body.nature);
|
|
25677
|
+
void NotificationService.clientCreated({
|
|
25678
|
+
orgId: org,
|
|
25679
|
+
orgName: req.body.name,
|
|
25680
|
+
nature: req.body.nature,
|
|
25681
|
+
createdBy
|
|
25682
|
+
});
|
|
25590
25683
|
res.status(201).json({ message: "Successfully created organization." });
|
|
25591
25684
|
return;
|
|
25592
25685
|
} catch (error2) {
|
|
@@ -91461,7 +91554,9 @@ function useNotificationPreferenceService() {
|
|
|
91461
91554
|
return categoriesForPermissions({
|
|
91462
91555
|
permissions,
|
|
91463
91556
|
isResident,
|
|
91464
|
-
isMarketplaceVendor: await belongsToMarketplaceVendor(db2, members)
|
|
91557
|
+
isMarketplaceVendor: await belongsToMarketplaceVendor(db2, members),
|
|
91558
|
+
// The staff switch is never opened by a role permission — see `staffOnly`.
|
|
91559
|
+
isStaff: await isSuperAdmin(userId)
|
|
91465
91560
|
});
|
|
91466
91561
|
}
|
|
91467
91562
|
async function getForUser(userId) {
|
|
@@ -92116,6 +92211,7 @@ export {
|
|
|
92116
92211
|
isSuperAdmin,
|
|
92117
92212
|
isTermsCurrent,
|
|
92118
92213
|
isValidTimezone,
|
|
92214
|
+
listStaffUserIds,
|
|
92119
92215
|
manpowerDesignationsSchema,
|
|
92120
92216
|
manpowerEvents,
|
|
92121
92217
|
manpowerMonitoringSchema,
|