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,39 @@
using System.ComponentModel.DataAnnotations;
namespace TrajetKmTracker.Api.Models.Entities;
/// <summary>
/// Adresse enregistrée dans le Carnet_Adresses, identifiée par une Dénomination unique
/// et réutilisable par sa Dénomination lors de la saisie/insertion d'un Trajet.
/// </summary>
public class AdresseNommee
{
public int Id { get; set; }
/// <summary>Libellé libre et unique identifiant l'adresse (1 à 100 caractères).</summary>
[Required, MaxLength(100)]
public string Denomination { get; set; } = string.Empty;
/// <summary>
/// Forme normalisée de la Dénomination (trim + minuscules + sans accents) servant de clé
/// d'unicité via l'index unique UX_AdresseNommee_Denomination. Calculée par le backend.
/// </summary>
[Required, MaxLength(100)]
public string DenominationNormalisee { get; set; } = string.Empty;
/// <summary>Texte d'adresse résolu via l'autocomplétion BAN (1 à 255 caractères).</summary>
[Required, MaxLength(255)]
public string Adresse { get; set; } = string.Empty;
/// <summary>Latitude (précision 6 décimales) ; null si le géocodage a échoué.</summary>
public double? Latitude { get; set; }
/// <summary>Longitude (précision 6 décimales) ; null si le géocodage a échoué.</summary>
public double? Longitude { get; set; }
/// <summary>Vrai si les coordonnées ont été obtenues (cache ou BAN) ; faux sinon.</summary>
public bool GeocodageReussi { get; set; } = false;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}