@justair/justair-library 4.8.19 → 4.8.20

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": "4.8.19",
3
+ "version": "4.8.20",
4
4
  "description": "JustAir Internal Library",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -0,0 +1,198 @@
1
+ import mongoose from "mongoose";
2
+ const sampleParametersEnum = [
3
+ "C6H6", // Benzene
4
+ "PB", // Lead
5
+ "AS", // Arsenic
6
+ "CD", // Cadmium
7
+ "CR", // Chromium
8
+ "NI", // Nickel
9
+ "BA", // Barium
10
+ "FE", // Iron
11
+ "CU", // Copper
12
+ "ZN", // Zinc
13
+ ];
14
+
15
+ const noteSchema = mongoose.Schema({
16
+ note: {
17
+ type: String,
18
+ required: true,
19
+ },
20
+ type: {
21
+ type: String,
22
+ required: true,
23
+ },
24
+ adminId: {
25
+ type: mongoose.Types.ObjectId,
26
+ ref: "Admin",
27
+ required: true,
28
+ },
29
+ adminName: {
30
+ type: String,
31
+ },
32
+ date: {
33
+ type: Date,
34
+ default: Date.now,
35
+ },
36
+ });
37
+
38
+ // Sample Site Audit Schema
39
+ const sampleSiteAuditSchema = mongoose.Schema(
40
+ {
41
+ monitorId: { type: mongoose.Types.ObjectId, ref: "SampleSites" },
42
+ orgId: { type: mongoose.Types.ObjectId, ref: "Organizations" },
43
+ timeUpdated: Date,
44
+ deletedAt: { type: Date, default: Date.now }, // Only populated on delete
45
+ monitorLocation: {
46
+ // Monitor GPS location (lat, lon)
47
+ type: { type: String, enum: ["Point"], required: true },
48
+ coordinates: { type: [Number], required: true },
49
+ },
50
+ },
51
+ {
52
+ timestamps: true,
53
+ }
54
+ );
55
+
56
+ // Create the SampleSiteAudit model
57
+ const SampleSiteAudit = mongoose.model("SampleSiteAudit", sampleSiteAuditSchema);
58
+
59
+ // Sample Sites Schema
60
+ const sampleSitesSchema = mongoose.Schema(
61
+ {
62
+ monitorCode: String,
63
+ // Managed By and Sponsored By fields
64
+ managedBy: String,
65
+ sponsoredBy: String,
66
+ measurementUpdate: Date,
67
+ isPrivate: { type: Boolean, default: false, required: true },
68
+ sponsor: { type: mongoose.Types.ObjectId, ref: "Organizations" },
69
+ sponsorName: String,
70
+ monitorLatitude: Number,
71
+ monitorLongitude: Number,
72
+ gpsLocation: {
73
+ type: { type: String, enum: ["Point"], required: true },
74
+ coordinates: { type: [Number], required: true },
75
+ },
76
+ location: Object,
77
+ context: [String],
78
+ parameters: [
79
+ {
80
+ type: String,
81
+ enum: sampleParametersEnum,
82
+ },
83
+ ],
84
+ notes: [noteSchema],
85
+ image: String,
86
+ },
87
+ {
88
+ timestamps: true,
89
+ }
90
+ );
91
+
92
+ // Geographic queries - already exists
93
+ sampleSitesSchema.index({ gpsLocation: "2dsphere" });
94
+
95
+ // Sponsor-based queries
96
+ sampleSitesSchema.index({ sponsor: 1, isActive: 1 });
97
+
98
+ // Location-based filtering
99
+ sampleSitesSchema.index({ "location.city": 1, "location.state": 1 });
100
+ sampleSitesSchema.index({ "location.neighborhood": 1 });
101
+ sampleSitesSchema.index({ "location.county": 1 });
102
+
103
+ // Query parameter filtering
104
+ sampleSitesSchema.index({ context: 1 });
105
+ sampleSitesSchema.index({ parameters: 1 });
106
+
107
+ // Pre-hook to log single document deletions
108
+ sampleSitesSchema.pre("findOneAndDelete", async function () {
109
+ const docToDelete = await this.model.findOne(this.getFilter()).lean();
110
+ if (docToDelete) {
111
+ console.log("Logging findOneAndDelete to sample site audit", docToDelete);
112
+ const auditLog = new SampleSiteAudit({
113
+ monitorId: docToDelete._id,
114
+ orgId: docToDelete.sponsor,
115
+ timeUpdated: docToDelete.updatedAt,
116
+ monitorLocation: {
117
+ type: "Point",
118
+ coordinates: [
119
+ docToDelete.monitorLongitude,
120
+ docToDelete.monitorLatitude,
121
+ ],
122
+ },
123
+ deletedAt: new Date(),
124
+ });
125
+ await auditLog.save();
126
+ }
127
+ });
128
+
129
+ // Pre-hook to log multiple document deletions
130
+ sampleSitesSchema.pre("deleteMany", async function () {
131
+ console.log("deleteMany pre-hook triggered for sample sites");
132
+ const docsToDelete = await this.model.find(this.getFilter()).lean();
133
+
134
+ if (docsToDelete.length) {
135
+ console.log(`Logging ${docsToDelete.length} sample site documents to audit`);
136
+ const auditLogs = docsToDelete.map((doc) => ({
137
+ monitorId: doc._id,
138
+ orgId: doc.sponsor,
139
+ timeUpdated: doc.updatedAt,
140
+ monitorLocation: {
141
+ type: "Point",
142
+ coordinates: [doc.monitorLongitude, doc.monitorLatitude],
143
+ },
144
+ deletedAt: new Date(),
145
+ }));
146
+
147
+ await SampleSiteAudit.insertMany(auditLogs);
148
+ }
149
+ });
150
+
151
+ // Pre-hook to log a single document deletion (for deleteOne)
152
+ sampleSitesSchema.pre("deleteOne", async function () {
153
+ console.log("deleteOne pre-hook triggered for sample sites");
154
+ const docToDelete = await this.model.findOne(this.getFilter()).lean();
155
+
156
+ if (docToDelete) {
157
+ console.log("Logging deleteOne to sample site audit", docToDelete);
158
+ const auditLog = new SampleSiteAudit({
159
+ monitorId: docToDelete._id,
160
+ orgId: docToDelete.sponsor,
161
+ timeUpdated: docToDelete.updatedAt,
162
+ monitorLocation: {
163
+ type: "Point",
164
+ coordinates: [
165
+ docToDelete.monitorLongitude,
166
+ docToDelete.monitorLatitude,
167
+ ],
168
+ },
169
+ deletedAt: new Date(),
170
+ });
171
+ await auditLog.save();
172
+ }
173
+ });
174
+
175
+ // Pre-hook to log multiple document updates
176
+ sampleSitesSchema.pre("updateMany", async function () {
177
+ const docsToUpdate = await this.model.find(this.getFilter()).lean();
178
+ if (docsToUpdate.length) {
179
+ console.log(`Logging ${docsToUpdate.length} sample site documents to audit`);
180
+ const auditLogs = docsToUpdate.map((doc) => ({
181
+ monitorId: doc._id,
182
+ orgId: doc.sponsor,
183
+ timeUpdated: doc.updatedAt,
184
+ monitorLocation: {
185
+ type: "Point",
186
+ coordinates: [doc.monitorLongitude, doc.monitorLatitude],
187
+ },
188
+ deletedAt: null, // Not a deletion, so this field is null
189
+ }));
190
+
191
+ await SampleSiteAudit.insertMany(auditLogs);
192
+ }
193
+ });
194
+
195
+ // Create the SampleSites model
196
+ const SampleSites = mongoose.model("SampleSites", sampleSitesSchema);
197
+
198
+ export { sampleSitesSchema, SampleSites, sampleSiteAuditSchema, SampleSiteAudit, sampleParametersEnum };