Une alternative à https://regieessencequebec.ca/
  • Dart 51%
  • Go 42.9%
  • Nix 2.5%
  • HTML 1%
  • JavaScript 0.9%
  • Other 1.7%
Find a file
charles@rumandcode.io 3087e46314 log real ips
2026-07-15 10:43:03 -04:00
app better chart 2026-07-13 14:06:13 -04:00
nix update hash 2026-07-13 11:08:27 -04:00
.envrc initial project setup 2026-04-02 09:50:45 -04:00
.gitignore init PocketBase backend + Flutter app 2026-06-08 08:23:37 -04:00
AGENTS.md update hash 2026-07-13 11:08:27 -04:00
flake.lock cleanup 2026-06-07 22:13:59 -04:00
flake.nix we ready 2026-06-15 15:25:20 -04:00
go.mod notifications 2026-07-13 10:58:17 -04:00
go.sum notifications 2026-07-13 10:58:17 -04:00
main.go log real ips 2026-07-15 10:43:03 -04:00
main_test.go visitors counting 2026-07-05 14:40:51 -04:00
Makefile fixies 2026-06-15 15:48:29 -04:00
mcp.go record usage 2026-07-09 13:35:55 -04:00
mcp_test.go record usage 2026-07-09 13:35:55 -04:00
prixdugaz.svg logo 2026-06-17 11:09:43 -04:00
push.go notifications 2026-07-13 10:58:17 -04:00
push_test.go notifications 2026-07-13 10:58:17 -04:00
README.md record usage 2026-07-09 13:35:55 -04:00

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) ou flutter build web pour un bundle statique.
  • Android : depuis le shell nix, flutter run -d android. Sur un émulateur, le backend tourne sur la machine hôte — utiliser 10.0.2.2 au lieu de localhost : --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