Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow sites and devices to belong to more than one Group #4038

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
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 @@
message: `{VALUE} must be unique!`,
});

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

Check warning on line 242 in src/device-registry/models/Device.js

View check run for this annotation

Codecov / codecov/patch

src/device-registry/models/Device.js#L241-L242

Added lines #L241 - L242 were not covered by tests
);

if (duplicateValues.length > 0) {
return new HttpError(

Check warning on line 246 in src/device-registry/models/Device.js

View check run for this annotation

Codecov / codecov/patch

src/device-registry/models/Device.js#L245-L246

Added lines #L245 - L246 were not covered by tests
`Duplicate values found in ${fieldName} array.`,
httpStatus.BAD_REQUEST
);
}
return null;

Check warning on line 251 in src/device-registry/models/Device.js

View check run for this annotation

Codecov / codecov/patch

src/device-registry/models/Device.js#L251

Added line #L251 was not covered by tests
};

deviceSchema.pre(
[
"update",
Expand Down Expand Up @@ -326,18 +340,16 @@
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);

Check warning on line 346 in src/device-registry/models/Device.js

View check run for this annotation

Codecov / codecov/patch

src/device-registry/models/Device.js#L344-L346

Added lines #L344 - L346 were not covered by tests
}

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);

Check warning on line 352 in src/device-registry/models/Device.js

View check run for this annotation

Codecov / codecov/patch

src/device-registry/models/Device.js#L350-L352

Added lines #L350 - L352 were not covered by tests
}
}

Expand Down Expand Up @@ -371,28 +383,20 @@
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 = [

Check warning on line 387 in src/device-registry/models/Device.js

View check run for this annotation

Codecov / codecov/patch

src/device-registry/models/Device.js#L387

Added line #L387 was not covered by tests
"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];

Check warning on line 397 in src/device-registry/models/Device.js

View check run for this annotation

Codecov / codecov/patch

src/device-registry/models/Device.js#L393-L397

Added lines #L393 - L397 were not covered by tests
}
});

next();
} catch (error) {
Expand All @@ -415,7 +419,7 @@
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
Loading