tabletcommand-incident 0.5.0 → 0.6.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.
Files changed (52) hide show
  1. package/.cspell/project-words.txt +2 -0
  2. package/build/rules/clear-field.js +1 -1
  3. package/build/rules/clear-field.js.map +1 -1
  4. package/build/rules/index.js +11 -2
  5. package/build/rules/index.js.map +1 -1
  6. package/build/rules/join-call-type-priority.js +18 -14
  7. package/build/rules/join-call-type-priority.js.map +1 -1
  8. package/build/rules/join-call-type-sacramento.js +50 -0
  9. package/build/rules/join-call-type-sacramento.js.map +1 -0
  10. package/build/test/index.js +74 -0
  11. package/build/test/index.js.map +1 -1
  12. package/build/test/mock.js +95 -13
  13. package/build/test/mock.js.map +1 -1
  14. package/build/test/rules/join-call-type-priority.js +16 -2
  15. package/build/test/rules/join-call-type-priority.js.map +1 -1
  16. package/build/test/rules/join-call-type-sacramento.js +36 -0
  17. package/build/test/rules/join-call-type-sacramento.js.map +1 -0
  18. package/definitions/domain.d.ts +1 -1
  19. package/definitions/domain.d.ts.map +1 -1
  20. package/definitions/incidentProcessor.d.ts +1 -1
  21. package/definitions/incidentProcessor.d.ts.map +1 -1
  22. package/definitions/index.d.ts +1 -1
  23. package/definitions/index.d.ts.map +1 -1
  24. package/definitions/rules/clear-field.d.ts +1 -1
  25. package/definitions/rules/clear-field.d.ts.map +1 -1
  26. package/definitions/rules/index.d.ts.map +1 -1
  27. package/definitions/rules/join-call-type-priority.d.ts +4 -3
  28. package/definitions/rules/join-call-type-priority.d.ts.map +1 -1
  29. package/definitions/rules/join-call-type-sacramento.d.ts +10 -0
  30. package/definitions/rules/join-call-type-sacramento.d.ts.map +1 -0
  31. package/definitions/rules/remove-person-from-unit.d.ts +1 -1
  32. package/definitions/rules/remove-person-from-unit.d.ts.map +1 -1
  33. package/definitions/setIncidentType.d.ts +2 -2
  34. package/definitions/setIncidentType.d.ts.map +1 -1
  35. package/definitions/store.d.ts +1 -1
  36. package/definitions/store.d.ts.map +1 -1
  37. package/definitions/test/mock.d.ts +3 -1
  38. package/definitions/test/mock.d.ts.map +1 -1
  39. package/definitions/test/rules/join-call-type-sacramento.d.ts +2 -0
  40. package/definitions/test/rules/join-call-type-sacramento.d.ts.map +1 -0
  41. package/definitions/types.d.ts +2 -2
  42. package/definitions/types.d.ts.map +1 -1
  43. package/package.json +17 -17
  44. package/src/rules/clear-field.ts +1 -1
  45. package/src/rules/index.ts +13 -2
  46. package/src/rules/join-call-type-priority.ts +23 -14
  47. package/src/rules/join-call-type-sacramento.ts +51 -0
  48. package/src/test/index.ts +94 -0
  49. package/src/test/mock.ts +119 -34
  50. package/src/test/rules/join-call-type-priority.ts +18 -2
  51. package/src/test/rules/join-call-type-sacramento.ts +40 -0
  52. package/test.sh +1 -1
