Change Order Validations

Overview

Change Order Validations provide a comprehensive system for ensuring data integrity and enforcing business rules throughout your change management process. This powerful feature allows you to run both built-in system validations and custom validation rules that align with your organization's specific requirements.

Why Validations Matter

In complex engineering environments, a single oversight can lead to costly errors, production delays, or compliance issues. The validation system helps you:

  • Prevent Errors Early: Catch issues before changes are approved and implemented

  • Enforce Standards: Ensure all changes meet your organization's requirements

  • Maintain Consistency: Apply the same rules across all change orders

  • Provide Transparency: Give reviewers clear visibility into validation results

  • Enable Custom Logic: Create organization-specific validation rules

Understanding Validation Types

The Duro platform provides two types of validations:

System Validations

Built-in validations that run automatically to ensure fundamental data integrity:

  • Items must not exist in other OPEN change orders (prevents conflicts)

  • Required fields must be populated

  • Data types must match expected formats

  • Cross-references must be valid

Custom Validations

JavaScript-based rules you create to enforce your specific business logic:

  • Cost threshold checks

  • Part number format validation

  • Required approver verification

  • Impact assessment requirements

  • Custom field dependencies

Running Validations

Validations can be triggered manually at any time during the DRAFT state of the change order lifecycle. Here's how to run validations and interpret the results:

Basic Validation Query

mutation ValidateChangeOrder($changeOrderId: ID!) {
  changeOrders {
    validate(id: $changeOrderId) {
      id
      isValid  # Overall validation result

      validationRun {
        id
        state  # PASS or FAIL
        summary {
          passCount
          failCount
          warningCount
        }

        results(pagination: { first: 50 }) {
          edges {
            node {
              name
              state
              errorMessage
            }
          }
        }
      }
    }
  }
}

Example Response

{
  "data": {
    "changeOrders": {
      "validate": {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "isValid": false,
        "validationRun": {
          "id": "987fcdeb-51a2-43d1-9876-543210fedcba",
          "state": "FAIL",
          "summary": {
            "passCount": 8,
            "failCount": 2,
            "warningCount": 1
          },
          "results": {
            "edges": [
              {
                "node": {
                  "name": "Items must not exist in other OPEN Change Orders",
                  "state": "FAIL",
                  "errorMessage": "Item P123-456 exists in Change Order CO-2024-001"
                }
              }
            ]
          }
        }
      }
    }
  }
}

Accessing Validation History

Every validation run is stored, allowing you to track how validation results change over time as issues are resolved.

Viewing Latest Validation Results

