Convex Wearablesv0.13.1
Reference

Data Model

Tables, indexes, and deduplication rules used by the component.

Core tables

TableDescriptionKey indexes
connectionsOAuth tokens and provider links per userby_user, by_user_provider, by_provider_user, by_provider_username, by_status
dataSourcesUser + provider + device/source combinationsby_user_provider, by_user_provider_device, by_connection
eventsWorkouts and sleep sessionsby_user_category_time, by_external_id, by_source_start_end
dataPointsRaw time-series samplesby_source_type_time, by_source_time, by_type_time
timeSeriesRollupsBucketed historical time-series aggregatesby_source_type_bucket, by_source_type_bucket_size, by_source_bucket, by_type_bucket
dailySummariesPrecomputed daily aggregatesby_user_category_date, by_user_date
syncJobsSync workflow recordsby_user, by_user_provider, by_user_status, by_status
oauthStatesTemporary OAuth PKCE stateby_state
backfillJobsLong-running historical data import trackingby_connection, by_status
workoutSegmentsLaps, splits, swim lengths, and strength setsby_event_kind_index, by_user_provider
workoutZonesHeart-rate and power time-in-zoneby_event_kind_zone, by_user_provider
garminActivityFileJobsEphemeral FIT callback processing stateby_connection_status, by_activity, by_event_external_id, by_expiry
providerWebhookReceiptsDurable, bounded WHOOP/Polar/Suunto callback inboxby_provider_idempotency, provider/status paging, by_expiry, by_connection_status
providerWebhookRegistrationsApplication-level live-provider configuration and safe statusby_provider
outgoingWebhookConfigurationGlobal opt-in switches, limits, retention, and optional callback handleby_key
outgoingWebhookUserTenantsHost-authorized user-to-tenant mapping for transactional captureby_user, by_tenant_user
outgoingWebhookEndpointsEncrypted tenant/user endpoint configuration and healthtenant/status and tenant/user/status indexes
outgoingWebhookEventsCanonical transactional outbox with tenant-scoped idempotency and bounded reference/snapshot bodiestenant/time, tenant/idempotency, fan-out, expiry indexes
outgoingWebhookDeliveriesDurable event-to-endpoint state plus its immutable selected delivery bodyevent/endpoint and tenant/endpoint/status/time indexes
outgoingWebhookAttemptsBounded response status and safe error historydelivery/time, endpoint/time, expiry indexes
outgoingWebhookOperationsHost-visible durable recovery and replay progresstenant/time, endpoint/status
TableDescriptionKey indexes
timeSeriesPolicyRulesDefault rules and preset rulesby_set, by_set_scope
timeSeriesPolicyAssignmentsPer-user preset assignmentby_user, by_preset
timeSeriesPolicySettingsGlobal maintenance settingsby_key
timeSeriesSeriesStatePer-source series maintenance cursorby_source_series, by_next_maintenance, by_user

Source provenance

dataSources separates the integration family (provider) from writer and device attribution (source, originalSourceName, deviceModel, deviceType, and softwareVersion). Events and raw/rollup time-series streams reference a stable dataSourceId.

Source-aware reads return row-level dataSourceId values plus a normalized dataSources sidecar. They preserve independent streams and do not define a canonical provider. See Source-Aware Reads.

Deduplication rules

Events

Events are deduplicated at two levels:

  1. externalId when the provider gives a stable identifier
  2. dataSourceId + startDatetime + endDatetime as a second guardrail

Data points

Raw data points are deduplicated by:

  • dataSourceId
  • seriesType
  • recordedAt

Rollups

Rollups are upserted by:

  • dataSourceId
  • seriesType
  • bucketMs
  • bucketStart

Query strategy

The component separates raw rows and rollups so that:

  • recent high-fidelity data can stay raw
  • older dense history can become cheaper rollup buckets
  • reads can choose the best available representation for the requested time range

For details on how tiers are resolved, see Storage Policies.

On this page