Skip to main content

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

Comment ça fonctionne

  1. Le frontend envoie une query/mutation GraphQL via nhost.graphql.request()
  2. La requête atteint Hasura (auto-hosted par Nhost)
  3. Hasura traduit le GraphQL en SQL optimisé et l’exécute sur PostgreSQL
  4. Les permissions Hasura filtrent les résultats selon le rôle (public/user/admin)
  5. 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 :
  1. Ouvrez la console Hasura (accessible via le dashboard Nhost)
  2. Allez sur une table → onglet Permissions
  3. Définissez les règles par rôle (public, user, admin)
  4. 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