2026-07-17 18:33:06 +02:00
|
|
|
package store
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// SyncState tracks how far back into Garmin history a backfill has already
|
|
|
|
|
// reached. Since activities are immutable once recorded, this lets a repeat
|
|
|
|
|
// backfill skip everything already covered instead of re-fetching it.
|
|
|
|
|
type SyncState struct {
|
|
|
|
|
EarliestSyncedDate *string // "YYYY-MM-DD", nil if backfill has never run
|
|
|
|
|
BackfillComplete bool // true once backfill has reached the configured horizon (or Garmin's own history start)
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-25 13:17:17 +02:00
|
|
|
// GetSyncState returns the current backfill watermark for userID.
|
|
|
|
|
func (db *DB) GetSyncState(ctx context.Context, userID int64) (SyncState, error) {
|
2026-07-17 18:33:06 +02:00
|
|
|
var s SyncState
|
2026-07-25 13:17:17 +02:00
|
|
|
err := db.QueryRowContext(ctx, `SELECT earliest_synced_date, backfill_complete FROM sync_state WHERE user_id = ?`, userID).
|
2026-07-17 18:33:06 +02:00
|
|
|
Scan(&s.EarliestSyncedDate, &s.BackfillComplete)
|
|
|
|
|
if err != nil {
|
2026-07-25 13:17:17 +02:00
|
|
|
return SyncState{}, fmt.Errorf("get sync state for user %d: %w", userID, err)
|
2026-07-17 18:33:06 +02:00
|
|
|
}
|
|
|
|
|
return s, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-25 13:17:17 +02:00
|
|
|
// UpdateSyncState records progress of a backfill run for userID.
|
|
|
|
|
func (db *DB) UpdateSyncState(ctx context.Context, userID int64, earliestSyncedDate string, complete bool) error {
|
2026-07-17 18:33:06 +02:00
|
|
|
_, err := db.ExecContext(ctx, `
|
2026-07-25 13:17:17 +02:00
|
|
|
UPDATE sync_state SET earliest_synced_date = ?, backfill_complete = ? WHERE user_id = ?`,
|
|
|
|
|
earliestSyncedDate, complete, userID)
|
2026-07-17 18:33:06 +02:00
|
|
|
if err != nil {
|
2026-07-25 13:17:17 +02:00
|
|
|
return fmt.Errorf("update sync state for user %d: %w", userID, err)
|
2026-07-17 18:33:06 +02:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|