Backend Go et PocketBase
Le backend étend PocketBase avec une API Go tout en gardant les règles métier indépendantes du
framework. main.go constitue la racine de composition et démarre les repositories, services,
handlers et workers.
Organisation
Section intitulée « Organisation »| Dossier | Responsabilité |
|---|---|
domain/<feature> |
entités, ports, services et erreurs stables |
api/ |
middleware, handlers HTTP, validation et autorisation |
dto/ |
corps et réponses propres au transport HTTP |
infra/pb/ |
repositories PocketBase |
infra/<provider>/ |
SMTP, IA, médias, iCalendar et temps réel |
migrations/ |
historique versionné du schéma PocketBase |
seeds/ |
données locales compilées uniquement avec le tag dev |
tests/domain/ |
tests unitaires des règles métier |
tests/integration/ |
migrations, repositories et API avec PocketBase isolé |
docs/openapi.yaml |
contrat HTTP public |
Ajouter un cas d’usage
Section intitulée « Ajouter un cas d’usage »- Modélisez l’entité, la commande et les erreurs dans
domain/<feature>. - Définissez les ports minimaux nécessaires au service.
- Testez le service avec des implémentations mémoire ou factices.
- Implémentez le repository sous
infra/. - Ajoutez les DTO sans réutiliser automatiquement les modèles PocketBase.
- Créez un handler mince qui valide, autorise, appelle le service et mappe les erreurs.
- Assemblez les dépendances dans
main.go. - Ajoutez le contrat OpenAPI et les tests d’intégration.
Un handler ne contient pas de calcul tarifaire, de transition éditoriale ou de règle de rôle
complexe. Un service de domaine ne reçoit pas *core.App, *core.RequestEvent ou un record
PocketBase.
Erreurs stables
Section intitulée « Erreurs stables »Le domaine expose des erreurs que l’API traduit vers des statuts et corps prévisibles. Distinguez :
- entrée invalide :
400ou422selon le contrat ; - authentification absente ou invalide :
401; - rôle insuffisant :
403; - ressource absente :
404; - conflit de version ou d’état :
409; - erreur inattendue :
500sans détail interne.
Ne renvoyez pas au client le message brut d’un fournisseur, d’une base ou d’une erreur Go.
Persistance PocketBase
Section intitulée « Persistance PocketBase »Les repositories traduisent les records en entités et inversement. Ils centralisent les noms de collections, filtres et relations. Le domaine ne dépend pas d’un identifiant ou d’un hook propre à PocketBase, sauf si cette notion appartient réellement au métier.
Les opérations multi-étapes qui doivent rester cohérentes utilisent les capacités transactionnelles appropriées. Une création partielle ne doit pas laisser des traductions ou relations orphelines.
Migrations
Section intitulée « Migrations »Toute modification de collection passe par migrations/ et doit fonctionner sur une base existante.
Checklist d’une migration
Section intitulée « Checklist d’une migration »- utilisez un identifiant et un ordre déterministes conformes au dépôt ;
- rendez les nouvelles colonnes compatibles avec les records actuels ;
- remplissez ou transformez les données avant d’imposer une contrainte ;
- prévoyez le retour arrière lorsqu’il n’entraîne pas de perte ;
- évitez une suppression irréversible dans le même déploiement qu’un remplacement ;
- testez la migration réelle dans
tests/integration; - vérifiez le seed après migration.
Pour un renommage, préférez ajouter, recopier, déployer les consommateurs puis supprimer dans une version ultérieure.
Traductions
Section intitulée « Traductions »Les contenus localisés utilisent la collection translations, indépendante du schéma des entités.
Les repositories résolvent la locale demandée, appliquent le fallback vers la locale par défaut et
renvoient une forme cohérente au domaine.
Une écriture back-office valide toutes les locales actives sans exiger qu’une traduction secondaire soit remplie. Le code de locale reçu doit exister et être activé.
Authentification du personnel
Section intitulée « Authentification du personnel »Le flux back-office combine mot de passe, challenge à usage unique et TOTP obligatoire. Les rôles
sont limités à admin, manager et author. Les handlers appliquent l’autorisation même si le
frontend masque l’action.
Le secret TOTP chiffré dépend de HARMONY_TOTP_ENCRYPTION_KEY. En production, fournissez une valeur
stable d’au moins 32 caractères. La changer invalide les secrets déjà chiffrés.
Calendriers externes
Section intitulée « Calendriers externes »Les URL iCalendar contiennent souvent un jeton. Elles sont chiffrées avec
HARMONY_CALENDAR_ENCRYPTION_KEY. Le worker examine les sources toutes les cinq minutes et respecte
leur intervalle configuré entre quinze minutes et vingt-quatre heures.
La prévisualisation valide le feed et découvre les libellés avant la création. La synchronisation associe ces libellés aux appartements Le Clos des Eucalyptus et produit des blocs de disponibilité.
Notifications, e-mail et temps réel
Section intitulée « Notifications, e-mail et temps réel »Les producteurs métier créent des notifications durables. Les adaptateurs peuvent ensuite envoyer un e-mail ou publier un événement temps réel. Une panne SMTP ne doit pas effacer la trace métier ; le statut d’acheminement reste consultable et relançable.
Le frontend consomme les notifications temps réel par un endpoint SSE BFF. Tout proxy devant ce flux doit désactiver le buffering et autoriser une connexion longue.
Le domaine média possède les imports, variantes, usages et galeries. Les limites de taille, formats et nombre d’éléments sont validées avant le traitement. Les fichiers ne sont jamais servis par un chemin arbitraire fourni par l’utilisateur : les routes de fichier valident la forme attendue.
Intelligence artificielle
Section intitulée « Intelligence artificielle »L’IA est désactivée par défaut. domain/ai.Gateway reste indépendant du fournisseur ; les clés,
modèles, appels HTTP et réponses brutes vivent sous infra/ai.
Chaque tentative crée un audit ai_runs avant l’appel puis le termine en succès ou échec. L’audit
conserve les métadonnées, hash, latence et usage, jamais la clé, le prompt complet, le texte source
ou la réponse générée. Les propositions de traduction restent soumises à validation humaine.
Validation
Section intitulée « Validation »make fmt-check vet staticcheckmake test-unitmake test-integrationmake contractmake buildmake verifymake verify exécute cette chaîne complète avec des délais distincts pour les tests unitaires et
d’intégration. Les tests d’intégration utilisent une base isolée et les migrations réelles.