Application web/mobile complète pour rechercher et suivre les horaires des transports publics CFF (SBB) avec notifications temps réel des perturbations.
- Autocomplétion intelligente des gares avec debounce (300ms)
- Recherche flexible : départ ou arrivée
- Inversement rapide des gares
- Sélection date/heure intuitive
- Affichage de 5 connexions avec détails complets
- Polling automatique toutes les 45 secondes
- Détection des perturbations (retards, changements de voie)
- Notifications push Web/Capacitor
- Proposition automatique d'itinéraires alternatifs
- Deep-linking vers les détails de l'alternative
- Recherche : formulaire avec autocomplétion
- Résultats : liste des connexions avec toggle alertes
- Détails : itinéraire détaillé avec segments
- À bord : informations train + lecture vocale (TTS)
- Paramètres : préférences alertes et affichage
- ARIA live regions pour les annonces
- Labels explicites sur tous les contrôles
- Gestion du focus après recherche
- Taille de police ajustable (A+/A−)
- Contraste élevé (prefers-contrast: more)
- Navigation clavier complète (Enter, Tab)
- Synthèse vocale (Web Speech API)
- Installable sur mobile et desktop
- Mode hors-ligne basique
- Cache des icônes et assets
- Manifest avec icônes SBB
- Structure i18n prête
- Français (défaut) et Allemand
- Service de traduction avec pipe
t
- Angular 19 (standalone components)
- Ionic 8.5.3
- TypeScript 5.7 (strict mode)
- RxJS pour la réactivité
- API CFF : https://timetable.search.ch/api/
- PWA support
npm installnpm startL'application sera accessible sur http://localhost:4200
npm run buildBuild de production dans dist/
npm testCouverture attendue :
- Services & utils : ≥ 80%
- Composants critiques : ≥ 60%
npx playwright install --with-deps
npx playwright testScénarios couverts :
- Autocomplétion → recherche → résultats
- Toggle Départ/Arrivée
- Détection perturbation → notification → deep-link
- Paramètres : persistance et effet UI
- Onboard : TTS
L'application demande l'autorisation d'afficher des notifications pour alerter des perturbations.
Configuration :
- Chrome/Edge : Paramètres > Confidentialité > Notifications
- Firefox : Paramètres > Vie privée > Permissions > Notifications
- Safari : Préférences > Sites web > Notifications
Si packagée avec Capacitor, les permissions sont gérées automatiquement.
L'application utilise l'API publique CFF de timetable.search.ch :
- Completion :
/api/completion.fr.json?term={query} - Route :
/api/route.fr.json?from={from}&to={to}&date={dd.MM.yyyy}&time={HH:mm}&time_type={depart|arrival}&num=5&show_delays=1&show_trackchanges=1
- Pas de push temps réel : polling toutes les 45s
- Rate limiting : respecter les limites de l'API
- Pas de clé API requise
- Icônes et assets statiques
- Réponses completion (60s, stale-while-revalidate)
- Pas de cache des itinéraires (données temps réel)
- Ouvrir l'application dans un navigateur
- Cliquer sur "Installer" dans la barre d'adresse
- L'application apparaît comme une app native
- ✅ ARIA live regions :
aria-live="polite"sur résultats et alertes - ✅ Labels :
aria-labelsur tous les boutons et inputs - ✅ Focus management : focus automatique sur première carte résultat
- ✅ Taille police : ajustable de 0.8x à 1.5x (rem)
- ✅ Contraste : mode contraste élevé + classe
.contrast-more - ✅ Clavier : navigation Tab, Enter pour valider
- ✅ TTS : lecture vocale de l'itinéraire
- ✅ prefers-contrast : détection automatique
Utiliser axe DevTools pour audit automatique :
npx @axe-core/cli http://localhost:4200- Palette couleurs SBB officielle (rouge #ec0000)
- Ionic components pour UI cohérente
- Mode sombre supporté
- Responsive : mobile-first
- Icônes de transport (via Ionic Icons en remplacement des icônes SBB obsolètes)
src/
├── app/
│ ├── components/ # Composants réutilisables
│ │ └── sbb-mode-icon/ # Icônes transport
│ ├── pages/ # Pages de l'app
│ │ ├── search-page/
│ │ ├── result-page/
│ │ ├── connection-details/
│ │ ├── onboard/
│ │ └── settings/
│ ├── services/ # Services métier
│ │ ├── api/
│ │ ├── disruptions/
│ │ ├── notifications/
│ │ ├── i18n/
│ │ └── storage/
│ ├── utils/ # Fonctions utilitaires
│ ├── pipes/ # Pipes personnalisés
│ ├── interfaces/ # Types TypeScript
│ └── shared/ # Constantes partagées
├── i18n/ # Fichiers de traduction
└── theme/ # Styles globaux
Workflow automatique sur push/PR :
npm ci- Installation dépendancesnpm run build --prod- Build productionnpm test- Tests unitairesnpx playwright test- Tests E2E- Upload artifacts (dist/, coverage/, playwright-report/)
- dist/ : build de production
- coverage/ : rapports de couverture
- playwright-report/ : rapports E2E
completion(term, signal?): autocomplétion garesroute(params): recherche itinéraires
startMonitoring(params): lance le pollingstopMonitoring(): arrête le pollingdisruptionAlert$: observable des alertes
requestPermission(): demande permissionsshowNotification(title, body, data?): affiche notification avec deep-link
getSettings(): récupère les préférencesupdateAlertPrefs(prefs): met à jour alertesupdateUiPrefs(prefs): met à jour UI (applique immédiatement)
t(key, fallback?): traduit une clésetLanguage(lang): change la langue
iconKeyFromLeg(leg): détermine l'icône pour un trajetgetLegCode(leg): extrait le code lignegetLineType(leg): type de transport
formatDate(date): format dd.MM.yyyyformatTime(date): format HH:mmformatDuration(minutes): format Xh YmingetDurationMinutes(start, end): durée en minutes
- Fork le projet
- Créer une branche (
git checkout -b feature/amazing-feature) - Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Ouvrir une Pull Request
Ce projet est un exemple éducatif utilisant l'API publique CFF.
Pour toute question :
- Ouvrir une issue sur GitHub
- Consulter la documentation API : https://timetable.search.ch/api/help
- SBB CFF FFS pour l'API publique
- search.ch pour l'hébergement de l'API
- Angular et Ionic pour les frameworks
- Communauté open-source
Développé avec ❤️ pour les utilisateurs des transports publics suisses