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

# FAQ développeur

> Questions fréquentes sur l'intégration API THE HIVE

# FAQ développeur

## Authentification

### Pourquoi je reçois `401 Unauthorized` ?

```mermaid theme={null}
flowchart TD
    E[401] --> C1{Header Authorization présent?}
    C1 -->|non| F1[Ajouter: Authorization: Bearer TOKEN]
    C1 -->|oui| C2{Format correct?}
    C2 -->|non| F2[Doit être: Bearer {access_token}]
    C2 -->|oui| C3{Token expiré? jwt.io pour vérifier exp}
    C3 -->|oui| F3[POST /auth/refresh-token]
    C3 -->|non| C4{Token blacklisté?}
    C4 -->|oui| F4[Login à nouveau]
    C4 -->|non| C5{Secret JWT correct côté serveur?}
```

Causes typiques :

* Token expiré (durée : 15 min) — refresh
* Token révoqué par logout
* Mauvaise env (token prod sur staging)
* Header mal formé : `Bearer<espace>TOKEN`

### Pourquoi `403 Forbidden` même avec un token valide ?

Rôle insuffisant. Consulter [Rôles & permissions](/roles-permissions) :

```mermaid theme={null}
flowchart TD
    E[403] --> R{Rôle actuel}
    R -->|CANDIDAT| C[Endpoints /candidats/me/* et publics]
    R -->|RECRUTEUR MEMBER| M[Gérer offres/candidatures mais pas entreprise]
    R -->|RECRUTEUR OWNER| O[Tout recruteur sauf admin]
    R -->|ADMIN| A[Admin sauf super-admin]
    R -->|SUPER_ADMIN| SA[Tout]
```

### Comment fonctionne la rotation refresh ?

Chaque `POST /auth/refresh-token` renvoie un **nouveau** refresh token et invalide l'ancien. Voir [JWT refresh](/concepts/jwt-refresh).

## Rate limiting

### Pourquoi `429 Too Many Requests` ?

```mermaid theme={null}
flowchart LR
    REQ[Request] --> RL[RateLimiter bucket]
    RL -->|tokens disponibles| OK[200]
    RL -->|vide| E[429 + Retry-After header]
    E --> WAIT[Client: attendre + backoff]
    WAIT --> REQ
```

Limites par endpoint, voir [Rate limiting](/rate-limiting). Respecter le header `Retry-After`.

### Comment éviter le rate limit ?

* Cache local agressif (30 s) pour les recherches publiques
* Pagination large (`size=50` max) pour réduire le nombre d'appels
* Webhooks (quand disponibles) ou polling ≥ 60 s

## Uploads

### Pourquoi `413 Payload Too Large` ?

Taille max dépend du type — voir [Uploads médias](/guides/uploads-medias) :

| Type         |   Max |
| ------------ | ----: |
| Logo         |  2 Mo |
| Bannière     |  5 Mo |
| Photo profil |  1 Mo |
| CV           |  5 Mo |
| KYC          | 10 Mo |

### Pourquoi `415 Unsupported Media Type` ?

MIME type non autorisé. Vérifier que :

* Le fichier a bien la bonne extension
* Le MIME détecté par le backend (`file --mime-type`) correspond à l'extension
* Envoyer en `multipart/form-data` (pas en JSON base64)

### Pourquoi `422` après upload ?

```mermaid theme={null}
flowchart TD
    E[422] --> T{Raison dans body}
    T -->|ratio_invalid| R1[Bannière = 16:9 obligatoire]
    T -->|av_infected| R2[ClamAV a détecté un virus]
    T -->|pdf_corrupt| R3[CV PDF invalide ou chiffré]
    T -->|image_corrupt| R4[Image tronquée ou format inconnu]
```

## Recherche

### Ma recherche full-text ne retourne rien

