MPPS Table Schema Implementation Guide

by Alex Johnson 39 views

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. The UNIQUE constraint enforces this uniqueness, preventing duplicate entries.
  • Status (status): This field indicates the current state of the procedure step, which can be IN PROGRESS, COMPLETED, or DISCONTINUED. The CHECK constraint 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, and start_datetime improve 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 the mpps table. When a new MPPS is created, its status is initially set to IN 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 an std::optional<mpps_record>, which means it can return either an mpps_record object 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 of mpps_record objects. Active MPPS records are typically those with a status of IN 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 of mpps_record objects. 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 the mpps table, such as pk, mpps_uid, status, start_datetime, end_datetime, station_ae, study_uid, and performed_series. The performed_series field is a vector of performed_series_info objects, 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 the COMPLETED state, it cannot be transitioned back to IN PROGRESS.
  • DISCONTINUED: This state indicates that the procedure step was discontinued before completion. Like COMPLETED, DISCONTINUED is a final state, and an MPPS record in this state cannot be transitioned back to IN 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 the create_mpps function, 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_mpps function, 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.