Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e307f33
✨ feat: refactor workout creation with dedicated page and improved UI
Netsbump Aug 1, 2025
80f201a
♻️ refactor: fix exercise display in workout elements step
Netsbump Aug 1, 2025
3bf21d6
Merge pull request #118 from Netsbump/feat/refactor-create-workout
Netsbump Aug 1, 2025
fa26148
✨ feat: add workout element repository and improve steps UI
Netsbump Aug 1, 2025
65ad8ec
Merge pull request #119 from Netsbump/feat/stepper-workout
Netsbump Aug 1, 2025
faa4f7b
✨ feat: improve workout creation page UI/UX
Netsbump Aug 2, 2025
0f750c2
✨ feat: improve workout creation UI/UX and layout responsiveness
Netsbump Aug 2, 2025
b8351ce
✨ feat: improve form submission handling and workout element layout
Netsbump Aug 2, 2025
00a7ef4
♻️ refactor: remove name field from Complex entity
Netsbump Aug 3, 2025
1d2a1e5
♻️ refactor: improve form handling and UI components
Netsbump Aug 3, 2025
075b46c
Merge pull request #120 from Netsbump/feat/ui-ux-front
Netsbump Aug 3, 2025
80242a0
♻️ refactor: simplify workout elements layout from grid to flex
Netsbump Aug 3, 2025
e1052de
♻️ refactor: improve complex categories and card display
Netsbump Aug 3, 2025
ad8c9fa
✨ feat: improve details panel responsive design
Netsbump Aug 11, 2025
8b2e3d5
✨ feat: enhance user profile display in sidebar with avatar and orang…
Netsbump Aug 11, 2025
3b49189
✨ feat: update sidebar styling
Netsbump Aug 11, 2025
a9c9884
✨ feat: enhance complex and exercise management with utility functions
Netsbump Aug 11, 2025
81ea588
♻️ refactor: centralize category badge styling in shared utils
Netsbump Aug 11, 2025
b041f92
✨ feat: improve table UI and layout consistency
Netsbump Aug 11, 2025
d02e9b3
✨ feat: improve UI consistency and search experience across data tables
Netsbump Aug 11, 2025
0d44cb8
✨ feat: update workout card and navigation components
Netsbump Aug 11, 2025
8183212
✨ feat: enhance workout cards with training session integration
Netsbump Aug 11, 2025
eba1678
✨ refactor: update exercise categories and improve workout card UI
Netsbump Aug 11, 2025
1f129d8
✨ feat: implement dashboard with statistics and quick actions
Netsbump Aug 11, 2025
bab03f0
✨ feat: enhance planning calendar UI and add internationalization sup…
Netsbump Aug 11, 2025
c129536
✨ feat: enhance workout creation stepper components
Netsbump Aug 11, 2025
c89c087
✨ feat: improve workout creation workflow and details panel
Netsbump Aug 11, 2025
b02734d
Merge pull request #121 from Netsbump/feat/workout-creation
Netsbump Aug 11, 2025
52fce80
✨ feat: enhance workout elements step UI and search functionality
Netsbump Aug 12, 2025
750f8b2
✨ feat: add editable descriptions for workout elements
Netsbump Aug 12, 2025
d69806d
✨ feat: redirect to planning or workouts after workout creation
Netsbump Aug 12, 2025
18e023c
Merge pull request #122 from Netsbump/feat/workout-complex-creation
Netsbump Aug 12, 2025
0ff463b
♻️ refactor: remove turbo and update package dependencies
Netsbump Aug 12, 2025
17430dc
💚 fix: ensure packages build before apps in CI pipeline
Netsbump Aug 12, 2025
9a46458
Merge pull request #123 from Netsbump/core/remove-turbo
Netsbump Aug 12, 2025
0e08541
✨ feat: add React Native mobile app with Expo in monorepo
Netsbump Aug 13, 2025
27fe14a
⬆️ upgrade: migrate to React 19 across monorepo and update lucide-react
Netsbump Aug 13, 2025
9a5136d
Merge pull request #124 from Netsbump/feat/init-mobile-app
Netsbump Aug 13, 2025
0620c3a
✨ feat: implement React Native mobile authentication with Better Auth
Netsbump Aug 13, 2025
2226d5e
ci (lint): biome-ignore lint any ts-rest
Netsbump Aug 13, 2025
d44ee1c
Merge pull request #125 from Netsbump/feat/mobile-connexion
Netsbump Aug 13, 2025
0ebf381
📝 docs: improve documentation for new developers
Netsbump Sep 22, 2025
d97f46a
Merge pull request #126 from Netsbump/docs/readme-and-env
Netsbump Sep 22, 2025
7962ded
🐛 fix(docker): improve API Docker build configuration for production
Netsbump Sep 22, 2025
ea0267f
Merge pull request #127 from Netsbump/fix/api-deploy
Netsbump Sep 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
run: pnpm install

