---
title: "App Stoneybatter Cross Training"
description: "Une application web sur mesure qui a réduit les frais de gestion web mensuels d'une salle de crossfit dublinoise de 97%"
canonical_url: "https://tcastanie.dev/portfolio/stoneybatter-cross-training-app"
---

> Index of every page on this site: [llms.txt](https://tcastanie.dev/llms.txt)

# App Stoneybatter Cross Training

Application web pour *Stoneybatter Cross Training*, une salle de crossfit située à Dublin, en Irlande.

![Aperçu récapitulatif du projet Stoneybatter Cross Training](https://tcastanie.dev/portfolio/stoneybatter_social.webp)

<callout icon="i-mingcute-fast-forward-line">

En passant d'une solution SaaS à une application web sur mesure, le gérant de la salle a réduit ses frais de gestion mensuels de 273€ à 8€.

</callout>

<card-group>
<card icon="i-mingcute-link-line" title="Site web" target="_blank" to="https://app.stoneybattercrosstraining.ie/">

app.stoneybattercrosstraining.ie

</card>

<card icon="i-mingcute-calendar-2-line" title="Déploiement">

26 février 2025

</card>

<card icon="i-mingcute-layout-11-line" title="Stack front-end">
<badge color="neutral" variant="outline">
<icon name="i-simple-icons-nuxt">



</icon>

 Nuxt

</badge>

<badge color="neutral" variant="outline">
<icon name="i-simple-icons-vuedotjs">



</icon>

 Vue.js

</badge>

<badge color="neutral" variant="outline">
<icon name="i-simple-icons-nuxt">



</icon>

 Nuxt UI

</badge>

<badge color="neutral" variant="outline">
<icon name="i-simple-icons-typescript">



</icon>

 TypeScript

</badge>
</card>

<card icon="i-mingcute-server-2-line" title="Stack back-end, paiements & emails">
<badge color="neutral" variant="outline">
<icon name="i-simple-icons-directus">



</icon>

 Directus

</badge>

<badge color="neutral" variant="outline" className="mr-2">
<icon name="i-unjs-nitro">



</icon>

 Nitro

</badge>

<badge color="neutral" variant="outline" className="mr-2">
<icon name="i-simple-icons-stripe">



</icon>

 Stripe

</badge>

<badge color="neutral" variant="outline">
<icon name="i-simple-icons-amazonsimpleemailservice">



</icon>

 aws SES

</badge>

<badge color="neutral" variant="outline">

![Logo Plunk](https://tcastanie.dev/portfolio/plunk-dark.svg) Plunk

</badge>
</card>
</card-group>

<note>

L'accès à l'app est réservé aux membres et nécessite une inscription.

</note>

## Contexte

Stoneybatter Cross Training est une salle de sport, spécialisée dans le Crossfit située à Dublin en Irlande. Des cours et des séances de crossfit sont proposés aux membres qui réservent leur place en avance. Les membres ont le choix entre acheter directement une ou plusieurs places, ou un abonnement mensuel à un tarif avantageux.

Le gérant de la salle utilisait une solution externe *SaaS* pour gérer les réservations, les paiements et la planification des cours avec les coachs. Le service ne répondait pas aux besoins métier du dirigeant, car il se voyait obligé d'envoyer des liens de paiement Stripe par WhatsApp, de maintenir à jour manuellement un tableur de suivi des membres et de relancer manuellement en cas d'échec de renouvellement.

Ce qui peut se résumer à un carnet et un stylo  au tarif de 273€ par mois.

## Aperçu

![Capture page d'accueil](https://tcastanie.dev/stoneybatter/home.webp)

L'app web Stoneybatter Cross Training propose à ses membres d'acheter des crédits pour ensuite réserver une place pour un cours de crossfit. Les cours sont composés d'une série d'exercices propre à chaque type de séance, et qui sont créés par les coachs de la salle. Le manager et les coachs ont accès à des fonctionnalités supplémentaires de type *CRUD* pour gérer les cours, les *workouts* et les membres.

## Fonctionnalités

### Calendrier de cours

![Capture du calendrier](https://tcastanie.dev/stoneybatter/calendar.webp)

### Paiements récurrents et uniques

![Capture page de paiement](https://tcastanie.dev/stoneybatter/paiement.webp)

### Authentification et gestion du compte membre

![Capture page de gestion du compte](https://tcastanie.dev/stoneybatter/account.webp)

![Capture page de connexion](https://tcastanie.dev/stoneybatter/login.webp)

### Administration par le gérant et les coachs

Le gérant et les coachs ont accès à des fonctionnalités d'administration pour créer, modifier et supprimer des éléments de l'app, en fonction de leur rôle.

![Capture exemple d'administration](https://tcastanie.dev/stoneybatter/admin.webp)

![Capture page de gestion](https://tcastanie.dev/stoneybatter/gestion.webp)

### Envoi automatique de mails

Des mails automatiques sont envoyés aux membres pour les informer de divers événements, comme la confirmation de réservation, la validation ou l'annulation d'une réservation en liste d'attente.

### Affichage plein écran de la séance

Pour afficher sur l'écran de télévision de la salle de sport.

![Photo télévision](https://tcastanie.dev/stoneybatter/fullscreen.webp)

## Stack technique

L'architecture de l'app est hébergée sur un serveur <icon name="i-mingcute-server-line" className="size-5">



</icon>

 contenant la base de données et **Nuxt** <icon name="i-simple-icons-nuxt" className="size-5">



</icon>

.

La base de données **SQLite** <icon name="i-simple-icons-sqlite" className="size-5">



</icon>

 est gérée via **Directus** <icon name="i-simple-icons-directus" className="size-5">



</icon>

. **Nuxt** <icon name="i-simple-icons-nuxt" className="size-5">



</icon>

 est utilisé en mode *SPA* afin de garantir une utilisation fluide du dashboard et est épaulé par **Nuxt UI** pour les styles. Le serveur **Nitro** <icon name="i-unjs-nitro" className="size-4">



</icon>

, intégré dans **Nuxt**, permet à la fois de gérer les paiements via **Stripe** <icon name="i-simple-icons-stripe" className="size-5">



</icon>

, de servir d'intermédiaire entre le Front-end et le Backend (*BFF*) mais aussi d'effectuer des tâches récurrentes (cron). Les mails automatiques sont envoyés via **Amazon SES** <icon name="i-simple-icons-amazonsimpleemailservice" className="size-5">



</icon>

 et leurs flux sont gérés par une instance de **Plunk**. Une sauvegarde automatique de la base de données est mise en place avec **Duplicati** <icon name="i-simple-icons-duplicati" className="size-5">



</icon>

.

## Processus

Création d'un site web caché (restriction IP) mis à jour automatiquement à chaque ajout de code afin de pouvoir mettre en place une méthode Agile adaptée. Le propriétaire de la salle de crossfit a pu utiliser et tester le site régulièrement afin de remonter les ajustements nécessaires lors de la phase de développement.

Le jour du déploiement, l'ensemble de la base des membres a été importée dans l'app, puis le site a été ouvert au public. Les membres ont pu se connecter et utiliser l'app immédiatement, en choisissant simplement un nouveau mot de passe.

## Maintenance et évolutions

Dans les semaines qui ont suivi le déploiement, nous avons apporté des améliorations et corrections de bugs mineurs remontés par les utilisateurs.

Environ un mois après la stabilisation de l'app, nous avons rajouté une nouvelle fonctionnalité d'ajouts de records personnels (*PRs*) pour les membres, qui leur permet de suivre leurs progrès sur tous les exercices de crossfit et de les comparer avec les records des autres membres, s'ils le souhaitent.

![Capture classement personal records](https://tcastanie.dev/stoneybatter/prs.webp)

## Résultats et impact

Le retour utilisateur qui a été le plus marquant est celui de la fluidité d'utilisation. La stack étant légère et les requêtes optimisées, l'app est très réactive et rapide (parfois trop pour certains membres habitués à l'ancienne solution !)

L'intégration des fonctionnalités PWA a permis de rassurer certains membres, en l'installant sur leur téléphone comme une application native.

Bien que pour la plupart des tâches d'administration le manager utilise son ordinateur pour être plus efficace, il a adoré pouvoir gérer certaines tâches rapides depuis son téléphone lorsqu'il est en déplacement, sans devoir les remettre à plus tard.

Le gérant de la salle a également pu réduire ses frais de gestion mensuels de 97% en passant de 273€ à 8€ par mois, en utilisant une solution sur mesure qui répond exactement à ses besoins métier.

## Mise à jour Avril 2026

Mise à jour de la stack technique du site et refonte front :

- Migration de **Nuxt** `v3` -> `v4`
- Migration de **Nuxt UI** `v2` -> `v3` -> `v4`
- Remplacement de **Zod** par **Valibot**
- Montées de version de **Directus** et **Stripe**
- Réécriture complète du code front pour être plus optimisé avec la logique métier et pour une expérience utilisateur plus rapide que jamais !

## Sitemap

See the full [sitemap](https://tcastanie.dev/sitemap.md) for all pages.
