Gestionnaire d'enclos de dragodinde (dofus 3 unity)
Go to file
POL Mickaël 3e485fd09b chore: normalise fins de ligne CRLF → LF dans tout le repo
Applique .gitattributes sur tous les fichiers existants.
Élimine les différences fantômes entre WSL et Windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 08:55:10 +02:00
docs chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
ntfy-redirect chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
src chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
tests chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
.gitattributes chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
.gitignore chore: gitignore refonte_graphique/ et .claude/ 2026-04-06 07:46:41 +02:00
algorithmes.md chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
CHANGELOG.md chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
CLAUDE.md chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
findings.md chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
icon.ico feat: infrastructure Electron + persistence + electron-updater 2026-04-06 05:43:04 +02:00
icon.png feat: infrastructure Electron + persistence + electron-updater 2026-04-06 05:43:04 +02:00
package-lock.json rename: Minuteur Dragodinde → Obsidienne 2026-04-06 07:34:07 +02:00
package.json rename: Minuteur Dragodinde → Obsidienne 2026-04-06 07:34:07 +02:00
playwright.config.ts chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
progress.md chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
README.md fix: double cercle blanc inventaire + nettoyage projet 2026-04-06 08:43:20 +02:00
task_plan.md chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
tsconfig.json chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
vite.config.ts chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00
vitest.config.ts chore: normalise fins de ligne CRLF → LF dans tout le repo 2026-04-06 08:55:10 +02:00

⚔ Obsidienne — Élevage Dragodinde (Dofus 3)

Application desktop Windows de gestion d'élevage de Dragodindes pour Dofus 3. Construite avec Electron + Vite + TypeScript en architecture DDD hexagonale.

🔗 Repo : https://gitea.mickael-pol.fr/mickael/dd-timer

Fonctionnalités

Élevage & Timers

  • 🐦 Gestion de 6 enclos indépendants avec jusqu'à 10 Dragodindes chacun
  • Timer en temps réel avec calcul automatique par tier de jauge (1→4)
  • 🐉 6 jauges : Baffeur, Caresseur, Foudroyeur, Abreuvoir, Dragofesse, Mangeoire (XP)
  • 🔄 Recharge de jauge en cours de session avec recalcul multi-segments
  • 🎯 Cibles sérénité et niveau par Dragodinde avec ETA en temps réel
  • 🖱 Drag & drop des enclos et des Dragodindes pour les réordonner

Reproduction

  • 💕 Accouplement — sélection des parents avec déduction automatique du bébé (63 races créables)
  • 🔬 Réapprovisionnement — arbre de reproduction avec genres ♂/♀ et inversions
  • 📦 Inventaire — stock ♂/♀ par race avec simulation proportionnelle multi-générations
  • 🔀 Workflows — plans de reproduction sauvegardables avec export/import sélectif

Statistiques & Dashboard

  • 📊 Dashboard — vue d'ensemble multi-enclos avec KPIs globaux
  • 📈 Statistiques — naissances par jour, répartition par race/génération, taux de réussite, meilleurs couples, races manquantes, activité par jour de la semaine
  • 🔍 Filtres de période — 7j, 14j, 30j, 3 mois, tout l'historique avec comparaison delta

Notifications & Paramètres

  • 🔔 Notifications natives Windows même application en arrière-plan
  • 📱 Notifications mobiles via ntfy (serveur self-hosted) avec QR codes de configuration
  • 🔊 4 sons d'alarme au choix (Arpège, Pulsation, Fanfare, Cloche)
  • Mise à jour automatique via Gitea Releases
  • 💾 Sauvegarde automatique locale

Design

  • 🎨 Design system Obsidienne — glassmorphism, Material Design 3, Material Symbols Outlined
  • 🌙 Interface sombre avec thème violet/gaming

