Dyrected
Model ContentOperational Views

Metrics

KPI cards above every view — counts, sums, averages, and JEXL math over native DB aggregates.

A metric is a KPI card that sits above the data. Instead of loading thousands of rows to compute ₦2,125,000 of collected outfits, the view runs a native aggregate query (count, sum, avg, min, max + where + cast), then optionally runs one JEXL transform or expression to combine, multiply, or round the result.

By the end you'll know the three shapes (aggregate vs aggregates vs expression) and when to reach for format, currency, subMetrics, and color.

Visual outcome

All aggregations run directly on the database engine for maximum speed, computing counts, sums, and averages across thousands of documents without in-memory loading.

Configuration patterns

1. Simple count metric

Display a count of matching documents:

import { defineView } from "@dyrected/core";

export const attendingGuests = defineView({
  slug: "attending-guests",
  label: "Attending Guests",
  layout: "table",
  filter: { attending: { equals: true } },
  columns: ["name", "guestCount"],
  metrics: [
    {
      label: "Total Attending",
      color: "emerald",
      aggregate: { count: "*", where: { attending: { equals: true } } },
    },
  ],
});

2. Distinct count of unique values

Count unique non-null values for a field (e.g. how many distinct tables have seated guests):

export const occupiedTables = {
  label: "Occupied Tables",
  color: "indigo",
  unit: "Tables",
  aggregate: {
    distinctCount: "tableNumber",
    where: { attending: { equals: true } },
  },
};

3. Calculated revenue with transform

Multiply an aggregated numeric sum by a unit price:

export const revenueMetric = {
  label: "Estimated Revenue",
  color: "rose",
  aggregate: {
    sum: "asoebiQuantity",
    cast: "number",
    where: { asoebiStatus: { in: ["paid", "collected"] } },
  },
  transform: "value * 25000",
  format: "currency",
  currency: "NGN", // Displays as: ₦2,125,000
};

value represents the returned aggregation result.

4. Multi-aggregate expressions & ratios

Combine multiple database operations using an expression:

export const attendanceRate = {
  label: "Attendance Rate",
  color: "amber",
  aggregates: {
    totalInvited:   { count: "*" },
    totalAttending: { count: "*", where: { attending: { equals: true } } },
  },
  expression: "math.round((aggregates.totalAttending / aggregates.totalInvited) * 100, 1)",
  format: "percent", // Displays as: 85.9%
};

5. Sub-metrics breakdown

Add secondary footer metrics under the primary hero card:

export const checkInMetric = {
  label: "Door Check-In",
  color: "emerald",
  unit: "Guests",
  aggregates: {
    checkedIn: { count: "*", where: { checkedIn: { equals: true } } },
    attending: { count: "*", where: { attending: { equals: true } } },
  },
  expression: "aggregates.checkedIn",
  subMetrics: [
    {
      label: "Pending",
      aggregates: {
        checkedIn: { count: "*", where: { checkedIn: { equals: true } } },
        attending: { count: "*", where: { attending: { equals: true } } },
      },
      expression: "aggregates.attending - aggregates.checkedIn",
    },
  ],
};

Options reference

PropertyTypeDescription
labelstring requiredTitle displayed on the metric card.
colorMetricColorTheme palette accent ("purple", "emerald", "amber", "rose", "blue", "indigo", "cyan", "orange").
unitstringOptional unit badge displayed alongside the hero value (e.g. "Guests", "Orders", "Tables").
aggregateAggregateOperationSingle operation { count: "*", distinctCount: "field", sum: "field", avg: "field", min: "field", max: "field", where?, cast?: "number" }.
aggregatesRecord<string, AggregateOperation>Named map of operations referenced in expression as aggregates.key.
transformstringJEXL formula evaluated over value for single aggregates (e.g. "value * 100").
expressionstringJEXL formula evaluated over aggregates (e.g. "aggregates.a + aggregates.b").
format"currency" | "number" | "percent"Formatter applied to the final number.
currencystring3-letter currency code (e.g. "USD", "NGN", "EUR") used when format: "currency".
subMetricsViewSubMetric[]Array of sub-metrics displayed in a compact breakdown footer under the main card.

UX guardrails

  • 2–4 cards per view: Keep the metric row focused on primary operational indicators.
  • Percentages are 0–100: Formulas formatted with format: "percent" should output values in the range 0–100.
  • Adaptive mobile layout: Cards with subMetrics automatically expand full-width on mobile viewports for clean horizontal readability.

Next steps

On this page

Dyrected| Cloud

Get your backend ready in minutes

Use a managed database, storage, APIs, and admin dashboard without setting up the infrastructure yourself.

Set Up My Backend