Releasesv0.1.0

Data model

Every canonical record, field and quantity name, with its unit, UCUM and LOINC codes.

This file is generated by go run ./internal/model/cmd/gendocs from internal/model. Do not edit it by hand: a test fails when it differs from the generator output.

Every connector maps what a provider sends into the records below. The ETL then converts units, validates, de-duplicates and writes them to the ohs_data schema. Every stored row carries tenant_id and user_id; the two are set by the pipeline and are never part of a content hash. Times are UTC. A field typed as a pointer is optional and reads as null in the API when absent.

Field names below are the Go names used inside the pipeline, not the wire names: the JSON the API returns uses snake_case names, and some differ (for example SummaryDate is date). Use ../api/openapi.yaml for the JSON shapes.

The read API returns these records with the provenance fields provider, source, device and ingested_at; see api.md. ECG recordings, ECG voltage samples and heartbeat (RR interval) samples are stored but have no read route yet: they are planned.

Canonical types

QuantitySample

QuantitySample represents a single scalar health measurement.

Stored in ohs_data.quantity_samples.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
ProviderstringThe integration the sample came through (apple_health, withings).
SourceSlugstringThe vendor that produced the sample. Equals Provider for a direct integration.
SourceNamestring
SourceBundleIDstring
DeviceIDstring
ProductTypestringExact hardware model that ran the writing app, for example Watch7,2.
DeviceModelstringModel of the device that took the reading.
WasUserEntered*boolNull when the source does not say.
ExternalIDstring
QuantityTypestringCanonical name from the table below, for example heart_rate.
Valuefloat64
UnitstringStorage unit of the quantity name, after conversion.
IsPrimarySourcebool
StartDatetime.Time
EndDatetime.Time
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.
ReplaceableboolWriter instruction, not a column: a later value for a still open window replaces the stored one.
SupersedeMovedboolWriter instruction, not a column: the external id names one figure of one record, so a stored copy under another start is deleted.

CategorySample

CategorySample represents a categorical health event.

Stored in ohs_data.category_samples.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
Providerstring
ExternalIDstring
CategoryTypestring
ValueIntint
ValueLabelstring
StartDatetime.Time
EndDatetime.Time
SourceNamestring
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.

SleepSession

SleepSession represents a structured sleep record with duration breakdowns.

Stored in ohs_data.sleep_sessions.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
Providerstring
ExternalIDstring
BedtimeStarttime.Time
BedtimeEndtime.Time
TotalSleepSeconds*int
DeepSleepSeconds*int
REMSleepSeconds*int
LightSleepSeconds*int
AwakeSeconds*int
SleepScore*float64
HRVAvgMs*float64
RestingHR*float64
RespiratoryRate*float64
SpO2Avg*float64
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.
ReplaceableboolWriter instruction, not a column: a re-scored session replaces the stored figures and phases.

SleepPhase

SleepPhase represents a single phase within a sleep session.

Stored in ohs_data.sleep_phases.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
Phasestringdeep, rem, light, awake, in_bed or asleep_core, after label normalization.
StartDatetime.Time
EndDatetime.Time
DurationSint
ParentContentHashstringContent hash of the parent session. Empty for an orphan phase.
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.

Workout

Workout represents a workout session with performance metrics.

Stored in ohs_data.workouts.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
Providerstring
ExternalIDstring
ActivityTypestring
StartDatetime.Time
EndDatetime.Time
DurationS*int
ActiveEnergyKcal*float64
DistanceM*float64
AvgHeartRate*float64
MaxHeartRate*float64
AvgSpeedMps*float64
ElevationGainM*float64
VO2Max*float64
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.
ReplaceableboolWriter instruction, not a column: an edited workout replaces the stored figures.

RoutePoint

RoutePoint represents a GPS coordinate from a workout route.

Stored in ohs_data.route_points.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
Timestamptime.Time
Latitudefloat64
Longitudefloat64
AltitudeM*float64
SpeedMps*float64
CourseDeg*float64
ParentContentHashstringContent hash of the parent workout. Empty for an orphan point.
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.

NutritionLog

NutritionLog represents a nutrition/dietary record.

Stored in ohs_data.nutrition_logs.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
Providerstring
ExternalIDstring
StartDatetime.Time
EndDate*time.Time
MealTypestring
EnergyKcal*float64
ProteinG*float64
CarbsG*float64
FatG*float64
FiberG*float64
SugarG*float64
SodiumMg*float64
NutrientsJSONmap[string]anyExtended nutrients by name.
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.
ReplaceableboolWriter instruction, not a column.

ECGRecording

ECGRecording represents ECG metadata (voltage data is in ECGVoltageSample).

Stored in ohs_data.ecg_recordings. No read route yet (planned): stored, not served by the API or MCP.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
StartDatetime.Time
EndDatetime.Time
Classificationint
SymptomsStatusint
AverageHeartRate*float64
SamplingFrequencyfloat64
NumberOfMeasurementsint
VoltagePathstring
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.

ECGVoltageSample

ECGVoltageSample represents a single voltage measurement from an ECG recording.

Stored in ohs_data.ecg_samples. No read route yet (planned): stored, not served by the API or MCP.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
ECGIDstring
UserIDstringOwning end user. Set by the pipeline.
TimeSinceSampleStartfloat64
VoltageUVfloat64Microvolts, converted from volts.
ParentContentHashstringContent hash of the parent recording. Empty for an orphan sample.
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.

