Skip to content

LIMS

Patients, samples, assays, and laboratory reports.

Entity Relationship Diagram

LIMS ERD

Entities

iris.domain.lims.entities

LIMS domain entities: Patient, Sample, Assay, Aliquot, TestResult, TestReport.

Aliquot

Bases: NamedEntity

A portion of a sample prepared for a specific assay.

Represents a physical sub-division of a Sample destined for a single Assay. quantity and unit describe the volume or mass taken; both are optional when the split was not measured.

Assay

Bases: NamedEntity

A laboratory assay with its type, protocol, status, and timeline.

Tracks the lifecycle of a single analytical run: which protocol was applied (protocol), who owns the run (owner), and its start/completion dates. status is a free-text field whose vocabulary is defined by the laboratory workflow.

Patient

Bases: NamedEntity

A patient with demographic and clinical information.

contact_info and sex are required; all other fields are optional to support partial registration. phenotypes lists observed HPO terms and links the patient record to the genomics domain for variant interpretation workflows.

Sample

Bases: NamedEntity

A biological sample collected from a patient.

specimen_type classifies the material (blood, saliva, tissue, …). The optional patient link may be absent for anonymous or environmental samples. external_id stores the identifier assigned by the referring institution or biobank.

TestReport

Bases: NamedEntity

A formal test report summarizing one or more test results.

Represents the document delivered to the requesting physician or patient. Authorization (is_authorized, authorized_by) and delivery (is_delivered, delivery_method) are tracked as immutable flags; state transitions are captured through domain events rather than in-place mutation.

TestResult

Bases: NamedEntity

The outcome of a laboratory assay applied to a sample.

Holds the tuple of ClinicalResult measurements produced by one Assay run on one Sample. reference_range and interpretation are free-text fields added by the reporting scientist.

Objects

iris.domain.lims.objects

LIMS domain value objects: AssayType, SpecimenType, ProtocolType, and result types.

AssayType

Bases: Enum

Enumeration of supported laboratory assay types.

label property

label

Return a human-readable label for this assay type.

ProtocolType

Bases: Enum

Enumeration of laboratory protocol procedure types.

label property

label

Return a human-readable label for this protocol type.

ResultType

Bases: Enum

The data type of a clinical test result value.

ResultCategory

Bases: Enum

High-level interpretation category for a clinical test result.

SpecimenType

Bases: Enum

Type of biological specimen collected from a patient.

label property

label

Return a human-readable label for this specimen type.

LaboratoryProtocol

A versioned laboratory protocol with validity period and limitations.

Captures the SOPs used in the laboratory. valid_from / valid_until bound the period during which the protocol is accredited; a None valid_until means the protocol is still current. limitations documents known technical constraints or exclusions.

ClinicalResult

A single clinical measurement with its type and value.

Exactly one of categorical_value, numerical_value, or text_value is expected to be non-None depending on result_type; the others remain None. Multiple ClinicalResult instances are grouped in a TestResult.

Repositories

iris.domain.lims.repositories

Repository interfaces for the LIMS domain.

PatientRepository

Bases: CrudRepository[Patient]

CRUD repository for Patient entities.

find_by_sample abstractmethod

find_by_sample(sample_id)

Return all patients linked to a given sample identifier.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_sample(self, sample_id: str) -> Sequence[Patient]:
    """Return all patients linked to a given sample identifier."""

find_by_phenotype abstractmethod

find_by_phenotype(phenotype)

Return all patients presenting the given phenotype.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_phenotype(self, phenotype: Phenotype) -> Sequence[Patient]:
    """Return all patients presenting the given phenotype."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

SampleRepository

Bases: CrudRepository[Sample]

CRUD repository for Sample entities.

find_by_patient abstractmethod

find_by_patient(patient_id)

Return all samples collected from a given patient.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_patient(self, patient_id: str) -> Sequence[Sample]:
    """Return all samples collected from a given patient."""

find_by_specimen_type abstractmethod

find_by_specimen_type(specimen_type)

Return all samples of the given specimen type.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_specimen_type(self, specimen_type: SpecimenType) -> Sequence[Sample]:
    """Return all samples of the given specimen type."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

AssayRepository

Bases: CrudRepository[Assay]

CRUD repository for Assay entities.

find_by_type abstractmethod

find_by_type(assay_type)

Return all assays of the given type.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_type(self, assay_type: AssayType) -> Sequence[Assay]:
    """Return all assays of the given type."""

find_by_status abstractmethod

find_by_status(status)

