Skip to Content
Living documentation — last reviewed 2026-05-28
FeaturesGoalsGoals — Data Model

Goals — Data Model

Schema: libs/db/src/lib/schema/goals.ts.

goals

ColumnTypeNotes
iduuid PK
membership_iduuid NOT NULLFK memberships(id)
organization_iduuid NOT NULL
typegoal_type NOT NULLbody_metric or exercise_pr
metric_typevarchar(50)Set when type=body_metric
exercise_iduuidFK exercises(id). Set when type=exercise_pr
directiongoal_direction NOT NULL DEFAULT 'increase'FIT-119 — without this, decrease goals auto-achieve
target_value_numericnumeric(14,4) NOT NULLComparison runs without parseFloat
start_value_numericnumeric(14,4)Baseline; nullable for legacy pre-FIT-119 rows
unitvarchar(50) NOT NULLkg, lb, %, cm, seconds, …
deadlinedateOptional
statusgoal_status NOT NULL DEFAULT 'active'active, achieved, cancelled
achieved_attimestamptzSet when status flips to achieved
created_at / updated_at / deleted_attimestamptzSoft-delete

Constraints:

  • goals_type_target_chk(type='body_metric' AND metric_type IS NOT NULL AND exercise_id IS NULL) OR (type='exercise_pr' AND exercise_id IS NOT NULL AND metric_type IS NULL).

Indexes:

  • goals_membership_status_idx partial on (membership_id, status) WHERE deleted_at IS NULL.
  • goals_org_idx on organization_id.
  • goals_exercise_idx partial on (exercise_id) WHERE NOT NULL AND deleted_at IS NULL.

Multi-org isolation

  • Both membership_id and organization_id carried.
  • A user with memberships in two orgs has separate goal sets per org.

PII handling

  • Goal data is sensitive-ish (weight loss targets) but less so than body_metrics; same plaintext / no field-level encryption stance.

Soft / hard delete

  • Soft via deleted_at. No hard-delete path.