DailySummary

DailySummary represents an aggregated daily score from a provider.

Stored in ohs_data.daily_summaries.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
Providerstring
SummaryDatetime.TimeThe user's local calendar day.
ReadinessScore*float64
ActivityScore*float64
SleepScore*float64
RecoveryScore*float64
StrainScore*float64
StepCount*int
ActiveKcal*float64
TotalKcal*float64
DistanceM*float64
FloorsClimbed*int
RestingHR*float64
HRVAvgMs*float64
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.
ReplaceableboolWriter instruction, not a column: the latest summary for the day wins.
RecordIDstringWriter instruction, not a column: the provider record whose figures the summary carries; not written once that record is deleted.

HeartbeatSample

HeartbeatSample represents a single beat-to-beat RR interval measurement.

Stored in ohs_data.heartbeat_samples.

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
SeriesIDstring
UserIDstringOwning end user. Set by the pipeline.
Timestamptime.Time
RRMSfloat64RR interval in milliseconds.
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.

Observation

Observation is a generic coded health fact (the long-tail catch-all).

Stored in ohs_data.observations. No connector writes it yet, and no read route serves it (planned).

FieldTypeNote
TenantIDstringOwning tenant. Set by the pipeline.
UserIDstringOwning end user. Set by the pipeline.
TStime.Time
EndTStime.Time
CanonicalCodestringControlled code, not free text.
ValueNum*float64
ValueCodestring
ValueTextstring
UnitUCUMstringUCUM unit of the value.
ValueCanonical*float64
Providerstring
SourceNamestring
DeviceIDstring
IsPrimarySourcebool
TypeConceptstringdevice, survey, ehr or derived.
SourceValuestring
S3Refstring
ContentHashstringDe-duplication identity of the source record. Part of the unique key with the time column.
Metadatamap[string]anyProvider fields kept as sent, plus timezone (IANA name) when the provider gives one.

MapResult

MapResult holds all canonical records produced from a single input record.

FieldTypeNote
QuantitySamples[]QuantitySample
CategorySamples[]CategorySample
SleepSessions[]SleepSession
SleepPhases[]SleepPhase
Workouts[]Workout
RoutePoints[]RoutePoint
NutritionLogs[]NutritionLog
ECGRecordings[]ECGRecording
ECGSamples[]ECGVoltageSample
HeartbeatSamples[]HeartbeatSample
DailySummaries[]DailySummary
Observations[]Observation
HighFrequencyboolThe result holds high volume data and is written with COPY.
SourceKeystringRaw object the batch was mapped from. Child records use it to find a parent that arrived in another object.
Deletions[]DeletionProvider records the provider deleted: their stored rows are removed and a tombstone in ohs_data.deleted_records keeps them from being written again.

Quantity names and storage units

A quantity sample is stored in the unit below. The ETL converts a known source unit into it (pounds to kilograms, Fahrenheit to Celsius, mmol/L to mg/dL and so on) and parks a sample whose unit it cannot convert. A quantity name that is not in this table is stored as the provider sent it, unit included. Percentages are stored as 0 to 100, not as fractions.

Quantity nameStorage unit
active_energy_burnedkcal
active_energy_burned_intradaykcal
apple_exercise_timemin
apple_move_timemin
apple_sleeping_wrist_temperaturecelsius
apple_stand_timemin
basal_body_temperaturecelsius
basal_energy_burnedkcal
blood_alcohol_contentpercent
blood_glucosemg/dL
blood_pressure_diastolicmmHg
blood_pressure_systolicmmHg
body_fat_masskg
body_fat_percentagepercent
body_masskg
body_mass_indexkg/m2
body_temperaturecelsius
body_temperature_deviationcelsius
bone_masskg
cycling_powerW
distance_cyclingm
distance_downhill_snow_sportsm
distance_swimmingm
distance_walking_runningm
distance_walking_running_intradaym
distance_wheelchairm
electrodermal_activityuS
environmental_audio_exposuredBASPL
environmental_sound_reductiondBASPL
flights_climbedcount
forced_expiratory_volume_1L
forced_vital_capacityL
headphone_audio_exposuredBASPL
heart_ratebpm
heightcm
hrv_rmssdms
hrv_sdnnms
inhaler_usagecount
insulin_deliveryIU
lean_body_masskg
muscle_masskg
nike_fuelcount
number_of_alcoholic_beveragescount
number_of_times_fallencount
oxygen_saturationpercent
peak_expiratory_flow_rateL/min
physical_effortkcal/kg/h
pulse_wave_velocitym/s
push_countcount
readiness_hrv_balanceindex
readiness_scorescore
recovery_high_timemin
respiratory_ratebpm
resting_heart_ratebpm
running_ground_contact_timems
running_powerW
running_speedm/s
running_stride_lengthm
running_vertical_oscillationcm
skin_temperaturecelsius
sleep_scorescore
step_countcount
step_count_intradaycount
strainindex
stress_high_timemin
underwater_depthm
uv_exposureindex
vascular_ageyears
visceral_fat_ratingindex
vo2_maxmL/kg/min
waist_circumferencecm
walking_heart_rate_averagebpm
walking_speedm/s
water_masskg
water_temperaturecelsius
workout_strainindex
Edit on GitHub

On this page