Return all assays in the given status.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_status(self, status: str) -> Sequence[Assay]:
    """Return all assays in the given status."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

AliquotRepository

Bases: CrudRepository[Aliquot]

CRUD repository for Aliquot entities.

find_by_sample abstractmethod

find_by_sample(sample_id)

Return all aliquots derived from a given sample.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_sample(self, sample_id: str) -> Sequence[Aliquot]:
    """Return all aliquots derived from a given sample."""

find_by_assay abstractmethod

find_by_assay(assay_id)

Return all aliquots used in a given assay.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_assay(self, assay_id: str) -> Sequence[Aliquot]:
    """Return all aliquots used in a given assay."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

TestReportRepository

Bases: CrudRepository[TestReport]

CRUD repository for TestReport entities.

find_by_date_range abstractmethod

find_by_date_range(start, end)

Return all reports with a report_date within [start, end].

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_date_range(self, start: dt.date, end: dt.date) -> Sequence[TestReport]:
    """Return all reports with a report_date within [start, end]."""

find_by_authorized abstractmethod

find_by_authorized(is_authorized)

Return reports filtered by authorization status.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_authorized(self, is_authorized: bool) -> Sequence[TestReport]:
    """Return reports filtered by authorization status."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

TestResultRepository

Bases: CrudRepository[TestResult]

CRUD repository for TestResult entities.

find_by_sample abstractmethod

find_by_sample(sample_id)

Return all results produced from a given sample.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_sample(self, sample_id: str) -> Sequence[TestResult]:
    """Return all results produced from a given sample."""

find_by_assay abstractmethod

find_by_assay(assay_id)

Return all results produced by a given assay.

Source code in src/iris/domain/lims/repositories.py
@abstractmethod
def find_by_assay(self, assay_id: str) -> Sequence[TestResult]:
    """Return all results produced by a given assay."""

get abstractmethod

get(identifier)

Return the entity matching identifier, or None if not found.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def get(self, identifier: str) -> T | None:
    """Return the entity matching `identifier`, or None if not found."""

save abstractmethod

save(entity)

Persist entity and return the saved version.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def save(self, entity: T) -> T:
    """Persist `entity` and return the saved version."""

delete abstractmethod

delete(identifier)

Remove the entity identified by identifier.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def delete(self, identifier: str) -> None:
    """Remove the entity identified by `identifier`."""

find_all abstractmethod

find_all()

Return all entities in the repository.

Source code in src/iris/domain/generic/repositories.py
@abstractmethod
def find_all(self) -> Sequence[T]:
    """Return all entities in the repository."""

Events

iris.domain.lims.events

Domain events for the LIMS bounded context.

PatientRegistered

Emitted when a new patient is registered in the system.

SampleCollected

Emitted when a biological sample is collected from a patient.

SampleReceived

Emitted when a sample is received at the laboratory.

AssayStarted

Emitted when a laboratory assay begins processing.

AssayCompleted

Emitted when a laboratory assay finishes processing.

AliquotCreated

Emitted when an aliquot is created from a sample for an assay.

TestResultRecorded

Emitted when a test result is recorded for a sample and assay.

TestReportIssued

Emitted when a test report is issued.

TestReportAuthorized

Emitted when a test report is authorized by a responsible person.

TestReportDelivered

Emitted when a test report is delivered to the patient or requestor.

Exceptions

iris.domain.lims.exceptions

Exceptions for the LIMS domain.

LimsError

Bases: Exception

Base exception for the LIMS domain.

PatientNotFoundError

Bases: LimsError

Raised when a patient cannot be found by the given identifier.

SampleNotFoundError

Bases: LimsError

Raised when a sample cannot be found by the given identifier.

AliquotNotFoundError

Bases: LimsError

Raised when an aliquot cannot be found by the given identifier.

AssayNotFoundError

Bases: LimsError

Raised when an assay cannot be found by the given identifier.

TestResultNotFoundError

Bases: LimsError

Raised when a test result cannot be found by the given identifier.

TestReportNotFoundError

Bases: LimsError

Raised when a test report cannot be found by the given identifier.

DuplicatePatientRegistrationError

Bases: LimsError

Raised when registering a patient that already exists in the system.

SampleNotReceivedError

Bases: LimsError

Raised when an operation requires a received sample but it has not been received yet.

AssayNotCompletedError

Bases: LimsError

Raised when an operation requires a completed assay but it has not finished.

ReportAlreadyAuthorizedError

Bases: LimsError

Raised when attempting to authorize a report that is already authorized.