Thank you for being patient! We're working hard on resolving the issue
Behind features = ["connector"]. Maps the
:~garmin:{authId}:<metric> rowkey family onto the
tento-lona-connector trait surface.
tento_garmin::connector::{
Garmin, // Integration marker
GarminClient, // grab-bag (HTTP client)
GarminBackendDeps, // host-impl seam
GarminAuth, // AuthProvider marker
GarminParams, // path params (authId)
sleep::{Sleep, logs::Logs},
stress::{Stress, logs::Logs},
hrv::{Hrv, logs::Logs},
}
GarminBackendDeps (host-impl)pub trait GarminBackendDeps: Send + Sync {
fn persist_cells<'a>(
&'a self,
row_id: Uuid,
cells: Vec<Cell>,
) -> BoxFuture<'a, anyhow::Result<()>>;
fn recent_log_cells<'a>(
&'a self,
owner: &'a Owner,
lookup_key: &'a str,
) -> BoxFuture<'a, anyhow::Result<Vec<Cell>>>;
}
The host implements this against its row store + cell store. The
Row::sync body in each metric module reads via
ctx.client.http (the Garmin SDK) and writes via
ctx.deps.persist_cells(...).
Garmin's per-stage date windows come from
tento_lona_connector::wearable_window_for_stage:
stage1 → last 7 daysstage2 → preceding ~3 weeksstage3 → ~year backfill before stage2Non-overlapping, so the orchestrator's per-stage dedup keeps concurrent jobs from racing.
For the full "how to add a new integration" walkthrough using Garmin as the worked example, see adding an integration.