Installation (utilisateurs)

  1. Télécharger Obsidienne Setup x.x.x.exe depuis la section Releases
  2. Clic droit → Propriétés → cocher "Débloquer" → OK (important, une seule fois)
  3. Double-cliquer pour lancer l'installation
  4. L'app apparaît dans le menu Démarrer et sur le Bureau

Si Windows affiche "Application inconnue" : cliquer "Informations complémentaires" → "Exécuter quand même"

Build (développeurs)

Prérequis

Commandes

npm install       # Installer les dépendances
npm start         # Dev (Vite + Electron)
npm test          # Tests unitaires (Vitest, depuis Windows)
npm run test:e2e  # Tests E2E (Playwright + Electron)
npm run build     # Build (Vite + electron-builder → NSIS installer)

L'installeur est généré dans dist/.

Tests

Tests unitaires, fonctionnels et régression

366 tests via Vitest — couverture de code 94% (v8).

npm test                # Lancer tous les tests
npm run test:watch      # Mode watch
npm run test:coverage   # Avec rapport de couverture
Couche Fichiers Tests Statements Branches Functions Lines
Domain 14 165 94100% 80100% 92100% 85100%
Application 3 128 92100% 76100% 100% 96100%
Infrastructure 2 19 100% 100% 100% 100%
Presentation 3 36
Régression 9 48
Fonctionnel 3 8

La couche Presentation est testée avec happy-dom pour Toast, ConfirmModal et UndoManager.

Tests E2E

24 tests E2E via Playwright + Electron.

npm run build && npm run test:e2e
Suite Tests Couverture
Navigation sidebar 8 Tableau de bord, statistiques, enclos, accouplement, réappro, inventaire, workflows, paramètres
Cycle de vie du timer 4 Activation jauge, démarrage, pause/reprise, reset
Recharge de jauge 2 Mise à jour "Alarme dans" et barre de jauge en temps réel
Workflow d'accouplement 5 Sélection parents, résultat bébé, enregistrement, filtres, recherche
Persistance 1 Survie des données après fermeture/réouverture
UI Feedback 4 Toast, ConfirmModal, Undo via toast

Sécurité et qualité

Les tests incluent des vérifications de :

  • Sécurité XSSesc() <20><>chappe correctement <, >, ", &
  • Sécurité import — validation structurelle complète des données importées (14 cas)
  • Validation HTTPS — rejet des URLs non-HTTPS pour ntfy
  • Protection textContent — Toast et ConfirmModal utilisent textContent (pas innerHTML)

⚠ Les tests doivent être lancés depuis un terminal Windows (pas WSL) — les bindings natifs Electron ne fonctionnent pas en WSL.

Publier une nouvelle version

L'application utilise electron-updater avec un fichier latest.yml pour la mise à jour automatique. Ce fichier est généré automatiquement par electron-builder lors du build et contient la version, le nom du fichier et le hash sha512.

# 1. Modifier la version dans package.json ("version": "1.x.x")
# 2. Build l'application
npm run build
# → Génère dans dist/ :
#   - Obsidienne Setup 1.x.x.exe
#   - latest.yml  (version + sha512, requis par electron-updater)

# 3. Committer et tagger
git add .
git commit -m "v1.x.x - description"
git tag v1.x.x
git push && git push --tags

# 4. Sur Gitea : Releases → Nouvelle release → tag v1.x.x
#    Attacher les 2 fichiers :
#    - Obsidienne Setup 1.x.x.exe
#    - latest.yml

Important

: le fichier latest.yml est obligatoire dans la release Gitea. Sans lui, electron-updater ne peut pas vérifier ni télécharger la mise à jour. L'app vérifie les mises à jour au démarrage (après 3s) via l'API Gitea Releases, puis pointe electron-updater vers le tag de la release pour lire latest.yml.

Architecture

src/
├── domain/          — Entités, value objects, services purs (aucune dépendance)
├── application/     — CommandBus/QueryBus, commandes et requêtes (CQRS)
├── infrastructure/  — LocalStorage, Electron IPC, notifications, audio
└── presentation/    — Composants UI, helpers live, styles CSS, état UI

