Skip to content

Repository files navigation

HyroxCoach

App mobile-first per prepararsi a una gara HYROX: genera un piano di allenamento periodizzato, traccia i workout svolti e riceve coaching adattivo basato su AI.

CI License: MIT React TypeScript Vite


Perché esiste

Nasce da un'esigenza personale: prepararmi a una gara HYROX con un piano che tenga conto della data della competizione, del mio livello e dell'attrezzatura che ho a disposizione — cose che le app generiche non fanno. Invece di un foglio Excel, ho costruito un piccolo prodotto completo: generazione del piano, tracciamento, e un coach AI che commenta e adatta il lavoro nel tempo.

È un progetto personale, ma l'ho trattato come un lavoro serio: logica di dominio separata e testata, secret gestiti lato server, tipizzazione stretta e CI. Il codice è pensato per essere letto.

Cosa fa

  • Genera un piano periodizzato a ritroso dalla data della gara, con le fasi classiche Base → Build → Peak → Taper.
  • Adatta i volumi al livello dell'atleta e sostituisce gli esercizi delle stazioni se manca l'attrezzatura.
  • Traccia i workout svolti (durata, sforzo percepito, % completamento, note) e i benchmark di performance per stazione.
  • Coaching AI (Claude): commenta le sessioni, analizza i punti deboli, chatta nel contesto del tuo piano e propone come adattare la settimana successiva in modo strutturato.
  • Mobile-first / PWA, tutto in localStorage: nessun account, i dati restano sul dispositivo.

Coaching AI

Il coach usa il modello Claude Haiku tramite una serverless function (Netlify). Quattro modalità:

Modalità Cosa fa Output
workout_comment Commenta un singolo workout appena registrato interpretando RPE e completamento Testo
adapt_week Propone come adattare la settimana successiva (rispettando la fase: mai caricare in Taper) JSON strutturato validato con schema
weak_points Analizza i punti deboli a partire da benchmark e log Testo
chat Coach conversazionale nel contesto del piano e dei dati dell'atleta Testo

🔒 La API key non è mai nel client. Vive solo come variabile d'ambiente ANTHROPIC_API_KEY sul server; il browser chiama /.netlify/functions/coach, mai direttamente l'API di Anthropic. L'adattamento della settimana usa un JSON schema per ottenere un output tipizzato e affidabile invece di parsare testo libero.

Stack

  • React 19 + TypeScript (strict) — type-safety a compile-time
  • Vite 6 — dev server e bundler
  • Tailwind CSS v4 — design system a token in @theme
  • React Router 7 — routing client-side
  • Vitest — test della logica di dominio
  • Netlify Functions — proxy serverless verso l'API di Claude
  • PWA (vite-plugin-pwa) — installabile, con asset generati

Architettura

Separazione netta tra logica pura e presentazione — la stessa filosofia di un service-layer backend: il dominio non sa nulla di React né del DOM, quindi è testabile in isolamento.

src/
├── lib/                 # Logica di dominio pura (nessuna dipendenza da React/DOM → testabile)
│   ├── engine.ts        #   Cuore: generatePlan() costruisce il piano a ritroso dalla gara
│   ├── coach.ts         #   Client verso la serverless function (la key sta sul server)
│   ├── types.ts         #   Modello dati (Profile, TrainingPlan, WorkoutLog, ...)
│   ├── storage.ts       #   Persistenza su localStorage
│   ├── util.ts          #   Date, formattazione tempi, id
│   └── *.test.ts        #   Test Vitest della logica
├── state/               # Store globale (Context) con auto-save su localStorage
├── pages/               # Le schermate: Dashboard, Generator, Plan, History, Performance, Coach
├── components/          # Layout (nav desktop/mobile), form riusabili, dettaglio workout
└── index.css            # Design system (token Tailwind v4 in @theme)

netlify/functions/
└── coach.mts            # Serverless proxy verso Claude — unico posto dove vive la API key

Flusso tipico: Generator crea profilo + piano → Plan mostra le settimane e da lì registri un workout → i log alimentano History e i contatori della Dashboard → il Coach commenta e propone adattamenti.

Scelte tecniche degne di nota

  • generatePlan(profile, today) è una funzione pura: dato lo stesso input produce lo stesso piano, quindi è testabile senza mock. I test verificano la somma delle settimane per fase, la presenza del race day, il troncamento della prima settimana e la sostituzione delle stazioni.
  • Output AI strutturato: l'adattamento della settimana non parsa testo libero ma usa un JSON schema, così il motore può applicarlo con sicurezza di tipo.
  • Secret management: nessuna key nel bundle; solo variabile d'ambiente server-side.
  • uid() non usa crypto.randomUUID(): non è disponibile in contesto non sicuro (http://<ip-lan>), e l'app va provata proprio così dal telefono in LAN.

Avvio in locale

Serve Node 20+.

npm install

npm run dev        # dev server con live reload, esposto in rete (vite --host) per provare da telefono
npm run build      # type-check (tsc --noEmit) + build di produzione in dist/
npm run preview    # serve la build di produzione
npm run test       # esegue i test (Vitest)

Per provare dal telefono: npm run dev stampa un URL Network: http://192.168.x.x:5173/ — aprilo dal telefono sulla stessa rete Wi-Fi.

Le funzioni AI girano solo su Netlify (o con netlify dev + una ANTHROPIC_API_KEY in .env). Con il semplice vite la chiamata al coach risponde 404: è atteso, il resto dell'app funziona.

Test

npm run test                              # tutti i test
npm run test -- src/lib/engine.test.ts    # un singolo file

Deploy

Deploy statico su Netlify: build in dist/, redirect SPA verso index.html e serverless function in netlify/functions/. La sola configurazione necessaria è la variabile d'ambiente ANTHROPIC_API_KEY.

Roadmap

  • App navigabile mobile-first
  • Persistenza locale + motore di periodizzazione in codice puro (testato)
  • Coaching AI via serverless (commento, adattamento, punti deboli, chat)
  • PWA installabile
  • Sincronizzazione multi-dispositivo (backend opzionale)
  • Export/import dei dati

Licenza

MIT © Matteo Aiello

About

Web app mobile-first per la preparazione HYROX: piano di allenamento periodizzato, tracking dei workout e coaching AI. React 19 · TypeScript · Vite · serverless Claude.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages