Skip to content

gfauredev/LogOut

Repository files navigation

lang
en

LogOut

Turn off your computer, Log your workOut

A simple, efficient and cross-platform workout logging application with 800+ exercises built-in, by Guilhem Fauré.

  • 💪 Easily log workout sessions with sets, reps, weights, distances, durations
  • 📊 Analytics panel with line charts to track progress over time
  • 🏋️ Browse the 870+ included exercises with search functionality
    • Easily add your custom exercises or customize existing ones
  • 📱 Mobile-first responsive design, bottom navigation bar, local-first

Project Structure

src/
  main.rs       # Application entry point and routing
  models/       # Data models: exercises, sessions, sets, enums
  services/     # Business: exercise DB, storage (IndexedDB), service worker
  components/   # UI components: home, exercise list, session view, analytics
  utils.rs      # Pure utility functions (date formatting, etc.)
e2e/app.spec.ts   # Playwright end-to-end tests
assets/styles.css # Application stylesheet
public/
  manifest.json # PWA manifest
  sw.js         # Service worker (JavaScript, required by the browser SW spec)

Tooling

Function Tool
Rust compilation [rustc]
Build system [Cargo]
Dependencies and environment [Nix]
Versionning and collaboration [Git] hosted on GitHub
Unit tests [Cargo test]
End-to-end tests (PWA) Playwright
End-to-end tests (Android) [Maestro]
Code coverage [cargo llvm-cov]
Rust language assistance [rust-analyzer] (LSP)
Documentation from code [rustdoc]
Rust formatting [rustfmt]
Rust quality control [Clippy]
Rust debugging [lldb]
Code edition [VS Code], [Helix]…

Building & Running

To build for web as a PWA, run

dx build --platform web --release

Output is written to target/dx/log-workout/release/web/public/.

To serve the PWA locally with hot-reload during development, run

dx serve # Serves at http://localhost:8080

GitHub Pages deployment

The PWA is deployed automatically on every push to main via .github/workflows/deploy.yml on https://gfauredev.github.io/LogOut.

Code Quality Conventions

Every pull request is validated by .github/workflows/ci.yml, ensuring that all five jobs pass before a PR can be merged.

Job Command Requirement
Formatting cargo fmt --check Code must match rustfmt style exactly
Linting cargo clippy -- -D warnings Zero Clippy warnings
Unit tests cargo llvm-cov … All unit tests pass, covering more than 90% of the codebase
E2E tests npx playwright test All Playwright tests pass
PageSpeed Lighthouse CLI Performance scores posted as PR comment

You can run them locally with the commands

cargo fmt --check # Formatting
cargo clippy -- -D warnings # Linting
cargo test # Unit tests
npx playwright test # E2E tests (starts dev server)

Unit Testing

Unit tests cover pure-Rust model functions (formatting, parsing, serialization), service stubs, and utility helpers. They compile and run on the native target — no browser or WASM toolchain required.

cargo test

The main branch must always pass 100% of unit tests, covering more than 90% of the codebase.

They can be run with cargo llvm-cov (might need to be installed).

cargo llvm-cov --bin log-workout # Summary inline
cargo llvm-cov --bin log-workout --lcov --output-path lcov.info # LCOV report

End-to-End Testing

End-to-end tests exercise the full application running with Playwright. They start dx serve automatically before the test run.

npx playwright test # Run the tests (headless by default)
npx playwright test --headed # Run tests within a visible browser

The main branch must always pass 100% of E2E tests. When a test fails, Playwright captures a screenshot automatically and saves it to test-results/.

Documentation

Other

  • Simple, flat structures are always preffered, do not nest if not necessary
    • Especially in HTML, a node with only one child can be replaced by it

TODO

Always prefer simpler, leaner structure with less nesting

  • Active Session
    • Add replay button on done exercises to quickly do another set
    • Fix notification not sending on phone, not producing sound even with all audio controls set to maximum
    • Ensure on every app start that notification permission is granted and display a toast warning if not
  • Past Sessions
    • Make clicking on an Exercise Tag bring to the corresponding Exercise in List
  • Make toasts last only 3s (currently stuck), consider using common component

Optimization & Technical

  • HTML structure, CSS
    • Prefer HTML semantic hierarchy over classes
    • Keep similar items styled by the same CSS
    • Remove unused (dead) CSS
  • Remove any magic number, making then into clearly named constants
    • In Rust and (especially) in CSS
  • Sign Android app and make it properly installable
  • Make Maestro tests pass
  • Split the SessionView god component into modular child components
  • Reduce allocations to the heap, especially in search loop
  • Improve indexedDB error handling with thiserror
  • Reduce boilerplate by using strum crate for enums serialization