Microservice Go de tracking d'événements : enregistrement de hits par client et par action, agrégation mensuelle, dashboard admin et interface client protégés par session.
Holmes est le service d’analytics maison de la plateforme Carder. Il expose un endpoint public POST /api/hits/:client_id/:action_id consommé par chaque page de carte NFC pour tracer les vues et les clics sur les liens ou badges — sans cookie, sans script tiers.
L’application est écrite entièrement en Go 1.23. La structure suit un découpage en couches classique, câblé par injection de dépendances via Uber fx.
main.go (fx.New → DI container)
│
├── Config (Viper — app.env + cors.yaml)
├── Database (GORM + SQLite)
├── Service (logique métier)
├── Middleware (session auth : admin / customer)
└── Handler (Echo routes)
Les templates HTML sont générés avec Templ — un compilateur qui transforme des fichiers .templ en fonctions Go typées, sans concaténation de chaînes ni html/template à l’exécution.
Le cœur du service est un upsert minimal :
UPDATE Views SET Count = Count + 1 WHERE client_id = ? AND action_id = ? AND month = ? AND year = ?RowsAffected == 0, INSERT d’une nouvelle ligne avec Count = 1Chaque entrée est dimensionnée par (client_id, action_id, month, year). Les requêtes de lecture agrègent avec SUM(Count) GROUP BY client_id, action_id pour consolider les totaux sur une période.
Deux niveaux d’accès protégés par Gorilla Sessions :
Le filtre mois/année du dashboard est un formulaire htmx-boosted : le rechargement partiel évite un full-page refresh sans ajouter de JavaScript custom.
Les origines CORS autorisées sont déclarées dans config/cors.yaml, rechargé à chaud via Viper + fsnotify. Les secrets (mot de passe admin, clé de cookie) sont injectés depuis un fichier app.env au démarrage, avec un panic explicite si COOKIE_SECRET est absent.
L’image Docker est déployée sur le même réseau Swarm que Carder, derrière Caddy (holmes.nsmobile.be). La base SQLite est persistée dans un volume ./database monté en bind. Un pipeline GitHub Actions build et déploie l’image automatiquement à chaque push sur la branche principale.
Projets similaires