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

SIMSBIOHUB-647: Create Observations Page #1444

Open
wants to merge 15 commits into
base: dev
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,25 @@
putObservations()
];

export const POST: Operation = [
authorizeRequestHandler((req) => {
return {

Check warning on line 64 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L64

Added line #L64 was not covered by tests
or: [
{
validProjectPermissions: [PROJECT_PERMISSION.COORDINATOR, PROJECT_PERMISSION.COLLABORATOR],
surveyId: Number(req.params.surveyId),
discriminator: 'ProjectPermission'
},
{
validSystemRoles: [SYSTEM_ROLE.DATA_ADMINISTRATOR],
discriminator: 'SystemRole'
}
]
};
}),
postObservations()
];

GET.apiDoc = {
description: 'Get all observations for the survey.',
tags: ['observation'],
Expand Down Expand Up @@ -354,6 +373,228 @@
}
};

POST.apiDoc = {
description: 'Insert/update/delete observations for the survey.',
tags: ['observation'],
security: [
{
Bearer: []
}
],
parameters: [
{
in: 'path',
name: 'projectId',
required: true
},
{
in: 'path',
name: 'surveyId',
required: true
}
],
requestBody: {
description: 'Survey observation record data',
required: true,
content: {
'application/json': {
schema: {
description: 'A single survey observation record.',
type: 'object',
additionalProperties: false,
required: ['standardColumns', 'subcounts'],
properties: {
standardColumns: {
description: 'Standard column data for an observation record.',
type: 'object',
additionalProperties: false,
required: ['itis_tsn'],
properties: {
survey_observation_id: {
type: 'integer',
minimum: 1,
description: 'Primary key of the observation record',
nullable: true
},
itis_tsn: {
type: 'integer'
},
itis_scientific_name: {
type: 'string',
nullable: true
},
survey_sample_site_id: {
type: 'integer',
minimum: 1,
nullable: true
},
survey_sample_method_id: {
type: 'integer',
minimum: 1,
nullable: true
},
survey_sample_period_id: {
type: 'integer',
minimum: 1,
nullable: true
},
count: {
type: 'integer',
description: "The observation record's count.",
nullable: true
},
latitude: {
type: 'number',
nullable: true
},
longitude: {
type: 'number',
nullable: true
},
observation_date: {
type: 'string',
nullable: true
},
observation_time: {
type: 'string',
nullable: true
},
revision_count: {
type: 'integer',
minimum: 0
}
}
},
subcounts: {
description: 'An array of observation subcount records.',
type: 'array',
items: {
type: 'object',
additionalProperties: false,
required: [
'subcount',
'comment',
'qualitative_measurements',
'quantitative_measurements',
'qualitative_environments',
'quantitative_environments'
],
properties: {
observation_subcount_id: {
type: 'integer',
minimum: 1,
description: 'Primary key of the subcount record',
nullable: true
},
observation_subcount_sign_id: {
type: 'integer',
minimum: 1,
description:
'The observation subcount sign ID, indicating whether the subcount was a direct sighting, footprints, scat, etc.',
nullable: true
},
comment: {
type: 'string',
nullable: true,
description: 'A comment or note about the subcount'
},
subcount: {
type: 'number',
description: "The subcount record's count."
},
qualitative_measurements: {
type: 'array',
items: {
type: 'object',
additionalProperties: false,
properties: {
measurement_id: {
type: 'string'
},
measurement_option_id: {
type: 'string'
}
}
}
},
quantitative_measurements: {
type: 'array',
items: {
type: 'object',
additionalProperties: false,
properties: {
measurement_id: {
type: 'string'
},
measurement_value: {
type: 'number'
}
}
}
},
qualitative_environments: {
type: 'array',
items: {
type: 'object',
additionalProperties: false,
properties: {
environment_qualitative_id: {
type: 'string',
format: 'uuid'
},
environment_qualitative_option_id: {
type: 'string',
format: 'uuid'
}
}
}
},
quantitative_environments: {
type: 'array',
items: {
type: 'object',
additionalProperties: false,
properties: {
environment_quantitative_id: {
type: 'string',
format: 'uuid'
},
value: {
type: 'number'
}
}
}
}
}
}
}
}
}
}
}
},
responses: {
204: {
description: 'Create observations OK'
},
400: {
$ref: '#/components/responses/400'
},
401: {
$ref: '#/components/responses/401'
},
403: {
$ref: '#/components/responses/403'
},
500: {
$ref: '#/components/responses/500'
},
default: {
$ref: '#/components/responses/default'
}
}
};

/**
* This record maps observation table sampling site site ID columns to sampling data
* columns that can be sorted on.
Expand Down Expand Up @@ -465,3 +706,53 @@
}
};
}

/**
* Inserts new observation records.
*
* @export
* @return {*} {RequestHandler}
*/
export function postObservations(): RequestHandler {
return async (req, res) => {
const connection = getDBConnection(req.keycloak_token);

Check warning on line 718 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L718

Added line #L718 was not covered by tests

try {
const surveyId = Number(req.params.surveyId);
const observationRow: InsertUpdateObservations = req.body;

Check warning on line 722 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L720-L722

Added lines #L720 - L722 were not covered by tests

defaultLog.debug({ label: 'insertUpdateSurveyObservations', surveyId });

Check warning on line 724 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L724

Added line #L724 was not covered by tests

await connection.open();

Check warning on line 726 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L726

Added line #L726 was not covered by tests

const observationService = new ObservationService(connection);

Check warning on line 728 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L728

Added line #L728 was not covered by tests

// Validate measurement data against fetched measurement definition
const critterBaseService = new CritterbaseService(getCritterbaseUser(req));
const observationSubCountEnvironmentService = new ObservationSubCountEnvironmentService(connection);

Check warning on line 732 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L731-L732

Added lines #L731 - L732 were not covered by tests

const isValid = await observationService.validateSurveyObservations(

Check warning on line 734 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L734

Added line #L734 was not covered by tests
[observationRow],
critterBaseService,
observationSubCountEnvironmentService
);

if (!isValid) {
throw new Error('Failed to save observation data, failed data validation.');

Check warning on line 741 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L741

Added line #L741 was not covered by tests
}

// Insert/update observation records
await observationService.insertUpdateManualSurveyObservations(surveyId, [observationRow]);

Check warning on line 745 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L745

Added line #L745 was not covered by tests

await connection.commit();

Check warning on line 747 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L747

Added line #L747 was not covered by tests

return res.status(204).send();

Check warning on line 749 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L749

Added line #L749 was not covered by tests
} catch (error) {
defaultLog.error({ label: 'putObservations', message: 'error', error });
await connection.rollback();
throw error;

Check warning on line 753 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L751-L753

Added lines #L751 - L753 were not covered by tests
} finally {
connection.release();

Check warning on line 755 in api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts

View check run for this annotation

Codecov / codecov/patch

api/src/paths/project/{projectId}/survey/{surveyId}/observations/index.ts#L755

Added line #L755 was not covered by tests
}
};
}
Loading
Loading