diff --git a/docs/README.md b/docs/README.md index c9a33a0..8fc71f2 100644 --- a/docs/README.md +++ b/docs/README.md @@ -110,10 +110,44 @@ any: value: "Y" ``` -- (AESER = 'Y' and (AESCAN = 'Y' or AESCONG = 'Y') +- (AESER = 'Y' and (AESCAN = 'Y' or AESCONG = 'Y')) or # line #1 to the right represents this or operator (AESER = 'Y' and AESCAN ^= 'Y' and AESCONG ^= 'Y') +## Dataset Metadata Submission Guide + +For rules that work with dataset submission metadata (for example, rules of type Dataset Metadata Check, Dataset Metadata Check against Define XML), the user can reference some dataset metadata attributes (`name`, `domain`, `is_ap`, `ap_suffix`) or apply operations over them (for example: `domain_is_custom`, `related_domain`, `related_domain_is_custom`). The practical result of using these attributes and operations for different dataset names is illustrated in the table below. + +Most of the metadata attributes below are derived automatically from the dataset name and its contents: +- **`name`** is the dataset name as known to the submission system — for XPT files, this is the filename minus the file extension (e.g., `QS` for `qs.xpt`). +- **`domain`** and **`rdomain`** come directly from the first row of the dataset — specifically the `DOMAIN` and `RDOMAIN` variables if they exist. +- **`is_supp`** is determined by the dataset name: if it starts with `SUPP` or `SQ`, it's considered a supplemental dataset. Not exposed for rule check logic. +- **`is_ap`** (Associated Persons) is determined two ways: for non-supplemental datasets, the dataset must contain an `APID` variable in its first row; for supplemental datasets, the `RDOMAIN` value must be exactly 4 characters and start with `AP` (e.g., `APQS`). +- **`ap_suffix`** is only populated for non-supplemental AP datasets, and is taken from characters 3–4 of the `DOMAIN` value (e.g., a `DOMAIN` of `APQS` gives a suffix of `QS`). +- **`unsplit_name`** and **`is_split`** are derived from the above — split datasets have a naming convention defined in the IG and whose name differs from their base domain (e.g., `QSX` is a split of `QS`). Determined by comparing name and domain with some logic to exclude supplemental domains. Neither property is available for use in rule check logic. +- **`domain_is_custom`**, **`related_domain`**, and **`related_domain_is_custom`** are computed by operations applied at rule evaluation time. Note that `domain_is_custom` applies only to the domain itself — supplemental and AP datasets built on top of a custom domain (e.g., `SUPPXX`, `APXX`, `SQAPXX`) are not themselves custom but their **`related_domain_is_custom`**. + +| name | unsplit_name | is_supp | domain | rdomain | is_ap | ap_suffix | domain_is_custom | related_domain | related_domain_is_custom | +| ------ | ------------ | ------- | ------ | ------- | ----- | --------- |------------------| -------------- | ------------------------ | +| QS | QS | False | QS | None | False | | False | | | +| QSX | QS | False | QS | None | False | | False | | | +| QSXX | QS | False | QS | None | False | | False | | | +| SUPPQS | SUPPQS | True | None | QS | False | | False | QS | | +| SUPPQSX | SUPPQS | True | None | QS | False | | False | QS | | +| SUPPQSXX | SUPPQS | True | None | QS | False | | False | QS | | +| APQS | APQS | False | APQS | None | True | QS | False | QS | | +| APQSX | APQS | False | APQS | None | True | QS | False | QS | | +| APQSXX | APQS | False | APQS | None | True | QS | False | QS | | +| SQAPQS | SQAPQS | True | None | APQS | True | | False | QS | | +| SQAPQSX | SQAPQS | True | None | APQS | True | | False | QS | | +| SQAPQSXX | SQAPQS | True | None | APQS | True | | False | | | +| RELREC | RELREC | False | None | None | False | | False | | | +| XX | XX | False | XX | None | False | | True | | | +| SUPPXX | SUPPXX | True | None | XX | False | | False | XX | True | +| APXX | APXX | False | APXX | None | True | XX | False | XX | True | +| SQAPXX | SQAPXX | True | None | APXX | True | | False | XX | True | +| FA | FA | False | FA | None | False | | False | | | + ## Business Rule Examples To provide a contrast to data rules, the following are some examples of business rule: diff --git a/docs/scope.md b/docs/scope.md index 3e0c663..4ea9e9e 100644 --- a/docs/scope.md +++ b/docs/scope.md @@ -31,7 +31,7 @@ The `include_split_datasets` flag (when set to `true`) allows split datasets to ### 4. Use Case Selection -The `Use_Case` field enables targeted dataset selection based on specific implementation scenarios. This is particularly important for TIG (Therapeutic Information Guidelines) v1.0, which is an integrated IG with different Use Case categories. +The `Use_Case` field enables targeted dataset selection based on specific implementation scenarios. This is particularly important for TIG (Tobacco Implementation Guide) v1.0, which is an integrated IG with different Use Case categories. ## Common Scope Configuration @@ -54,13 +54,13 @@ The `Use_Case` field enables targeted dataset selection based on specific implem ## Use Case Functionality in TIG -The `Use_Case` field in the Scope section plays a significant role in the TIG (Therapeutic Information Guidelines) implementation. TIG v1.0 is an integrated Implementation Guide with different Use Case categories that help determine which datasets are relevant for specific validation scenarios. +The `Use_Case` field in the Scope section plays a significant role in the TIG (Tobacco Implementation Guide) implementation. TIG v1.0 is an integrated Implementation Guide with different Use Case categories that help determine which datasets are relevant for specific validation scenarios. ### Use Case Categories TIG v1.0 defines several key Use Case categories: -- `INDH`: Investigational New Drug Human -- `PROD`: Production/Marketing +- `INDH`: Investigational Health +- `PROD`: Product Description - `NONCLIN`: Non-Clinical - `ANALYSIS`: Analysis datasets diff --git a/src/components/TestStep/ResultsTestStep.tsx b/src/components/TestStep/ResultsTestStep.tsx index f12fcfb..957ee6c 100644 --- a/src/components/TestStep/ResultsTestStep.tsx +++ b/src/components/TestStep/ResultsTestStep.tsx @@ -19,8 +19,8 @@ export default function ResultsTestStep() { ).length; const testResultHasErrors = (currentRecordResult: object): boolean => - (currentRecordResult["executionStatus"] ?? "execution_error") === - "execution_error" && + (currentRecordResult["executionStatus"] ?? "execution error") === + "execution error" && ((currentRecordResult["errors"] ?? []).length === 0 || currentRecordResult["errors"].length - varSkipCount(currentRecordResult) > @@ -73,7 +73,7 @@ export default function ResultsTestStep() { ) => aggregateRecordResult + (currentRecordResult["executionStatus"] === - "issue_reported" && "errors" in currentRecordResult + "issue reported" && "errors" in currentRecordResult ? currentRecordResult["errors"].length : 0), 0 diff --git a/tests/test_rule_editor.py b/tests/test_rule_editor.py index 42ef76f..921b5ee 100644 --- a/tests/test_rule_editor.py +++ b/tests/test_rule_editor.py @@ -199,7 +199,7 @@ def save_screenshot(driver, name_prefix="screenshot"): ], "FA": [ { - "executionStatus": "issue_reported", + "executionStatus": "issue reported", "dataset": "fa.xpt", "domain": "FA", "variables": [ @@ -267,7 +267,7 @@ def save_screenshot(driver, name_prefix="screenshot"): ], "IE": [ { - "executionStatus": "issue_reported", + "executionStatus": "issue reported", "dataset": "ie.xpt", "domain": "IE", "variables": [ @@ -299,7 +299,7 @@ def save_screenshot(driver, name_prefix="screenshot"): ], "LB": [ { - "executionStatus": "issue_reported", + "executionStatus": "issue reported", "dataset": "lb.xpt", "domain": "LB", "variables": [