trainlog/docs/sync_exchange.md

5.3 KiB

Trainlog synchronization exchange

Status

MOBILE_EXPORT_V1=FROZEN_FOR_IMPLEMENTATION
TRAINLOG_FORMAT_V1=FROZEN_UNCHANGED

This document defines a synchronization artifact. It is not the frozen Trainlog session JSON v1 format.

Android → PC artifact

Shared-storage path:

Download/Trainlog/trainlog-mobile-export-v1.json

Format header:

{
  "format": "trainlog-mobile-export",
  "version": 1
}

The artifact is a complete idempotent mobile snapshot containing:

exercises
sessions
body_observations

Exercises

Each exercise contains:

exercise_id
name
recording_mode
tracking_mode
data_fields

Sessions

Each session contains:

session_id
started_at
session_type
exercises

Each session exercise snapshots:

exercise_id
name
recording_mode
tracking_mode
data_fields
load_mode
rest_seconds

For SETS:

sets[]
    reps
or
    duration_seconds

For CONTINUOUS:

continuous
    duration_seconds
    speed_kmh optional
    distance_km optional

A continuous exercise has no synthetic set.

Body observations

Each body observation contains:

observation_id
observed_at
only the metrics actually measured

Transport

Android writes its own export into shared Downloads storage.

Desktop reads the artifact through direct libmtp transport.

No filesystem mount is required.

No SQLite database file is transferred.

PC → Android

A separate canonical catalog artifact will be defined and implemented after Android → PC export is validated on physical hardware.

The PC → Android path must not overload frozen Trainlog JSON v1.

Desktop import of mobile export v1

The desktop importer is:

tools/import_mobile_export.py

It validates the complete mobile snapshot before opening a write transaction.

Properties:

transactional
idempotent by stable IDs
exercise reconciliation by normalized name
profile conflicts rejected
unknown JSON fields rejected
no SQLite file copying

For mobile SETS v1, the Android form records one uniform set metric. The desktop importer derives:

target_sets = number of logged sets
target_reps or target_duration = uniform logged value

and preserves all performed sets separately.

A v1 mobile session with heterogeneous set metrics or 0 reps is rejected rather than inventing a desktop target.

Continuous activities remain target-less and are imported only into continuous_activity.

Recommended validation sequence:

python tools/import_mobile_export.py   /tmp/trainlog-mobile-export-v1.json   --dry-run

python tools/import_mobile_export.py   /tmp/trainlog-mobile-export-v1.json

Running the real import a second time must import nothing new and report the existing IDs as skipped.

Bidirectional synchronization v1

One desktop Sync action now performs both directions:

Android → PC
    direct-MTP download
    strict transactional import

PC → Android
    canonical PC exercise catalog export
    direct-MTP publication

The Android app obtains one persistent Storage Access Framework grant for:

Download/Trainlog

After this one-time grant, Android can import the PC-created catalog without broad storage permissions.

The Sync page displays persistent synchronization history instead of remote snapshot counts. A snapshot remaining present is not a pending queue item and must not be shown as a "candidate".

User-facing session history timestamps are displayed as:

DD/MM/YYYY HH:MM

Canonical RFC3339 storage remains unchanged.

Automatic Android outbox and sync request

Android no longer requires a manual export action.

The mobile snapshot is refreshed automatically on:

application start
exercise save
session save
body observation save
PC catalog apply

The Android Sync screen exposes:

Synchroniser maintenant

This writes:

Download/Trainlog/trainlog-sync-request-v1.json

with a stable request ID and timestamp.

The next PC-agent slice consumes this request and writes a sync receipt.

Validated bidirectional transport checkpoint

Validated on the physical Samsung device:

ANDROID_TO_PC_MTP=PASS
DESKTOP_MOBILE_IMPORT_V1=PASS
DESKTOP_MOBILE_IMPORT_IDEMPOTENT=PASS

PC_CATALOG_EXPORT_V1=PASS
PC_TO_ANDROID_MTP_PUBLISH=PASS

Artifacts:

Android → PC
    Download/Trainlog/trainlog-mobile-export-v1.json

PC → Android
    Download/Trainlog/trainlog-pc-catalog-v1.json

Both are synchronization artifacts and remain separate from frozen TRAINLOG_FORMAT_V1.

The Android Storage Access Framework folder grant must target:

Download/Trainlog

and the UI must permit changing the stored folder selection.

Remaining synchronization work:

persistent structured sync history
selectable sync detail
common sync engine
trainlog-syncd
Android-triggered request/receipt workflow
automatic mobile snapshot maintenance