@@ -0,0 +1,51 @@
1
+ import _ from "lodash";
2
+
3
+ import { CADIncident } from "tabletcommand-backend-models";
4
+ import { IncidentRule, IncidentRuleChange } from ".";
5
+
6
+ export class IncidentRuleJoinCallTypeSacramento implements IncidentRule {
7
+ name = "Join Call Type - Priority";
8
+ matched = false;
9
+ changed = false;
10
+ changes: IncidentRuleChange[] = [];
11
+
12
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
13
+ apply(item: Partial<CADIncident>, _atDate: Date): Partial<CADIncident> {
14
+ // Set key in uppercase
15
+ const appendPriorityMap: Record<string, string> = {
16
+ "CODE 2": "C2",
17
+ };
18
+
19
+ const prioMatching: string[] = _.keys(appendPriorityMap);
20
+ let providedPrio = "";
21
+ if (_.isString(item.AgencyIncidentPriorityDescription)) {
22
+ providedPrio = _.trim(item.AgencyIncidentPriorityDescription).toUpperCase();
23
+ }
24
+ let providedCallType = "";
25
+ if (item.AgencyIncidentCallTypeDescription) {
26
+ providedCallType = _.trim(item.AgencyIncidentCallTypeDescription);
27
+ }
28
+
29
+ const canProcess = providedPrio !== "" && providedCallType !== "" && prioMatching.indexOf(providedPrio) > -1;
30
+ if (!canProcess) {
31
+ return item;
32
+ }
33
+
34
+ const nextPrio = appendPriorityMap[providedPrio];
35
+ item.AgencyIncidentCallTypeDescription = `${nextPrio} - ${providedCallType}`;
36
+
37
+ this.matched = true;
38
+ this.changed = true;
39
+
40
+ this.changes.push({
41
+ name: this.name,
42
+ matched: this.matched,
43
+ changed: this.changed,
44
+ change: {
45
+ AgencyIncidentCallTypeDescription: item.AgencyIncidentCallTypeDescription,
46
+ },
47
+ });
48
+
49
+ return item;
50
+ }
51
+ }
package/src/test/index.ts CHANGED
@@ -312,6 +312,53 @@ describe("index", function() {
312
312
  });
313
313
  });
314
314
 
315
+ context("CONFIRE Regional Emergency Communications - San Bernardino County CA", function() {
316
+ const atDate = new Date();
317
+ const sampleIncidentNumber = "Confire-SB-0001";
318
+
319
+ function validateRulesResult(sut: HandleProcessIncidentRequestResult) {
320
+ if ("error" in sut) {
321
+ assert.fail(sut.error.toString());
322
+ } else {
323
+ const {
324
+ incident
325
+ } = sut;
326
+
327
+ assert.strictEqual(incident?.AgencyIncidentCallTypeDescription, "SHORTNESS OF BREATH (C3)");
328
+ }
329
+ }
330
+
331
+ it("process stream through legacy", async function() {
332
+ const department = mock.departmentConfire;
333
+ const departmentId = department._id.toString();
334
+ const existingStreamItems = await mock.getIncidentStreamItems(departmentId, sampleIncidentNumber);
335
+ const streamItem = _.first(existingStreamItems);
336
+
337
+ if (!streamItem) {
338
+ assert.fail("Expecting a stream item");
339
+ return;
340
+ }
341
+
342
+ const sut = await incidentProcessor.handleProcessIncidentRequestLegacy(streamItem, department, atDate);
343
+ validateRulesResult(sut);
344
+ });
345
+
346
+ it("process stream through correction", async function() {
347
+ const department = mock.departmentConfire;
348
+ const departmentId = department._id.toString();
349
+ const existingStreamItems = await mock.getIncidentStreamItems(departmentId, sampleIncidentNumber);
350
+ const streamItem = _.first(existingStreamItems);
351
+
352
+ if (!streamItem) {
353
+ assert.fail("Expecting a stream item");
354
+ return;
355
+ }
356
+
357
+ const sut = await incidentProcessor.handleProcessIncidentRequestCorrection(streamItem.incidentNumber, department, atDate);
358
+ validateRulesResult(sut);
359
+ });
360
+ });
361
+
315
362
  context("Jackson County - Testing", function() {
316
363
  const atDate = new Date();
317
364
  const sampleIncidentNumber = "Jackson-County-Test-0001";
@@ -366,6 +413,53 @@ describe("index", function() {
366
413
  });
367
414
  });
368
415
 
