GXP environments have unique requirements that can be addressed through Tulip App building and configuration. Tulip has a standardized set of best practices to ensure compliance that are described here.
In this article you'll find:
A list of the best practices and recommendations for building Apps in a GXP environment
Information on how to implement the best practices within Tulip Apps to ensure GXP compliance, including audit-trail traceability and data integrity.
This article assumes prior knowledge of basic Tulip concepts such as variables, tables, and completion records. Please reference applicable articles as necessary.
Best practices covered in this article:
Capture genealogy and history record:
1.1 Use the completions data to create an unchangeable history record
1.2 Use the completions data to create full traceability when modifying tables
1.3 Use the completions data to show full traceability of changes to historic entries
Best Practices for managing process parameters (e.g., unit of measure, decimal precision, and variable naming convention)
Minimum practice for display of standard information on each step
Capturing e-signatures with signature forms
Managing exceptions and enabling review by exception
Working with and managing date- time stamps
1.1 Capture genealogy and history record: Use the completions data to create an unchangeable history record
History records are compiled by linking a Tulip table record (i.e. row in a table) with completions data (entries/rows). Any Tulip table record that is included in completions data can be used for this linking, therefore the table record needed for the history record will be loaded in the App at the same time that an App completion occurs. Be sure to include app completions in your trigger logic when manipulating record data.
History records are compiled from multiple completions, therefore Apps should "complete" at the points in the process where data needs to be logged. It therefore may be required for an App to complete multiple times during execution. Note that completing an App clears non-persistant variables and this should be considered during App design.
1.2 Capture genealogy and history record: Use the completions data to create full traceability when modifying tables
When working with table records, ensure traceability with completions: Reminder: Manipulation of data in table records during App execution happens in real time and is not tied to App completion. To keep data contemporaneous, include table data manipulation in the same trigger sequence as the App completion.
1.3 Capture genealogy and history record: Use the completions data to handle full traceability of changes to historic entries
Correction to history record entries can be only be done by adding new completion data. There is no way to change values in a completion record, intentionally. This is intentional to assure original data is maintained.
A simple way to think of it is, a completion record is an audit trail of an App executing. Data that has been already committed to the completion record is corrected by an additional completion record entry.
Example of correction implemented in Apps
How to make the correction: Execute the App or App steps again, with an optional variable that defines the record as a "correction."
Create a variable “Record Type” that is assigned standard values such as “Normal”, “Correction”, etc. that can be used to sort/filter the completion record.
In most cases it is enough to use the captured dates to sort through correction entries, as this is chronological order with the most recent entry being the valid value.
2. Best Practices for managing process parameters (e.g., unit of measure, decimal precision and variable naming practices)
Use additional helper variables to save the Unit Of Measurement for process data. For process and production data, it is always important to specify Unit of Measurement (UOM), e.g. °C, Kg, Liters, Ph., etc.
- Do this with an additional variable (helper variable) that can either be selected or has a static value.
- Helper variables will be saved in the completion record.
Use app trigger logic logic and expression to manage decimal precision. Certain process parameters may require a specific precision, i.e., number of decimal places. This needs to be managed in the App through trigger logic and expressions.
Use clear variable naming to highlight key variables. e,g. Critical Process Parameters (CPP), or Critical Quality Attribute (CQA)
- Certain process parameters have to be defined as Critical Process Parameters (CPP), or Critical Quality Attribute (CQA)
- There is no current way to tag variables in Tulip so the simplest way to do this is by adding either a prefix or suffix to variable names. E.g. variable names such as “temperature_CPP”, “CQA_Assay B”, etc. [Should we state this more simply by just saying: "Any data point can be tagged with a variable name that includes the key indicator, such as CPP or CQA."?]
3. Minimum standard information to be displayed on each step
The following elements should be shown on each step in order to provide to the user the appropriate context:
The name or unique ID of the main item that the App is used to process. "Item" E.g. Batch , Order , Equipment, Tool that is being used or processed. In some cases there will be multiple items.
The Logged-In User
The version of the App
The App Step name
4. Capturing e-signatures with signature forms
Use signature title or additional variable capture/input on step to give context for the signatures. Remember that e-signature requirements dictate that a signature includes
What are you signing for? The context for the signature can be described in the signature step name, e.g. Batch, Order, Equipment, etc.
Why are you signing? The reason the signature in the title of the signature form.
- Alternatively a variable can be added to the form to capture reason
Who is signing? Username, full name, and password that is provided by the Signature Form widget feature.
When signed? The date/time stamp of when the signature was applied. This is automatically captured as completion data when the signature form step is completed. [confirm this is true]
The following are a few recommended ways to capture context of the signature.
Use the form title and username label to define the reason for an e-signature. The form title and username label is captured in the completion data and therefore is a good way to capture the reason.
Group steps that require an e-signature and include the signature form as the last step in the group.
Use a text input label or single select dropdown list that describes the intent of signature.
Create a summary step before the signature to provide the user the context of what s/he is signing for.
5. Managing exceptions and enabling review by exception
The following is important to allow review of exceptions related to a history record.
Use an app variable to define the record type (e.g., normal, correction, exception - see section 1.3) to enable exceptions to be easily identified.
Use a table to collate the exceptions for review. Every exception (defect, observation, etc.) should be stored as a single record in a Tulip table including all relevant information (information on exception, date/time, app, order/batch, operator etc.). In addition to being stored in the completion data, these records can be linked to the batch or order.
In the exception table include a column that links or reference the artifact that the exception is for. For example batch, material, equipment, order
6. Working with and managing date time stamps
Timestamps in the completion record are captured in UTC with an offset for time zone.
Date and time formatting can be set at the instance level for all Apps. This is done in the "Settings/Date And Time" option.
Date time formats can be formatted in the expression editor. When displaying or entering date time make sure to display the date/time based on consistent format.
- GxP time formats require unambiguous format, e.g. “04-Jul-2020”
- Use expression to format date/time display in Apps and Analytics.
- Dates can be formatted to the specified format by using the FORMAT_DATE_TZ() function in the expression editor.