@justair/justair-library 3.3.2 → 3.3.4-alpha

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@justair/justair-library",
3
- "version": "3.3.2",
3
+ "version": "3.3.4-alpha",
4
4
  "description": "JustAir Internal Library",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/index.js CHANGED
@@ -27,7 +27,12 @@ import {
27
27
  import { contextsSchema, Contexts } from "./models/contexts.js";
28
28
  import { parametersSchema, Parameters } from "./models/parameters.js";
29
29
  import { usersSchema, Users } from "./models/users.js";
30
- import { eventsSchema, Events } from "./models/events.js";
30
+ import {
31
+ eventsSchema,
32
+ Events,
33
+ eventsAuditSchema,
34
+ EventsAudit,
35
+ } from "./models/events.js";
31
36
  import {
32
37
  qaNotificationsSchema,
33
38
  QANotifications,
@@ -83,4 +88,6 @@ export {
83
88
  usageMetricsSchema,
84
89
  Audit,
85
90
  auditSchema,
91
+ EventsAudit,
92
+ eventsAuditSchema,
86
93
  };
@@ -1,5 +1,33 @@
1
1
  import mongoose from "mongoose";
2
- //TODO: Capture historical data, every hour record AQI values for monitors
2
+
3
+ // Events Audit Schema
4
+ const eventsAuditSchema = mongoose.Schema(
5
+ {
6
+ monitorId: { type: mongoose.Types.ObjectId, ref: "Monitors" },
7
+ parameter: {
8
+ type: String,
9
+ enum: ["AQI", "PID"],
10
+ },
11
+ values: Object,
12
+ alertLevels: Object,
13
+ currentMonitorState: {
14
+ type: String,
15
+ enum: ["Collocation", "Deployed", "Maintenance", "Pending Deployment"],
16
+ },
17
+ pollutantsFlags: {
18
+ type: Object,
19
+ default: {},
20
+ },
21
+ deletedAt: { type: Date, default: null },
22
+ },
23
+ {
24
+ timestamps: true,
25
+ }
26
+ );
27
+
28
+ const EventsAudit = mongoose.model("EventsAudit", eventsAuditSchema);
29
+
30
+ // Events Schema
3
31
  const eventsSchema = mongoose.Schema(
4
32
  {
5
33
  monitorId: { type: mongoose.Types.ObjectId, ref: "Monitors" },
@@ -16,7 +44,7 @@ const eventsSchema = mongoose.Schema(
16
44
  pollutantsFlags: {
17
45
  type: Object,
18
46
  default: {},
19
- }
47
+ },
20
48
  },
21
49
  {
22
50
  timestamps: true,
@@ -26,5 +54,71 @@ const eventsSchema = mongoose.Schema(
26
54
  eventsSchema.index({ monitorId: 1 });
27
55
  eventsSchema.index({ parameter: 1 });
28
56
 
57
+ // Pre-hook to log single document deletions
58
+ eventsSchema.pre("findOneAndDelete", async function () {
59
+ const docToDelete = await this.model.findOne(this.getFilter());
60
+ if (docToDelete) {
61
+ console.log("Logging findOneAndDelete to events audit", docToDelete);
62
+ const auditLog = new EventsAudit({
63
+ ...docToDelete.toObject(),
64
+ deletedAt: new Date(),
65
+ });
66
+ await auditLog.save();
67
+ }
68
+ });
69
+
70
+ // Pre-hook to log multiple document deletions
71
+ eventsSchema.pre("deleteMany", async function () {
72
+ const docsToDelete = await this.model.find(this.getFilter()).lean();
73
+ if (docsToDelete.length) {
74
+ console.log(`Logging ${docsToDelete.length} documents to events audit`);
75
+ const auditLogs = docsToDelete.map((doc) => ({
76
+ ...doc,
77
+ deletedAt: new Date(),
78
+ }));
79
+ await EventsAudit.insertMany(auditLogs);
80
+ }
81
+ });
82
+
83
+ // Pre-hook to log a single document deletion (for deleteOne)
84
+ eventsSchema.pre("deleteOne", async function () {
85
+ const docToDelete = await this.model.findOne(this.getFilter()).lean();
86
+ if (docToDelete) {
87
+ console.log("Logging deleteOne to events audit", docToDelete);
88
+ const auditLog = new EventsAudit({
89
+ ...docToDelete,
90
+ deletedAt: new Date(),
91
+ });
92
+ await auditLog.save();
93
+ }
94
+ });
95
+
96
+ // Pre-hook to log single document updates
97
+ eventsSchema.pre("findOneAndUpdate", async function () {
98
+ const docToUpdate = await this.model.findOne(this.getFilter()).lean();
99
+ if (docToUpdate) {
100
+ console.log("Logging findOneAndUpdate to events audit", docToUpdate);
101
+ const auditLog = new EventsAudit({
102
+ ...docToUpdate,
103
+ deletedAt: null, // Not deleted
104
+ });
105
+ await auditLog.save();
106
+ }
107
+ });
108
+
109
+ // Pre-hook to log multiple document updates
110
+ eventsSchema.pre("updateMany", async function () {
111
+ const docsToUpdate = await this.model.find(this.getFilter()).lean();
112
+ if (docsToUpdate.length) {
113
+ console.log(`Logging ${docsToUpdate.length} documents to events audit`);
114
+ const auditLogs = docsToUpdate.map((doc) => ({
115
+ ...doc,
116
+ deletedAt: null, // Not deleted
117
+ }));
118
+ await EventsAudit.insertMany(auditLogs);
119
+ }
120
+ });
121
+
29
122
  const Events = mongoose.model("Events", eventsSchema);
30
- export { eventsSchema, Events };
123
+
124
+ export { eventsSchema, Events, EventsAudit, eventsAuditSchema };
@@ -90,6 +90,41 @@ measurementsSchema.pre("deleteOne", async function () {
90
90
  }
91
91
  });
92
92
 
93
+ // Pre-hook to log single document updates
94
+ measurementsSchema.pre("findOneAndUpdate", async function () {
95
+ const docToUpdate = await this.model.findOne(this.getFilter()).lean();
96
+ if (docToUpdate) {
97
+ console.log("Logging findOneAndUpdate to audit", docToUpdate);
98
+ const auditLog = new Audit({
99
+ monitorId: docToUpdate.monitorId,
100
+ orgId: docToUpdate.orgId,
101
+ timeUpdated: docToUpdate.timeUpdated,
102
+ measurements: docToUpdate.measurements,
103
+ monitorState: docToUpdate.monitorState,
104
+ deletedAt: null, // No deletion happening, so set it to null or undefined
105
+ });
106
+ await auditLog.save();
107
+ }
108
+ });
109
+
110
+ // Pre-hook to log multiple document updates
111
+ measurementsSchema.pre("updateMany", async function () {
112
+ const docsToUpdate = await this.model.find(this.getFilter()).lean();
113
+ if (docsToUpdate.length) {
114
+ console.log(`Logging ${docsToUpdate.length} documents to audit`);
115
+ const auditLogs = docsToUpdate.map((doc) => ({
116
+ monitorId: doc.monitorId,
117
+ orgId: doc.orgId,
118
+ timeUpdated: doc.timeUpdated,
119
+ measurements: doc.measurements,
120
+ monitorState: doc.monitorState,
121
+ deletedAt: null, // No deletion happening
122
+ }));
123
+
124
+ await Audit.insertMany(auditLogs);
125
+ }
126
+ });
127
+
93
128
  const Measurements = mongoose.model("Measurements", measurementsSchema);
94
129
 
95
130
  export { measurementsSchema, Measurements, Audit, auditSchema };
@@ -0,0 +1,40 @@
1
+ import mongoose from "mongoose";
2
+
3
+ const parametersEnum = [
4
+ "NO2",
5
+ "SO2",
6
+ "PM2.5",
7
+ "PM10",
8
+ "Temperature",
9
+ "Humidity",
10
+ "OZONE",
11
+ "VOC",
12
+ "CO",
13
+ "NO",
14
+ "PM1",
15
+ "WS And Direction",
16
+ ];
17
+
18
+ const monitorTypeSchema = mongoose.Schema(
19
+ {
20
+ model: {
21
+ type: String,
22
+ required: true,
23
+ },
24
+
25
+ supplier: {
26
+ type: mongoose.Types.ObjectId,
27
+ required: true,
28
+ ref: "MonitorSuppliers",
29
+ },
30
+
31
+ parameters: {
32
+ type: String,
33
+ enum: parametersEnum,
34
+ required: true,
35
+ },
36
+ },
37
+ { timestamps: true }
38
+ );
39
+
40
+ const monitorType = mongoose.model("MonitorType", monitorTypeSchema);
@@ -1,5 +1,47 @@
1
- import mongoose from "mongoose";
1
+ import mongoose from "mongoose";import { emitWarning } from "process";
2
+ const parametersEnum = [
3
+ "NO2",
4
+ "SO2",
5
+ "PM2.5",
6
+ "PM10",
7
+ "Temperature",
8
+ "Humidity",
9
+ "OZONE",
10
+ "VOC",
11
+ "CO",
12
+ "NO",
13
+ "PM1",
14
+ "WS And Direction",
15
+ ];
2
16
 
17
+ const parameterThresholdsSchema = mongoose.Schema({
18
+ parameter: {
19
+ type: Map,
20
+ of: new mongoose.Schema({
21
+ invalid: {
22
+ upper: Number,
23
+ lower: Number,
24
+ },
25
+
26
+ warning: {
27
+ upper: Number,
28
+ lower: Number,
29
+ },
30
+ }),
31
+ },
32
+ });
33
+
34
+ /*Ensure the parameter value is one of our valid parameters */
35
+ parameterThresholdsSchema.path('parameter').validate(function(value) {
36
+ for (let key of value.keys()) {
37
+ if (!parametersEnum.includes(key)) {
38
+ return false;
39
+ }
40
+ }
41
+ return true;
42
+ }, 'Invalid parameter key');
43
+
44
+ // Monitors Schema
3
45
  const monitorsSchema = mongoose.Schema(
4
46
  {
5
47
  monitorCode: String,
@@ -57,20 +99,7 @@ const monitorsSchema = mongoose.Schema(
57
99
  parameters: [
58
100
  {
59
101
  type: String,
60
- enum: [
61
- "NO2",
62
- "SO2",
63
- "PM2.5",
64
- "PM10",
65
- "Temperature",
66
- "Humidity",
67
- "OZONE",
68
- "VOC",
69
- "CO",
70
- "NO",
71
- "PM1",
72
- "WS And Direction",
73
- ],
102
+ enum: parametersEnum,
74
103
  },
75
104
  ],
76
105
  latestPM2_5: Number,
@@ -79,6 +108,7 @@ const monitorsSchema = mongoose.Schema(
79
108
  calculatedAverages: [Object],
80
109
  images: [String],
81
110
  isActive: { type: Boolean, default: true },
111
+ parameterThresholds: { type: Map, of: parameterThresholdsSchema },
82
112
  },
83
113
  {
84
114
  timestamps: true,