> ## Documentation Index
> Fetch the complete documentation index at: https://docs-kit.lucdidion.lu/llms.txt
> Use this file to discover all available pages before exploring further.

# Nhost & GraphQL

> Architecture backend avec Nhost, Hasura et API Layer GraphQL

## 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.

```mermaid theme={null}
graph LR
    A[React Frontend] --> B[Nhost Client]
    B --> C[Hasura GraphQL Engine]
    C --> D[(PostgreSQL)]
    B --> E[Nhost Auth]
    B --> F[Nhost Storage]

    style B fill:#3B82F6
    style C fill:#22C55E
    style D fill:#6366F1
```

***

## Stack backend

**Nhost Cloud (eu-central-1)** fournit :

* **PostgreSQL** — Base de données relationnelle (13 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`

```typescript theme={null}
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

```typescript theme={null}
// 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 :

```sql theme={null}
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

```mermaid theme={null}
sequenceDiagram
    participant User
    participant App
    participant NhostAuth
    participant Hasura

    User->>App: Email + Password
    App->>NhostAuth: signInEmailPassword()
    NhostAuth-->>App: JWT Access Token + Refresh Token
    App->>Hasura: GraphQL request (Authorization: Bearer JWT)
    Hasura-->>App: Données filtrées par rôle
```

### Implémentation

**Fichier :** `src/lib/auth.tsx`

Le contexte d'authentification utilise `nhost.auth` :

```typescript theme={null}
// 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.

```typescript theme={null}
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

```typescript theme={null}
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

```bash theme={null}
# .env
VITE_NHOST_SUBDOMAIN=your_subdomain    # Ex: gqvlmqwbsmkhlllmgbyw
VITE_NHOST_REGION=eu-central-1         # Région Nhost
```

<Warning>
  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.
</Warning>

***

## 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

<CardGroup cols={2}>
  <Card title="API Layer" icon="code" href="/development/api-layer">
    apiCall, apiCallVoid et exemples GraphQL
  </Card>

  <Card title="Database Schema" icon="database" href="/database/schema">
    Structure des 13 tables PostgreSQL
  </Card>

  <Card title="Permissions" icon="shield" href="/database/rls">
    Détail des permissions Hasura par table
  </Card>

  <Card title="Nhost Docs" icon="book" href="https://docs.nhost.io">
    Documentation officielle Nhost
  </Card>
</CardGroup>
