VRPlatformVRPlatform

Data Integrity

Validation rules, issues, warnings, and resolution strategies

Data Integrity

Overview

VRPlatform validates data continuously to maintain accounting integrity. When issues are detected, they appear in the issues array on API responses.

Understanding issues helps you:

  • Build robust integrations
  • Handle edge cases gracefully
  • Provide meaningful feedback to users
  • Identify and resolve data problems

The Issues Array

Many entities include an issues array:

{
  "id": "entity-123",
  "status": "active",
  "issues": [
    {
      "code": "locked",
      "severity": "warning",
      "message": "Cannot modify - data is attached to owner statement",
      "context": {
        "statementIds": ["stmt-456"]
      }
    }
  ]
}

Issue Structure

FieldDescription
codeMachine-readable identifier for programmatic handling
severityerror (blocking) or warning (informational)
messageHuman-readable description
contextAdditional details specific to the issue type

Severity Levels

SeverityMeaningAction Required
errorOperation blocked or data invalidMust resolve before proceeding
warningPotential problem detectedReview recommended, operation proceeds

Issue Categories

Locking Issues

Issues related to data locking:

CodeSeverityDescriptionResolution
lockedwarningData cannot be modifiedDelete statement or wait for period to reopen
priorToClosedPerioderrorDate is before books closedUse a date after books closed

Context includes:

  • reasons - Array of lock reasons
  • statementIds - Statements causing the lock

Reservation Issues

Issues with reservations:

CodeSeverityDescriptionResolution
guestTotalsMismatchwarningCalculated totals differ from sourceReview payment lines, may need adjustment
inactiveListingwarningReservation on inactive propertyActivate listing or mark reservation inactive
lineNotFounderrorReferenced payment line missingCheck source data, resync if needed
unassignedAccounterrorPayment line has no account mappingConfigure account mapping for line type

Owner Statement Issues

Issues with owner statements:

CodeSeverityDescriptionResolution
emptyJournalEntryAccountIdserrorEntries missing account assignmentsConfigure account mappings
netRevenueLayoutMismatcherrorLayout calculation doesn't matchReview layout configuration
listingInactiveerrorStatement for inactive listingActivate listing first
balanceMismatch_startwarningStarting balance differs from previous endCheck for missed transactions
balanceMismatch_endwarningEnding balance calculation differsReview financials
unpaidReservationswarningReservations with outstanding balancesConsider collecting before publishing
previousMonthJournalEntrieswarningEntries from prior periods includedMay need adjustments

Context includes:

  • journalEntryIds - Affected entry IDs
  • affected - Count of affected items

Statement Row Issues

Issues on individual statement rows:

CodeSeverityDescription
previousPeriodJournalEntrieswarningRow contains entries from prior period
unpaidReservationwarningReservation hasn't been paid

Account Issues

Issues with accounts:

CodeSeverityDescriptionResolution
unassignedAccounterrorRequired account not configuredAssign account in settings
inactiveAccountwarningReferenced account is inactiveActivate account or use different one

Ownership Period Issues

Issues with ownership periods:

CodeSeverityDescriptionResolution
lockedwarningPeriod has locked dataCannot modify dates affecting locked entries

Statement Layout Issues

Issues with statement layouts:

CodeSeverityDescriptionResolution
lockedwarningLayout has attached statementsCannot modify, create new layout instead

Context includes:

  • attachedStatementCount - Number of statements using this layout

Connection Issues

Issues with connections:

CodeSeverityDescriptionResolution
credentialsExpirederrorAuthentication needs refreshRe-authenticate the connection
apiLimitReachedwarningRate limits exceededWait and retry
syncFailederrorSync operation failedCheck connection settings, retry

Handling Issues in Integrations

Check Issues on Every Response

const response = await api.getReservation(id);

// Check for errors
const errors = response.issues.filter(i => i.severity === 'error');
if (errors.length > 0) {
  // Handle blocking issues
  throw new Error(`Reservation has errors: ${errors.map(e => e.code).join(', ')}`);
}

// Log warnings
const warnings = response.issues.filter(i => i.severity === 'warning');
if (warnings.length > 0) {
  console.warn('Reservation warnings:', warnings);
}

Handle Specific Issue Codes

const issues = response.issues;

// Handle locking
const lockIssue = issues.find(i => i.code === 'locked');
if (lockIssue) {
  const { statementIds } = lockIssue.context;
  // Inform user which statements are blocking
  showMessage(`Data is locked by statements: ${statementIds.join(', ')}`);
}

// Handle missing accounts
const accountIssue = issues.find(i => i.code === 'unassignedAccount');
if (accountIssue) {
  const { accountIds } = accountIssue.context;
  // Prompt user to configure accounts
  redirectToAccountSettings(accountIds);
}

Retry Strategies

For transient issues:

async function retryOnRateLimit(operation, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await operation();
    } catch (error) {
      if (error.code === 'apiLimitReached') {
        await sleep(Math.pow(2, i) * 1000); // Exponential backoff
        continue;
      }
      throw error;
    }
  }
}

Best Practices

  1. Always check the issues array - Don't assume success just because the request returned 200

  2. Distinguish errors from warnings - Errors block operations; warnings are informational

  3. Use context for details - The context object provides actionable information

  4. Log warnings - Even non-blocking issues may indicate data quality problems

  5. Surface issues to users - Show meaningful messages, not just error codes

  6. Handle common codes explicitly - Build specific handling for codes you expect to encounter

  7. Retry transient issues - Rate limits and sync failures may resolve on retry

On this page