#!/usr/bin/env bash # Lance en mode développement le backend (port 8080) et le frontend Angular (port 4200) # avec la base SQLite réelle. À utiliser hors Docker, pour le développement local. # # Usage : ./run-dev.sh # Arrêt : Ctrl+C (les deux processus sont arrêtés ensemble). set -uo pipefail RACINE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # --- Backend (.NET 8) ------------------------------------------------------- export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH" export DOTNET_ROOT="$HOME/.dotnet" # Base réelle, chemin ABSOLU pour éviter deux bases selon le dossier de lancement. export ConnectionStrings__Default="Data Source=$RACINE/backend/TrajetKmTracker.Api/trajets.db" export ASPNETCORE_ENVIRONMENT=Development # Clé OpenRouteService : lue depuis .env (ORS_API_KEY) et injectée sous le nom attendu # par la configuration .NET (ORS__ApiKey). Sans clé valide, le backend calcule les # distances à vol d'oiseau (fallback Haversine) au lieu de la distance routière réelle. if [[ -z "${ORS__ApiKey:-}" && -f "$RACINE/.env" ]]; then ORS_KEY_FROM_ENV="$(grep -E '^ORS_API_KEY=' "$RACINE/.env" | head -n1 | cut -d= -f2- || true)" if [[ -n "$ORS_KEY_FROM_ENV" ]]; then export ORS__ApiKey="$ORS_KEY_FROM_ENV" echo "→ Clé ORS chargée depuis .env (calcul de distance routière activé)." else echo "⚠ Aucune clé ORS dans .env : distances calculées à vol d'oiseau." fi fi echo "→ Démarrage du backend sur http://localhost:8080 (base : $RACINE/backend/TrajetKmTracker.Api/trajets.db)" dotnet run --project "$RACINE/backend/TrajetKmTracker.Api" --urls http://localhost:8080 & PID_BACK=$! # --- Frontend (Angular via nvm/Node 22) ------------------------------------- export NVM_DIR="$HOME/.nvm" # shellcheck source=/dev/null . "$NVM_DIR/nvm.sh" nvm use 22 >/dev/null # Vide le cache de compilation Angular pour garantir un bundle à jour, notamment # le polyfill zone.js (sans lui, la vue ne se rafraîchit pas sur les réponses HTTP : # `window.Zone` doit être défini au runtime). Un cache périmé peut resservir un # ancien polyfills sans zone.js. echo "→ Nettoyage du cache Angular (.angular/cache)" rm -rf "$RACINE/frontend/.angular/cache" echo "→ Démarrage du frontend sur http://localhost:4200 (première compilation : patiente…)" ( cd "$RACINE/frontend" && npm start ) & PID_FRONT=$! # --- Arrêt propre des deux processus ---------------------------------------- cleanup() { echo "" echo "→ Arrêt…" kill "$PID_BACK" "$PID_FRONT" 2>/dev/null || true pkill -f "TrajetKmTracker.Api" 2>/dev/null || true } trap cleanup EXIT INT TERM # --- Attente active : ng serve prêt à répondre en HTTP 200 ------------------ # La première compilation (surtout après vidage du cache) peut prendre 30–60 s. # Tant que ng serve n'a pas fini, le port répond « connexion refusée » (HTTP 000) # et le navigateur chargerait une page incomplète (zone.js absent → window.Zone # undefined). On ne montre l'invitation qu'une fois le serveur réellement prêt. attendre_frontend() { local url="http://localhost:4200/" local max=120 # secondes local t=0 printf "→ Compilation du frontend" while [ "$t" -lt "$max" ]; do # Le process ng serve est-il toujours vivant ? if ! kill -0 "$PID_FRONT" 2>/dev/null; then echo "" echo "✗ Le frontend s'est arrêté avant d'être prêt (voir les logs ci-dessus)." return 1 fi local code code=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo 000) if [ "$code" = "200" ]; then echo " prêt." return 0 fi printf "." sleep 2 t=$((t + 2)) done echo "" echo "✗ Le frontend n'a pas répondu 200 au bout de ${max}s. Vérifie les logs ng serve." return 1 } if attendre_frontend; then echo "" echo "======================================================================" echo " Application prête." echo " Backend : http://localhost:8080/api" echo " Frontend : http://localhost:4200 ← ouvre cette URL maintenant" echo "" echo " Au premier chargement, fais Ctrl+Shift+R pour vider le cache navigateur." echo " Vérif : dans la console DevTools, 'window.Zone' doit renvoyer un objet." echo "======================================================================" echo "" fi wait