- name: Run build
run: pnpm run build
run: pnpm build

test:
name: Run Tests
Expand Down
4 changes: 4 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
prefer-workspace-packages=true
strict-peer-dependencies=false
auto-install-peers=true
strict-engines=true
56 changes: 44 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ DropIt est une application web conçue pour optimiser le suivi et la gestion de
## Fonctionnalités

- Gestion du profil : Les utilisateurs créent et mettent à jour leur profil, y compris les informations de base et les statistiques de performance telles que le poids et la taille.
- Gestion des athlètes : Les coachs ont accès à une interface de gestion pour accéder aux profils des athlètes, créer et publier des entraînements, et gérer une bibliothèque d'exercices.
- Gestion des athlètes : Les coachs ont accès à une interface de gestion pour accéder aux profils des athlètes
- Gestion des entrainements : Les coachs ont accès à une interface de gestion pour créer et consulter une bibliothèque d'exercices, de blocs d'exercices et d'entrainements.
- Calendrier d'entraînement personnalisé : Les athlètes peuvent visualiser la programmation quotidienne avec des détails sur les exercices, les pourcentages de travail et les répétitions.
- Gestion des performances : Une page dédiée permet aux athlètes de saisir et de visualiser leurs maxima pour chaque exercice.
- Notifications et Annonces : Un système de notifications informe les utilisateurs des mises à jour importantes, avec des annonces et des messages de la part des coachs.
- Réglages et Support : Les utilisateurs peuvent accéder aux réglages de l'application, y compris la gestion du compte, le changement de mot de passe, la FAQ et l'aide.

## Fonctionnalités à Venir

- Suivi de la Progression : Des graphiques et des visualisations pour un suivi détaillé des progrès.
- Mode Hors Ligne : Permettant l'accès aux fonctionnalités essentielles même sans connexion internet.
- Personnalisation de l'Interface : Introduction d'un mode clair/sombre et options de choix de langue.
- Notifications et Annonces : Un système de notifications informe les utilisateurs des mises à jour importantes, avec des annonces et des messages de la part des coachs.
- Réglages et Support : Les utilisateurs peuvent accéder aux réglages de l'application, y compris la gestion du compte, le changement de mot de passe, la FAQ et l'aide.

<p align="right">(<a href="#readme-top">retour en haut</a>)</p>

Expand All @@ -82,11 +82,11 @@ DropIt est une application web conçue pour optimiser le suivi et la gestion de
- Front-End : React, TypeScript, TanStack (Query + Router), Shadcn + Tailwind
- Back-End : Nest.js + MikroORM
- Base de Données : PostgreSQL
- Recherche: Typesense
- Cache: Redis
- Recherche: Typesense (à venir)
- Cache: Redis (à venir)
- CI/CD : Docker, Docker Compose, GitHub Actions
- Qualité du Code : Biome
- Monorepo: Turborepo
- Monorepo: Pnpm workspaces

<p align="right">(<a href="#readme-top">retour en haut</a>)</p>

Expand Down Expand Up @@ -128,27 +128,60 @@ pnpm build

### Configuration des variables d'environnements

Il y a seulement un seul fichier `.env` à la racine qui faut créer
Créer les fichiers de configuration :

