Skip to content

Commit

Permalink
Merge pull request #4038 from airqo-platform/en-entity-groups
Browse files Browse the repository at this point in the history
allow sites and devices to belong to more than one Group
  • Loading branch information
Baalmart authored Dec 10, 2024
2 parents 9cab881 + 68a0b0f commit c1e369b
Show file tree
Hide file tree
Showing 14 changed files with 193 additions and 82 deletions.
12 changes: 6 additions & 6 deletions src/device-registry/config/global/db-projections.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const dbProjections = {
lat_long: 1,
country: 1,
network: 1,
group: 1,
groups: 1,
data_provider: 1,
district: 1,
sub_county: 1,
Expand Down Expand Up @@ -379,7 +379,7 @@ const dbProjections = {
mobility: 1,
status: 1,
network: 1,
group: 1,
groups: 1,
api_code: 1,
serial_number: 1,
authRequired: 1,
Expand Down Expand Up @@ -591,7 +591,7 @@ const dbProjections = {
shape: 1,
createdAt: 1,
network: 1,
group: 1,
groups: 1,
sites: "$sites",
numberOfSites: {
$cond: {
Expand Down Expand Up @@ -675,7 +675,7 @@ const dbProjections = {
name: 1,
description: 1,
cohort_tags: 1,
group: 1,
groups: 1,
createdAt: 1,
visibility: 1,
cohort_codes: 1,
Expand Down Expand Up @@ -817,7 +817,7 @@ const dbProjections = {
airqloud_tags: 1,
isCustom: 1,
network: 1,
group: 1,
groups: 1,
metadata: 1,
center_point: 1,
sites: "$sites",
Expand Down Expand Up @@ -1065,7 +1065,7 @@ const dbProjections = {
date: 1,
description: 1,
network: 1,
group: 1,
groups: 1,
activityType: 1,
maintenanceType: 1,
recallType: 1,
Expand Down
6 changes: 3 additions & 3 deletions src/device-registry/models/Activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ const activitySchema = new Schema(
type: String,
trim: true,
},
group: {
type: String,
groups: {
type: [String],
trim: true,
},
activityType: { type: String, trim: true },
Expand Down Expand Up @@ -70,7 +70,7 @@ activitySchema.methods = {
_id: this._id,
device: this.device,
network: this.network,
group: this.group,
groups: this.groups,
date: this.date,
description: this.description,
activityType: this.activityType,
Expand Down
6 changes: 3 additions & 3 deletions src/device-registry/models/Airqloud.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ const airqloudSchema = new Schema(
type: String,
trim: true,
},
group: {
type: String,
groups: {
type: [String],
trim: true,
},
airqloud_tags: {
Expand Down Expand Up @@ -152,7 +152,7 @@ airqloudSchema.methods.toJSON = function() {
name: this.name,
long_name: this.long_name,
network: this.network,
group: this.group,
groups: this.groups,
description: this.description,
airqloud_tags: this.airqloud_tags,
admin_level: this.admin_level,
Expand Down
18 changes: 9 additions & 9 deletions src/device-registry/models/Cohort.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const cohortSchema = new Schema(
trim: true,
required: [true, "the network is required!"],
},
group: {
type: String,
groups: {
type: [String],
trim: true,
},
name: {
Expand Down Expand Up @@ -81,7 +81,7 @@ cohortSchema.methods.toJSON = function() {
cohort_tags,
cohort_codes,
network,
group,
groups,
visibility,
} = this;
return {
Expand All @@ -92,7 +92,7 @@ cohortSchema.methods.toJSON = function() {
cohort_tags,
cohort_codes,
network,
group,
groups,
};
};

Expand Down Expand Up @@ -202,7 +202,7 @@ cohortSchema.statics.list = async function(
name: 1,
createdAt: 1,
network: 1,
group: 1,
groups: 1,
devices: {
$cond: {
if: { $eq: [{ $size: "$devices" }, 0] },
Expand All @@ -214,15 +214,15 @@ cohortSchema.statics.list = async function(
.sort({ createdAt: -1 })
.project(inclusionProjection)
.project(exclusionProjection)
.group({
.groups({
_id: "$_id",
visibility: { $first: "$visibility" },
cohort_tags: { $first: "$cohort_tags" },
cohort_codes: { $first: "$cohort_codes" },
name: { $first: "$name" },
createdAt: { $first: "$createdAt" },
network: { $first: "$network" },
group: { $first: "$group" },
groups: { $first: "$groups" },
devices: { $first: "$devices" },
})
.skip(skip ? parseInt(skip) : 0)
Expand All @@ -240,7 +240,7 @@ cohortSchema.statics.list = async function(
name: cohort.name,
network: cohort.network,
createdAt: cohort.createdAt,
group: cohort.group,
groups: cohort.groups,
numberOfDevices: cohort.devices ? cohort.devices.length : 0,
devices: cohort.devices
? cohort.devices
Expand All @@ -250,7 +250,7 @@ cohortSchema.statics.list = async function(
status: device.status,
name: device.name,
network: device.network,
group: device.group,
groups: device.groups,
device_number: device.device_number,
description: device.description,
long_name: device.long_name,
Expand Down
76 changes: 40 additions & 36 deletions src/device-registry/models/Device.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ const deviceSchema = new mongoose.Schema(
trim: true,
required: [true, "the network is required!"],
},
group: {
type: String,
groups: {
type: [String],
trim: true,
},
serial_number: {
Expand Down Expand Up @@ -237,6 +237,20 @@ deviceSchema.plugin(uniqueValidator, {
message: `{VALUE} must be unique!`,
});

const checkDuplicates = (arr, fieldName) => {
const duplicateValues = arr.filter(
(value, index, self) => self.indexOf(value) !== index
);

if (duplicateValues.length > 0) {
return new HttpError(
`Duplicate values found in ${fieldName} array.`,
httpStatus.BAD_REQUEST
);
}
return null;
};

deviceSchema.pre(
[
"update",
Expand Down Expand Up @@ -326,18 +340,16 @@ deviceSchema.pre(
this.device_codes.push(this.serial_number);
}

// Check for duplicate values in cohorts array
const duplicateValues = this.cohorts.filter(
(value, index, self) => self.indexOf(value) !== index
);
// Check for duplicates in cohorts
const cohortsDuplicateError = checkDuplicates(this.cohorts, "cohorts");
if (cohortsDuplicateError) {
return next(cohortsDuplicateError);
}

if (duplicateValues.length > 0) {
return next(
new HttpError(
"Duplicate values found in cohorts array.",
httpStatus.BAD_REQUEST
)
);
// Check for duplicates in groups
const groupsDuplicateError = checkDuplicates(this.groups, "groups");
if (groupsDuplicateError) {
return next(groupsDuplicateError);
}
}

Expand Down Expand Up @@ -371,28 +383,20 @@ deviceSchema.pre(
updateData.access_code = access_code.toUpperCase();
}

// Handle $addToSet for device_codes, previous_sites, and pictures
const addToSetUpdates = {};

if (updateData.device_codes) {
addToSetUpdates.device_codes = { $each: updateData.device_codes };
delete updateData.device_codes; // Remove from main update object
}

if (updateData.previous_sites) {
addToSetUpdates.previous_sites = { $each: updateData.previous_sites };
delete updateData.previous_sites; // Remove from main update object
}

if (updateData.pictures) {
addToSetUpdates.pictures = { $each: updateData.pictures };
delete updateData.pictures; // Remove from main update object
}

// If there are any $addToSet updates, merge them into the main update object
if (Object.keys(addToSetUpdates).length > 0) {
updateData.$addToSet = addToSetUpdates;
}
// Handle array fields using $addToSet
const arrayFieldsToAddToSet = [
"device_codes",
"previous_sites",
"groups",
"pictures",
];
arrayFieldsToAddToSet.forEach((field) => {
if (updateData[field]) {
updateData.$addToSet = updateData.$addToSet || {};
updateData.$addToSet[field] = { $each: updateData[field] };
delete updateData[field];
}
});

next();
} catch (error) {
Expand All @@ -415,7 +419,7 @@ deviceSchema.methods = {
alias: this.alias,
mobility: this.mobility,
network: this.network,
group: this.group,
groups: this.groups,
api_code: this.api_code,
serial_number: this.serial_number,
authRequired: this.authRequired,
Expand Down
8 changes: 4 additions & 4 deletions src/device-registry/models/Grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ const gridSchema = new Schema(
trim: true,
required: [true, "the network is required!"],
},
group: {
type: String,
groups: {
type: [String],
trim: true,
},
geoHash: {
Expand Down Expand Up @@ -121,7 +121,7 @@ gridSchema.methods.toJSON = function() {
name,
long_name,
network,
group,
groups,
visibility,
description,
grid_tags,
Expand All @@ -139,7 +139,7 @@ gridSchema.methods.toJSON = function() {
description,
grid_tags,
network,
group,
groups,
admin_level,
grid_codes,
centers,
Expand Down
8 changes: 8 additions & 0 deletions src/device-registry/models/Location.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ const locationSchema = new Schema(
type: String,
trim: true,
},
groups: {
type: [String],
trim: true,
},
location_tags: {
type: Array,
default: [],
Expand Down Expand Up @@ -124,6 +128,7 @@ locationSchema.methods = {
isCustom: this.isCustom,
location: this.location,
network: this.network,
groups: this.groups,
metadata: this.metadata,
};
},
Expand Down Expand Up @@ -190,6 +195,7 @@ locationSchema.statics = {
isCustom: 1,
metadata: 1,
network: 1,
groups: 1,
sites: "$sites",
};

Expand All @@ -200,6 +206,7 @@ locationSchema.statics = {
admin_level: 1,
description: 1,
network: 1,
groups: 1,
metadata: 1,
};

Expand Down Expand Up @@ -306,6 +313,7 @@ locationSchema.statics = {
description: 1,
admin_level: 1,
network: 1,
groups: 1,
isCustom: 1,
metadata: 1,
},
Expand Down
8 changes: 4 additions & 4 deletions src/device-registry/models/Photo.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const photoSchema = new Schema(
type: String,
trim: true,
},
group: {
type: String,
groups: {
type: [String],
trim: true,
},
device_id: {
Expand Down Expand Up @@ -83,7 +83,7 @@ photoSchema.methods = {
tags: this.tags,
name: this.name,
network: this.network,
group: this.group,
groups: this.groups,
image_url: this.image_url,
device_id: this.device_id,
site_id: this.site_id,
Expand Down Expand Up @@ -158,7 +158,7 @@ photoSchema.statics = {
description: 1,
metadata: 1,
network: 1,
group: 1,
groups: 1,
})
.skip(skip ? skip : 0)
.limit(limit ? limit : 1000)
Expand Down
Loading

0 comments on commit c1e369b

Please sign in to comment.