From 4aa5b8cd344c10ba46e882b734465b2a20268fa2 Mon Sep 17 00:00:00 2001 From: "Robert St. John" Date: Sat, 10 Aug 2024 07:36:16 -0600 Subject: [PATCH] refactor(service): delete unused observation update functions --- service/src/api/observation.js | 169 ------------------------------ service/src/models/observation.js | 69 ------------ 2 files changed, 238 deletions(-) diff --git a/service/src/api/observation.js b/service/src/api/observation.js index d804f1bc3..355db3e4b 100644 --- a/service/src/api/observation.js +++ b/service/src/api/observation.js @@ -47,7 +47,6 @@ Observation.prototype.getAll = function(options, callback) { /** * TODO: this can be deleted when these refs go away * * routes/index.js - * * routes/observations.js */ Observation.prototype.getById = function(observationId, options, callback) { if (typeof options === 'function') { @@ -58,174 +57,6 @@ Observation.prototype.getById = function(observationId, options, callback) { ObservationModel.getObservationById(this._event, observationId, options, callback); }; -Observation.prototype.validate = function(observation) { - const errors = {}; - let message = ''; - - if (observation.type !== 'Feature') { - errors.type = { error: 'required', message: observation.type ? 'type is required' : 'type must equal "Feature"' }; - message += observation.type ? '\u2022 type is required\n' : '\u2022 type must equal "Feature"\n' - } - - // validate timestamp - const properties = observation.properties || {}; - const timestampError = fieldFactory.createField({ - type: 'date', - required: true, - name: 'timestamp', - title: 'Date' - }, properties).validate(); - if (timestampError) { - errors.timestamp = timestampError; - message += `\u2022 ${timestampError.message}\n`; - } - - // validate geometry - const geometryError = fieldFactory.createField({ - type: 'geometry', - required: true, - name: 'geometry', - title: 'Location' - }, observation).validate(); - if (geometryError) { - errors.geometry = geometryError; - message += `\u2022 ${geometryError.message}\n`; - } - - const formEntries = properties.forms || []; - const formCount = formEntries.reduce((count, form) => { - count[form.formId] = (count[form.formId] || 0) + 1; - return count; - }, {}) - - const formDefinitions = {}; - - // Validate total number of forms - if (this._event.minObservationForms != null && formEntries.length < this._event.minObservationForms) { - errors.minObservationForms = new Error("Insufficient number of forms"); - message += `\u2022 Total number of forms in observation must be at least ${this._event.minObservationForms}\n`; - } - - if (this._event.maxObservationForms != null && formEntries.length > this._event.maxObservationForms) { - errors.maxObservationForms = new Error("Exceeded maximum number of forms"); - message += `\u2022 Total number of forms in observation cannot be more than ${this._event.maxObservationForms}\n`; - } - - // Validate forms min/max occurrences - const formError = {}; - this._event.forms - .filter(form => !form.archived) - .forEach(formDefinition => { - formDefinitions[formDefinition._id] = formDefinition; - - const count = formCount[formDefinition.id] || 0; - if (formDefinition.min && count < formDefinition.min) { - formError[formDefinition.id] = { - error: 'min', - message: `${formDefinition.name} form must be included in observation at least ${formDefinition.min} times` - } - - message += `\u2022 ${formDefinition.name} form must be included in observation at least ${formDefinition.min} times\n`; - } else if (formDefinition.max && (count > formDefinition.max)) { - formError[formDefinition.id] = { - error: 'max', - message: `${formDefinition.name} form cannot be included in observation more than ${formDefinition.max} times` - } - - message += `\u2022 ${formDefinition.name} form cannot be included in observation more than ${formDefinition.max} times\n`; - } - }); - - // TODO attachment-work, validate attachment restrictions and min/max - - if (Object.keys(formError).length) { - errors.form = formError; - } - - // Validate form fields - const formErrors = []; - - formEntries.forEach(formEntry => { - let fieldsMessage = ''; - const fieldsError = {}; - - formDefinitions[formEntry.formId].fields - .filter(fieldDefinition => !fieldDefinition.archived) - .forEach(fieldDefinition => { - const field = fieldFactory.createField(fieldDefinition, formEntry, observation); - const fieldError = field.validate(); - - if (fieldError) { - fieldsError[field.name] = fieldError; - fieldsMessage += ` \u2022 ${fieldError.message}\n`; - } - }); - - if (Object.keys(fieldsError).length) { - formErrors.push(fieldsError); - message += `${formDefinitions[formEntry.formId].name} form is invalid\n`; - message += fieldsMessage; - } - }); - - if (formErrors.length) { - errors.forms = formErrors - } - - if (Object.keys(errors).length) { - const err = new Error('Invalid Observation'); - err.name = 'ValidationError'; - err.status = 400; - err.message = message; - err.errors = errors; - return err; - } -}; - -// TODO create is gone, do I need to figure out if this is an observation create? -Observation.prototype.update = function(observationId, observation, callback) { - if (this._user) observation.userId = this._user._id; - if (this._deviceId) observation.deviceId = this._deviceId; - - const err = this.validate(observation); - if (err) return callback(err); - - ObservationModel.updateObservation(this._event, observationId, observation, (err, updatedObservation) => { - if (updatedObservation) { - EventEmitter.emit(ObservationEvents.events.update, updatedObservation.toObject({event: this._event}), this._event, this._user); - - // Remove any deleted attachments from file system - /* - TODO: this might not even work. observation form entries are not stored - with field entry keys for attachment fields, so finding attachments based - on matching form entry keys with form field names will not produce any - results. - */ - const {forms: formEntries = []} = observation.properties || {}; - formEntries.forEach(formEntry => { - const formDefinition = this._event.forms.find(form => form._id === formEntry.formId); - Object.keys(formEntry).forEach(fieldName => { - const fieldDefinition = formDefinition.fields.find(field => field.name === fieldName); - if (fieldDefinition && fieldDefinition.type === 'attachment') { - const attachmentsField = formEntry[fieldName] || []; - attachmentsField.filter(attachmentField => attachmentField.action === 'delete').forEach(attachmentField => { - const attachment = observation.attachments.find(attachment => attachment._id.toString() === attachmentField.id); - if (attachment) { - console.info(`deleting attachment ${attachment.id} for field ${fieldName} on observation ${observation.id}`) - new Attachment(this._event, observation).delete(attachment._id, err => { - log.warn('Error removing deleted attachment from file system', err); - }); - } - }); - } - }); - }); - } - - callback(err, updatedObservation); - }); -}; - Observation.prototype.addFavorite = function(observationId, user, callback) { ObservationModel.addFavorite(this._event, observationId, user, callback); }; diff --git a/service/src/models/observation.js b/service/src/models/observation.js index 9a9440eee..9c74545dc 100644 --- a/service/src/models/observation.js +++ b/service/src/models/observation.js @@ -137,75 +137,6 @@ exports.getObservationById = function (event, observationId, options, callback) observationModel(event).findById(observationId, fields, callback); }; -exports.updateObservation = function (event, observationId, update, callback) { - let addAttachments = []; - let removeAttachments = []; - const { forms = [] } = update.properties || {}; - forms.map(observationForm => { - observationForm._id = observationForm._id || new mongoose.Types.ObjectId(); - delete observationForm.id; - return observationForm; - }) - .forEach(formEntry => { - // TODO: move to app or web layer - const formDefinition = event.forms.find(form => form._id === formEntry.formId); - Object.keys(formEntry).forEach(fieldName => { - const fieldDefinition = formDefinition.fields.find(field => field.name === fieldName); - if (fieldDefinition && fieldDefinition.type === 'attachment') { - const attachments = formEntry[fieldName] || []; - addAttachments = addAttachments.concat(attachments - .filter(attachment => attachment.action === 'add') - .map(attachment => { - return { - observationFormId: formEntry._id, - fieldName: fieldName, - name: attachment.name, - contentType: attachment.contentType - } - })); - - removeAttachments = removeAttachments.concat(attachments - .filter(attachment => attachment.action === 'delete') - .map(attachment => attachment.id) - ); - - delete formEntry[fieldName] - } - }); - }); - - const ObservationModel = observationModel(event); - ObservationModel.findById(observationId) - .then(observation => { - if (!observation) { - observation = new ObservationModel({ - _id: observationId, - userId: update.userId, - deviceId: update.deviceId, - states: [{ name: 'active', userId: update.userId }] - }); - } - - observation.type = update.type; - observation.geometry = update.geometry; - observation.properties = update.properties; - observation.attachments = observation.attachments.concat(addAttachments); - observation.attachments = observation.attachments.filter(attachment => { - return !removeAttachments.includes(attachment._id.toString()) - }); - - return observation.save(); - }) - .then(observation => { - return observation - .populate([{ path: 'userId', select: 'displayName' }, { path: 'important.userId', select: 'displayName' }]); - }) - .then(observation => { - callback(null, observation); - }) - .catch(err => callback(err)); -}; - exports.removeObservation = function (event, observationId, callback) { observationModel(event).findByIdAndRemove(observationId, callback); };