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

> Gestion des fichiers (logos, assets) via Nhost Storage

## Vue d'ensemble

Kit'Asso utilise **Nhost Storage** pour gérer les fichiers statiques (logos d'outils, assets du site). Nhost Storage offre un service de fichiers intégré avec CDN, permissions par rôle et URLs publiques.

**Avantages :**

* Intégré au backend Nhost (pas de service externe)
* Permissions automatiques via les rôles Hasura
* URLs publiques permanentes
* Validation de type et taille de fichiers

***

## Configuration

### URL de base

L'URL de stockage est construite à partir du subdomain et de la région Nhost :

```typescript theme={null}
const STORAGE_BASE_URL = `https://${nhostSubdomain}.storage.${nhostRegion}.nhost.run/v1/files`;
```

### Fichier : `src/lib/storage.ts`

Ce fichier centralise toutes les opérations de stockage :

```typescript theme={null}
import { nhost } from '../api/client';

const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
const MAX_FILE_SIZE = 2 * 1024 * 1024; // 2MB
```

***

## Upload de fichiers

### Fonction d'upload

```typescript theme={null}
async function uploadFile(file: File): Promise<string> {
  // 1. Valider le fichier
  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é. Utilisez JPEG, PNG, GIF ou WebP');
  }

  // 2. Upload vers Nhost Storage
  const { error, fileMetadata } = await nhost.storage.upload({
    file,
    bucketId: 'default',
  });

  if (error) throw new Error(`Erreur upload: ${error.message}`);

  // 3. Construire l'URL publique
  const fileId = fileMetadata.id;
  return `${STORAGE_BASE_URL}/${fileId}`;
}
```

### Utilisation dans l'admin

```typescript theme={null}
const handleLogoUpload = async (file: File) => {
  try {
    const logoUrl = await uploadFile(file);

    // Sauvegarder l'URL dans la table tools via GraphQL
    await toolsApi.update(toolId, { logo_url: logoUrl });

    toast.success('Logo uploadé avec succès');
  } catch (error) {
    toast.error(error.message);
  }
};
```

***

## Récupération de fichiers

### Affichage dans un composant

```typescript theme={null}
// L'URL est stockée dans tool.logo_url
<img src={tool.logo_url} alt={`Logo ${tool.name}`} loading="lazy" />
```

### Composant avec fallback

```typescript theme={null}
function ToolLogo({ url, name, size = 'md' }) {
  const [error, setError] = useState(false);

  if (!url || error) {
    // Fallback : initiales du nom
    return (
      <div className="w-12 h-12 rounded-lg bg-indigo-100 flex items-center justify-center">
        <span className="text-indigo-600 font-semibold">
          {name.charAt(0).toUpperCase()}
        </span>
      </div>
    );
  }

  return (
    <img
      src={url}
      alt={`Logo ${name}`}
      className="w-12 h-12 rounded-lg object-cover"
      onError={() => setError(true)}
      loading="lazy"
    />
  );
}
```

***

## Permissions Storage

Les permissions de Nhost Storage sont gérées via la console Nhost :

* **Upload** : uniquement les utilisateurs authentifiés (admin)
* **Lecture** : publique (les URLs de fichiers sont accessibles à tous)
* **Suppression** : uniquement les utilisateurs authentifiés

***

## Bonnes pratiques

### ✅ À faire

* Valider les fichiers avant upload (type + taille)
* Utiliser des IDs uniques (générés par Nhost) plutôt que des noms de fichiers
* Nettoyer les fichiers orphelins (logos non référencés dans la DB)
* Gérer les erreurs d'upload gracieusement (ne pas bloquer l'utilisateur)

### ❌ À éviter

* Ne pas stocker de fichiers sensibles (les URLs sont publiques)
* Ne pas uploader sans validation côté client
* Ne pas oublier de mettre à jour la DB quand un logo change

***

## Ressources

<CardGroup cols={2}>
  <Card title="Database Schema" icon="database" href="/database/schema">
    Table site\_assets pour références centralisées
  </Card>

  <Card title="Admin Dashboard" icon="shield" href="/features/admin">
    Interface d'upload dans le panel Tools
  </Card>

  <Card title="Nhost & GraphQL" icon="plug" href="/architecture/nhost-graphql">
    Architecture backend
  </Card>

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