Vécu projet : EVQuest (Tauri + React) Date : Mars 2026 Stack : Tauri v2, React 18, FastAPI, YAML config
Contexte
Au premier lancement, l'app détecte l'absence de configuration et guide l'utilisateur à travers un setup progressif avant d'accéder à l'interface principale.
Problème
Comment savoir si c'est le premier lancement ? Et comment guider l'utilisateur sans le submerger d'un formulaire géant ?
config.yaml absent ──→ Wizard
config.yaml présent + setup_completed: false ──→ Wizard
config.yaml présent + setup_completed: true ──→ Dashboard direct
Fichier de config : config.yaml (ou .json) dans le répertoire données utilisateur :
- Desktop Tauri/Electron :
%APPDATA%\AppName\(Windows),~/Library/Application Support/AppName/(macOS) - Web : BDD côté serveur (table
user_settings)
Solution
Principes UX
- Progressif — une étape à la fois, pas un formulaire géant
- Skippable — chaque étape optionnelle peut être ignorée (sauf la config critique)
- Découverte auto — pré-remplir tout ce qui peut l'être (détection de fichiers, système, etc.)
- Feedback visuel — barre de progression, état de chaque étape
- Réversible — pouvoir revenir en arrière
- Terminable — un endpoint explicite qui marque le setup comme complété
Flux type (adapté d'EVQuest)
Étape 1 : Découverte / Configuration source
→ Détection automatique + validation utilisateur
→ API : GET /discovery → PATCH /config/{type}
Étape 2 : Profil utilisateur
→ Infos essentielles, préférences de base
→ API : POST /profiles
Étape 3 : Import initial / Connexion
→ Première action concrète (import de données, connexion service...)
→ API : POST /import → GET /status (polling progression)
Étape finale : Complétion
→ Résumé de ce qui a été configuré
→ API : POST /setup/complete → setup_completed: true
→ Redirection vers le dashboard
Implémentation frontend (React)
// Pattern : state machine simple
type WizardStep = 'sources' | 'profile' | 'import' | 'complete';
function SetupWizard() {
const [step, setStep] = useState<WizardStep>('sources');
const [completed, setCompleted] = useState<Set<WizardStep>>(new Set());
// Navigation
const next = () => { /* marquer step comme completed, avancer */ };
const back = () => { /* reculer */ };
const skip = () => { /* marquer comme skipped, avancer */ };
return (
<div>
<ProgressBar steps={ALL_STEPS} current={step} completed={completed} />
{step === 'sources' && <SourcesStep onNext={next} onSkip={skip} />}
{step === 'profile' && <ProfileStep onNext={next} onBack={back} />}
{/* ... */}
</div>
);
}
Backend : endpoint de complétion
@router.post("/setup/complete")
async def complete_setup():
config = load_config()
config["setup_completed"] = True
save_config(config)
return {"status": "ok"}
Test du wizard
# Déclencher le wizard : supprimer/renommer le fichier config
# Windows desktop :
del %APPDATA%\AppName\config.yaml
# Vérifier :
# 1. Wizard s'affiche (pas le dashboard)
# 2. Chaque étape fonctionne indépendamment
# 3. Skip fonctionne sur les étapes optionnelles
# 4. Après "Terminer" → dashboard
# 5. Relancer → dashboard direct (pas de wizard)
Pourquoi
Un fichier config.yaml avec un flag setup_completed est préféré à un flag en BDD car la BDD n'existe peut-être pas encore au premier lancement (c'est justement le wizard qui peut la créer). Le wizard progressif (une étape à la fois) plutôt qu'un formulaire unique améliore le taux de complétion et permet la découverte automatique avant de demander des inputs manuels.
Points d'attention
- Crash pendant le wizard — le setup ne doit pas être marqué complété tant que l'utilisateur n'a pas explicitement terminé. Si l'app crash à l'étape 2, elle reprend à l'étape 2.
- Reset du wizard — prévoir un moyen (settings avancés ou CLI) pour relancer le wizard si l'utilisateur veut reconfigurer.
- Migration — si le format de config évolue entre versions, l'auto-migration doit gérer le cas
setup_completedcorrectement.
Dernière mise à jour : mars 2026