Changelog

v1.1.6

Architecture

  • 🏗 Refonte architecture DDD hexagonale — migration complète du monolithe index.html vers une architecture en couches (domain / application / infrastructure / presentation) avec Vite + TypeScript + Vitest
    • Domain : entités (Enclos, Dragodinde), value objects (GaugeType, Tier, XpTable, Race), services purs (GaugeCalculator, BreedingService)
    • Application : CQRS — CommandBus, QueryBus, 15+ commandes, 8+ requêtes
    • Infrastructure : LocalStorageRepository, ElectronNotification, WebAudioAlarm
    • Presentation : composants TypeScript, helpers live, CSS modulaire
    • Tests : suites unitaires, fonctionnelles et de régression (Vitest)

Design Obsidienne

  • 🎨 Refonte graphique complète "Obsidienne" — nouveau design system glassmorphism avec tokens Material Design 3, polices Manrope/Inter/Plus Jakarta Sans
    • obsidienne.css (~4500 lignes) : feuille de styles MD3 complète, 37+ variables CSS tokens
    • Material Symbols Outlined : migration de tous les emojis vers des icônes vectorielles
    • Sidebar : logo, sections organisées (Principal, Enclos, Outils), pastille de statut timer, Paramètres dans le footer
    • App Shell : layout app-shell (sidebar + main-area), header hamburger
    • Dashboard : grille KPI (bébés, DD actives, couples, taux de réussite, races)
    • EnclosView : barres de jauge visuelles avec gradient par tier, bouton timer Material
    • DragodindeCard : stats avec icônes Material, jauge XP (niveau + % + ETA)
    • Accouplement : layout single-page (Parent 1 | Coeur+inputs | Parent 2 + grille de races), glassmorphism, chips génération, drag & drop
    • Réapprovisionnement : arbre de reproduction redesigné avec cartes glassmorphism
    • Inventaire : grille de stock ♂/♀ redesignée, simulateur avec résultats visuels
    • Workflows : cartes workflow avec barres de progression, export/import sélectif
    • Statistiques : écran complet avec graphiques, donut, heatmap, avatars de races
    • Paramètres : cartes son avec sélection visuelle, toggle notifications, modal ntfy redesignée
    • UpdateBanner : aligné sur le design MD3

Nouvelles fonctionnalités

  • Toast notifications — feedbacks visuels success/error en bas à droite avec glassmorphism, auto-dismiss (3s/5s/10s), bouton d'action optionnel (ex: Annuler)
  • Modale de confirmation glassmorphism — remplace tous les confirm() et alert() natifs par une modale stylisée, clic extérieur = annulation
  • Undo actions destructives — snapshot/restore 1 niveau avec expiration 10s, bouton Annuler dans le toast + raccourci Ctrl+Z
  • Backup/export global — export JSON avec métadonnées (app, version, date), import avec validation et confirmation, accessible depuis Paramètres
  • Écran Statistiques — naissances par jour (barres), répartition des races (donut), naissances par génération, activité par jour de la semaine (heatmap), taux de réussite par race, meilleurs couples (top 10), races manquantes groupées par génération, détail par race
  • Filtres de période sur les statistiques — 7j, 14j, 30j, 3 mois, tout l'historique avec comparaison delta (+/) par rapport à la période précédente
  • Export/Import de workflows — sélection individuelle ou globale, dialogue natif Windows, import avec déduplication des IDs
  • Drag & drop accouplement — cartes de race glissables vers Parent 1 / Parent 2, feedback visuel et vérification de compatibilité
  • Images des dragodindes (66 races en base64) sur tous les écrans
  • Barres de recherche sur accouplement, réapprovisionnement, inventaire et workflows
  • Sauvegarde de workflow depuis les résultats de réappro et d'inventaire
  • Simulation proportionnelle inventaire — allocation dynamique multi-générations
  • Filtres par génération sur les workflows + mises à jour en temps réel
  • Numérotation smart des enclos — comble les trous lors de la création

