Vue d’ensemble
Kit’Asso utilise Nhost comme backend-as-a-service, qui fournit automatiquement une API GraphQL via Hasura au-dessus de PostgreSQL. Ce choix permet une mise en place rapide avec auto-génération des queries/mutations GraphQL, permissions granulaires, authentification intégrée et file storage.
Stack backend
Nhost Cloud (eu-central-1) fournit :
- PostgreSQL — Base de données relationnelle (10 tables)
- Hasura — API GraphQL auto-générée avec permissions par rôle
- Nhost Auth — Authentification email/password avec JWT
- Nhost Storage — Upload et stockage de fichiers (logos, assets)
Client Nhost
Fichier : src/api/client.ts
import { createClient } from '@nhost/nhost-js';
const nhostSubdomain = import.meta.env.VITE_NHOST_SUBDOMAIN || 'gqvlmqwbsmkhlllmgbyw';
const nhostRegion = import.meta.env.VITE_NHOST_REGION || 'eu-central-1';
export const nhost = createClient({
subdomain: nhostSubdomain,
region: nhostRegion,
});
Le client expose trois services principaux :
nhost.graphql.request({ query, variables }) — requêtes GraphQL
nhost.auth.signIn(...) / nhost.auth.signOut() — authentification
nhost.storage.upload(...) — upload de fichiers
Flux de données : GraphQL via Hasura
- Le frontend envoie une query/mutation GraphQL via
nhost.graphql.request()
- La requête atteint Hasura (auto-hosted par Nhost)
- Hasura traduit le GraphQL en SQL optimisé et l’exécute sur PostgreSQL
- Les permissions Hasura filtrent les résultats selon le rôle (public/user/admin)
- La réponse remonte au frontend
Exemple concret
// Requête GraphQL pour lister les outils
const query = `
query GetTools {
tools(order_by: { name: asc }) {
id
name
description
pricing_tier
category_id
}
}
`;
const result = await nhost.graphql.request({ query });
const tools = result.body?.data?.tools || [];
Hasura traduit automatiquement en :
SELECT id, name, description, pricing_tier, category_id
FROM tools
ORDER BY name ASC
-- + filtrage automatique par les permissions du rôle
Permissions Hasura (au lieu de RLS)
Kit’Asso utilise les permissions Hasura pour contrôler l’accès aux données, ce qui remplace le mécanisme Row Level Security (RLS) natif de PostgreSQL.
Rôles
- public — Visiteurs non authentifiés
- user / admin — Utilisateurs authentifiés (JWT Nhost)
Règles par domaine
Contenu public (tools, categories, filters) :
SELECT : autorisé pour public (tous les visiteurs)
INSERT / UPDATE / DELETE : autorisé pour admin uniquement
Contenu avec statut (workflows, packs, quizzes) :
SELECT public : uniquement status = 'active' ou is_active = true
SELECT admin : tous les enregistrements (y compris drafts)
INSERT / UPDATE / DELETE : admin uniquement
Quiz responses :
INSERT public : autorisé (soumission de quiz)
SELECT : admin uniquement (analytics)
Configuration dans Hasura Console
Les permissions se configurent dans la console Hasura de votre projet Nhost :
- Ouvrez la console Hasura (accessible via le dashboard Nhost)
- Allez sur une table → onglet Permissions
- Définissez les règles par rôle (public, user, admin)
- Ajoutez des row-level checks si nécessaire (ex:
status = 'active')
Authentification Nhost
Flux d’authentification
Implémentation
Fichier : src/lib/auth.tsx
Le contexte d’authentification utilise nhost.auth :
// Connexion
await nhost.auth.signIn({ email, password });
// Déconnexion
await nhost.auth.signOut();
// Vérifier la session
const session = nhost.auth.getSession();
const isAuthenticated = !!session;
Nhost gère automatiquement :
- Stockage du JWT en mémoire
- Refresh automatique du token avant expiration
- Injection du header
Authorization: Bearer <token> dans les requêtes GraphQL
Nhost Storage
Upload de fichiers
Fichier : src/lib/storage.ts
Kit’Asso utilise Nhost Storage pour stocker les logos des outils et les assets du site.
import { nhost } from '../api/client';
// Upload d'un logo
const { error, fileMetadata } = await nhost.storage.upload({
file,
bucketId: 'default',
});
// Construire l'URL publique
const STORAGE_BASE_URL = `https://${subdomain}.storage.${region}.nhost.run/v1/files`;
const publicUrl = `${STORAGE_BASE_URL}/${fileMetadata.id}`;
Validation côté client
const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
const MAX_FILE_SIZE = 2 * 1024 * 1024; // 2MB
function validateFile(file: File) {
if (file.size > MAX_FILE_SIZE) throw new Error('Fichier trop volumineux (max 2MB)');
if (!ALLOWED_IMAGE_TYPES.includes(file.type)) throw new Error('Format non supporté');
}
Variables d’environnement
# .env
VITE_NHOST_SUBDOMAIN=your_subdomain # Ex: gqvlmqwbsmkhlllmgbyw
VITE_NHOST_REGION=eu-central-1 # Région Nhost
Ne commitez JAMAIS le .env ! Il est dans .gitignore.
Les valeurs par défaut dans client.ts sont pour l’environnement de développement partagé uniquement.
URLs Nhost générées
À partir du subdomain et region, Nhost construit automatiquement :
- GraphQL :
https://{subdomain}.hasura.{region}.nhost.run/v1/graphql
- Auth :
https://{subdomain}.auth.{region}.nhost.run/v1
- Storage :
https://{subdomain}.storage.{region}.nhost.run/v1
Ressources