trainlog/README.md

189 lines
4.5 KiB
Markdown

# Trainlog
Trainlog is a local-first workout and body-tracking system with two user
interfaces:
- a native Android application optimized for fast data entry during training;
- a C17/ncursesw TUI used for durable history, editing, visualization,
statistics, and synchronization.
The desktop SQLite database is the canonical long-term history. Android keeps
its own local SQLite database so recording remains usable independently from the
desktop.
## Current status
```text
TRAINLOG_FORMAT_V1=FROZEN
DESKTOP_SCHEMA_V5=PASS
ANDROID_LOCAL_WORKFLOWS=PASS
VARIABLE_REPETITION_SETS=PASS
CONTINUOUS_ACTIVITY_TRACKING=PASS
DIRECT_MTP_TRANSPORT=PASS
COMMON_SYNC_ENGINE=PASS
TRAINLOG_SYNCD=PASS
ANDROID_TRIGGERED_SYNC=PASS
ANDROID_SYNC_RECEIPT=PASS
BIDIRECTIONAL_SYNC_V1=PASS
DESKTOP_TESTS=19/19 PASS
ANDROID_BUILD=PASS
```
## Architecture
```text
Android application
local SQLite store
|
automatic mobile snapshot
|
v
Download/Trainlog on Android storage
|
| direct MTP / libmtp
v
trainlog_sync_run()
/ \
/ \
Android -> PC PC -> Android
snapshot import catalog publish
\ /
\ /
sync receipt
|
v
Android
Desktop TUI --------------------+
| |
+-- same sync engine -------+
|
v
desktop SQLite
canonical long-term history
```
No SQLite database file is copied between devices. The desktop does not require
a GVFS/FUSE mount of the phone.
## Exercise model
Trainlog does not infer behavior from exercise names.
```text
recording_mode = SETS | CONTINUOUS
tracking_mode = REPS | DURATION
data_fields = SPEED_KMH | DISTANCE_KM
```
Valid model-v1 combinations are:
```text
SETS + REPS
SETS + DURATION
CONTINUOUS + DURATION
```
Actual repetition sets are stored independently. Compact input supports:
```text
5x10
4,5,6,7,8,9,10,9,8,7,6,5,4
4..10..4
```
## Repository layout
```text
android/ native Kotlin/Compose Android client
tui/ C17 ncursesw desktop application and core
docs/ canonical project documentation
format/ frozen Trainlog JSON v1 schema material
examples/ valid frozen-format examples
tests/ fixtures and cross-component tests
tools/ validators, import/export helpers, sync daemon tooling
```
## Desktop build and validation
```bash
meson setup --reconfigure build
meson compile -C build
meson test -C build --print-errorlogs
python tools/validate_json.py
python tools/validate_import_contract.py
git diff --check
```
## Android build
The local Android SDK is intentionally not committed. Configure it with either
`ANDROID_HOME` or `android/local.properties`.
Example:
```bash
cd android
printf 'sdk.dir=%s\n' "$HOME/Android/Sdk" > local.properties
JAVA_HOME=/usr/lib/jvm/java-17-openjdk \
./gradlew assembleDebug
```
## Android-triggered synchronization
Build the desktop first, then install the user service:
```bash
bash tools/install_syncd_user.sh
```
Check it with:
```bash
systemctl --user is-active trainlog-syncd.service
tail -f ~/.local/state/trainlog/syncd.log
```
On Android:
```text
Sync
-> Synchroniser maintenant
```
The request is consumed by `trainlog-syncd`, the shared bidirectional engine
runs, a receipt is returned to Android, and the PC catalog is applied locally.
## Documentation
- `docs/current_state.md`: compact canonical implementation snapshot;
- `docs/architecture.md`: component and ownership boundaries;
- `docs/exercise_data_model.md`: exercise semantics;
- `docs/database.md`: desktop SQLite schema and migrations;
- `docs/android.md`: Android behavior;
- `docs/tui.md`: desktop TUI behavior;
- `docs/sync_exchange.md`: MTP synchronization artifacts and protocol;
- `docs/exchange_format.md`: frozen Trainlog JSON v1 contract;
- `docs/tests.md`: validation strategy;
- `docs/roadmap.md`: completed gates and future cursor;
- `AGENTS.md`: development contract.
## Development principles
- local-first;
- no mandatory cloud account;
- user-owned data;
- versioned persistent and exchange formats;
- stable identities;
- idempotent synchronization;
- no fake data representation to force incompatible models together;
- strict compiler warnings;
- documentation and tests are part of feature completion.