2023-05-13 04:06:23 +01:00
|
|
|
"""This module declareds the pydantic schema representation for devices."""
|
|
|
|
|
|
|
|
from datetime import datetime
|
|
|
|
from abc import ABC
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
from pydantic import BaseModel, validator
|
|
|
|
|
|
|
|
from backend.models.records import AvpuScore, RespirationScore
|
|
|
|
|
|
|
|
|
|
|
|
class AbstractRecordCreate(BaseModel, ABC):
|
|
|
|
"""Base class containing fields common to all vitals records during creation."""
|
|
|
|
|
|
|
|
measured: datetime
|
|
|
|
|
|
|
|
@validator('measured')
|
|
|
|
def assert_measured_is_valid(cls, measured: datetime) -> datetime:
|
2023-05-15 09:34:31 +01:00
|
|
|
if measured >= datetime.now(tz=measured.tzinfo):
|
2023-05-13 04:06:23 +01:00
|
|
|
raise ValueError("Time of measurement cannot be in the future.")
|
|
|
|
return measured
|
|
|
|
|
|
|
|
class AbstractRecord(BaseModel, ABC):
|
|
|
|
"""Base class containing fields common to all vitals records for display."""
|
|
|
|
|
|
|
|
id: int
|
|
|
|
measured: datetime
|
|
|
|
device_id: int
|
|
|
|
|
|
|
|
@validator('measured')
|
|
|
|
def assert_measured_is_valid(cls, measured: datetime) -> datetime:
|
2023-05-15 09:34:31 +01:00
|
|
|
if measured >= datetime.now(tz=measured.tzinfo):
|
2023-05-13 04:06:23 +01:00
|
|
|
raise ValueError("Time of measurement cannot be in the future.")
|
|
|
|
return measured
|
|
|
|
|
2023-05-15 09:34:31 +01:00
|
|
|
class Config:
|
|
|
|
orm_mode = True
|
|
|
|
|
2023-05-13 04:06:23 +01:00
|
|
|
|
|
|
|
class AbstractHeartRateRecord(BaseModel, ABC):
|
|
|
|
value: int
|
|
|
|
|
|
|
|
@validator('value')
|
|
|
|
def assert_value_is_valid(cls, value):
|
|
|
|
if value < 0:
|
|
|
|
raise ValueError("Value cannot be negative.")
|
|
|
|
if value >= 32767:
|
|
|
|
raise ValueError("Value is too large.")
|
|
|
|
return value
|
|
|
|
|
|
|
|
class HeartRateRecordCreate(AbstractRecordCreate, AbstractHeartRateRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class HeartRateRecord(AbstractRecord, AbstractHeartRateRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class AbstractAvpuScoreRecord(BaseModel, ABC):
|
|
|
|
value: AvpuScore
|
|
|
|
|
|
|
|
class AvpuScoreRecordCreate(AbstractRecordCreate, AbstractAvpuScoreRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class AvpuScoreRecord(AbstractRecord, AbstractAvpuScoreRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class AbstractBodyTemperatureRecord(BaseModel, ABC):
|
|
|
|
value: Decimal
|
|
|
|
|
|
|
|
@validator('value')
|
|
|
|
def assert_value_is_valid(cls, value: Decimal) -> Decimal:
|
|
|
|
if value < 0:
|
|
|
|
raise ValueError("Value cannot be negative.")
|
|
|
|
if value >= 100:
|
|
|
|
raise ValueError("Value cannot exceed '99.99'.")
|
|
|
|
if len(value.as_tuple().digits) > 4:
|
|
|
|
raise ValueError("Value can have at most two digits after the decimal point.")
|
|
|
|
return value
|
|
|
|
|
|
|
|
class BodyTemperatureRecordCreate(AbstractRecordCreate, AbstractBodyTemperatureRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class BodyTemperatureRecord(AbstractRecord, AbstractBodyTemperatureRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class AbstractBloodPressureRecord(BaseModel, ABC):
|
|
|
|
value_systolic: int
|
|
|
|
value_diastolic: int
|
|
|
|
|
|
|
|
@validator('value_systolic')
|
|
|
|
def assert_value_systolic_is_valid(cls, value_systolic):
|
|
|
|
if value_systolic < 0:
|
|
|
|
raise ValueError("Value (systolic) cannot be negative.")
|
|
|
|
if value_systolic >= 32767:
|
|
|
|
raise ValueError("Value (systolic) is too large.")
|
|
|
|
return value_systolic
|
|
|
|
|
|
|
|
@validator('value_diastolic')
|
|
|
|
def assert_value_diastolic_is_valid(cls, value_diastolic):
|
|
|
|
if value_diastolic < 0:
|
|
|
|
raise ValueError("Value (diastolic) cannot be negative.")
|
|
|
|
if value_diastolic >= 32767:
|
|
|
|
raise ValueError("Value (diastolic) is too large.")
|
|
|
|
return value_diastolic
|
|
|
|
|
|
|
|
class BloodPressureRecordCreate(AbstractRecordCreate, AbstractBloodPressureRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class BloodPressureRecord(AbstractRecord, AbstractBloodPressureRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class AbstractBloodOxygenRecord(BaseModel, ABC):
|
|
|
|
value: Decimal
|
|
|
|
|
|
|
|
@validator('value')
|
|
|
|
def assert_value_is_valid(cls, value: Decimal) -> Decimal:
|
|
|
|
if value < 0:
|
|
|
|
raise ValueError("Value cannot be negative.")
|
|
|
|
if value > 100:
|
|
|
|
raise ValueError("Value cannot exceed '100.00'.")
|
|
|
|
if len(value.as_tuple().digits) > 5:
|
|
|
|
raise ValueError("Value can have at most two digits after the decimal point.")
|
|
|
|
return value
|
|
|
|
|
|
|
|
class BloodOxygenRecordCreate(AbstractRecordCreate, AbstractBloodOxygenRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class BloodOxygenRecord(AbstractRecord, AbstractBloodOxygenRecord):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class AbstractRespirationScoreScoreRecord(BaseModel, ABC):
|
|
|
|
value: RespirationScore
|
|
|
|
|
2023-05-15 09:34:31 +01:00
|
|
|
class RespirationScoreRecordCreate(AbstractRecordCreate, AbstractRespirationScoreScoreRecord):
|
2023-05-13 04:06:23 +01:00
|
|
|
pass
|
|
|
|
|
2023-05-15 09:34:31 +01:00
|
|
|
class RespirationScoreRecord(AbstractRecord, AbstractRespirationScoreScoreRecord):
|
2023-05-13 04:06:23 +01:00
|
|
|
pass
|