MPPS Table Schema Implementation Guide
In this article, we will delve into the implementation of the mpps table schema, a crucial component for Modality Performed Procedure Step (MPPS) tracking. This detailed guide will walk you through the purpose, structure, implementation, and testing of the mpps table, ensuring a robust and efficient tracking system.
Overview of MPPS and Its Importance
MPPS (Modality Performed Procedure Step) tracking is essential in modern healthcare environments, particularly in radiology. It provides a mechanism to monitor the progress and status of medical imaging procedures. By implementing the mpps table schema, healthcare providers can accurately track each step of a procedure, from initiation to completion, ensuring data integrity and workflow efficiency.
The mpps table schema implementation discussed here traces back to SRS-SVC-007 and FR-3.4, highlighting its significance in fulfilling specific system requirements. This implementation is also part of a larger effort, as indicated by its parent epic #8, showcasing its role in a broader system architecture.
Understanding the mpps Table Schema
The mpps table is designed to store comprehensive information about each performed procedure step. Let's break down the table definition to understand each component:
CREATE TABLE mpps (
-- Primary Key
mpps_pk INTEGER PRIMARY KEY AUTOINCREMENT,
-- Unique Business Key
mpps_uid TEXT NOT NULL UNIQUE, -- SOP Instance UID
-- Status
status TEXT NOT NULL, -- IN PROGRESS, COMPLETED, DISCONTINUED
-- Timing
start_datetime TEXT, -- Performed Procedure Step Start
end_datetime TEXT, -- Performed Procedure Step End
-- Station Info
station_ae TEXT, -- Performed Station AE Title
station_name TEXT, -- Performed Station Name
modality TEXT, -- Modality
-- References
study_uid TEXT, -- Study Instance UID
accession_no TEXT, -- Accession Number
-- Scheduled Step Reference (from worklist)
scheduled_step_id TEXT, -- Scheduled Procedure Step ID
requested_proc_id TEXT, -- Requested Procedure ID
-- Performed Series (JSON array)
performed_series TEXT, -- JSON: [{series_uid, protocol, images}]
-- Metadata
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
-- Constraints
CHECK (status IN ('IN PROGRESS', 'COMPLETED', 'DISCONTINUED'))
);
-- Indexes
CREATE INDEX idx_mpps_status ON mpps(status);
CREATE INDEX idx_mpps_station ON mpps(station_ae);
CREATE INDEX idx_mpps_study ON mpps(study_uid);
CREATE INDEX idx_mpps_date ON mpps(start_datetime);
- Primary Key (
mpps_pk): This is an auto-incrementing integer that uniquely identifies each record in the table. It's a standard practice for database tables to have a primary key for efficient data retrieval and management. - Unique Business Key (
mpps_uid): This field stores the SOP Instance UID, ensuring that each MPPS record is uniquely identified across the system. TheUNIQUEconstraint enforces this uniqueness, preventing duplicate entries. - Status (
status): This field indicates the current state of the procedure step, which can beIN PROGRESS,COMPLETED, orDISCONTINUED. TheCHECKconstraint ensures that only these three values are allowed, maintaining data integrity. - Timing (
start_datetime,end_datetime): These fields record the start and end times of the procedure step, providing valuable information for tracking and analysis. The format is typically a text representation of the date and time. - Station Info (
station_ae,station_name,modality): These fields store information about the station where the procedure is performed, including the AE Title, station name, and modality (e.g., CT, MRI). This information is crucial for understanding the context of the procedure. - References (
study_uid,accession_no): These fields link the MPPS record to the corresponding study, using the Study Instance UID and Accession Number. This allows for easy retrieval of related information across different tables. - Scheduled Step Reference (
scheduled_step_id,requested_proc_id): These fields reference the scheduled procedure step from the worklist, using the Scheduled Procedure Step ID and Requested Procedure ID. This helps in tracking the procedure from its scheduled state to its performed state. - Performed Series (
performed_series): This field stores a JSON array containing information about the performed series, including the series UID, protocol, and number of images. JSON format allows for flexible storage of structured data within a single field. - Metadata (
created_at,updated_at): These fields automatically record the creation and update timestamps of the record, providing an audit trail of changes made to the data. - Indexes: The indexes created on
status,station_ae,study_uid, andstart_datetimeimprove the performance of queries that filter or sort by these fields. Indexes speed up data retrieval by allowing the database to quickly locate specific records.
Implementing MPPS Operations
The implementation of MPPS operations involves creating a class, such as index_database, that encapsulates the necessary functionalities. These operations typically include creating, updating, finding, and listing MPPS records. Let's examine the key operations in detail:
class index_database {
public:
// N-CREATE: Create MPPS in "IN PROGRESS" status
common::Result<int64_t> create_mpps(
const std::string& mpps_uid,
const core::dicom_dataset& dataset);
// N-SET: Update MPPS status and attributes
common::Result<void> update_mpps(
const std::string& mpps_uid,
const core::dicom_dataset& dataset);
// Find MPPS by UID
std::optional<mpps_record> find_mpps(
const std::string& mpps_uid) const;
// List active MPPS for a station
std::vector<mpps_record> list_active_mpps(
const std::string& station_ae) const;
// Find MPPS by study UID
std::vector<mpps_record> find_mpps_by_study(
const std::string& study_uid) const;
};
struct mpps_record {
int64_t pk;
std::string mpps_uid;
std::string status;
std::string start_datetime;
std::string end_datetime;
std::string station_ae;
std::string study_uid;
std::vector<performed_series_info> performed_series;
};
create_mpps: This function is responsible for creating a new MPPS record in the database. It takes the MPPS UID and a DICOM dataset as input. The DICOM dataset contains the attributes needed to populate themppstable. When a new MPPS is created, its status is initially set toIN PROGRESS.update_mpps: This function updates an existing MPPS record. It takes the MPPS UID and a DICOM dataset as input. The DICOM dataset contains the attributes to be updated. This function is used to change the status of the MPPS, as well as update other attributes such as the end datetime or performed series information.find_mpps: This function retrieves an MPPS record from the database based on its UID. It returns anstd::optional<mpps_record>, which means it can return either anmpps_recordobject if the MPPS is found, or an empty optional if the MPPS is not found. This is a safe way to handle cases where the MPPS may not exist.list_active_mpps: This function retrieves a list of active MPPS records for a specific station. It takes the station AE Title as input and returns a vector ofmpps_recordobjects. Active MPPS records are typically those with a status ofIN PROGRESS.find_mpps_by_study: This function retrieves a list of MPPS records associated with a specific study. It takes the Study Instance UID as input and returns a vector ofmpps_recordobjects. This is useful for retrieving all MPPS records related to a particular study.mpps_record: This struct represents a single MPPS record. It contains fields that correspond to the columns in themppstable, such aspk,mpps_uid,status,start_datetime,end_datetime,station_ae,study_uid, andperformed_series. Theperformed_seriesfield is a vector ofperformed_series_infoobjects, allowing for multiple performed series to be associated with a single MPPS record.
MPPS Status Transitions: A State Machine Approach
The status of an MPPS record follows a defined state machine, ensuring that transitions occur logically and consistently. The state machine diagram below illustrates the allowed status transitions:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MPPS State Machine β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β N-CREATE (status = "IN PROGRESS") β
β β
β βΌ β
β βββββββββββββββββββ β
β β IN PROGRESS β β
β ββββββββββ¬βββββββββ β
β β
β βββββββββββββββββΌββββββββββββββββ β
β β N-SET β N-SET β
β β (COMPLETED) β (DISCONTINUED)β β
β βΌ βΌ βΌ β
β βββββββββββββ βββββββββββββ ββββββββββββββββ β
β β COMPLETED β β (Stay) β β DISCONTINUED β β
β βββββββββββββ βββββββββββββ ββββββββββββββββ β
β β
β Note: COMPLETED and DISCONTINUED are final states β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
IN PROGRESS: This is the initial state of an MPPS record when it is created. It indicates that the procedure step is currently being performed.COMPLETED: This state indicates that the procedure step has been successfully completed. Once an MPPS record is in theCOMPLETEDstate, it cannot be transitioned back toIN PROGRESS.DISCONTINUED: This state indicates that the procedure step was discontinued before completion. LikeCOMPLETED,DISCONTINUEDis a final state, and an MPPS record in this state cannot be transitioned back toIN PROGRESS.
The N-CREATE operation always creates an MPPS record in the IN PROGRESS state. The N-SET operation is used to update the status to either COMPLETED or DISCONTINUED. It's crucial to enforce these status transitions in the implementation to maintain data integrity and prevent illogical state changes.
Testing the MPPS Table Implementation
Thorough testing is essential to ensure that the MPPS table implementation functions correctly and meets the required specifications. Unit tests play a crucial role in verifying the behavior of individual components and operations. Here are some examples of unit tests that can be implemented:
// Test MPPS creation
TEST(MPPSTableTest, CreateMPPS) {
auto db = create_test_database();
core::dicom_dataset ds;
ds.set_string(tags::performed_station_ae, "CT_SCANNER_1");
ds.set_string(tags::modality, "CT");
ds.set_string(tags::pps_start_datetime, "20231115120000");
auto result = db.create_mpps("1.2.3.4.5.100", ds);
ASSERT_TRUE(result.is_ok());
auto mpps = db.find_mpps("1.2.3.4.5.100");
ASSERT_TRUE(mpps.has_value());
EXPECT_EQ(mpps->status, "IN PROGRESS");
}
// Test MPPS status update
TEST(MPPSTableTest, UpdateMPPSStatus) {
auto db = create_test_database();
create_test_mpps(db, "1.2.3.4.5.100");
core::dicom_dataset update;
update.set_string(tags::pps_status, "COMPLETED");
update.set_string(tags::pps_end_datetime, "20231115130000");
auto result = db.update_mpps("1.2.3.4.5.100", update);
ASSERT_TRUE(result.is_ok());
auto mpps = db.find_mpps("1.2.3.4.5.100");
EXPECT_EQ(mpps->status, "COMPLETED");
}
// Test invalid status transition
TEST(MPPSTableTest, InvalidStatusTransition) {
auto db = create_test_database();
create_test_mpps(db, "1.2.3.4.5.100");
// First complete it
db.update_mpps("1.2.3.4.5.100", make_complete_update());
// Then try to set back to IN PROGRESS
core::dicom_dataset update;
update.set_string(tags::pps_status, "IN PROGRESS");
auto result = db.update_mpps("1.2.3.4.5.100", update);
EXPECT_TRUE(result.is_err()); // Should fail
}
- Test MPPS creation: This test verifies that a new MPPS record can be created successfully and that its initial status is set to
IN PROGRESS. It involves creating a DICOM dataset with the necessary attributes, calling thecreate_mppsfunction, and then verifying that the MPPS record exists in the database with the correct status. - Test MPPS status update: This test verifies that the status of an existing MPPS record can be updated correctly. It involves creating an MPPS record, updating its status using the
update_mppsfunction, and then verifying that the status has been updated in the database. - Test invalid status transition: This test verifies that invalid status transitions are prevented. It involves creating an MPPS record, completing it, and then attempting to set its status back to
IN PROGRESS. The test should assert that this operation fails, ensuring that the status transition rules are enforced.
Acceptance Criteria for Successful Implementation
The successful implementation of the MPPS table schema can be measured against the following acceptance criteria:
- [ ] Table created with correct schema
- [ ] N-CREATE creates MPPS in "IN PROGRESS"
- [ ] N-SET updates attributes correctly
- [ ] Status constraints enforced
- [ ] JSON performed_series works correctly
- [ ] Unit tests pass with >90% coverage
These criteria ensure that the table structure, operations, and data integrity are all functioning as expected. Achieving >90% unit test coverage is crucial for ensuring the reliability and robustness of the implementation.
Conclusion
Implementing the mpps table schema is a critical step in building a comprehensive medical imaging management system. By following this guide, developers can create a robust and efficient MPPS tracking system that ensures data integrity and workflow efficiency. Proper implementation and thorough testing are key to meeting the stringent requirements of healthcare environments.
For more information on related topics, consider exploring resources on DICOM standards.