Timer & Jauges

  • Calcul de jauge multi-segments — gère les recharges intermédiaires et le gel au cap absolu
  • Recharge de jauge en cours de session — bouton rechargement avec snapshot { atSec, level }
  • Session timer robuste — continue en temps réel après complétion automatique
  • Alarme unique — se déclenche une seule fois quand toutes les cibles sont atteintes
  • Détection de complétion via setInterval — fonctionne même en arrière-plan
  • Jauges débloquées après session — sélection de nouvelles jauges avant la session suivante
  • Commande nouvelle-fournee — réinitialise timer + jauges + DD
  • ETA niveau 200 — barre de progression et pourcentage en temps réel
  • Boutons reset cibles — réinitialise sérénité ou niveau depuis la card DD

Corrections

  • 🐛 Recette Ebène — parents inversés corrigés
  • 🐛 Simulation inventaire — algorithme glouton → allocation proportionnelle
  • 🐛 Dirty flag — le rAF loop ne reconstruit plus le DOM inutilement
  • 🐛 Persistance inventaireupdate-settings gère le champ inventaire
  • 🐛 Baffeur/Caresseur — exclusion mutuelle, contrainte de signe sur cible sérénité
  • 🐛 Sons d'alarme — fréquences corrigées, bouton Test fonctionnel via WebAudio
  • 🐛 CSP — ajout img-src data: et https://api.qrserver.com
  • 🐛 Statistiques — les races Gen 1 (Rousse, Dorée, Amande) ne sont plus comptées car non créables (63 races au lieu de 66)
  • 🐛 Export workflows — dialogue de sauvegarde pointe vers Documents par défaut
  • 🐛 Sidebar footer — corrigé le footer masqué par la barre des tâches Windows (calc(100vh / 1.15) pour compenser le zoom global)
  • 🐛 Notifications ntfy — migration de l'API headers vers l'API JSON pour le support UTF-8 (corrige les caractères accentués "pr?tes" → "prêtes")
  • 🐛 Redémarrage timer — empêche le redémarrage d'un timer quand toutes les cibles sont déjà atteintes (évite l'alarme en boucle après complétion)
  • 🐛 Nouvelle fournée — le bouton n'apparaît que si toutes les DD ont 20000 en maturité, endurance et amour
  • 🐛 Timer jauges vides — interdit le démarrage du timer quand toutes les jauges actives sont à 0
  • 🐛 Jauge vide en cours de session — affichage ∞ dans le countdown, alerte visuelle "⚠ Rechargez la jauge" avec animation pulsante, badge jauge vide sur le dashboard
  • 🐛 Recharge jauge temps réel — le countdown "Alarme dans" et les stats se mettent à jour en temps réel pendant la saisie (event input en plus du blur), avec consolidation des recharges proches (< 2s) pour éviter la pollution du tableau
  • 🐛 Recharge en pause — les recharges de jauge sont maintenant acceptées quand le timer est en pause (pas uniquement pendant l'exécution)

Sécurité & Robustesse

  • 🔒 Sandbox Electronsandbox: true dans webPreferences pour isoler le renderer
  • 🔒 HTTPS forcé pour ntfy — rejet des URLs HTTP, seules les connexions chiffrées sont acceptées
  • 🔒 Suppression de executeJavaScript — badge DEV migré vers IPC sécurisé (dev-mode)
  • 🔒 Validation structurelle import — vérification complète du schéma (id, name, dragodindes, gaugeLevels, timer) avant import
  • 🔒 Sanitisation XSSesc() sur toutes les données utilisateur + textContent dans Toast/ConfirmModal
  • 🛡 try/catch sur tous les appels electronAPI — export, import, workflows (plus de crash silencieux)
  • 🛡 Erreurs de sauvegarde loggéesLocalStorageRepository.save() ne masque plus les erreurs
  • 🛡 Promesse Sidebar catchéegetVersion() ne génère plus d'erreur non gérée
  • 🛡 Nettoyage Ctrl+Z listenerremoveEventListener dans destroy() pour éviter les memory leaks
  • 🛡 Toast stale container — protection isConnected contre les conteneurs DOM détachés

UI

  • 🐛 Double cercle blanc inventaire — les images de dragodindes dans l'inventaire utilisent maintenant le même style carré arrondi que l'accouplement et le réappro

Renommage

  • 🏷 Renommage "Minuteur Dragodinde" → "Obsidienne" — nouveau nom d'application, raccourcis, titre, tray, notifications
  • 🔄 Migration automatique des données — copie transparente du fichier de sauvegarde depuis l'ancien dossier %APPDATA%\Minuteur Dragodinde\ au premier lancement
  • 🔄 GUID NSIS fixe — l'installeur reconnaît l'ancienne version et la remplace proprement (pas de doublon)
  • 🔄 Rétrocompatibilité import — les backups exportés avec app: 'minuteur-dragodinde' restent importables

Nettoyage

  • 🗑 Suppression scripts build.bat / build.ps1npm run build suffit
  • 🗑 Suppression maquettes graphiques du suivi Git (refonte_graphique/)

Technique

  • Migration electron-updater — vérification sha512 via latest.yml, installation NSIS native, restart auto
  • 🎨 Icône Windows native — migration icon.pngicon.ico
  • 🧪 366 tests (unitaires, fonctionnels, régression, sécurité) — couverture 94% via Vitest + v8
  • 🧪 24 tests E2E Playwright + Electron — navigation, timer, recharge jauge, accouplement, persistance, toast, modale de confirmation, undo

v1.1.5

  • Onglet Accouplement — selection des 2 parents, deduction automatique du bebe, saisie du nombre de couples et bebes obtenus pour alimenter les statistiques globales
  • Sidebar navigation — menu hamburger avec panneau lateral overlay (Dashboard, Enclos, Accouplement, Reappro, Inventaire, Workflows, Parametres)
  • Onglet Parametres — son d'alarme, notifications PC et mobile regroupes dans une vue dediee accessible via la sidebar
  • Reappro ♂/♀ — chaque etape de l'arbre affiche les genres necessaires (♂/♀) avec toggle d'inversion par croisement
  • 🎨 Statistiques globales integrees au Dashboard (bebes, couples, taux de reussite, races obtenues)
  • 🎨 Onglets horizontaux simplifies — seuls Dashboard et Enclos restent, le reste est dans la sidebar
  • 🔧 Retrait du systeme de bebes des enclos — les accouplements se font desormais via l'onglet dedie
  • 🔧 Migration automatique des donnees bebes existantes vers les statistiques archivees
  • 🗑 Suppression de l'onglet Statistiques (donnees conservees dans le Dashboard)

v1.1.4

  • Cible serenite par DD — champ cible avec ETA en temps reel (calcul automatique baffeur/caresseur necessaire)
  • Cible niveau par DD — champ cible avec ETA en temps reel (modele XP lineaire base sur le tier de la mangeoire)
  • Inventaire ♂/♀ — saisie du nombre de males et femelles par race dans l'inventaire
  • Contraintes de genre — le calcul d'inventaire respecte la regle ♂+♀ obligatoire (plus de croisement ♂+♂ ou ♀+♀)
  • Bouton "Reinitialiser l'inventaire" — remet a zero tous les stocks de DD (avec confirmation native)
  • Affichage du sexe des parents — les resultats de croisement indiquent quel parent est ♂ et lequel est ♀
  • 🎨 Serenite et XP reintegrees dans la barre de pills (comme endurance, amour, etc.)
  • 🎨 Lignes dediees cible + ETA pour serenite et niveau sous les pills
  • 🎨 Badges compacts pour les noms de jauges longs (baffeur, caresseur, mangeoire) sur les cartes DD
  • 🎨 Zone de clic elargie sur les inputs ♂/♀ de l'inventaire
  • 🎨 Padding et espacement corriges sur les cartes inventaire
  • 🔧 Correction timer XP incorrect — affichait ~23h au lieu du temps reel
  • 🔧 Correction defocus input reproducteur — l'input perdait le focus car oninput declenchait un rebuild DOM
  • 🔧 Correction bebes produits — les bebes issus de croisements sont maintenant neutres (sexe inconnu) au lieu d'etre assignes ♂/♀ arbitrairement
  • Cache DOM gel() — les ~500+ appels getElementById par tick passent par un cache Map
  • Verification de mise a jour uniquement au demarrage (suppression du check toutes les heures)

v1.1.3

  • Reinitialisation des statistiques — bouton dans l'onglet Statistiques pour remettre a zero tous les bebes, historiques et stats archivees (avec confirmation)
  • Inputs intelligents — les champs numeriques se vident au clic pour saisir facilement, et restaurent la valeur precedente si rien n'est change
  • 🔧 Correction "vider l'enclos" / "nouvelle fournee" / "supprimer enclos" — remplacement de confirm() par un dialogue natif Electron pour corriger le bug qui rendait tous les inputs inutilisables
  • 🔧 Correction du bug "enclos vide" — apres avoir vide un enclos ou lance une nouvelle fournee, une dragodinde est automatiquement ajoutee et les inputs restent editables
  • 🔧 Correction "nouvelle fournee" — ne vide plus l'historique de session des bebes, seul "vider l'enclos" le fait
  • 🔧 Correction des statistiques globales — supprimer un enclos conserve desormais ses stats dans les statistiques globales (archivage automatique)
  • 🔧 Correction du bouton "Quitter" — utilisation de process.exit() pour forcer l'arret complet du processus

v1.1.2

  • 💾 Sauvegarde persistante — les donnees sont maintenant sauvegardees dans un fichier JSON, plus de perte de statistiques apres une mise a jour
  • Dialogue de fermeture — cliquer sur la croix propose de minimiser en arriere-plan ou de quitter completement

v1.1.1

  • 🔧 Correction de la mise a jour automatique — l'app se relance maintenant toute seule apres installation
  • 🔧 Correction de l'affichage du titre des notifications ntfy (encodage base64 supprime)

v1.1.0

  • 📱 Notifications mobiles (ntfy) — Alerte sur telephone quand un enclos est pret, via serveur ntfy self-hosted
    • Modale de configuration avec QR code pour installer l'app ntfy (Play Store / App Store)
    • QR code d'abonnement automatique via page de redirection (ntfy-redirect)
    • Bouton de test des notifications
    • Envoi via le processus principal Electron (pas de CORS)
  • 🐣 Systeme de bebes — Ajout de bebes dragodindes issus de la reproduction dans chaque enclos
    • Modale de selection par generation et race avec images
    • Historique des bebes par enclos
  • 📊 Onglet Statistiques — Vue globale de l'elevage avec KPIs, repartition par race, et progression par enclos
  • 🖱 Drag & drop des onglets d'enclos pour les reordonner
  • 🐉 Images des dragodindes par race avec couleurs par generation
  • 📝 Sous-onglets par enclos (Elevage / Historique bebes)
  • 🔧 Mode DEV — Donnees isolees et badge DEV visible quand lance avec npm start
  • Mise a jour automatique via Gitea Releases avec banniere de progression dans l'interface
  • 🔧 Correction de l'identifiant applicatif (fr.mickael-pol.obsidienne)
  • 🔧 Masquage des spinners natifs sur les champs numeriques

v1.0.0

  • Version initiale

Mentions légales

Dofus et Dragodinde sont des marques déposées d'Ankama Games. Cette application est un projet non officiel, développé par un fan. Elle n'est ni affiliée, ni approuvée, ni sponsorisée par Ankama Games.

Les icônes utilisent Material Symbols (Apache 2.0). Les polices proviennent de Google Fonts (OFL).