No description
  • HTML 63.4%
  • Java 32.7%
  • CSS 3.8%
Find a file
2026-07-05 15:43:43 +02:00
.mvn/wrapper Initial commit 2026-04-27 14:36:09 +02:00
docs Wat er is gedaan 2026-07-04 20:11:02 +02:00
src kleine fix 2026-07-04 20:14:46 +02:00
.gitattributes Initial commit 2026-04-27 14:36:09 +02:00
.gitignore Initial commit 2026-04-27 14:36:09 +02:00
CLAUDE.md toevoegen 2026-07-04 20:14:36 +02:00
Dockerfile development-04: aanpassing Dockerfile 2026-04-27 16:22:14 +02:00
mvnw Initial commit 2026-04-27 14:36:09 +02:00
mvnw.cmd Initial commit 2026-04-27 14:36:09 +02:00
pom.xml development-20: registratie voor de officele AR-8 gebruikers 2026-05-09 11:33:26 +02:00
README.md Wat er is gedaan 2026-07-04 20:11:02 +02:00

AR-8 — CrossFit Training App

Een full-stack CrossFit training tracking app voor AR-8. Gebruikers kunnen trainingen bekijken, scores loggen, personal records bijhouden, events aanmelden en hun level opbouwen via een puntensysteem.

Live: https://ar-8.nl
GitHub: https://github.com/fabian19921/AR8 (privé)


Tech Stack

Laag Technologie
Backend Spring Boot 4, Java 21
Database PostgreSQL
Frontend Thymeleaf + plain JavaScript
Auth JWT (JSON Web Tokens)
Foto opslag Cloudinary
Hosting Render.com
Package com.laverman.STM1D

Lokaal opstarten

Vereisten

  • Java 21
  • Maven
  • PostgreSQL database

Stappen

# 1. Clone de repo
git clone https://github.com/fabian19921/AR8.git
cd AR8

# 2. Maak een lokale PostgreSQL database aan
createdb ar8_db

# 3. Stel omgevingsvariabelen in (zie hieronder)

# 4. Start de app
mvn spring-boot:run

De app draait op http://localhost:8080


Omgevingsvariabelen

Zet deze in application.properties of als environment variables op Render:

# Database
spring.datasource.url=jdbc:postgresql://localhost:5432/ar8_db
spring.datasource.username=jouw_gebruikersnaam
spring.datasource.password=jouw_wachtwoord

# JWT
jwt.secret=jouw_jwt_secret

# Cloudinary
cloudinary.cloud-name=jouw_cloud_name
cloudinary.api-key=jouw_api_key
cloudinary.api-secret=jouw_api_secret

# Email (wachtwoord reset)
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=jouw_email
spring.mail.password=jouw_app_wachtwoord

Database migraties

Alle migraties zijn handmatig uitgevoerd. Bij een nieuwe installatie deze SQL queries draaien:

-- Punten systeem
ALTER TABLE users ADD COLUMN IF NOT EXISTS punten INT DEFAULT 0;
UPDATE users SET punten = 0 WHERE punten IS NULL;

-- Profielfoto
ALTER TABLE users ADD COLUMN IF NOT EXISTS profiel_foto_url VARCHAR(500);
ALTER TABLE users ADD COLUMN IF NOT EXISTS profiel_foto_public_id VARCHAR(255);

-- Groepsfoto bij event registraties
ALTER TABLE event_registraties ADD COLUMN IF NOT EXISTS groeps_foto BOOLEAN DEFAULT FALSE;
ALTER TABLE event_registraties ADD COLUMN IF NOT EXISTS groeps_foto_url VARCHAR(500);
ALTER TABLE event_registraties ADD COLUMN IF NOT EXISTS groeps_foto_public_id VARCHAR(255);

-- Ranking timestamp voor maandelijks leaderboard
ALTER TABLE event_registraties ADD COLUMN IF NOT EXISTS ranking_ingevuld_op TIMESTAMP;
UPDATE event_registraties SET ranking_ingevuld_op = '2026-05-01 00:00:00' WHERE ranking_ingevuld = true;

Functionaliteiten

Gebruikers

  • Registreren / inloggen via JWT
  • Wachtwoord reset via email
  • Profielpagina met foto upload (Cloudinary + Cropper.js)
  • Rollen: USER en ADMIN

Trainingen

  • Trainingsplan per dag aanmaken (ADMIN)
  • Blokken: warming up, kracht, WOD, oefenblok, accessory
  • Score typen: kg, tijd, rondes, reps, meter, geen
  • RX / Scaled toggle per blokje
  • Vinkje voor blokjes zonder score
  • Buddy workout systeem (max 4 personen)
  • Personal Records automatisch bijhouden
  • Weekbalk met navigatie

Puntensysteem (50 levels)

  • +1 punt per ingevuld score blokje of vinkje
  • +5 bonus punten als alle blokjes van een dag gedaan zijn (minimaal 3 blokjes)
  • +25 punten per event met eindranking ingevuld
  • Buddy gebruikers krijgen dezelfde punten als de captain
  • 50 levels van Rookie → Always Ready
  • Voortgangsbalk op home pagina
  • Maandelijks leaderboard (reset elke maand, toont top 5)

Events

  • Events aanmaken met foto (ADMIN)
  • Registreren als individueel, buddy of team
  • Foto upload per deelnemer met Cropper.js
  • Eindranking invullen
  • Atleten overzichtspagina per event

WOD Timer

  • For Time (telt op, optioneel tijdslimiet)
  • EMOM (instelbaar rondes + tijdsduur)
  • Interval (werk + rusttijd + rondes)
  • 10 seconden aftellen bij start
  • Geluidsignalen via Web Audio API
  • Scherm blijft aan via Wake Lock API

Overig

  • Notities per dag
  • Contact pagina
  • AR-8 Atleet aanmelding + goedkeuring door admin

Mappenstructuur

src/main/
├── java/com/laverman/STM1D/
│   ├── config/          # CloudinaryConfig, SecurityConfig
│   ├── controller/      # REST controllers
│   ├── model/           # JPA entities
│   ├── repository/      # Spring Data repositories
│   └── service/         # Business logic
└── resources/
    ├── templates/        # Thymeleaf HTML pagina's
    │   └── static/      # style.css, images
    └── application.properties

Deployment op Render

  1. Push naar GitHub (main branch)
  2. Render pikt automatisch de nieuwe versie op (auto-deploy aan)
  3. SQL migraties handmatig uitvoeren via Render PostgreSQL console
  4. Environment variables staan ingesteld onder Environment in het Render dashboard

Security

  • XSS-bescherming in de frontend: alle dynamische waarden (namen, scores, notificaties, event-/qualifier-velden) worden ge-escaped met de gedeelde helper esc() uit static/js/esc.js voordat ze via innerHTML gerenderd worden. Nieuwe templates die innerHTML met dynamische data gebruiken moeten /js/esc.js includen en esc() toepassen.
  • Security headers: SecurityConfig zet een Content-Security-Policy (o.a. connect-src 'self' tegen token-exfiltratie, frame-ancestors 'none' tegen clickjacking). Externe bronnen die zijn toegestaan: cdnjs.cloudflare.com (cropper.js) en res.cloudinary.com (foto's).
  • Tests hiervoor staan in src/test/java/com/laverman/STM1D/config/SecurityHeadersTest.java.

Bekende limieten

  • Leaderboard berekent punten real-time voor alle gebruikers — bij >100 gebruikers eventueel caching toevoegen
  • Geen push notificaties (Garmin API vereist zakelijke goedkeuring)
  • trainingplan.html heeft een bekend responsive probleem op kleine schermen (< 380px)