Skip to main content

Calculations

The Calculations feature (Admin > Metamodel > Calculations tab) lets you define formulas that automatically compute field values when cards are saved. This is powerful for deriving metrics, scores, and aggregations from your architecture data.

How It Works

  1. An admin defines a formula targeting a specific card type and field
  2. When any card of that type is created or updated, the formula runs automatically
  3. The result is written to the target field
  4. The target field is marked as read-only on the card detail page (users see a "calculated" badge)

Creating a Calculation

Click + New Calculation and configure:

FieldDescription
NameDescriptive name for the calculation
Target TypeThe card type this calculation applies to
Target FieldThe field where the result is stored
FormulaThe expression to evaluate (see syntax below)
Execution OrderOrder of execution when multiple calculations exist for the same type (lower runs first)
ActiveEnable or disable the calculation

Formula Syntax

Formulas use a safe, sandboxed expression language. You can reference card attributes, related card data, and lifecycle information.

Context Variables

VariableDescriptionExample
fieldKeyAny attribute from the current cardbusinessCriticality
related_{type_key}Array of related cards of a given typerelated_applications
lifecycle_plan, lifecycle_active, etc.Lifecycle date valueslifecycle_endOfLife

Built-in Functions

FunctionDescriptionExample
IF(condition, true_val, false_val)Conditional logicIF(riskLevel == "critical", 100, 25)
SUM(array)Sum of numeric valuesSUM(PLUCK(related_applications, "costTotalAnnual"))
AVG(array)Average of numeric valuesAVG(PLUCK(related_applications, "dataQuality"))
MIN(array)Minimum valueMIN(PLUCK(related_itcomponents, "riskScore"))
MAX(array)Maximum valueMAX(PLUCK(related_itcomponents, "costAnnual"))
COUNT(array)Number of itemsCOUNT(related_interfaces)
ROUND(value, decimals)Round a numberROUND(avgCost, 2)
ABS(value)Absolute valueABS(delta)
COALESCE(a, b, ...)First non-null valueCOALESCE(customScore, 0)
LOWER(text)Lowercase textLOWER(status)
UPPER(text)Uppercase textUPPER(category)
CONCAT(a, b, ...)Join stringsCONCAT(firstName, " ", lastName)
CONTAINS(text, search)Check if text contains substringCONTAINS(description, "legacy")
PLUCK(array, key)Extract a field from each itemPLUCK(related_applications, "name")
FILTER(array, key, value)Filter items by field valueFILTER(related_interfaces, "status", "ACTIVE")
MAP_SCORE(value, mapping)Map categorical values to scoresMAP_SCORE(criticality, {"high": 3, "medium": 2, "low": 1})

Example Formulas

Total annual cost from related applications:

SUM(PLUCK(related_applications, "costTotalAnnual"))

Risk score based on criticality:

IF(riskLevel == "critical", 100, IF(riskLevel == "high", 75, IF(riskLevel == "medium", 50, 25)))

Count of active interfaces:

COUNT(FILTER(related_interfaces, "status", "ACTIVE"))

TIME Model placement (Tolerate / Invest / Migrate / Eliminate) — the same example you'll see in the Formula Reference panel inside Admin → Metamodel → Calculations when creating a new calculation. Target type = Application, target field = timeModel. Assumes you have added two single_select fields named businessFit and technicalFit with options excellent, adequate, insufficient, unreasonable:

# ── TIME Model (Tolerate / Invest / Migrate / Eliminate) ──
# Assumes single_select fields: businessFit and technicalFit
# with options: excellent, adequate, insufficient, unreasonable.
#
# Scoring: Map each dimension to 1-4 numeric scale.
# Business Fit = Y-axis (how well does it serve the business?)
# Technical Fit = X-axis (how healthy is the technology?)
#
# Quadrant logic (threshold at score 2.5):
# Invest = high business + high technical
# Migrate = high business + low technical
# Tolerate = low business + high technical
# Eliminate = low business + low technical
#
bf = MAP_SCORE(data.businessFit, {"excellent": 4, "adequate": 3, "insufficient": 2, "unreasonable": 1})
tf = MAP_SCORE(data.technicalFit, {"excellent": 4, "adequate": 3, "insufficient": 2, "unreasonable": 1})
IF(bf is None or tf is None, None, IF(bf >= 2.5, IF(tf >= 2.5, "invest", "migrate"), IF(tf >= 2.5, "tolerate", "eliminate")))

This is also the worked example referenced by the EA Beginner's Guide.

Comments are supported using #:

# Calculate weighted risk score
IF(businessCriticality == "missionCritical", riskScore * 2, riskScore)

Running Calculations

Calculations run automatically when a card is saved. You can also manually trigger a calculation to run across all cards of the target type:

  1. Find the calculation in the list
  2. Click the Run button
  3. The formula is evaluated for every matching card and results are saved

Execution Order

When multiple calculations target the same card type, they run in the order specified by their execution order value. This is important when one calculation depends on the result of another — set the dependency to run first (lower number).