1. Vérifier `q=mot+complet` (espaces → `+` ou `%20`)
2. Essayer des variantes : `dev`, `developer`, `développeur`
3. Le ranking est pondéré — voir [FTS](/models/offre#full-text-search)
4. Retirer les filtres (typeContrat, villeId) un à un

### Comment trier les résultats ?

```http theme={null}
GET /v1/api/offres/search?q=java&sort=pertinence    # défaut
GET /v1/api/offres/search?q=java&sort=dateRecent
GET /v1/api/offres/search?q=java&sort=salaireDesc
```

## Environnements

### Mon code staging ne marche pas en prod

Vérifier :

* `base_url` différente (voir [Environnements](/environnements))
* CORS : staging accepte `localhost`, prod non
* Quotas plus stricts en prod
* Comptes staging **ne sont pas** migrés en prod

### Comment tester sans compte réel ?

Un compte `demo@wethehivers.com` avec rôle CANDIDAT existe sur **staging uniquement**. Demander le mot de passe à l'équipe tech.

## SDK / Types

### Où trouver les types TypeScript / Java / Python ?

Générer depuis `openapi.json` :

```mermaid theme={null}
flowchart LR
    OAS[openapi.json] --> TS[openapi-typescript]
    OAS --> JAVA[openapi-generator-maven-plugin]
    OAS --> PY[openapi-python-client]
    TS --> APP1[App React/Node]
    JAVA --> APP2[Service Spring]
    PY --> APP3[Script Python]
```

Détails : [Snippets JS](/dx/snippets-js), [Java](/dx/snippets-java), [Python](/dx/snippets-python).

### Un SDK officiel est-il prévu ?

Non à court terme. La génération depuis OpenAPI couvre les besoins avec `0` maintenance côté backend.

## Collections

### Postman / Insomnia / Bruno ?

Toutes disponibles — voir [Collections API](/dx/collections). Mises à jour automatiquement à chaque push backend (CI GitLab).

### Mes variables d'environnement ne se remplissent pas

Les collections fournissent un **script post-login** qui stocke `access_token` / `refresh_token` dans l'environnement actif. Vérifier :

* L'environnement est bien **sélectionné** (pas "No Environment")
* Le script est bien au niveau **collection** pour Postman
* Bruno : `bru.setEnvVar` dans `script:post-response`

## Production

### Comment monitorer mon intégration ?

* Logguer `X-Request-Id` renvoyé par chaque réponse (corrélation avec les logs backend)
* Tracer les codes 4xx/5xx dans Sentry / DataDog
* Alerter sur taux d'erreur > 1% sur 5 min
* Dashboard uptime externe (UptimeRobot, Pingdom)

```mermaid theme={null}
flowchart LR
    APP[App] --> REQ[Request]
    REQ --> LOG[Log request id + status]
    LOG -->|4xx/5xx| SENTRY[Sentry]
    SENTRY --> ALERT[Alert Slack]
    REQ --> METRIC[Métrique temps réponse]
    METRIC --> DASH[Dashboard]
```

### Cache : quoi, quand, combien ?

| Ressource                            | TTL recommandé | Stratégie                 |
| ------------------------------------ | -------------- | ------------------------- |
| `/offres/search` (public)            | 30 s           | Par clé (query + filtres) |
| `/offres/{slug}`                     | 5 min          | Par slug                  |
| `/regions`, `/villes`, `/categories` | 24 h           | Global                    |
| `/candidats/me/*`                    | 0              | Pas de cache              |

### Comment rafraîchir après publication d'une offre ?

Backend purge CDN + invalide cache interne à chaque publish. Côté client :

* Revalider après une action qui modifie les données
* Pour SSR / SSG : utiliser `stale-while-revalidate`

## Sécurité

### Dois-je stocker le refresh token en localStorage ?

⚠️ **À éviter en prod**. Recommandations :

```mermaid theme={null}
flowchart TD
    CTX[Contexte] --> D{Type d'app}
    D -->|SPA Browser| C1[Cookie HttpOnly + SameSite=Strict + Secure]
    D -->|Mobile natif| C2[Keychain iOS / Keystore Android]
    D -->|CLI / Script| C3[Variable d'env + chiffrement au repos]
    D -->|Serveur proxy| C4[Redis chiffré]
```

localStorage reste acceptable pour le **access token** court (15 min) puisque le risque XSS est temporellement limité.

### CORS : mes requêtes sont bloquées

Les origines whitelistées sont :

* `https://wethehivers.com` (candidat)
* `https://recruteur.wethehivers.com`
* `https://staging.wethehivers.com` (staging)
* `http://localhost:3000` / `:3001` (dev uniquement)

Toute autre origine → bloquée. Pour un proxy serveur-à-serveur, CORS ne s'applique pas.

## Contact & support

| Canal           | Usage                                      |
| --------------- | ------------------------------------------ |
| Email tech      | `tech@wethehivers.com`                     |
| GitLab issues   | Bugs reproductibles                        |
| Discord Dev     | Questions rapides (invitation sur demande) |
| Pager astreinte | Incidents prod uniquement — via email      |

## Voir aussi

* [Authentification](/authentication)
* [Rate limiting](/rate-limiting)
* [Environnements](/environnements)
