- Nouveau parametre global Precision_Distance (sous-menu Application de la Page_Parametrage, entre Compte et Vehicules), persiste via une entite singleton ParametresApplication, expose par GET/PUT /api/parametres-application - Arrondi superieur (ceiling) applique a l'affichage et aux agregats : trajet simple, aller/retour (arrondi puis doublement), totaux jour/mois/annee, carte, export PDF et bareme kilometrique - jamais a la distance brute stockee - Refonte du Montant_Previsionnel : le montant mensuel (80%) porte desormais sur le seul mois affiche (tranche determinee par le cumul annuel) ; nouvelle ligne Montant_Previsionnel_Annuel (100%, sans minoration, sur le cumul) - Backend : PrecisionDistanceService (ArrondirDistance), integration dans ResumeService/TotauxService/RemboursementService/MontantRegleService, migration EF Core ; 7 tests de propriete (FsCheck) + tests existants, 62/62 verts - Frontend : ParametresApplicationService (signal partage), composant de parametrage, fonction miroir arrondirDistance, adaptation de la liste des trajets, du panneau des totaux, de la carte et des montants regles - Specs : nouvelle spec precision-distances-km (requirements/design/tasks) ; mise a jour de requirements.md, design.md et design-requirements.md de schotziad-km-tracker (Requirement 22, renvois croises, Montant_Previsionnel) - Suppression du fichier chromium .deb suivi par erreur dans le depot
15 KiB
Implementation Plan: Précision des distances (km)
Overview
Cette implémentation ajoute un paramètre global Precision_Distance (0/1/2 décimales) avec arrondi supérieur (ceiling) systématique côté backend et frontend, refond le calcul du Montant_Previsionnel (mensuel recentré sur le mois affiché + nouveau montant annuel 100%), et propage la cohérence de l'arrondi à la liste des trajets, aux totaux, à la carte, à l'export PDF et au barème kilométrique.
L'ordre des tâches suit les dépendances réelles : entité + migration → service de précision pur → intégration dans les services d'agrégation existants → refonte du calcul prévisionnel → cohérence carte/PDF → tests backend → couche frontend (service/util → composant/route → consommateurs) → vérification finale.
Tasks
-
1. Backend — Entité
ParametresApplicationet migration EF Core- Créer
Models/Entities/ParametresApplication.cs(singletonId = 1,PrecisionDistanceKmdéfaut 2,UpdatedAt) - Ajouter
DbSet<ParametresApplication> ParametresApplicationet la configurationOnModelCreating(contrainte CHECKIN (0,1,2), cléValueGeneratedNever(), index unique singleton) dansData/AppDbContext.cs - Générer la migration EF Core (
dotnet ef migrations add AjoutParametresApplication) créant la table avec la contrainte CHECK - Requirements: 1.1, 1.2
- Créer
-
2. Backend — Service de précision et exception métier
- 2.1 Créer l'exception
Services/Exceptions/PrecisionDistanceInvalideException.cs(même modèle queMontantRegleNegatifException)- Requirements: 1.6
- 2.2 Créer
Services/IPrecisionDistanceService.cs(ObtenirAsync,DefinirAsync,ArrondirDistance)- Requirements: 1.1, 1.2, 1.3, 1.4, 1.6, 1.8, 3.1, 3.2, 3.3, 3.4, 3.5, 4.2
- 2.3 Implémenter
Services/PrecisionDistanceService.csGetOrCreateAsyncprivé créant la ligne singleton par défaut (2) si absenteObtenirAsync/DefinirAsyncavec validation stricte{0,1,2}levantPrecisionDistanceInvalideExceptionArrondirDistance:Ceiling(distance × 10^precision) / 10^precision- Requirements: 1.1, 1.2, 1.5, 1.6, 1.8, 3.1, 3.2, 3.3, 3.4, 3.5
- * 2.4 Écrire les tests de propriété pour
PrecisionDistanceService- Property 1: Arrondi supérieur exact et jamais inférieur à la distance brute — Validates: Requirements 3.1, 3.2, 3.3, 3.4, 3.5
- Property 4: Validation stricte de la précision — Validates: Requirements 1.6
- Property 5: Invariance de la distance brute stockée face à un changement de précision — Validates: Requirements 1.5, 1.8
- * 2.5 Écrire les tests unitaires
PrecisionDistanceServiceObtenirAsyncretourne 2 par défaut quand la table est vide (Exigence 1.2)DefinirAsync(3)lèvePrecisionDistanceInvalideException(Exigence 1.6, cas concret)- Requirements: 1.2, 1.6
- 2.1 Créer l'exception
-
3. Backend — DTOs et contrôleur
ParametresApplicationController- 3.1 Créer
Models/DTOs/ParametresApplicationDtos.cs(ParametresApplicationDto,SavePrecisionDistanceDto)- Requirements: 1.3, 1.4
- 3.2 Créer
Controllers/ParametresApplicationController.cs(GET/PUTapi/parametres-application, mappingPrecisionDistanceInvalideException→ 400)- Requirements: 1.3, 1.4, 1.6, 1.7
- 3.3 Enregistrer
IPrecisionDistanceService/PrecisionDistanceServicedansProgram.cs(AddScoped, section services métier)- Requirements: 1.1, 1.3, 1.4
- * 3.4 Écrire les tests d'intégration du contrôleur
PUT /api/parametres-applicationavecprecisionDistanceKm = 3retourne 400 (Exigence 1.6)GET/PUT /api/parametres-applicationsans jeton retourne 401 (Exigence 1.7)- Requirements: 1.3, 1.4, 1.6, 1.7
- 3.1 Créer
-
4. Checkpoint — Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
-
5. Backend — Intégration de l'arrondi dans les services d'agrégation existants
- 5.1 Modifier
Services/ResumeService.cs: injecterIPrecisionDistanceService, appliquerArrondirDistance(Distance, precision) × (AllerRetour ? 2 : 1)par trajet dansConstruireResumeMensuel, exposerTrajetDto.Distancedéjà arrondi, sommer les valeurs déjà arrondies pourTotalKmsans second arrondi- Requirements: 4.1, 4.2, 4.3, 5.2, 5.3
- 5.2 Modifier
Services/TotauxService.cs: injecterIPrecisionDistanceService, remplacer la fonction localeEffective(distance, allerRetour)par l'arrondi avant doublement, supprimer leMath.Round(..., 2, ...)final existant surTotalJour/TotalMois/TotalAnnuelPartiel- Requirements: 4.1, 4.2, 4.3, 5.1, 5.4
- 5.3 Modifier
Services/RemboursementService.cs: injecterIPrecisionDistanceService, construirekmMoisMapà partir des distances arrondies par trajet (au lieu de la distance brute), garantissanttotalKmAnnuelet chaqueKmMoiscomme sommes de distances déjà arrondies- Requirements: 4.1, 4.2, 4.3, 6.3, 6.4, 6.6
- * 5.4 Écrire le test de propriété pour la sommation
- Property 2: Arrondi avant doublement pour Aller_Retour — Validates: Requirements 4.1, 4.2, 4.3
- Property 3: Sommation de distances déjà arrondies sans arrondi supplémentaire — Validates: Requirements 5.1, 5.2, 5.3, 5.4
- * 5.5 Écrire le test unitaire de l'exemple chiffré Aller_Retour
- Cas 12.30 km, précision 0 → 26 km (et non 25 km), en plus de la Property 2
- Requirements: 4.2
- 5.1 Modifier
-
6. Backend — Refonte de
MontantRegleService.GetMontantPrevisionnelAsync- 6.1 Créer/modifier le DTO
MontantPrevisionnelDto(TotalMoisKm,TotalAnnuelPartielKm,MontantPrevisionnelMensuel,MontantPrevisionnelAnnuel) dansModels/DTOs/- Requirements: 6.1, 6.2, 7.1, 8.1, 8.2, 8.4
- 6.2 Modifier
Services/IMontantRegleService.csetServices/MontantRegleService.cs: injecterIPrecisionDistanceService, calculertotalMoisAffiche/totalAnnuelPartielà partir des distances arrondies, déterminer la tranche via le cumul annuel (baremeAnnuel), appliquer son coefficient/base au total du mois pourMontantPrevisionnelMensuel(80%), calculerMontantPrevisionnelAnnuel(100% sur le cumul)- Requirements: 6.1, 6.2, 6.6, 7.1, 7.2, 7.4, 8.1, 8.2, 8.5
- * 6.3 Écrire les tests de propriété pour le calcul prévisionnel
- Property 6: Montant_Previsionnel_Mensuel dépend uniquement du mois affiché — Validates: Requirements 7.1, 7.2
- Property 7: Montant_Previsionnel_Annuel égal au barème plein sur le cumul — Validates: Requirements 8.2, 8.5
- * 6.4 Écrire les tests unitaires de
GetMontantPrevisionnelAsync- Véhicule introuvable →
VehiculeNotFoundException(comportement existant inchangé) - Cas limite : trajets avec distance
nullignorés dans la somme - Requirements: 6.1, 6.2, 7.1, 8.1, 8.2
- Véhicule introuvable →
- 6.1 Créer/modifier le DTO
-
7. Backend — Cohérence carte et export PDF
- 7.1 Vérifier/corriger l'endpoint trajets/journée (
ITrajetService/TrajetsController, méthode consommée parTrajetService.getTrajetsJournee) pour renvoyer la Distance_Effective_Arrondie viaIPrecisionDistanceService- Requirements: 9.1, 9.4
- 7.2 Vérifier
Services/PdfService.cs(AssemblerModeleMensuelAsync, composition des tables mensuelle/annuelle) : confirmer qu'aucun recalcul de distance brute ne subsiste et que le modèle assemblé provient intégralement deIResumeService/IRemboursementServicedéjà corrigés- Requirements: 9.2, 9.3
- * 7.3 Écrire les tests de propriété de cohérence carte/PDF
- Property 8: Cohérence de l'infobulle carte avec la Distance_Effective_Arrondie — Validates: Requirements 9.1
- Property 9: Modèle de données PDF cohérent avec les résumés/régularisations — Validates: Requirements 9.2, 9.3
- * 7.4 Écrire le test d'intégration de cohérence croisée
- Scénario bout-en-bout (SQLite en mémoire) : créer des trajets sur plusieurs mois, changer Precision_Distance, vérifier l'égalité des valeurs entre
ResumeService,TotauxServiceetRemboursementService(Exigence 9.4) - Requirements: 9.4
- Scénario bout-en-bout (SQLite en mémoire) : créer des trajets sur plusieurs mois, changer Precision_Distance, vérifier l'égalité des valeurs entre
- * 7.5 Écrire les tests d'intégration de génération PDF
- Génération effective d'un PDF mensuel et d'un PDF annuel (1 exemple chacun), vérifier l'absence d'exception après les changements de modèle
- Requirements: 9.2, 9.3
- 7.1 Vérifier/corriger l'endpoint trajets/journée (
-
8. Checkpoint — Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
-
9. Frontend — Modèle, service et utilitaire d'arrondi
- 9.1 Créer
core/models/parametres-application.model.ts(ParametresApplication { precisionDistanceKm: number })- Requirements: 1.3, 1.4
- 9.2 Créer
core/services/parametres-application.service.ts(ParametresApplicationService: signal partagéprecisionDistance,charger(),definirPrecisionDistance())- Requirements: 1.3, 1.4, 2.3, 2.4, 2.5
- 9.3 Créer
shared/utils/arrondir-distance.ts(arrondirDistance,distanceEffectiveArrondie), miroir exact de la formule backend- Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 4.1, 4.2, 4.3, 5.5
- * 9.4 Écrire les tests unitaires de
arrondirDistance/distanceEffectiveArrondie- Cas 12.30 km, précision 0, aller-retour → 26 km (miroir du test backend)
- Cas limites par précision (0/1/2) et valeurs proches d'un seuil d'arrondi
- Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 4.1, 4.2, 4.3
- * 9.5 Mettre à jour
core/models/bareme.model.tsetcore/services/bareme.service.tsavec les nouveaux champsMontantPrevisionnel(totalMoisKm,totalAnnuelPartielKm,montantPrevisionnelMensuel,montantPrevisionnelAnnuel)- Requirements: 6.1, 7.1, 8.1, 8.2, 8.4
- 9.1 Créer
-
10. Frontend — Composant
ParametresApplicationComponentet route/menu- 10.1 Créer
features/parametres-application/parametres-application.component.ts(+.html,.scss) : sélection 0/1/2, présélection de la valeur courante, confirmation de succès, restauration + notification d'erreur en cas d'échec- Requirements: 2.2, 2.3, 2.4, 2.5
- 10.2 Ajouter la route
/parametrage/applicationdansapp.routes.ts, entrecompteetvehicules, gardée uniquement parauthGuard(pasprofilConfigureGuard)- Requirements: 2.1, 2.6
- 10.3 Ajouter le lien « Application » entre « Compte » et « Véhicules » dans
features/parametrage/parametrage.component.html- Requirements: 2.1
- * 10.4 Écrire les tests unitaires du composant
ParametresApplicationComponent- Présélection de la valeur courante au chargement (Exigence 2.3)
choisir()restaure la sélection précédente et notifie une erreur si l'appel HTTP échoue (Exigence 2.5)- Requirements: 2.3, 2.4, 2.5
- * 10.5 Écrire le test de structure du menu de paramétrage
- Vérifier le positionnement du lien « Application » entre « Compte » et « Véhicules »
- Requirements: 2.1
- 10.1 Créer
-
11. Frontend — Chargement initial dans
AppComponent- 11.1 Modifier
app.component.tspour appelerParametresApplicationService.charger()au même moment que le chargement du profil (effect déclenché à l'authentification)- Requirements: 1.3, 5.5
- 11.1 Modifier
-
12. Checkpoint — Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
-
13. Frontend — Adaptation des composants consommateurs
- 13.1 Modifier
features/trajet-list/trajet-list.component.ts(méthodedistanceAffichee) : formater selonParametresApplicationService.precisionDistance()au lieu d'un arrondi fixe à 2 décimales- Requirements: 3.1, 3.2, 3.3, 3.4, 3.5
- 13.2 Modifier
features/panneau-totaux/panneau-totaux.component.ts+.html: format dynamique des distances basé surprecisionDistance(), ajout de la ligne « Montant prévisionnel annuel » sous l'indication de versement mensuelle, consommation demontantPrevisionnelMensuel/montantPrevisionnelAnnuel- Requirements: 5.4, 5.5, 8.1, 8.3, 8.4
- 13.3 Modifier
features/carte-trajets/carte-trajets.component.ts(méthodecontenuInfobulle) :toFixed(precision)dynamique basé surParametresApplicationService.precisionDistance()- Requirements: 9.1
- 13.4 Modifier
features/montants-regles/montants-regles.component.ts: liremontantPrevisionnelMensuelau lieu demontantPrevisionnel- Requirements: 7.1, 7.3
- * 13.5 Écrire les tests unitaires des composants adaptés
TrajetListComponent.distanceAfficheeformate selon la précision courantePanneauTotauxComponentaffiche la nouvelle ligne « Montant prévisionnel annuel »CarteTrajetsComponent.contenuInfobulleutilise la précision couranteMontantsReglesComponentaffichemontantPrevisionnelMensuelsans erreur de liaison après le renommage du DTO- Requirements: 3.1, 5.4, 7.1, 7.3, 8.1, 8.3, 8.4, 9.1
- 13.1 Modifier
-
14. Checkpoint final — Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
-
15. Vérification finale
- 15.1 Exécuter le build backend (
dotnet build) et le build frontend (ng build/npm run build), corriger toute erreur de compilation résultant des changements de DTO/modèle- Requirements: 1.1–9.4 (non-régression globale)
- 15.2 Exécuter l'ensemble des tests backend (
dotnet test) et frontend (ng test/vitest --run), vérifier que toutes les propriétés et tous les tests unitaires/intégration passent- Requirements: 1.1–9.4 (non-régression globale)
- 15.1 Exécuter le build backend (
Notes
- Les tâches marquées
*sont optionnelles (tests) et peuvent être ignorées pour un MVP plus rapide, mais restent recommandées vu la présence de 9 Correctness Properties dans le design. - Chaque tâche référence les exigences granulaires concernées pour la traçabilité.
- Les checkpoints garantissent une validation incrémentale avant de passer à la couche suivante (backend cœur → calcul prévisionnel → cohérence carte/PDF → frontend).
- Les tests de propriété utilisent FsCheck (déjà présent dans
SchotzIadKmTracker.Tests.csproj), avec au moins 100 itérations par propriété et le tag de traçabilité// Feature: precision-distances-km, Property {n}: {texte}. - La tâche 6.2 constitue une rupture de contrat mineure sur
MontantPrevisionnelDto: les tâches frontend 9.5 et 13.4 doivent être réalisées après la tâche 6.1 pour rester synchronisées avec les nouveaux noms de champs.
Task Dependency Graph
{
"waves": [
{ "id": 0, "tasks": ["1"] },
{ "id": 1, "tasks": ["2.1"] },
{ "id": 2, "tasks": ["2.2"] },
{ "id": 3, "tasks": ["2.3"] },
{ "id": 4, "tasks": ["2.4", "2.5", "3.1"] },
{ "id": 5, "tasks": ["3.2"] },
{ "id": 6, "tasks": ["3.3"] },
{ "id": 7, "tasks": ["3.4"] },
{ "id": 8, "tasks": ["5.1", "5.2", "5.3"] },
{ "id": 9, "tasks": ["5.4", "5.5", "6.1"] },
{ "id": 10, "tasks": ["6.2"] },
{ "id": 11, "tasks": ["6.3", "6.4", "7.1"] },
{ "id": 12, "tasks": ["7.2"] },
{ "id": 13, "tasks": ["7.3", "7.4", "7.5"] },
{ "id": 14, "tasks": ["9.1"] },
{ "id": 15, "tasks": ["9.2"] },
{ "id": 16, "tasks": ["9.3", "9.5"] },
{ "id": 17, "tasks": ["9.4", "10.1"] },
{ "id": 18, "tasks": ["10.2", "10.3"] },
{ "id": 19, "tasks": ["10.4", "10.5", "11.1"] },
{ "id": 20, "tasks": ["13.1", "13.2", "13.3", "13.4"] },
{ "id": 21, "tasks": ["13.5"] },
{ "id": 22, "tasks": ["15.1"] },
{ "id": 23, "tasks": ["15.2"] }
]
}