@7365admin1/core 3.53.7 → 3.53.8

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@7365admin1/core",
3
3
  "license": "MIT",
4
- "version": "3.53.7",
4
+ "version": "3.53.8",
5
5
  "author": "7365admin1",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",
@@ -13,6 +13,7 @@ import {
13
13
  ORG_MARKETPLACE_VENDOR_FIELD,
14
14
  categoriesForPermissions,
15
15
  categorySupportsChannel,
16
+ notificationCategory,
16
17
  notificationCategoryLabel,
17
18
  } from "./.build/utils/notification-category.util.mjs";
18
19
 
@@ -42,7 +43,7 @@ describe("notification categories", () => {
42
43
  }
43
44
  });
44
45
 
45
- it("the four safety categories now send, and are on by default and switchable", () => {
46
+ it("the four safety categories are on by default and switchable", () => {
46
47
  const safety = NOTIFICATION_CATEGORIES.filter((c) => c.safety);
47
48
 
48
49
  assert.deepEqual(keys(safety), [
@@ -56,7 +57,6 @@ describe("notification categories", () => {
56
57
  // nothing about them is special-cased: no "locked" flag, so they behave
57
58
  // like any other switch.
58
59
  assert.ok(!("locked" in category));
59
- assert.equal(category.rendered, true, category.key);
60
60
 
61
61
  // a safety alert is permission-scoped, never a resident default — a
62
62
  // category with no resource would reach nobody.
@@ -71,7 +71,6 @@ describe("notification categories", () => {
71
71
  it("a role holding only the safety module is offered only that switch", () => {
72
72
  const cases = {
73
73
  "incident-reports:create": "incidentReport",
74
- "emergency-contact:update": "emergencyContact",
75
74
  "virtual-patrol:see-all": "virtualPatrol",
76
75
  "site-settings:update": "cameraFault",
77
76
  };
@@ -143,7 +142,7 @@ describe("notification categories", () => {
143
142
  (c) => c.channels.email,
144
143
  ).map((c) => c.key);
145
144
 
146
- assert.deepEqual(emailCapable, ["serviceProviderInvite"]);
145
+ assert.deepEqual(emailCapable, []);
147
146
  });
148
147
 
149
148
  it("every channel a category cannot use explains itself in plain words", () => {
@@ -174,10 +173,50 @@ describe("notification categories", () => {
174
173
  it("channel support is a fact about the category, not a preference", () => {
175
174
  assert.equal(categorySupportsChannel("workOrder", "push"), true);
176
175
  assert.equal(categorySupportsChannel("workOrder", "email"), false);
177
- assert.equal(categorySupportsChannel("serviceProviderInvite", "email"), true);
176
+ assert.equal(categorySupportsChannel("serviceProviderInvite", "email"), false);
178
177
  assert.equal(categorySupportsChannel("not-a-module", "push"), false);
179
178
  });
180
179
 
180
+ // -------------------------------------------------------------------------
181
+ // What the September 2026 audit fixed. Both of these FAIL against the
182
+ // catalogue as it stood before it: `serviceProviderInvite` declared
183
+ // `email: true` and `emergencyContact` declared `rendered: true`.
184
+ // -------------------------------------------------------------------------
185
+
186
+ it("no category offers a switchable Email row, because no sender reads one", () => {
187
+ // `filterRecipients`/`isChannelEnabled` are never called with "email"
188
+ // anywhere in the estate, so a movable Email switch would govern nothing.
189
+ for (const category of NOTIFICATION_CATEGORIES) {
190
+ assert.equal(
191
+ category.channels.email,
192
+ false,
193
+ `${category.key} offers a live Email switch that no sender consults`,
194
+ );
195
+ assert.ok(
196
+ category.channelNote?.email,
197
+ `${category.key} dims Email without saying why`,
198
+ );
199
+ }
200
+ });
201
+
202
+ it("emergency contacts are not offered, because nothing calls their sender", () => {
203
+ // The sender exists in `notification.service.ts`, but emergency contacts
204
+ // are written in `iservice365-API-core` and the caller there was never
205
+ // merged. A switch over a message that cannot arrive is the defect this
206
+ // whole catalogue exists to prevent.
207
+ const category = notificationCategory("emergencyContact");
208
+ assert.equal(category.rendered, false);
209
+
210
+ for (const permissions of [["emergency-contact:update"], ["*"]]) {
211
+ assert.ok(
212
+ !keys(categoriesForPermissions({ permissions, isResident: true })).includes(
213
+ "emergencyContact",
214
+ ),
215
+ `offered to ${permissions.join()}`,
216
+ );
217
+ }
218
+ });
219
+
181
220
  it("category keys are unique", () => {
182
221
  const all = NOTIFICATION_CATEGORIES.map((c) => c.key);
183
222
  assert.equal(new Set(all).size, all.length);
@@ -332,7 +371,6 @@ const BEFORE = {
332
371
  "prelovedMarketplace",
333
372
  "serviceProviderInvite",
334
373
  "incidentReport",
335
- "emergencyContact",
336
374
  "virtualPatrol",
337
375
  "cameraFault",
338
376
  ],
@@ -340,7 +378,7 @@ const BEFORE = {
340
378
  "bulletin-board": ["bulletinBoard"],
341
379
  "bulletin-board-mgmt": ["bulletinBoard"],
342
380
  "bulletin-videos-mgmt": ["bulletinBoard"],
343
- "emergency-contact": ["emergencyContact"],
381
+ "emergency-contact": [],
344
382
  "event-mgmt": ["event"],
345
383
  "facility-booking-mgmt": ["facilityBooking"],
346
384
  "facility-mgmt": ["facilityBooking"],
@@ -413,11 +451,7 @@ describe("existing categories are untouched by the marketplace addition", () =>
413
451
  for (const category of NOTIFICATION_CATEGORIES) {
414
452
  if (NEW_KEYS.includes(category.key)) continue;
415
453
 
416
- assert.equal(
417
- category.channels.email,
418
- category.key === "serviceProviderInvite",
419
- category.key,
420
- );
454
+ assert.equal(category.channels.email, false, category.key);
421
455
  assert.equal(category.channels.inApp, true, category.key);
422
456
  assert.equal(category.channels.push, true, category.key);
423
457
  }