416
+ context("Sacramento Regional Fire Communications Center", function() {
417
+ const atDate = new Date();
418
+ const sampleIncidentNumber = "Sacramento-SB-0001";
419
+
420
+ function validateRulesResult(sut: HandleProcessIncidentRequestResult) {
421
+ if ("error" in sut) {
422
+ assert.fail(sut.error.toString());
423
+ } else {
424
+ const {
425
+ incident
426
+ } = sut;
427
+
428
+ assert.strictEqual(incident?.AgencyIncidentCallTypeDescription, "C2 - PUBLIC ASSISTANCE");
429
+ }
430
+ }
431
+
432
+ it("process stream through legacy", async function() {
433
+ const department = mock.departmentSacramento;
434
+ const departmentId = department._id.toString();
435
+ const existingStreamItems = await mock.getIncidentStreamItems(departmentId, sampleIncidentNumber);
436
+ const streamItem = _.first(existingStreamItems);
437
+
438
+ if (!streamItem) {
439
+ assert.fail("Expecting a stream item");
440
+ return;
441
+ }
442
+
443
+ const sut = await incidentProcessor.handleProcessIncidentRequestLegacy(streamItem, department, atDate);
444
+ validateRulesResult(sut);
445
+ });
446
+
447
+ it("process stream through correction", async function() {
448
+ const department = mock.departmentSacramento;
449
+ const departmentId = department._id.toString();
450
+ const existingStreamItems = await mock.getIncidentStreamItems(departmentId, sampleIncidentNumber);
451
+ const streamItem = _.first(existingStreamItems);
452
+
453
+ if (!streamItem) {
454
+ assert.fail("Expecting a stream item");
455
+ return;
456
+ }
457
+
458
+ const sut = await incidentProcessor.handleProcessIncidentRequestCorrection(streamItem.incidentNumber, department, atDate);
459
+ validateRulesResult(sut);
460
+ });
461
+ });
462
+
369
463
  context("San Mateo County", function() {
370
464
  const atDate = new Date();
371
465
  const sampleIncidentNumber = "San-Mateo-0001";
package/src/test/mock.ts CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  CADIncidentStream,
7
7
  Department,
8
8
  MongooseModule,
9
- convertToObjectId as ObjectId,
10
9
  } from "tabletcommand-backend-models";
11
10
 
12
11
  export default function({
@@ -16,29 +15,41 @@ export default function({
16
15
  models: BackendModels,
17
16
  mongoose: MongooseModule,
18
17
  }) {
19
- const departmentAlameda = {
20
- _id: ObjectId("63695b86cd105785080ef488"),
18
+ const ObjectId = mongoose.Types.ObjectId;
19
+
20
+ const departmentAlameda: Department = {
21
+ _id: new ObjectId("63695b86cd105785080ef488"),
21
22
  department: "Alameda County Regional ECC - Production",
22
- } as unknown as Department;
23
+ apikey: "ala1",
24
+ rtsChannelPrefix: "AL1",
25
+ } as Department;
23
26
 
24
- const departmentCalfireLNU = {
25
- _id: ObjectId("57292e6a396b8faa39000019"),
27
+ const departmentCalfireLNU: Department = {
28
+ _id: new ObjectId("57292e6a396b8faa39000019"),
26
29
  department: "CalFire - LNU",
27
- } as unknown as Department;
30
+ apikey: "lnu2",
31
+ rtsChannelPrefix: "LN2",
32
+ } as Department;
28
33
 
29
- const departmentCalfireCZU = {
30
- _id: ObjectId("52eea230066ce400000007f9"),
34
+ const departmentCalfireCZU: Department = {
35
+ _id: new ObjectId("52eea230066ce400000007f9"),
31
36
  department: "CalFire - CZU",
32
- } as unknown as Department;
37
+ apikey: "czu3",
38
+ rtsChannelPrefix: "CZ3",
39
+ } as Department;
33
40
 
34
- const departmentClarkCounty = {
35
- _id: ObjectId("5c1016b2ebcdc419d00a3ecb"),
41
+ const departmentClarkCounty: Department = {
42
+ _id: new ObjectId("5c1016b2ebcdc419d00a3ecb"),
36
43
  department: "Clark County Fire Department",
37
- } as unknown as Department;
44
+ apikey: "cla4",
45
+ rtsChannelPrefix: "CL4",
46
+ } as Department;
38
47
 
39
48
  const departmentId = "558365a198b2fa4278000053";
40
- const departmentDemoRTS = {
41
- _id: ObjectId(departmentId),
49
+ const departmentDemoRTS: Department = {
50
+ _id: new ObjectId(departmentId),
51
+ apikey: "demo5",
52
+ rtsChannelPrefix: "DEM5",
42
53
  ackDelimiter: "???",
43
54
  department: "Demo RTS Fire Department",
44
55
  incidentTypes: [
@@ -67,35 +78,61 @@ export default function({
67
78
  ]
68
79
  } as unknown as Department;
69
80
 
70
- const departmentJacksonCountyTest = {
71
- _id: ObjectId("661db49dc30f898ba3594c9a"),
81
+ const departmentJacksonCountyTest: Department = {
82
+ _id: new ObjectId("661db49dc30f898ba3594c9a"),
72
83
  department: "Jackson County - Testing",
73
- } as unknown as Department;
84
+ apikey: "jac6",
85
+ rtsChannelPrefix: "JC6",
86
+ } as Department;
74
87
 
75
- const departmentSanMateoCounty = {
76
- _id: ObjectId("5238fb0228dd530000000132"),
88
+ const departmentSanMateoCounty: Department = {
89
+ _id: new ObjectId("5238fb0228dd530000000132"),
77
90
  department: "San Mateo County",
78
- } as unknown as Department;
91
+ apikey: "smo7",
92
+ rtsChannelPrefix: "SM7",
93
+ } as Department;
79
94
 
80
- const departmentSantaCruzRegional = {
81
- _id: ObjectId("51b8bea159aaf4fa3e000378"),
95
+ const departmentSantaCruzRegional: Department = {
96
+ _id: new ObjectId("51b8bea159aaf4fa3e000378"),
82
97
  department: "Santa Cruz Regional Communications",
83
- } as unknown as Department;
98
+ apikey: "scr8",
99
+ rtsChannelPrefix: "SCR8",
100
+ } as Department;
84
101
 
85
- const departmentSouthernMarin = {
86
- _id: ObjectId("5175b66dd114ea2bee000037"),
102
+ const departmentSouthernMarin: Department = {
103
+ _id: new ObjectId("5175b66dd114ea2bee000037"),
87
104
  department: "Southern Marin",
88
- } as unknown as Department;
105
+ apikey: "sou9",
106
+ rtsChannelPrefix: "SM9",
107
+ } as Department;
89
108
 
90
- const departmentVerdugo = {
91
- _id: ObjectId("6387f8028dc3b9c15bd2afc8"),
109
+ const departmentVerdugo: Department = {
110
+ _id: new ObjectId("6387f8028dc3b9c15bd2afc8"),
92
111
  "department": "Verdugo Communications",
93
- } as unknown as Department;
112
+ apikey: "ver10",
113
+ rtsChannelPrefix: "VE10",
114
+ } as Department;
94
115
 
95
- const departmentYolo = {
96
- _id: ObjectId("660c60e25a572c9f4a20972a"),
116
+ const departmentYolo: Department = {
117
+ _id: new ObjectId("660c60e25a572c9f4a20972a"),
97
118
  "department": "Yolo Emergency Communications Agency",
98
- } as unknown as Department;
119
+ apikey: "yol11",
120
+ rtsChannelPrefix: "YL11",
121
+ } as Department;
122
+
123
+ const departmentConfire: Department = {
124
+ _id: new ObjectId("56131f724143487a10000001"),
125
+ "department": "CONFIRE Regional Emergency Communications - San Bernardino County CA",
126
+ apikey: "con12",
127
+ rtsChannelPrefix: "CO12",
128
+ } as Department;
129
+
130
+ const departmentSacramento: Department = {
131
+ _id: new ObjectId("523bc3e85f1720abda000085"),
132
+ "department": "Sacramento Regional Fire Communications Center",
133
+ apikey: "sac13",
134
+ rtsChannelPrefix: "SA13",
135
+ } as Department;
99
136
 
100
137
  const incidentStreamItems: Partial<CADIncidentStream>[] = [
101
138
  {
@@ -723,6 +760,50 @@ export default function({
723
760
  }
724
761
  ],
725
762
  },
763
+ },
764
+ {
765
+ departmentId: departmentConfire._id.toString(),
766
+ "incidentNumber": "Confire-SB-0001",
767
+ "uuid": "d3d23200-e0fa-443f-b647-5f18d15bbccc",
768
+ "tag": "871e3d05-1572-4d81-ba29-0ab01b4e6d91",
769
+ "createdAt": new Date("2024-01-22T10:11:47.617+0000"),
770
+ "payload": {
771
+ "AgencyID": "EMS1143",
772
+ "IncidentNumber": "Confire-SB-0001",
773
+ "EntryDateTime": "2024-01-22T02:08:06-08:00",
774
+ "AgencyIncidentCallTypeDescription": "SHORTNESS OF BREATH",
775
+ "AgencyIncidentPriorityDescription": "C3",
776
+ "ClosedDateTime": "",
777
+ "Comment": [
778
+ {
779
+ "CommentSource": "VF49",
780
+ "CommentDateTime": "2024-01-22T02:11:20-08:00",
781
+ "Comment": "Comment 1"
782
+ }
783
+ ],
784
+ },
785
+ },
786
+ {
787
+ departmentId: departmentSacramento._id.toString(),
788
+ "incidentNumber": "Sacramento-SB-0001",
789
+ "uuid": "d3d23200-e0fa-443f-b647-5f18daabbccc",
790
+ "tag": "871e3d05-1572-4d81-ba29-0ab01b4e6d91",
791
+ "createdAt": new Date("2024-01-22T10:11:47.617+0000"),
792
+ "payload": {
793
+ "AgencyID": "EMS1143",
794
+ "IncidentNumber": "Sacramento-SB-0001",
795
+ "EntryDateTime": "2024-01-22T02:08:06-08:00",
796
+ "AgencyIncidentCallTypeDescription": "PUBLIC ASSISTANCE",
797
+ "AgencyIncidentPriorityDescription": "CODE 2",
798
+ "ClosedDateTime": "",
799
+ "Comment": [
800
+ {
801
+ "CommentSource": "VF49",
802
+ "CommentDateTime": "2024-01-22T02:11:20-08:00",
803
+ "Comment": "Comment 1"
804
+ }
805
+ ],
806
+ },
726
807
  }
727
808
  ];
728
809
 
@@ -804,8 +885,10 @@ export default function({
804
885
  departmentAlameda,
805
886
  departmentCalfireLNU,
806
887
  departmentClarkCounty,
888
+ departmentConfire,
807
889
  departmentDemoRTS,
808
890
  departmentJacksonCountyTest,
891
+ departmentSacramento,
809
892
  departmentSanMateoCounty,
810
893
  departmentSantaCruzRegional,
811
894
  departmentSouthernMarin,
@@ -851,8 +934,10 @@ export default function({
851
934
  departmentCalfireCZU,
852
935
  departmentCalfireLNU,
853
936
  departmentClarkCounty,
854
- departmentJacksonCountyTest,
937
+ departmentConfire,
855
938
  departmentDemoRTS,
939
+ departmentJacksonCountyTest,
940
+ departmentSacramento,
856
941
  departmentSanMateoCounty,
857
942
  departmentSantaCruzRegional,
858
943
  departmentSouthernMarin,
@@ -15,7 +15,7 @@ describe("IncidentRuleJoinCallTypePriority", function describeFunc() {
15
15
 
16
16
  const dateStr = "2022-12-08T11:53:42.000Z";
17
17
  const atDate = new Date(dateStr);
18
- const rule = new IncidentRuleJoinCallTypePriority("PrioCallType");
18
+ const rule = new IncidentRuleJoinCallTypePriority("PrioCallType", "space");
19
19
  const result = rule.apply(testItem, atDate);
20
20
  assert.isTrue(rule.matched);
21
21
  assert.isTrue(rule.changed);
@@ -31,10 +31,26 @@ describe("IncidentRuleJoinCallTypePriority", function describeFunc() {
31
31
 
32
32
  const dateStr = "2022-12-08T11:53:42.000Z";
33
33
  const atDate = new Date(dateStr);
34
- const rule = new IncidentRuleJoinCallTypePriority("CallTypePrio", "-");
34
+ const rule = new IncidentRuleJoinCallTypePriority("CallTypePrio", "dash");
35
35
  const result = rule.apply(testItem, atDate);
36
36
  assert.isTrue(rule.matched);
37
37
  assert.isTrue(rule.changed);
38
38
  assert.equal(result.AgencyIncidentCallTypeDescription, "Structure Fire - 3A");
39
39
  });
40
+
41
+ it("Call Type (Prio)", function() {
42
+ const testItem = {
43
+ IncidentNumber: "i1239",
44
+ AgencyIncidentCallTypeDescription: "SICK - Sick Person",
45
+ AgencyIncidentPriorityDescription: "P1",
46
+ };
47
+
48
+ const dateStr = "2022-12-08T11:53:42.000Z";
49
+ const atDate = new Date(dateStr);
50
+ const rule = new IncidentRuleJoinCallTypePriority("CallTypePrio", "()");
51
+ const result = rule.apply(testItem, atDate);
52
+ assert.isTrue(rule.matched);
53
+ assert.isTrue(rule.changed);
54
+ assert.equal(result.AgencyIncidentCallTypeDescription, "SICK - Sick Person (P1)");
55
+ });
40
56
  });
@@ -0,0 +1,40 @@
1
+ import { assert } from "chai";
2
+ import "mocha";
3
+
4
+ import {
5
+ IncidentRuleJoinCallTypeSacramento,
6
+ } from "../../rules/join-call-type-sacramento";
7
+
8
+ describe("IncidentRuleJoinCallTypeSacramento", function describeFunc() {
9
+ it("Matches Code 2", function() {
10
+ const testItem = {
11
+ IncidentNumber: "i1239",
12
+ AgencyIncidentCallTypeDescription: "SICK PERSON",
13
+ AgencyIncidentPriorityDescription: "CODE 2"
14
+ };
15
+
16
+ const dateStr = "2022-12-08T11:53:42.000Z";
17
+ const atDate = new Date(dateStr);
18
+ const rule = new IncidentRuleJoinCallTypeSacramento();
19
+ const result = rule.apply(testItem, atDate);
20
+ assert.isTrue(rule.matched);
21
+ assert.isTrue(rule.changed);
22
+ assert.equal(result.AgencyIncidentCallTypeDescription, "C2 - SICK PERSON");
23
+ });
24
+
25
+ it("Does Not Match Code 3", function() {
26
+ const testItem = {
27
+ IncidentNumber: "i1239",
28
+ AgencyIncidentCallTypeDescription: "FALL",
29
+ AgencyIncidentPriorityDescription: "CODE 3"
30
+ };
31
+
32
+ const dateStr = "2022-12-08T11:53:42.000Z";
33
+ const atDate = new Date(dateStr);
34
+ const rule = new IncidentRuleJoinCallTypeSacramento();
35
+ const result = rule.apply(testItem, atDate);
36
+ assert.isFalse(rule.matched);
37
+ assert.isFalse(rule.changed);
38
+ assert.equal(result.AgencyIncidentCallTypeDescription, "FALL");
39
+ });
40
+ });
package/test.sh CHANGED
@@ -17,7 +17,7 @@ if hash brew 2>/dev/null; then
17
17
  fi
18
18
  fi
19
19
 
20
- NODE_VERSION="v16.19.0"
20
+ NODE_VERSION="v20.11.1"
21
21
 
22
22
  nvm use $NODE_VERSION || nvm install $NODE_VERSION
23
23