@justair/justair-library 4.7.13 → 4.7.15-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.
@@ -1,364 +1,365 @@
1
- import mongoose from "mongoose";
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
- "DP",
16
- ];
17
-
18
- const noteSchema = mongoose.Schema({
19
- note: {
20
- type: String,
21
- required: true,
22
- },
23
- type: {
24
- type: String,
25
- required: true,
26
- },
27
- monitorState: {
28
- type: String,
29
- required: true,
30
- },
31
- adminId: {
32
- type: mongoose.Types.ObjectId,
33
- ref: "Admin",
34
- required: true,
35
- },
36
- adminName: {
37
- type: String,
38
- },
39
- date: {
40
- type: Date,
41
- default: Date.now,
42
- },
43
- });
44
-
45
- const correctionSchema = mongoose.Schema(
46
- {
47
- equationType: {
48
- type: String,
49
- enum: ["linear", "custom"],
50
- required: true,
51
- },
52
- equation: {
53
- type: String,
54
- required: function () {
55
- return this.equationType === 'custom';
56
- },
57
- },
58
- context: {
59
- type: String,
60
- enum: ["field", "colocation"],
61
- required: false,
62
- },
63
- variables: {
64
- required: function () {
65
- return this.equationType === 'linear';
66
- },
67
- type: Object,
68
- },
69
- dateCreated: {
70
- type: Date,
71
- default: Date.now,
72
- },
73
- applyCorrection: { type: Boolean, default: true },
74
- },
75
- { _id: false } // no separate _id for sub-docs
76
- );
77
-
78
- const correctionHistorySchema = mongoose.Schema(
79
- {
80
- pollutant: {
81
- type: String,
82
- required: true,
83
- },
84
- oldValue: {
85
- type: correctionSchema,
86
- default: undefined,
87
- },
88
- newValue: {
89
- type: correctionSchema,
90
- default: undefined,
91
- },
92
- changedAt: {
93
- type: Date,
94
- default: Date.now,
95
- },
96
- },
97
- { _id: false }
98
- );
99
-
100
- // Monitor Audit Schema
101
- const monitorAuditSchema = mongoose.Schema(
102
- {
103
- monitorId: { type: mongoose.Types.ObjectId, ref: "Monitors" },
104
- orgId: { type: mongoose.Types.ObjectId, ref: "Organizations" },
105
- timeUpdated: Date,
106
- deletedAt: { type: Date, default: Date.now }, // Only populated on delete
107
- monitorProperties: Object, // Stores properties of the monitor
108
- monitorState: String, // Tracks the state of the monitor (e.g., "Deployed", "Maintenance")
109
- monitorLocation: {
110
- // Monitor GPS location (lat, lon)
111
- type: { type: String, enum: ["Point"], required: true },
112
- coordinates: { type: [Number], required: true },
113
- },
114
- parameterThresholds: Object,
115
- corrections: {
116
- type: Map,
117
- of: correctionSchema,
118
- default: {},
119
- },
120
- correctionHistory: {
121
- type: [correctionHistorySchema],
122
- default: [],
123
- },
124
- },
125
- {
126
- timestamps: true,
127
- }
128
- );
129
-
130
- // Create the MonitorAudit model
131
- const MonitorAudit = mongoose.model("MonitorAudit", monitorAuditSchema);
132
-
133
- // Monitors Schema
134
- const monitorsSchema = mongoose.Schema(
135
- {
136
- monitorCode: String,
137
- monitorSupplier: {
138
- type: String,
139
- enum: [
140
- "clarity",
141
- "aeroqual",
142
- "purple air",
143
- "reference monitor",
144
- "earthview",
145
- "sensit",
146
- "blue sky",
147
- "aq mesh",
148
- "quant aq",
149
- "airGradient",
150
- "oizom",
151
- "metOne",
152
- ],
153
- },
154
- monitorType: String,
155
- monitorIdFromSupplier: String,
156
- measurementUpdate: Date,
157
- monitorProperties: Object,
158
- isPrivate: { type: Boolean, default: false, required: true },
159
- monitorState: {
160
- type: String,
161
- enum: ["Collocation", "Deployed", "Maintenance", "Pending Deployment"],
162
- },
163
- monitorStateHistory: [Object],
164
- monitorAlertStatus: {
165
- type: String,
166
- enum: [
167
- "Good",
168
- "Moderate",
169
- "Unhealthy for SG",
170
- "Unhealthy",
171
- "Very Unhealthy",
172
- "Hazardous",
173
- "Bad",
174
- ],
175
- default: "Good",
176
- },
177
- sponsor: { type: mongoose.Types.ObjectId, ref: "Organizations" },
178
- sponsorName: String,
179
- monitorLatitude: Number,
180
- monitorLongitude: Number,
181
- gpsLocation: {
182
- type: { type: String, enum: ["Point"], required: true },
183
- coordinates: { type: [Number], required: true },
184
- },
185
- location: Object,
186
- context: [String],
187
- colocationDate: Date,
188
- deploymentDate: Date,
189
- subscriptionDate: Date,
190
- parameters: [
191
- {
192
- type: String,
193
- enum: parametersEnum,
194
- },
195
- ],
196
- latestPM2_5: Number,
197
- latestAQI_PM2_5: Number,
198
- notes: [noteSchema],
199
- calculatedAverages: [Object],
200
- images: [String],
201
- isActive: { type: Boolean, default: true },
202
- parameterThresholds: Object,
203
- completionPercentageThresholds: Object,
204
- // A Map, keyed by pollutant (e.g. "PM2_5"), storing Correction sub-docs
205
- corrections: {
206
- type: Map,
207
- of: correctionSchema,
208
- default: {},
209
- },
210
- correctionHistory: {
211
- type: [correctionHistorySchema],
212
- default: [],
213
- },
214
- applyCorrections: { type: Boolean, default: false },
215
- pausedParameters: {
216
- type: [{ parameter: String, timestamp: Date, isPaused: Boolean }],
217
- default: [],
218
- },
219
- },
220
- {
221
- timestamps: true,
222
- }
223
- );
224
-
225
- // Geographic queries - already exists
226
- monitorsSchema.index({ gpsLocation: "2dsphere" });
227
-
228
- // Sponsor-based queries
229
- monitorsSchema.index({ sponsor: 1, isPrivate: 1, isActive: 1 });
230
-
231
- // Location-based filtering
232
- monitorsSchema.index({ "location.city": 1, "location.state": 1 });
233
- monitorsSchema.index({ "location.neighborhood": 1 });
234
- monitorsSchema.index({ "location.county": 1 });
235
-
236
- // Query parameter filtering
237
- monitorsSchema.index({ monitorSupplier: 1, monitorState: 1 });
238
- monitorsSchema.index({ context: 1 });
239
- monitorsSchema.index({ parameters: 1 });
240
-
241
- // Monitor lookups by supplier
242
- monitorsSchema.index({ sponsor: 1, monitorSupplier: 1 });
243
-
244
- // Keep existing single-field indexes for backward compatibility
245
- monitorsSchema.index({ monitorSupplier: 1 });
246
- monitorsSchema.index({ monitorIdFromSupplier: 1 });
247
- monitorsSchema.index({ monitorState: 1 });
248
-
249
- // Pre-hook to log single document deletions
250
- monitorsSchema.pre("findOneAndDelete", async function () {
251
- const docToDelete = await this.model.findOne(this.getFilter()).lean();
252
- if (docToDelete) {
253
- console.log("Logging findOneAndDelete to monitor audit", docToDelete);
254
- const auditLog = new MonitorAudit({
255
- monitorId: docToDelete._id,
256
- orgId: docToDelete.sponsor,
257
- timeUpdated: docToDelete.updatedAt,
258
- monitorProperties: docToDelete.monitorProperties,
259
- monitorState: docToDelete.monitorState,
260
- monitorLocation: {
261
- type: "Point",
262
- coordinates: [
263
- docToDelete.monitorLongitude,
264
- docToDelete.monitorLatitude,
265
- ],
266
- },
267
- parameterThresholds: docToDelete.parameterThresholds,
268
- corrections: docToDelete.corrections,
269
- correctionHistory: docToDelete.correctionHistory,
270
- applyCorrections: docToDelete.applyCorrections,
271
- deletedAt: new Date(),
272
- });
273
- await auditLog.save();
274
- }
275
- });
276
-
277
- // Pre-hook to log multiple document deletions
278
- monitorsSchema.pre("deleteMany", async function () {
279
- console.log("deleteMany pre-hook triggered for monitors");
280
- const docsToDelete = await this.model.find(this.getFilter()).lean();
281
-
282
- if (docsToDelete.length) {
283
- console.log(`Logging ${docsToDelete.length} monitor documents to audit`);
284
- const auditLogs = docsToDelete.map((doc) => ({
285
- monitorId: doc._id,
286
- orgId: doc.sponsor,
287
- timeUpdated: doc.updatedAt,
288
- monitorProperties: doc.monitorProperties,
289
- monitorState: doc.monitorState,
290
- monitorLocation: {
291
- type: "Point",
292
- coordinates: [doc.monitorLongitude, doc.monitorLatitude],
293
- },
294
- parameterThresholds: doc.parameterThresholds,
295
- corrections: doc.corrections,
296
- correctionHistory: doc.correctionHistory,
297
- applyCorrections: doc.applyCorrections,
298
- deletedAt: new Date(),
299
- }));
300
-
301
- await MonitorAudit.insertMany(auditLogs);
302
- }
303
- });
304
-
305
- // Pre-hook to log a single document deletion (for deleteOne)
306
- monitorsSchema.pre("deleteOne", async function () {
307
- console.log("deleteOne pre-hook triggered for monitors");
308
- const docToDelete = await this.model.findOne(this.getFilter()).lean();
309
-
310
- if (docToDelete) {
311
- console.log("Logging deleteOne to monitor audit", docToDelete);
312
- const auditLog = new MonitorAudit({
313
- monitorId: docToDelete._id,
314
- orgId: docToDelete.sponsor,
315
- timeUpdated: docToDelete.updatedAt,
316
- monitorProperties: docToDelete.monitorProperties,
317
- monitorState: docToDelete.monitorState,
318
- monitorLocation: {
319
- type: "Point",
320
- coordinates: [
321
- docToDelete.monitorLongitude,
322
- docToDelete.monitorLatitude,
323
- ],
324
- },
325
- parameterThresholds: docToDelete.parameterThresholds,
326
- corrections: docToDelete.corrections,
327
- correctionHistory: docToDelete.correctionHistory,
328
- applyCorrections: docToDelete.applyCorrections,
329
- deletedAt: new Date(),
330
- });
331
- await auditLog.save();
332
- }
333
- });
334
-
335
- // Pre-hook to log multiple document updates
336
- monitorsSchema.pre("updateMany", async function () {
337
- const docsToUpdate = await this.model.find(this.getFilter()).lean();
338
- if (docsToUpdate.length) {
339
- console.log(`Logging ${docsToUpdate.length} monitor documents to audit`);
340
- const auditLogs = docsToUpdate.map((doc) => ({
341
- monitorId: doc._id,
342
- orgId: doc.sponsor,
343
- timeUpdated: doc.updatedAt,
344
- monitorProperties: doc.monitorProperties,
345
- monitorState: doc.monitorState,
346
- monitorLocation: {
347
- type: "Point",
348
- coordinates: [doc.monitorLongitude, doc.monitorLatitude],
349
- },
350
- parameterThresholds: doc.parameterThresholds,
351
- corrections: doc.corrections,
352
- correctionHistory: doc.correctionHistory,
353
- applyCorrections: doc.applyCorrections,
354
- deletedAt: null, // Not a deletion, so this field is null
355
- }));
356
-
357
- await MonitorAudit.insertMany(auditLogs);
358
- }
359
- });
360
-
361
- // Create the Monitors model
362
- const Monitors = mongoose.model("Monitors", monitorsSchema);
363
-
364
- export { monitorsSchema, Monitors, monitorAuditSchema, MonitorAudit };
1
+ import mongoose from "mongoose";
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
+ "DP",
16
+ ];
17
+
18
+ const noteSchema = mongoose.Schema({
19
+ note: {
20
+ type: String,
21
+ required: true,
22
+ },
23
+ type: {
24
+ type: String,
25
+ required: true,
26
+ },
27
+ monitorState: {
28
+ type: String,
29
+ required: true,
30
+ },
31
+ adminId: {
32
+ type: mongoose.Types.ObjectId,
33
+ ref: "Admin",
34
+ required: true,
35
+ },
36
+ adminName: {
37
+ type: String,
38
+ },
39
+ date: {
40
+ type: Date,
41
+ default: Date.now,
42
+ },
43
+ });
44
+
45
+ const correctionSchema = mongoose.Schema(
46
+ {
47
+ equationType: {
48
+ type: String,
49
+ enum: ["linear", "custom"],
50
+ required: true,
51
+ },
52
+ equation: {
53
+ type: String,
54
+ required: function () {
55
+ return this.equationType === 'custom';
56
+ },
57
+ },
58
+ context: {
59
+ type: String,
60
+ enum: ["field", "colocation"],
61
+ required: false,
62
+ },
63
+ variables: {
64
+ required: function () {
65
+ return this.equationType === 'linear';
66
+ },
67
+ type: Object,
68
+ },
69
+ dateCreated: {
70
+ type: Date,
71
+ default: Date.now,
72
+ },
73
+ applyCorrection: { type: Boolean, default: true },
74
+ },
75
+ { _id: false } // no separate _id for sub-docs
76
+ );
77
+
78
+ const correctionHistorySchema = mongoose.Schema(
79
+ {
80
+ pollutant: {
81
+ type: String,
82
+ required: true,
83
+ },
84
+ oldValue: {
85
+ type: correctionSchema,
86
+ default: undefined,
87
+ },
88
+ newValue: {
89
+ type: correctionSchema,
90
+ default: undefined,
91
+ },
92
+ changedAt: {
93
+ type: Date,
94
+ default: Date.now,
95
+ },
96
+ },
97
+ { _id: false }
98
+ );
99
+
100
+ // Monitor Audit Schema
101
+ const monitorAuditSchema = mongoose.Schema(
102
+ {
103
+ monitorId: { type: mongoose.Types.ObjectId, ref: "Monitors" },
104
+ orgId: { type: mongoose.Types.ObjectId, ref: "Organizations" },
105
+ timeUpdated: Date,
106
+ deletedAt: { type: Date, default: Date.now }, // Only populated on delete
107
+ monitorProperties: Object, // Stores properties of the monitor
108
+ monitorState: String, // Tracks the state of the monitor (e.g., "Deployed", "Maintenance")
109
+ monitorLocation: {
110
+ // Monitor GPS location (lat, lon)
111
+ type: { type: String, enum: ["Point"], required: true },
112
+ coordinates: { type: [Number], required: true },
113
+ },
114
+ parameterThresholds: Object,
115
+ corrections: {
116
+ type: Map,
117
+ of: correctionSchema,
118
+ default: {},
119
+ },
120
+ correctionHistory: {
121
+ type: [correctionHistorySchema],
122
+ default: [],
123
+ },
124
+ },
125
+ {
126
+ timestamps: true,
127
+ }
128
+ );
129
+
130
+ // Create the MonitorAudit model
131
+ const MonitorAudit = mongoose.model("MonitorAudit", monitorAuditSchema);
132
+
133
+ // Monitors Schema
134
+ const monitorsSchema = mongoose.Schema(
135
+ {
136
+ monitorCode: String,
137
+ monitorSupplier: {
138
+ type: String,
139
+ enum: [
140
+ "clarity",
141
+ "aeroqual",
142
+ "purple air",
143
+ "reference monitor",
144
+ "earthview",
145
+ "sensit",
146
+ "blue sky",
147
+ "aq mesh",
148
+ "quant aq",
149
+ "airGradient",
150
+ "oizom",
151
+ "metOne",
152
+ ],
153
+ },
154
+ monitorType: String,
155
+ monitorIdFromSupplier: String,
156
+ measurementUpdate: Date,
157
+ monitorProperties: Object,
158
+ isPrivate: { type: Boolean, default: false, required: true },
159
+ monitorState: {
160
+ type: String,
161
+ enum: ["Collocation", "Deployed", "Maintenance", "Pending Deployment"],
162
+ },
163
+ monitorStateHistory: [Object],
164
+ monitorAlertStatus: {
165
+ type: String,
166
+ enum: [
167
+ "Good",
168
+ "Moderate",
169
+ "Unhealthy for SG",
170
+ "Unhealthy",
171
+ "Very Unhealthy",
172
+ "Hazardous",
173
+ "Bad",
174
+ ],
175
+ default: "Good",
176
+ },
177
+ sponsor: { type: mongoose.Types.ObjectId, ref: "Organizations" },
178
+ sponsorName: String,
179
+ monitorLatitude: Number,
180
+ monitorLongitude: Number,
181
+ gpsLocation: {
182
+ type: { type: String, enum: ["Point"], required: true },
183
+ coordinates: { type: [Number], required: true },
184
+ },
185
+ location: Object,
186
+ context: [String],
187
+ colocationDate: Date,
188
+ deploymentDate: Date,
189
+ subscriptionDate: Date,
190
+ parameters: [
191
+ {
192
+ type: String,
193
+ enum: parametersEnum,
194
+ },
195
+ ],
196
+ latestPM2_5: Number,
197
+ latestAQI_PM2_5: Number,
198
+ notes: [noteSchema],
199
+ calculatedAverages: [Object],
200
+ images: [String],
201
+ isActive: { type: Boolean, default: true },
202
+ parameterThresholds: Object,
203
+ completionPercentageThresholds: Object,
204
+ networkAnomalyThresholds: Object,
205
+ // A Map, keyed by pollutant (e.g. "PM2_5"), storing Correction sub-docs
206
+ corrections: {
207
+ type: Map,
208
+ of: correctionSchema,
209
+ default: {},
210
+ },
211
+ correctionHistory: {
212
+ type: [correctionHistorySchema],
213
+ default: [],
214
+ },
215
+ applyCorrections: { type: Boolean, default: false },
216
+ pausedParameters: {
217
+ type: [{ parameter: String, timestamp: Date, isPaused: Boolean }],
218
+ default: [],
219
+ },
220
+ },
221
+ {
222
+ timestamps: true,
223
+ }
224
+ );
225
+
226
+ // Geographic queries - already exists
227
+ monitorsSchema.index({ gpsLocation: "2dsphere" });
228
+
229
+ // Sponsor-based queries
230
+ monitorsSchema.index({ sponsor: 1, isPrivate: 1, isActive: 1 });
231
+
232
+ // Location-based filtering
233
+ monitorsSchema.index({ "location.city": 1, "location.state": 1 });
234
+ monitorsSchema.index({ "location.neighborhood": 1 });
235
+ monitorsSchema.index({ "location.county": 1 });
236
+
237
+ // Query parameter filtering
238
+ monitorsSchema.index({ monitorSupplier: 1, monitorState: 1 });
239
+ monitorsSchema.index({ context: 1 });
240
+ monitorsSchema.index({ parameters: 1 });
241
+
242
+ // Monitor lookups by supplier
243
+ monitorsSchema.index({ sponsor: 1, monitorSupplier: 1 });
244
+
245
+ // Keep existing single-field indexes for backward compatibility
246
+ monitorsSchema.index({ monitorSupplier: 1 });
247
+ monitorsSchema.index({ monitorIdFromSupplier: 1 });
248
+ monitorsSchema.index({ monitorState: 1 });
249
+
250
+ // Pre-hook to log single document deletions
251
+ monitorsSchema.pre("findOneAndDelete", async function () {
252
+ const docToDelete = await this.model.findOne(this.getFilter()).lean();
253
+ if (docToDelete) {
254
+ console.log("Logging findOneAndDelete to monitor audit", docToDelete);
255
+ const auditLog = new MonitorAudit({
256
+ monitorId: docToDelete._id,
257
+ orgId: docToDelete.sponsor,
258
+ timeUpdated: docToDelete.updatedAt,
259
+ monitorProperties: docToDelete.monitorProperties,
260
+ monitorState: docToDelete.monitorState,
261
+ monitorLocation: {
262
+ type: "Point",
263
+ coordinates: [
264
+ docToDelete.monitorLongitude,
265
+ docToDelete.monitorLatitude,
266
+ ],
267
+ },
268
+ parameterThresholds: docToDelete.parameterThresholds,
269
+ corrections: docToDelete.corrections,
270
+ correctionHistory: docToDelete.correctionHistory,
271
+ applyCorrections: docToDelete.applyCorrections,
272
+ deletedAt: new Date(),
273
+ });
274
+ await auditLog.save();
275
+ }
276
+ });
277
+
278
+ // Pre-hook to log multiple document deletions
279
+ monitorsSchema.pre("deleteMany", async function () {
280
+ console.log("deleteMany pre-hook triggered for monitors");
281
+ const docsToDelete = await this.model.find(this.getFilter()).lean();
282
+
283
+ if (docsToDelete.length) {
284
+ console.log(`Logging ${docsToDelete.length} monitor documents to audit`);
285
+ const auditLogs = docsToDelete.map((doc) => ({
286
+ monitorId: doc._id,
287
+ orgId: doc.sponsor,
288
+ timeUpdated: doc.updatedAt,
289
+ monitorProperties: doc.monitorProperties,
290
+ monitorState: doc.monitorState,
291
+ monitorLocation: {
292
+ type: "Point",
293
+ coordinates: [doc.monitorLongitude, doc.monitorLatitude],
294
+ },
295
+ parameterThresholds: doc.parameterThresholds,
296
+ corrections: doc.corrections,
297
+ correctionHistory: doc.correctionHistory,
298
+ applyCorrections: doc.applyCorrections,
299
+ deletedAt: new Date(),
300
+ }));
301
+
302
+ await MonitorAudit.insertMany(auditLogs);
303
+ }
304
+ });
305
+
306
+ // Pre-hook to log a single document deletion (for deleteOne)
307
+ monitorsSchema.pre("deleteOne", async function () {
308
+ console.log("deleteOne pre-hook triggered for monitors");
309
+ const docToDelete = await this.model.findOne(this.getFilter()).lean();
310
+
311
+ if (docToDelete) {
312
+ console.log("Logging deleteOne to monitor audit", docToDelete);
313
+ const auditLog = new MonitorAudit({
314
+ monitorId: docToDelete._id,
315
+ orgId: docToDelete.sponsor,
316
+ timeUpdated: docToDelete.updatedAt,
317
+ monitorProperties: docToDelete.monitorProperties,
318
+ monitorState: docToDelete.monitorState,
319
+ monitorLocation: {
320
+ type: "Point",
321
+ coordinates: [
322
+ docToDelete.monitorLongitude,
323
+ docToDelete.monitorLatitude,
324
+ ],
325
+ },
326
+ parameterThresholds: docToDelete.parameterThresholds,
327
+ corrections: docToDelete.corrections,
328
+ correctionHistory: docToDelete.correctionHistory,
329
+ applyCorrections: docToDelete.applyCorrections,
330
+ deletedAt: new Date(),
331
+ });
332
+ await auditLog.save();
333
+ }
334
+ });
335
+
336
+ // Pre-hook to log multiple document updates
337
+ monitorsSchema.pre("updateMany", async function () {
338
+ const docsToUpdate = await this.model.find(this.getFilter()).lean();
339
+ if (docsToUpdate.length) {
340
+ console.log(`Logging ${docsToUpdate.length} monitor documents to audit`);
341
+ const auditLogs = docsToUpdate.map((doc) => ({
342
+ monitorId: doc._id,
343
+ orgId: doc.sponsor,
344
+ timeUpdated: doc.updatedAt,
345
+ monitorProperties: doc.monitorProperties,
346
+ monitorState: doc.monitorState,
347
+ monitorLocation: {
348
+ type: "Point",
349
+ coordinates: [doc.monitorLongitude, doc.monitorLatitude],
350
+ },
351
+ parameterThresholds: doc.parameterThresholds,
352
+ corrections: doc.corrections,
353
+ correctionHistory: doc.correctionHistory,
354
+ applyCorrections: doc.applyCorrections,
355
+ deletedAt: null, // Not a deletion, so this field is null
356
+ }));
357
+
358
+ await MonitorAudit.insertMany(auditLogs);
359
+ }
360
+ });
361
+
362
+ // Create the Monitors model
363
+ const Monitors = mongoose.model("Monitors", monitorsSchema);
364
+
365
+ export { monitorsSchema, Monitors, monitorAuditSchema, MonitorAudit };