query GetLatestValidation($changeOrderId: ID!) {
  changeOrders {
    get(filter: { ids: [$changeOrderId] }) {
      connection {
        edges {
          node {
            id
            name
            isValid

            latestValidationRun {
              id
              state
              createdAt
              createdBy {
                name
              }

              summary {
                passCount
                failCount
                warningCount
              }

              # Get detailed results with logs
              results(pagination: { first: 100 }) {
                edges {
                  node {
                    name
                    validationType  # SYSTEM or CUSTOM
                    state          # PASS, FAIL, or WARNING
                    onFailure      # ERROR or WARNING
                    errorMessage

                    # Access validation logs for debugging
                    logs {
                      error {
                        message
                      }
                      info {
                        message
                      }
                      all {
                        message
                        type
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Viewing Historical Validation Runs

Track how validation results have changed over time:

query GetValidationHistory($changeOrderId: ID!) {
  changeOrders {
    get(filter: { ids: [$changeOrderId] }) {
      connection {
        edges {
          node {
            id

            # Get all historical validation runs
            validationRuns(pagination: { first: 10 }) {
              edges {
                node {
                  id
                  collectionId
                  state
                  createdAt
                  createdBy {
                    name
                  }

                  summary {
                    passCount
                    failCount
                    warningCount
                  }

                  # Can drill into specific failed validations
                  results(pagination: { first: 100 }) {
                    edges {
                      node {
                        name
                        state
                        errorMessage
                      }
                    }
                  }
                }
              }
              totalCount
            }
          }
        }
      }
    }
  }
}

Understanding Validation Results

Each validation result provides detailed information to help you understand and resolve issues:

Validation States

  • PASS: The validation succeeded without issues

  • FAIL: The validation failed and must be resolved

  • WARNING: The validation found potential issues that should be reviewed

OnFailure Behavior

  • ERROR: Blocks the change order from proceeding (hard stop)

  • WARNING: Alerts reviewers but doesn't block progress (soft warning)

Validation Logs

Each validation generates detailed logs that help with debugging:

logs {
  # Informational messages about validation execution
  info {
    message
  }

  # Warnings about potential issues
  warn {
    message
  }

  # Error details when validation fails
  error {
    message
  }

  # All logs in chronological order
  all {
    message
    type  # "info", "warn", "error", or "log"
  }
}

Working with Custom Validations

Custom validations allow you to implement organization-specific business rules. When a custom validation runs, you can access both the validation result and the underlying rule definition:

query GetCustomValidationDetails($changeOrderId: ID!) {
  changeOrders {
    get(filter: { ids: [$changeOrderId] }) {
      connection {
        edges {
          node {
            latestValidationRun {
              results(pagination: { first: 50 }) {
                edges {
                  node {
                    name
                    validationType
                    state
                    errorMessage

                    # Only populated for CUSTOM validations
                    validationRule {
                      id
                      name
                      type
                      version
                      code  # The JavaScript validation code
                      library {
                        id
                        name
                      }
                    }

                    # Debug custom validation execution
                    logs {
                      all {
                        message
                        type
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Practical Examples

Example 1: Check Only Failed Validations

When debugging validation failures, focus on just the problems:

query GetFailedValidations($changeOrderId: ID!) {
  changeOrders {
    get(filter: { ids: [$changeOrderId] }) {
      connection {
        edges {
          node {
            id
            name
            isValid

            latestValidationRun {
              state
              summary {
                failCount
                warningCount
              }

              # Fetch all results, then filter client-side
              results(pagination: { first: 100 }) {
                edges {
                  node {
                    name
                    state
                    errorMessage
                    logs {
                      error {
                        message
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Then filter the results in your application code:

const failedValidations = data.changeOrders.get.connection.edges[0]
  .node.latestValidationRun.results.edges
  .filter(edge => edge.node.state === 'FAIL' || edge.node.state === 'WARNING');

Example 2: Monitor Validation Progress

Track validation improvements over multiple runs:

query CompareValidationRuns($changeOrderId: ID!) {
  changeOrders {
    get(filter: { ids: [$changeOrderId] }) {
      connection {
        edges {
          node {
            # Current state
            latestValidationRun {
              createdAt
              summary {
                passCount
                failCount
                warningCount
              }
            }

            # Historical comparison
            validationRuns(pagination: { first: 5 }) {
              edges {
                node {
                  createdAt
                  summary {
                    passCount
                    failCount
                    warningCount
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Example 3: Validation Integration Workflow

Here's a complete workflow for integrating validations into your change order process:

// 1. Create or update a change order
const changeOrderId = await createChangeOrder(changeOrderData);

// 2. Run validations
const validationResult = await runValidation(changeOrderId);

// 3. Check if valid
if (!validationResult.isValid) {
  // 4. Get detailed failure information
  const failures = validationResult.validationRun.results.edges
    .filter(edge => edge.node.state !== 'PASS')
    .map(edge => ({
      name: edge.node.name,
      error: edge.node.errorMessage,
      severity: edge.node.onFailure
    }));

  // 5. Display failures to user
  displayValidationErrors(failures);

  // 6. Allow user to fix issues
  await promptUserToResolveIssues(failures);

  // 7. Re-run validations after fixes
  const retryResult = await runValidation(changeOrderId);

  if (retryResult.isValid) {
    console.log('All validations passed!');
  }
}

// 8. Proceed with approval workflow only if valid
if (validationResult.isValid) {
  await submitForApproval(changeOrderId);
}

Best Practices

1. Run Validations Early and Often

Don't wait until the approval stage to run validations. Run them:

  • After initial change order creation

  • After any significant updates

  • Before submitting for approval

  • After resolving validation failures

2. Provide Clear Error Messages

When creating custom validations, ensure error messages are actionable:

  • ✅ Good: "Part number ABC-123 must have an associated drawing document"

  • ❌ Avoid: "Validation failed"

3. Use Warnings Appropriately

Reserve warnings for issues that should be reviewed but don't necessarily block progress:

  • Missing optional documentation

  • Unusual but acceptable values

  • Recommendations for best practices

Track validation patterns across change orders to identify:

  • Common failure points in your process

  • Training opportunities for users

  • Potential system improvements

5. Leverage Validation Logs

Use the detailed logs to:

  • Debug custom validation logic

  • Understand validation execution flow

  • Provide context to users about failures

Troubleshooting

Common Issues

Validation Runs But Shows No Results

Ensure you're requesting the results field with proper pagination:

validationRun {
  results(pagination: { first: 100 }) {  # Don't forget pagination
    edges {
      node {
        name
        state
      }
    }
  }
}

Custom Validation Not Running

Verify that:

  • The validation rule is active in your library

  • The validation rule code is syntactically correct

  • The change order meets the criteria for the validation to run

Inconsistent Validation Results

Check for:

  • Data changes between validation runs

  • Updates to validation rules

  • Different validation contexts (some validations may be conditional)

Next Steps

  1. Review your organization's validation requirements

  2. Implement custom validations for your specific needs

  3. Integrate validation checks into your change order workflow

  4. Monitor validation metrics to improve your process

For more information on creating custom validation rules, see the Change Order Workflows documentation.

Last updated