SchotzIAD KM Tracker : suivi des trajets kilométriques (Angular + .NET 8)

Application complète de saisie et de suivi des trajets kilométriques avec
calcul de distance routière (OpenRouteService), barème kilométrique, résumés
et régularisation annuelle.

Backend (ASP.NET Core .NET 8, EF Core, SQLite) :
- Trajets (CRUD, réordonnancement, insertion), calcul de distance ORS avec
  fallback Haversine, géométrie d'itinéraire stockée par trajet, recalcul en masse.
- Profil, véhicules (avec dénomination), carnet d'adresses nommées, cache d'adresses.
- Barème kilométrique : tranches multiples par puissance fiscale, borne max
  exclusive avec 'illimité' (KmMax nullable), coefficient à 3 décimales,
  recopie du dernier barème connu.
- Résumés mensuel/annuel, montants réglés, régularisation, export PDF.

Frontend (Angular 22, zoneless + signals) :
- Consultation par jour, navigation temporelle synchronisée, carte Leaflet,
  formulaire de trajet (adresses nommées, domicile, autocomplétion BAN).
- Détection de changement zoneless (indépendante de zone.js).

Hébergement : Docker Compose (nginx + backend), scripts run-dev.sh / run-docker.sh.
This commit is contained in:
2026-09-14 02:08:27 +02:00
commit e3f946f7d4
225 changed files with 38168 additions and 0 deletions
@@ -0,0 +1,31 @@
using TrajetKmTracker.Api.Models.DTOs;
namespace TrajetKmTracker.Api.Services;
/// <summary>
/// Logique métier du profil utilisateur (singleton Id = 1) : lecture, sauvegarde avec
/// géocodage BAN de l'Adresse_Domicile et détermination de l'état de configuration (onboarding).
/// </summary>
public interface IProfilService
{
/// <summary>
/// Retourne le profil (singleton Id = 1). Crée l'enregistrement à la volée s'il est absent
/// afin de garantir qu'un profil vide soit toujours disponible à la lecture.
/// </summary>
Task<ProfilDto> GetProfilAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Sauvegarde le profil. Géocode l'Adresse_Domicile via la BAN : en cas de succès, stocke les
/// coordonnées et positionne <c>DomicileGeocode = true</c> (avec mise en cache de l'adresse) ;
/// en cas d'échec BAN, persiste l'adresse textuelle sans coordonnées et <c>DomicileGeocode = false</c>
/// sans lever d'exception (Requirements 10.2, 10.7, 10.8).
/// </summary>
Task<ProfilDto> SaveProfilAsync(SaveProfilDto dto, CancellationToken cancellationToken = default);
/// <summary>
/// Détermine l'état de configuration du profil (onboarding) :
/// <c>EstConfigure = true</c> si et seulement si un Profil existe avec un Nom ET un Prénom non vides
/// (après trim) ET qu'au moins un Véhicule existe (Property 31, Requirements 16.1, 16.2).
/// </summary>
Task<EtatProfilDto> GetEtatAsync(CancellationToken cancellationToken = default);
}