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-665: Habitat Features Database Schema #1483

Merged
merged 17 commits into from
Feb 26, 2025
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
3 changes: 2 additions & 1 deletion api/src/database-models/alert.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { z } from 'zod';
import { AlertSeverityType } from '../database-units/alert_severity';

/**
* Alert Model.
Expand All @@ -10,7 +11,7 @@ export const AlertModel = z.object({
alert_type_id: z.number(),
name: z.string(),
message: z.string(),
severity: z.enum(['info', 'success', 'error', 'warning']),
severity: AlertSeverityType,
data: z.object({}).nullable(),
record_end_date: z.string().nullable(),
create_date: z.string(),
Expand Down
20 changes: 20 additions & 0 deletions api/src/database-units/alert_severity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { z } from 'zod';

/**
* Alert Severity Data Type.
*
* @description Enum for `alert_severity` database type.
*/
export enum AlertSeverity {
INFO = 'info',
WARNING = 'warning',
ERROR = 'error',
SUCCESS = 'success'
}

/**
* Alert Severity Data Type.
*
* @description Type for `alert_severity` database type.
*/
export const AlertSeverityType = z.nativeEnum(AlertSeverity);
36 changes: 36 additions & 0 deletions api/src/database-units/quantitative_unit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { z } from 'zod';

/**
* Quantitative Unit Data Type.
*
* @description Enum for `quantitative_unit` database type.
*/
export enum QuantitativeUnit {
MILLIMETER = 'millimeter',
CENTIMETER = 'centimeter',
METER = 'meter',
MILLIGRAM = 'milligram',
GRAM = 'gram',
KILOGRAM = 'kilogram',
PERCENT = 'percent',
CELSIUS = 'celsius',
PPT = 'ppt',
SCF = 'SCF',
DEGREES = 'degrees',
PH = 'pH',
SECONDS = 'seconds',
METERS_SQUARED = 'meters squared',
COUNT = 'count',
GHZ = 'GHz',
HZ = 'Hz',
AMPS = 'amps',
VOLTS = 'volts',
MEGAPIXELS = 'megapixels'
}

/**
* Quantitative Unit Data Type.
*
* @description Type for `quantitative_unit` database type.
*/
export const QuantitativeUnitType = z.nativeEnum(QuantitativeUnit);
9 changes: 4 additions & 5 deletions api/src/models/alert-view.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { z } from 'zod';
import { AlertRecord } from '../database-models/alert';

export const AlertStatus = z.enum(['active', 'expired']);
export type AlertStatus = z.infer<typeof AlertStatus>;

export const AlertRecordWithStatus = AlertRecord.extend({
create_date: z.string(),
status: z.enum(['active', 'expired'])
status: AlertStatus
});
export type AlertRecordWithStatus = z.infer<typeof AlertRecordWithStatus>;

Expand All @@ -17,7 +20,3 @@ export interface IAlertFilterObject {
expiresAfter?: string;
types?: string[];
}

// Define severity and status types
export type IAlertSeverity = 'info' | 'success' | 'error' | 'warning';
export type IAlertStatus = 'active' | 'expired';
3 changes: 2 additions & 1 deletion api/src/openapi/schemas/alert.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { OpenAPIV3 } from 'openapi-types';
import { AlertSeverity } from '../../database-units/alert_severity';

