Skip to Content
Living documentation — last reviewed 2026-05-28
FeaturesMetric SetsMetric Sets

Metric Sets

Status: Shipped. Last reviewed: 2026-05-28

What

A reusable taxonomy + per-member ledger of performance metrics — 1RM lifts, pace, body fat %, etc. — distinct from the body composition timeline in ../body-metrics/. Three primitives:

  1. metric_definitions — global catalogue of measurable quantities. slug (machine), nameI18n (locale-keyed display), unit, kind.
  2. metric_sets — named collections of definitions owned by exactly one of: a member, a workout template, or an organization (CHECK enforces 1-of-3).
  3. member_metrics — recorded values: member × definition → numeric value, unit, recorded_at, source.

Why

  • Programming uses % 1RM percentages. Resolving “75% of back squat 1RM” requires knowing the member’s current 1RM — member_metrics is the lookup table.
  • Coaches assemble sets of “what I care about for this athlete” (member-owned) or “what every athlete on this template needs” (workout-owned) or “the defaults for my gym” (org-owned).
  • The old polymorphic (owner_type, owner_id) shape was replaced with three real FKs + a CHECK constraint for referential integrity.

Personas

PersonaSurfaceCapabilities
Coach (staff)Workout builder / assign sidebarCreate sets, attach definitions, resolve a set for a member
CoachMember detail pageRecord metric values on behalf of member
Member (via mobile / web)Self-report metricsList own values, see latest
API consumerGET /metric-sets/:setId/resolve?memberId=...Returns { definition, latestValue } for each member metric in the set

Capabilities

  • Cataloguemetric_definitions is global (not org-scoped). All orgs share the same vocabulary.
  • Member-owned set — “Athlete X’s personal lifts catalogue”.
  • Workout-owned set — pre-fills % 1RM lookups for a specific workout template.
  • Org-owned set — gym defaults; surfaced when no more-specific set exists.
  • ResolveMetricSetsService.resolve(setId, memberId) returns each definition with the member’s latest recorded value.

Capabilities (gaps)

  • No UI for managing metric_definitions (seeded only).
  • No “fall through” resolver — if a member has no value for a definition, the resolved entry returns null. Programming UI shows it as “unknown 1RM”.
  • ../body-metrics/ — separate concept; covers body composition tracking.
  • ../workouts/metric_sets.workoutId ties a set to a workout template for prescription resolution.
  • ../goals/ — exercise-PR goals can use a member_metrics row as the current value.

Source code

  • API: apps/api/src/metric-sets/
  • DB: libs/db/src/lib/schema/metric-sets.ts
  • Shared: libs/shared/src/lib/schemas/metric-set.ts