A full-stack data visualization platform that transforms raw export data from the Hevy workout app into an interactive analytics dashboard.
Fitness apps often lock advanced analytics behind paywalls. HevyStats solves this by providing a personal dashboard to visualize progress, track volume, and calculate estimated 1RM (One Rep Max) using your own data.
The system ingests "dirty," denormalized CSV logs, processes them via a custom ETL pipeline, and stores them in a normalized PostgreSQL database for efficient querying.
- ETL Data Pipeline: Parses raw CSV files (
streamprocessing), filters duplicates, and normalizes data into Relational Tables. - Interactive Dashboard: Visualizes estimated 1RM and Volume trends over time using Chart.js with gradient styling.
- Smart Logbook: Searchable history with date range filtering and accordion-style details (Set, Reps, RPE, Notes).
- Data Integrity: Uses SQL Transactions (
BEGIN,COMMIT,ROLLBACK) to ensure partial imports never corrupt the database. - Performance: optimized SQL queries to handle aggregation on the database layer, not the application layer.
- Backend: Node.js, Express.js
- Database: PostgreSQL (Raw SQL, 3NF Schema)
- Frontend: HTML5, Bootstrap 5, Chart.js, Vanilla JS
- Tools: Multer (File Handling), CSV-Parser
The project transforms flat file data into a 3NF (Third Normal Form) structure:
workouts: Unique sessions (Date, Title, Notes).exercises: Dictionary of exercise names to prevent redundancy.sets: The transactional data linking workouts and exercises (Weight, Reps, RPE).
- Node.js installed
- PostgreSQL installed and running
git clone https://github.com/fabianluz/HevyStats.git
cd HevyStatsnpm install
Create a PostgreSQL database named hevy_clone and run the script found in database.sql.
Update db.js with your local PostgreSQL credentials:
const pool = new Pool({
user: "postgres",
host: "localhost",
database: "hevy_clone",
password: "YOUR_PASSWORD",
port: 5432,
});node server.js
Visit http://localhost:3000 in your browser.
Developed by Fabian Luz