```bash
# Fichier .env à la racine (pour le monorepo)
cp .env.example .env

# Fichier .env pour l'API (requis car l'API s'exécute depuis apps/api/)
cp apps/api/.env.example apps/api/.env
```

### Lancer le projet (développement)

Démarrer les services via Docker Compose (ex: PostgreSQL, Redis, Typesence):
Démarrer les services via Docker Compose (ex: PostgreSQL, PgAdmin):

```bash
docker-compose up -d
```

Lancer le monorepo (backend + frontend) en mode développement:
Lancer le monorepo (backend + frontends) en mode développement:

```bash
pnpm dev
```

<p align="right">(<a href="#readme-top">retour en haut/a>)</p>
### Données de test (Seeds)

Lors du premier lancement de l'application, des données de test sont automatiquement créées dans la base de données, incluant :
- Un super admin (Sten Levasseur - [email protected])
- Un coach pour tester l'interface web
- Un club par défaut
- Des utilisateurs/athlètes générés avec Faker (15-25 athlètes)

### Connexion à l'interface Web

Pour tester l'interface web, vous pouvez vous connecter avec le coach :
- **Email** : `[email protected]`
- **Mot de passe** : `Password123!`

### Application Mobile (React Native)

Une application mobile est disponible dans `apps/mobile/`. Elle se lance automatiquement avec `pnpm dev` (qui lance toutes les apps en parallèle). Pour la tester :

