Files
MadJax 09c24d5f59 UX consultation, trajets aller/retour et rafraîchissement des totaux
- Totaux : rafraîchissement immédiat du panneau (jour/mois/année + montant
  prévisionnel) après création/modification/suppression/réordonnancement d'un
  trajet, sans changer de jour (ViewChild + méthode publique rafraichir()).
- Trajets Aller/Retour : case à cocher au formulaire ; la distance comptée est
  doublée (distance simple stockée + booléen AllerRetour, distance effective
  utilisée dans tous les agrégats : totaux, résumés, barème, régularisation, PDF).
  Migration TrajetAllerRetour. Badge « A/R » dans une colonne dédiée en début de
  ligne pour garder date/adresses alignées.
- Mise en page de la page Trajets : vue à hauteur fixe où seule la liste défile ;
  colonne gauche figée (sélecteur de date + navigation, totaux, carte) et bande
  fixe (véhicule + bouton d'ajout) au-dessus de la liste. Layout applicatif global
  en pleine hauteur (app.component).
- run-dev.sh : chargement de la clé JWT depuis .env (ou secret de dev aléatoire) et
  Auth__FrontendBaseUrl sur le frontend dev ; rappel du lien de reset journalisé.

Build backend (solution) et frontend (production) OK.
2026-09-15 12:33:10 +02:00

144 lines
6.2 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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/SchotzIadKmTracker.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
# --- Authentification (dev) -------------------------------------------------
# Clé de signature JWT : lue depuis .env (JWT_SECRET_KEY). Si absente, on génère
# un secret ALÉATOIRE de développement (valable pour cette session). En dev, cela
# signifie que les sessions existantes sont invalidées à chaque relance du script,
# ce qui est acceptable ; en production, définis JWT_SECRET_KEY dans .env.
if [[ -z "${JWT__SecretKey:-}" ]]; then
JWT_KEY_FROM_ENV=""
if [[ -f "$RACINE/.env" ]]; then
JWT_KEY_FROM_ENV="$(grep -E '^JWT_SECRET_KEY=' "$RACINE/.env" | head -n1 | cut -d= -f2- || true)"
fi
# Ignore la valeur placeholder du .env.example si elle a été copiée telle quelle.
if [[ -n "$JWT_KEY_FROM_ENV" && "$JWT_KEY_FROM_ENV" != "change-me-generate-a-long-random-secret" ]]; then
export JWT__SecretKey="$JWT_KEY_FROM_ENV"
echo "→ Clé JWT chargée depuis .env."
else
# Secret de dev aléatoire (>= 32 octets) : openssl si dispo, sinon /dev/urandom.
if command -v openssl >/dev/null 2>&1; then
export JWT__SecretKey="$(openssl rand -base64 48)"
else
export JWT__SecretKey="$(head -c 48 /dev/urandom | base64)"
fi
echo "⚠ Aucune clé JWT dans .env : secret de développement aléatoire généré (sessions invalidées à chaque relance)."
fi
fi
# URL de base du frontend pour les liens de réinitialisation (dev = ng serve sur 4200).
export Auth__FrontendBaseUrl="${Auth__FrontendBaseUrl:-http://localhost:4200}"
# SMTP non configuré en dev : le lien de réinitialisation est journalisé dans la
# sortie du backend (repli LoggingEmailService). Cherche « reset-password?token= »
# dans les logs pour tester la réinitialisation sans email réel.
echo "→ Démarrage du backend sur http://localhost:8080 (base : $RACINE/backend/SchotzIadKmTracker.Api/trajets.db)"
dotnet run --project "$RACINE/backend/SchotzIadKmTracker.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 "SchotzIadKmTracker.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 " Auth : à la 1re utilisation, crée le compte via /register puis connecte-toi."
echo " Reset de mot de passe (dev) : le lien est journalisé dans la sortie backend"
echo " ci-dessus (cherche « reset-password?token= »), aucun email n'est envoyé."
echo "======================================================================"
echo ""
fi
wait