clqms-fe1/docs/backend-api-calculation.md

3.4 KiB

Backend API Specification: Calculation Engine

Overview

Endpoint to evaluate calculated test formulas and return computed values with proper rounding and error handling.

Endpoint

POST /api/calculate/evaluate

Request Body

{
  // The formula expression using test codes as variables
  // Example: "CHOL - HDL - (TG/5)"
  formula: string;
  
  // Map of test codes to their current numeric values
  // Example: { "CHOL": 180, "HDL": 45, "TG": 150 }
  values: Record<string, number>;
  
  // Decimal precision for rounding (0-6)
  // Default: 2
  decimal?: number;
}

Response Body

Success (200)

{
  status: "success";
  data: {
    // The computed result value
    result: number;
    
    // The result rounded to specified decimal places
    resultRounded: number;
    
    // Formula that was evaluated (for verification)
    evaluatedFormula: string;
  }
}

Error (400/422)

{
  status: "error";
  message: string;
  error: {
    // Error type for frontend handling
    type: "MISSING_VALUE" | "INVALID_EXPRESSION" | "DIVISION_BY_ZERO" | "SYNTAX_ERROR";
    
    // Missing variable names if applicable
    missingVars?: string[];
    
    // Position of syntax error if applicable
    position?: number;
  }
}

Formula Syntax

Supported Operators

  • Arithmetic: +, -, *, /, ^ (power)
  • Parentheses: ( ) for grouping
  • Functions: abs(), round(), floor(), ceil(), min(), max(), sqrt()

Variable Names

  • Test codes are used as variable names directly
  • Case-sensitive (CHOL ≠ chol)
  • Must match exactly (word boundaries)

Examples

Simple subtraction:

Formula: "CHOL - HDL"
Values: { "CHOL": 180, "HDL": 45 }
Result: 135

Complex with division:

Formula: "CHOL - HDL - (TG/5)"
Values: { "CHOL": 180, "HDL": 45, "TG": 150 }
Result: 105

With decimal rounding:

Formula: "(HGB * MCV) / 100"
Values: { "HGB": 14.2, "MCV": 87.5 }
Decimal: 2
Result: 12.43

Validation Rules

  1. Missing Values: If any variable in formula is not provided in values, return MISSING_VALUE error
  2. Division by Zero: Return DIVISION_BY_ZERO error if encountered
  3. Invalid Syntax: Return SYNTAX_ERROR with position if formula cannot be parsed
  4. Non-numeric Values: Return MISSING_VALUE if any value is not a valid number

Batch Endpoint (Optional)

For efficiency when recalculating multiple CALC tests:

POST /api/calculate/evaluate-batch
// Request
{
  calculations: [
    {
      testSiteId: number;
      formula: string;
      values: Record<string, number>;
      decimal?: number;
    }
  ]
}

// Response
{
  status: "success";
  data: {
    results: [
      {
        testSiteId: number;
        result: number;
        resultRounded: number;
        error?: {
          type: string;
          message: string;
        }
      }
    ]
  }
}

Frontend Integration

The frontend will:

  1. Build dependency graph from test definitions
  2. Detect when member test values change
  3. Call this API to compute dependent CALC tests
  4. Update UI with computed values
  5. Mark CALC tests as changedByAutoCalc for save tracking

Security Considerations

  1. Never use eval() or similar unsafe evaluation
  2. Use a proper expression parser (mathjs, muparser, or custom parser)
  3. Sanitize/validate formula input before parsing
  4. Limit computation time to prevent DoS