2026-03-16 16:23:29 +07:00
|
|
|
---
|
|
|
|
|
layout: clqms-post.njk
|
|
|
|
|
tags: clqms
|
|
|
|
|
title: "Calculator Service Operators Reference"
|
2026-04-02 05:15:21 +07:00
|
|
|
description: "Concept, API contracts, and simplified operator reference for the calc engine"
|
2026-03-17 15:31:51 +07:00
|
|
|
date: 2026-03-17
|
2026-03-16 16:23:29 +07:00
|
|
|
order: 7
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
# Calculator Service: Concept and API Contract
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
## Concept
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
`CalculatorService` evaluates formulas for test results using runtime variables.
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Use it when you need to:
|
|
|
|
|
|
|
|
|
|
- transform a raw result into a calculated result,
|
|
|
|
|
- apply factors or demographic values (age, gender),
|
|
|
|
|
- reuse formula logic from test configuration.
|
|
|
|
|
|
|
|
|
|
Two API patterns are used in practice:
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
1. **By Test Site ID** - uses the calculation definition configured for that test site.
|
|
|
|
|
2. **By Test Code/Name** - resolves by test code or test name and returns a compact result map.
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Responses normally follow `{ status, message, data }`, except the compact test-code endpoint,
|
|
|
|
|
which returns a key/value map.
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Example API Contract
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
### 1) Calculate by Test Site
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-03-17 15:31:51 +07:00
|
|
|
```http
|
2026-04-02 05:15:21 +07:00
|
|
|
POST /api/calc/testsite/{testSiteID}
|
2026-03-17 15:31:51 +07:00
|
|
|
Content-Type: application/json
|
2026-04-02 05:15:21 +07:00
|
|
|
```
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Purpose: Evaluate the configured formula for a specific test site.
|
|
|
|
|
|
|
|
|
|
Request example:
|
|
|
|
|
|
|
|
|
|
```json
|
2026-03-17 15:31:51 +07:00
|
|
|
{
|
|
|
|
|
"result": 85,
|
|
|
|
|
"gender": "female",
|
|
|
|
|
"age": 30
|
|
|
|
|
}
|
2026-03-16 16:23:29 +07:00
|
|
|
```
|
2026-03-17 15:31:51 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Success response example:
|
2026-03-17 15:31:51 +07:00
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"status": "success",
|
|
|
|
|
"data": {
|
|
|
|
|
"result": 92.4,
|
|
|
|
|
"testSiteID": 123,
|
|
|
|
|
"formula": "{result} * {factor} + {age}",
|
|
|
|
|
"variables": {
|
|
|
|
|
"result": 85,
|
|
|
|
|
"gender": "female",
|
|
|
|
|
"age": 30
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Error response example:
|
2026-03-17 15:31:51 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"status": "error",
|
|
|
|
|
"message": "Missing variable: factor",
|
|
|
|
|
"data": null
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2) Calculate by Test Code or Name
|
2026-03-17 15:31:51 +07:00
|
|
|
|
|
|
|
|
```http
|
2026-04-02 05:15:21 +07:00
|
|
|
POST /api/calc/testcode/{testCodeOrName}
|
2026-03-17 15:31:51 +07:00
|
|
|
Content-Type: application/json
|
2026-04-02 05:15:21 +07:00
|
|
|
```
|
2026-03-17 15:31:51 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Purpose: Evaluate a calculation by test code/name and return a compact map.
|
|
|
|
|
|
|
|
|
|
Request example:
|
|
|
|
|
|
|
|
|
|
```json
|
2026-03-17 15:31:51 +07:00
|
|
|
{
|
|
|
|
|
"result": 110,
|
|
|
|
|
"factor": 1.1
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Success response example:
|
2026-03-17 15:31:51 +07:00
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"GLU": 121
|
|
|
|
|
}
|
2026-03-16 16:23:29 +07:00
|
|
|
```
|
|
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Error response example:
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{}
|
|
|
|
|
```
|
|
|
|
|
|
2026-03-16 16:23:29 +07:00
|
|
|
---
|
|
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
## Formula Reference (Simplified)
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-03-17 15:31:51 +07:00
|
|
|
### Arithmetic Operators
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
| Operator | Meaning | Example |
|
|
|
|
|
|----------|---------|---------|
|
|
|
|
|
| `+` | Add | `5 + 3` |
|
|
|
|
|
| `-` | Subtract | `10 - 4` |
|
|
|
|
|
| `*` | Multiply | `6 * 7` |
|
|
|
|
|
| `/` | Divide | `20 / 4` |
|
|
|
|
|
| `%` | Modulo | `20 % 6` |
|
|
|
|
|
| `**` | Power | `2 ** 3` |
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-03-17 15:31:51 +07:00
|
|
|
### Comparison Operators
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
| Operator | Meaning | Example |
|
|
|
|
|
|----------|---------|---------|
|
2026-03-17 15:31:51 +07:00
|
|
|
| `==` | Equal | `{result} == 10` |
|
|
|
|
|
| `!=` | Not equal | `{result} != 10` |
|
|
|
|
|
| `<` | Less than | `{result} < 10` |
|
|
|
|
|
| `<=` | Less than or equal | `{result} <= 10` |
|
|
|
|
|
| `>` | Greater than | `{result} > 10` |
|
|
|
|
|
| `>=` | Greater than or equal | `{result} >= 10` |
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-03-17 15:31:51 +07:00
|
|
|
### Logical Operators
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
| Operator | Meaning | Example |
|
|
|
|
|
|----------|---------|---------|
|
|
|
|
|
| `&&` (`and`) | Logical AND | `{result} > 0 && {factor} > 0` |
|
|
|
|
|
| `\|\|` (`or`) | Logical OR | `{gender} == 1 \|\| {gender} == 2` |
|
|
|
|
|
| `!` (`not`) | Logical NOT | `!({result} > 0)` |
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-03-17 15:31:51 +07:00
|
|
|
### Conditional Operators
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
| Operator | Meaning | Example |
|
|
|
|
|
|----------|---------|---------|
|
2026-03-17 15:31:51 +07:00
|
|
|
| `?:` | Ternary | `{result} > 10 ? {result} : 10` |
|
2026-04-02 05:15:21 +07:00
|
|
|
| `??` | Null fallback | `{result} ?? 0` |
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
### Functions
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
| Function | Meaning | Example |
|
|
|
|
|
|----------|---------|---------|
|
|
|
|
|
| `min(a, b, ...)` | Lowest value | `min({result}, 10)` |
|
|
|
|
|
| `max(a, b, ...)` | Highest value | `max({result}, 10)` |
|
2026-03-17 15:31:51 +07:00
|
|
|
| `constant(name)` | PHP constant by name | `constant("PHP_INT_MAX")` |
|
|
|
|
|
| `enum(name)` | PHP enum case by name | `enum("App\\Enum\\Status::Active")` |
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
### Constants
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
| Constant | Meaning |
|
|
|
|
|
|----------|---------|
|
|
|
|
|
| `true` | Boolean true |
|
|
|
|
|
| `false` | Boolean false |
|
|
|
|
|
| `null` | Null |
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
### Variables Commonly Used
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
| Variable | Type | Meaning |
|
|
|
|
|
|----------|------|---------|
|
|
|
|
|
| `{result}` | Float | Input result value |
|
|
|
|
|
| `{factor}` | Float | Multiplier (default usually `1`) |
|
|
|
|
|
| `{gender}` | Integer | `0` unknown, `1` female, `2` male |
|
|
|
|
|
| `{age}` | Float | Patient age |
|
|
|
|
|
| `{ref_low}` | Float | Reference low |
|
|
|
|
|
| `{ref_high}` | Float | Reference high |
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Gender can be passed as either numeric values (`0`, `1`, `2`) or strings
|
|
|
|
|
(`"unknown"`, `"female"`, `"male"`) and is normalized.
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
### Formula Notes
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
- Use parentheses for precedence: `(2 + 3) * 4`.
|
|
|
|
|
- Use `**` for exponentiation; `^` is XOR.
|
|
|
|
|
- Implicit multiplication is not supported (`2x` is invalid, use `2 * x`).
|
2026-03-16 16:23:29 +07:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
## Quick Usage Examples
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
```txt
|
|
|
|
|
{result} * {factor} + 10
|
|
|
|
|
{weight} / ({height} ** 2)
|
|
|
|
|
{result} * (1 + 0.1 * {gender})
|
2026-03-16 16:23:29 +07:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
## Validation and Errors
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Validate formulas before saving.
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Typical error cases:
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
- invalid syntax,
|
|
|
|
|
- missing variable,
|
|
|
|
|
- non-numeric value after normalization,
|
|
|
|
|
- division by zero.
|
2026-03-16 16:23:29 +07:00
|
|
|
|
2026-04-02 05:15:21 +07:00
|
|
|
Recommended flow: validate formula -> save formula -> evaluate with guarded error handling.
|