/**
* Base schema for system alerts
Expand All @@ -23,7 +24,7 @@ const baseSystemAlertSchema: OpenAPIV3.SchemaObject = {
severity: {
description: 'Severity level of the alert',
type: 'string',
enum: ['info', 'success', 'warning', 'error']
enum: Object.values(AlertSeverity)
},
data: {
description: 'Data associated with the alert',
Expand Down
15 changes: 8 additions & 7 deletions api/src/paths/alert/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import { SYSTEM_IDENTITY_SOURCE } from '../../constants/database';
import { SYSTEM_ROLE } from '../../constants/roles';
import { AlertSeverity } from '../../database-units/alert_severity';
import * as db from '../../database/db';
import { HTTPError } from '../../errors/http-error';
import { IAlertSeverity, IAlertStatus } from '../../models/alert-view';
import { AlertRecordWithStatus } from '../../models/alert-view';
import { AlertService } from '../../services/alert-service';
import { getMockDBConnection, getRequestHandlerMocks } from '../../__mocks__/db';
import { createAlert, getAlerts } from '../alert';
Expand All @@ -21,14 +22,14 @@ describe('getAlerts', () => {
describe('as a system user', () => {
it('returns a list of system alerts', async () => {
const mockTotal = 10;
const mockAlerts = [
const mockAlerts: AlertRecordWithStatus[] = [
{
alert_id: 1,
name: 'Alert 1',
message: 'Message 1',
alert_type_id: 1,
severity: 'error' as IAlertSeverity,
status: 'active' as IAlertStatus,
severity: AlertSeverity.ERROR,
status: 'active',
data: null,
record_end_date: null,
create_date: '2020-01-01T10:10:10'
Expand All @@ -38,8 +39,8 @@ describe('getAlerts', () => {
name: 'Alert 2',
message: 'Message 2',
alert_type_id: 2,
severity: 'error' as IAlertSeverity,
status: 'active' as IAlertStatus,
severity: AlertSeverity.ERROR,
status: 'active',
data: null,
record_end_date: null,
create_date: '2020-01-01T10:10:10'
Expand Down Expand Up @@ -126,7 +127,7 @@ describe('createAlert', () => {
name: 'New Alert',
message: 'New alert message',
alert_type_id: 1,
severity: 'medium'
severity: AlertSeverity.INFO
};

const mockDBConnection = getMockDBConnection({ open: sinon.stub(), commit: sinon.stub() });
Expand Down
9 changes: 5 additions & 4 deletions api/src/paths/alert/{alertId}/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import sinonChai from 'sinon-chai';
import { deleteAlert, getAlertById, updateAlert } from '.';
import { SYSTEM_IDENTITY_SOURCE } from '../../../constants/database';
import { SYSTEM_ROLE } from '../../../constants/roles';
import { AlertSeverity } from '../../../database-units/alert_severity';
import * as db from '../../../database/db';
import { HTTPError } from '../../../errors/http-error';
import { IAlertSeverity, IAlertStatus } from '../../../models/alert-view';
import { AlertRecordWithStatus } from '../../../models/alert-view';
import { AlertService } from '../../../services/alert-service';
import { getMockDBConnection, getRequestHandlerMocks } from '../../../__mocks__/db';

Expand All @@ -20,13 +21,13 @@ describe('getAlerts', () => {

describe('as a system user', () => {
it('returns a single system alert', async () => {
const mockAlert = {
const mockAlert: AlertRecordWithStatus = {
alert_id: 1,
name: 'Alert 1',
message: 'Message 1',
alert_type_id: 1,
severity: 'error' as IAlertSeverity,
status: 'active' as IAlertStatus,
severity: AlertSeverity.ERROR,
status: 'active',
data: null,
record_end_date: null,
create_date: '2020-01-01T10:10:10'
Expand Down
22 changes: 12 additions & 10 deletions api/src/repositories/alert-repository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import chai, { expect } from 'chai';
import { QueryResult } from 'pg';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import { IAlertSeverity } from '../models/alert-view';
import { AlertSeverity } from '../database-units/alert_severity';
import { AlertRecordWithStatus, IAlertCreateObject, IAlertUpdateObject } from '../models/alert-view';
import { getMockDBConnection } from '../__mocks__/db';
import { AlertRepository } from './alert-repository';

Expand All @@ -18,16 +19,17 @@ describe('AlertRepository', () => {

describe('getAlerts', () => {
it('should return an array of alerts with empty filters', async () => {
const mockRows = [
const mockRows: AlertRecordWithStatus[] = [
{
alert_id: 1,
name: 'Alert 1',
message: 'This is an alert.',
alert_type_id: 1,
data: {},
severity: 'error' as IAlertSeverity,
severity: AlertSeverity.ERROR,
status: 'active',
record_end_date: null,
status: 'active'
create_date: '2020-01-01'
}
];
const mockQueryResponse = { rows: mockRows, rowCount: 1 } as unknown as QueryResult<any>;
Expand All @@ -52,7 +54,7 @@ describe('AlertRepository', () => {
message: 'This is an alert.',
alert_type_id: 1,
data: {},
severity: 'error',
severity: AlertSeverity.ERROR,
record_end_date: null,
status: 'active'
}
Expand Down Expand Up @@ -80,7 +82,7 @@ describe('AlertRepository', () => {
message: 'This is an alert.',
alert_type_id: 1,
data: {},
severity: 'error',
severity: AlertSeverity.ERROR,
record_end_date: null,
status: 'active'
}
Expand Down Expand Up @@ -109,13 +111,13 @@ describe('AlertRepository', () => {
});

const alertRepository = new AlertRepository(mockDBConnection);
const alert = {
const alert: IAlertUpdateObject = {
alert_id: 1,
name: 'Updated Alert',
message: 'Updated message',
alert_type_id: 1,
data: {},
severity: 'error' as IAlertSeverity,
severity: AlertSeverity.ERROR,
record_end_date: null
};

Expand All @@ -135,12 +137,12 @@ describe('AlertRepository', () => {
});

const alertRepository = new AlertRepository(mockDBConnection);
const alert = {
const alert: IAlertCreateObject = {
name: 'New Alert',
message: 'New alert message',
alert_type_id: 1,
data: {},
severity: 'error' as IAlertSeverity,
severity: AlertSeverity.ERROR,
record_end_date: null
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
import SQL from 'sql-template-strings';
import { z } from 'zod';
import { QuantitativeUnitType } from '../database-units/quantitative_unit';
import { getKnex } from '../database/db';
import { BaseRepository } from './base-repository';

// Environment unit type definition.
export const EnvironmentUnit = z.enum([
// Should be kept in sync with the database table `environment_unit`
'millimeter',
'centimeter',
'meter',
'milligram',
'gram',
'kilogram',
'percent',
'celsius',
'ppt',
'SCF',
'degrees',
'pH'
]);
export type EnvironmentUnit = z.infer<typeof EnvironmentUnit>;

// Qualitative environment option type definition.
const QualitativeEnvironmentOption = z.object({
environment_qualitative_option_id: z.string().uuid(),
Expand All @@ -46,7 +29,7 @@ const QuantitativeEnvironmentTypeDefinition = z.object({
description: z.string().nullable(),
min: z.number().nullable(),
max: z.number().nullable(),
unit: EnvironmentUnit.nullable()
unit: QuantitativeUnitType.nullable()
});
export type QuantitativeEnvironmentTypeDefinition = z.infer<typeof QuantitativeEnvironmentTypeDefinition>;

Expand Down
11 changes: 6 additions & 5 deletions api/src/services/alert-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import chai, { expect } from 'chai';
import { afterEach, describe, it } from 'mocha';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import { AlertRecordWithStatus, IAlertCreateObject, IAlertFilterObject, IAlertSeverity } from '../models/alert-view';
import { AlertSeverity } from '../database-units/alert_severity';
import { AlertRecordWithStatus, IAlertCreateObject, IAlertFilterObject } from '../models/alert-view';
import { AlertRepository } from '../repositories/alert-repository';
import { getMockDBConnection } from '../__mocks__/db';
import { AlertService } from './alert-service';
Expand All @@ -26,7 +27,7 @@ describe('AlertService', () => {
message: 'Message 1',
alert_type_id: 1,
data: {},
severity: 'error' as IAlertSeverity,
severity: AlertSeverity.ERROR,
status: 'active',
record_end_date: null,
create_date: '2020-01-01T10:10:10'
Expand Down Expand Up @@ -73,7 +74,7 @@ describe('AlertService', () => {
message: 'Message 1',
alert_type_id: 1,
data: {},
severity: 'error' as IAlertSeverity,
severity: AlertSeverity.ERROR,
status: 'active',
record_end_date: null,
create_date: '2020-01-01T10:10:10'
Expand All @@ -99,7 +100,7 @@ describe('AlertService', () => {
message: 'New alert message',
alert_type_id: 1,
data: {},
severity: 'error' as IAlertSeverity,
severity: AlertSeverity.ERROR,
record_end_date: null
};

Expand All @@ -124,7 +125,7 @@ describe('AlertService', () => {
message: 'Updated message',
alert_type_id: 1,
data: {},
severity: 'error' as IAlertSeverity,
severity: AlertSeverity.ERROR,
status: 'active',
record_end_date: null,
create_date: '2020-01-01T10:10:10'
Expand Down
28 changes: 25 additions & 3 deletions app/src/interfaces/useReferenceApi.interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
/**
* A qualitative environment unit.
* A quantitative unit.
*
* Note: should be kept in sync with the `quantitative_unit` enum in the database.
*/
export type EnvironmentUnit = 'millimeter' | 'centimeter' | 'meter' | 'milligram' | 'gram' | 'kilogram';
export type QuantitativeUnit =
| 'millimeter'
| 'centimeter'
| 'meter'
| 'milligram'
| 'gram'
| 'kilogram'
| 'percent'
| 'celsius'
| 'ppt'
| 'SCF'
| 'degrees'
| 'pH'
| 'seconds'
| 'meters squared'
| 'count'
| 'GHz'
| 'Hz'
| 'amps'
| 'volts'
| 'megapixels';

/**
* A quantitative environment type definition.
Expand All @@ -12,7 +34,7 @@ export type EnvironmentQuantitativeTypeDefinition = {
description: string | null;
min: number | null;
max: number | null;
unit: EnvironmentUnit | null;
unit: QuantitativeUnit | null;
};

/**
Expand Down
Loading
Loading