- Dart 51%
- Go 42.9%
- Nix 2.5%
- HTML 1%
- JavaScript 0.9%
- Other 1.7%
| app | ||
| nix | ||
| .envrc | ||
| .gitignore | ||
| AGENTS.md | ||
| flake.lock | ||
| flake.nix | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| main_test.go | ||
| Makefile | ||
| mcp.go | ||
| mcp_test.go | ||
| prixdugaz.svg | ||
| push.go | ||
| push_test.go | ||
| README.md | ||
prixdugaz.ca
Carte des prix de l'essence au Québec — Flutter + PocketBase.
Ce projet utilise le stack FluBase (Flutter + PocketBase). L'ancien
stack Go+htmx+Leaflet est conservé dans la branche v1 à titre de
référence historique.
Stack
- Backend : Go 1.26+ avec PocketBase
embarqué comme package Go. Cron 5 min qui rapatrie le GeoJSON de
la Régie de l'énergie du Québec et alimente une collection
stations(lecture publique). - Frontend : Flutter 3.41+,
flutter_map(OpenStreetMap, sans clé API), client REST minimal pour PocketBase. Cible web d'abord, mobile-friendly par construction (même codebase Android/iOS). - Source de données : Régie de l'énergie Québec (GeoJSON gzip, 2458 stations, mis à jour plusieurs fois par jour).
Démarrage rapide
# Entrer dans le shell de dev (Go, Flutter, Android SDK)
nix develop
# ou, si direnv est installé :
direnv allow
# Backend
CGO_ENABLED=0 go run . # écoute sur :8090
# Dans un autre terminal :
cd app
flutter pub get
flutter run -d web-server --web-port=8080
Ouvrir http://localhost:8080. La carte s'initialement centrée sur le Québec, charge les ~2450 stations à l'ouverture, et affiche un marqueur étiqueté du prix régulier à chaque station.
Cibles
- Web :
flutter run -d web-server(par défaut) ouflutter build webpour un bundle statique. - Android : depuis le shell nix,
flutter run -d android. Sur un émulateur, le backend tourne sur la machine hôte — utiliser10.0.2.2au lieu delocalhost:--dart-define=API_BASE_URL=http://10.0.2.2:8090. - iOS : pas encore configuré. À venir.
Variables d'environnement / --dart-define
| Côté | Variable / flag | Défaut |
|---|---|---|
| Backend | PD_DATA_DIR (PocketBase data dir) |
./pb_data |
| Backend | --http=HOST:PORT (PB CLI flag) |
127.0.0.1:8090 |
| Frontend | --dart-define=API_BASE_URL=... |
http://localhost:8090 |
Endpoints utiles
| Chemin | Description |
|---|---|
GET /api/collections/stations/records?page=1&perPage=500 |
Liste paginée des stations |
GET /api/health |
Santé du backend |
GET /_/ |
UI d'admin PocketBase |
POST /mcp |
Serveur MCP public (voir ci-bas) |
Le compte admin PocketBase se crée au premier accès à /_/.
L'agent n'a pas ces identifiants et ne les crée pas.
Serveur MCP public
Le backend expose un serveur MCP
(Model Context Protocol) public en lecture seule à /mcp (transport
« streamable HTTP », sans état, sans authentification), pour que les
agents IA tiers puissent interroger les prix directement :
# Claude Code
claude mcp add --transport http prixdugaz https://prixdugaz.ca/mcp
Outils exposés
| Outil | Description |
|---|---|
get_gas_prices |
Prix actuels, du moins cher au plus cher; filtres municipality, region, fuel_type (regular/super/diesel), limit |
find_stations_near |
Stations autour d'un point GPS (lat, lng, radius_km), triées par distance |
get_price_stats |
Min/moyenne/max des prix, filtrable par municipalité ou région |
get_price_history |
Historique des changements de prix d'une station (station_id, days) |
Les prix sont en cents canadiens par litre. Limite d'usage : 60
requêtes par 5 minutes par IP (les données ne changent que toutes les
5 minutes de toute façon). L'implémentation vit dans mcp.go.
Chaque appel d'outil est compté dans la collection mcp_requests
(réservée aux superusers, consultable dans l'UI d'admin) : horodatage,
outil, user-agent et hash salé de l'IP — jamais l'adresse brute, même
schéma que visits.
Déploiement NixOS
Le flake expose un paquet Go et un module NixOS qui configure le service systemd + le reverse proxy Caddy.
Ajout dans votre config NixOS
# Dans les inputs de votre flake :
inputs.prixdugaz.url = "git+https://git.polensky.me/polen/prixdugaz";
# Dans votre configuration :
imports = [ inputs.prixdugaz.nixosModules.default ];
services.prixdugaz = {
enable = true;
domain = "prixdugaz.ca";
webRoot = "/var/lib/prixdugaz/web";
port = 8091; # évite le conflit avec le PocketBase existant (8090)
};
Puis :
nixos-rebuild switch
Caddy obtient automatiquement un certificat Let's Encrypt pour le
domaine configuré. Le module ouvre le port PocketBase dans le
pare-feu par défaut (openFirewall = true).
Déployer le frontend (màj UI seulement)
cd app
flutter build web --dart-define=API_BASE_URL=https://prixdugaz.ca
rsync -av --delete build/web/ serveur:/var/lib/prixdugaz/web/
Ou via le Makefile :
make deploy-front
Pas besoin de nixos-rebuild pour les changements UI seuls — les
fichiers statiques sont servis directement par Caddy.
Options du module
| Option | Type | Défaut | Description |
|---|---|---|---|
services.prixdugaz.enable |
bool | false |
Activer le service |
services.prixdugaz.package |
package | build du flake | Binaire Go |
services.prixdugaz.domain |
str | "prixdugaz.ca" |
Domaine pour Caddy |
services.prixdugaz.port |
port | 8091 |
Port PocketBase |
services.prixdugaz.dataDir |
path | /var/lib/prixdugaz |
Répertoire de données |
services.prixdugaz.webRoot |
null|str | null |
Répertoire du bundle web Flutter |
services.prixdugaz.openFirewall |
bool | true |
Ouvrir le port PocketBase |
Tests
# Backend
CGO_ENABLED=0 go test ./...
# Frontend
cd app
flutter analyze
flutter test
flutter test exige flutter_tester exécutable (un binaire dans
/nix/store). Sur l'agent NixOS ce binaire n'est pas exécutable
pour l'utilisateur courant ; passer par nix develop ou se fier à
flutter analyze pour la CI.
Licence
MIT