1. Installez Expo Go sur votre téléphone
2. Scannez le QR code affiché dans le terminal (l'app mobile démarre avec `pnpm dev`)

Pour vous connecter, utilisez l'un des utilisateurs générés par les seeds. Les noms et emails étant générés par Faker, consultez directement la base de données via PgAdmin pour récupérer les identifiants.

**Accès PgAdmin** :
- URL : http://localhost:5050
- Email : `[email protected]`
- Mot de passe : `admin`
- Mot de passe universel pour tous les utilisateurs seeds : `Password123!`

<p align="right">(<a href="#readme-top">retour en haut</a>)</p>

<!-- LICENCE -->
<p id="licence"></p>
Expand All @@ -165,7 +198,6 @@ Distribué sous la Licence MIT. Voir le fichier LICENSE pour plus d'informations

## Contact

Bluesky - [@mon_bluesky] - [email protected]
Linkedin
**LinkedIn** : [Sten Levasseur](https://www.linkedin.com/in/sten-levasseur/)

<p align="right">(<a href="#readme-top">retour en haut</a>)</p>
31 changes: 31 additions & 0 deletions apps/api/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# DATABASE
DB_USER=postgres
DB_PASSWORD=example
DB_NAME=dropit
DB_PORT=5432
DB_HOST=localhost

# DATABASE TESTS
DB_USER_TEST=postgres
DB_PASSWORD_TEST=example
DB_NAME_TEST=dropit_test
DB_PORT_TEST=5433
DB_HOST_TEST=localhost

# PGADMIN
[email protected]
PGADMIN_DEFAULT_PASSWORD=admin
PGADMIN_PORT=5050

# API
API_PORT=3000
BETTER_AUTH_SECRET=1G9ueZXVQSRINjcRri14LqXWDYkV3fOd
TRUSTED_ORIGINS=http://localhost:3000,http://localhost:5173

# CLIENT
VITE_API_URL=http://localhost:3000

# BREVO API KEY
BREVO_API_KEY=
BREVO_FROM_EMAIL=
BREVO_FROM_NAME=
81 changes: 24 additions & 57 deletions apps/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,88 +1,55 @@
# =============================================================================
# DOCKERFILE - API NESTJS DROPIT (Version optimisée)
# DOCKERFILE - API NESTJS DROPIT
# =============================================================================
# Inspiré des meilleures pratiques pour monorepos

# -----------------------------------------------------------------------------
# STAGE 1: Base avec pnpm
# STAGE 1: Base
# -----------------------------------------------------------------------------
FROM node:20-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
# Version fixe pour éviter les conflits de lockfile
# Use pnpm version according to our package.json, if not the pnpm store will not be in synced later on, resulting in errors
RUN corepack enable && corepack prepare [email protected] --activate
WORKDIR /app

# -----------------------------------------------------------------------------
# STAGE 2: Builder - Installation et build
# STAGE 2: Builder - Installing deps, building and deploying
# -----------------------------------------------------------------------------
FROM base AS builder

# Installation des outils système nécessaires
RUN apk add --no-cache python3 make g++
# pnpm fetch does require only lockfile
COPY pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
RUN pnpm fetch

# pnpm fetch nécessite seulement le lockfile
COPY pnpm-lock.yaml pnpm-workspace.yaml ./
RUN pnpm fetch --ignore-scripts

# Copier le code source après fetch
# Copy source after fetch
COPY . .
RUN pnpm install -r --offline --prefer-offline --ignore-scripts

# Build des packages dans le bon ordre (pnpm gère les dépendances)
RUN pnpm --filter "@dropit/schemas" build
RUN pnpm --filter "@dropit/contract" build
RUN pnpm --filter "@dropit/permissions" build

# Build de l'API
RUN pnpm --filter api build
RUN pnpm install -r --offline --prefer-offline

# Créer un dossier de déploiement avec seulement les deps nécessaires
RUN pnpm deploy --prod --filter="./apps/api" /app/deploy
RUN pnpm --filter {apps/api}... build

# Copier manuellement le dossier dist car pnpm deploy ne l'inclut pas toujours
RUN cp -r /app/apps/api/dist /app/deploy/dist
# Create a deploy folder with only the required deps
# This respects gitignore, so remember to include your dist folder in the "files" section of your package.json
RUN pnpm deploy --prod --filter="./apps/api" /app/api

# -----------------------------------------------------------------------------
# STAGE 3: Production - Image finale ultra-légère
# STAGE 3: Production - Final Image
# -----------------------------------------------------------------------------
FROM base AS runner

# Installation de dumb-init pour gestion des signaux
RUN apk add --no-cache dumb-init

# Création utilisateur non-root
RUN addgroup -g 1001 -S nodejs && adduser -S nestjs -u 1001

WORKDIR /app

# Copier les fichiers de production depuis le stage deploy
COPY --from=builder /app/deploy/node_modules ./node_modules
COPY --from=builder /app/deploy/dist ./dist
COPY --from=builder /app/deploy/package.json ./package.json

# Copier les packages buildés (nécessaires pour les imports workspace)
COPY --from=builder /app/packages/schemas/dist ./node_modules/@dropit/schemas/dist
COPY --from=builder /app/packages/contract/dist ./node_modules/@dropit/contract/dist
COPY --from=builder /app/packages/permissions/dist ./node_modules/@dropit/permissions/dist

# Configuration des permissions
RUN chown -R nestjs:nodejs /app
USER nestjs

# Variables d'environnement
# Set environment
ENV NODE_ENV=production
ENV PORT=3000

# Exposition du port
EXPOSE 3000
COPY --from=builder /app/api/node_modules ./node_modules
COPY --from=builder /app/api/dist ./dist
COPY --from=builder /app/api/package.json ./package.json

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"
# Expose port
EXPOSE 3000

# Point d'entrée avec dumb-init
ENTRYPOINT ["dumb-init", "--"]
ENV MIKRO_ORM_CLI_USE_TS_NODE=false
ENV MIKRO_ORM_CLI_CONFIG=dist/config/mikro-orm.config.js

# Commande de démarrage
CMD ["node", "dist/main.js"]
# Start the application after syncing the database
CMD ["sh", "-c", "pnpm db:sync && pnpm run start:prod"]
22 changes: 14 additions & 8 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,26 @@
"author": "",
"private": true,
"license": "UNLICENSED",
"packageManager": "[email protected]",
"files": [
"dist"
],
"scripts": {
"build": "nest build",
"start": "nest start",
"dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"db:create": "mikro-orm database:create && pnpm db:migration:up",
"db:sync": "mikro-orm schema:update --run",
"db:fresh": "mikro-orm schema:fresh --seed --run --config=./src/config/mikro-orm.config.ts",
"db:migration:up": "mikro-orm migration:up",
"db:migration:down": "mikro-orm migration:down",
"db:migration:create": "mikro-orm migration:create",
"db:migration:list": "mikro-orm migration:list",
"db:seed": "mikro-orm seeder:run --config=./src/config/mikro-orm.config.ts",
"typecheck": "tsc --noEmit",
"clean": "rm -rf dist",
"db:create": "npx mikro-orm database:create && pnpm db:migration:up",
"db:sync": "npx mikro-orm schema:update --run",
"db:fresh": "npx mikro-orm schema:fresh --seed --run --config=./src/config/mikro-orm.config.ts",
"db:migration:up": "npx mikro-orm migration:up",
"db:migration:down": "npx mikro-orm migration:down",
"db:migration:create": "npx mikro-orm migration:create",
"db:migration:list": "npx mikro-orm migration:list",
"db:seed": "npx mikro-orm seeder:run --config=./src/config/mikro-orm.config.ts",
"test": "jest",
"test:unit": "jest --testPathIgnorePatterns=src/test/",
"test:unit:watch": "jest --testPathIgnorePatterns=src/test/ --watch",
Expand Down
3 changes: 2 additions & 1 deletion apps/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ async function bootstrap() {
// Configuration Swagger
SwaggerModule.setup('api', app, openApiDocument);

await app.listen(PORT);
await app.listen(PORT, '0.0.0.0');
console.log(`Application is running on: http://localhost:${PORT}`);
console.log(`Also accessible on network: http://192.168.1.147:${PORT}`);
}

bootstrap();
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ export class ComplexUseCase {
}

// 2. Validate the data
if (!data.name) {
throw new BadRequestException('Complex name is required');
}
if (!data.exercises) {
throw new BadRequestException('Exercises are required');
}
Expand All @@ -114,7 +111,6 @@ export class ComplexUseCase {

// 5. Create the complex
const complex = new Complex();
complex.name = data.name;
complex.complexCategory = complexCategory;
complex.description = data.description || '';

Expand Down Expand Up @@ -144,16 +140,16 @@ export class ComplexUseCase {
await this.complexRepository.save(complex);

// 9. Get the created complex
const created = await this.complexRepository.getOne(complex.id, coachFilterConditions);
if (!created) {
const complexCreated = await this.complexRepository.getOne(complex.id, coachFilterConditions);
if (!complexCreated) {
throw new NotFoundException('Complex not found');
}

// 10. Map the complex
const dto = ComplexMapper.toDto(created);
const complexDto = ComplexMapper.toDto(complexCreated);

// 11. Present the complex
return ComplexPresenter.presentOne(dto);
return ComplexPresenter.presentCreationSuccess(complexDto);
} catch (error) {
return ComplexPresenter.presentCreationError(error as Error);
}
Expand All @@ -177,10 +173,6 @@ export class ComplexUseCase {
}

// 4. Update the complex properties
if (data.name) {
complexToUpdate.name = data.name;
}

if (data.description !== undefined) {
complexToUpdate.description = data.description;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class ExerciseUseCase {
const exerciseDto = ExerciseMapper.toDto(createdExercise);

//7. Return exercise
return ExercisePresenter.presentOne(exerciseDto);
return ExercisePresenter.presentCreationSuccess(exerciseDto);
} catch (error) {
return ExercisePresenter.presentCreationError(error as Error);
}
Expand Down
3 changes: 0 additions & 3 deletions apps/api/src/modules/training/domain/complex.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ export class Complex {
)
exercises = new Collection<ExerciseComplex>(this);

@Property()
name!: string;

@Property({ nullable: true })
description?: string;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class MikroWorkoutElementRepository extends EntityRepository<WorkoutEleme
return await this.em.persistAndFlush(workoutElement);
}

async remove(id: string): Promise<void> {
async remove(id: string, organizationId: string): Promise<void> {
const workoutElement = await this.em.findOne(WorkoutElement, { id });

if (workoutElement) {
Expand Down
Loading