# Rapports de problèmes

> Comment une automatisation liste les rapports de problèmes ouverts envoyés depuis les pages TradeCatalog connectées.

Les employés des fournisseurs et les acheteurs connectés peuvent envoyer un bug ou un commentaire depuis n’importe quelle page de l’application. Chaque rapport est stocké avec le statut ouvert et envoyé par courriel à Happy Webs.

Cette page est destinée à l’automatisation qui récupère ces rapports. Elle n’est pas une clé d’API d’espace de travail, et n’est pas dans le document OpenAPI.

## Authentification

La requête utilise un jeton porteur. Le jeton est le secret du Worker `FEEDBACK_REPORTS_TOKEN`.

Définissez-le une fois, en dehors de git :

```bash
wrangler secret put FEEDBACK_REPORTS_TOKEN
```

Pour le développement local, utilisez le même nom dans `.dev.vars`. Ne pas valider la valeur.

Envoyez-le sur chaque requête :

```http
GET /api/feedback-reports?since=2026-10-15T00:00:00.000Z HTTP/1.1
Host: tradecatalog.app
Authorization: Bearer <FEEDBACK_REPORTS_TOKEN>
```

```bash
curl "https://tradecatalog.app/api/feedback-reports?since=2026-10-15T00:00:00.000Z" \
  -H "Authorization: Bearer $FEEDBACK_REPORTS_TOKEN"
```

Si le secret est absent, ou si l’en-tête est absent ou incorrect, la réponse est `401` avec `WWW-Authenticate: Bearer realm="feedback-reports"`. Il n’y a pas de cookie, pas de clé API d’espace de travail, et pas de CORS.

**GET** `/api/feedback-reports`

## Liste des rapports ouverts

`since` est requis. Il s’agit d’une date au format ISO-8601 ou d’un temps Unix en millisecondes. La liste contient les rapports ouverts créés **après** cette date, du plus ancien au plus récent, jusqu’à 100.

| Nom     | Type   | Obligatoire | Description                                                                                                                                                                               |
| ------- | ------ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `since` | chaîne | oui         | Limite inférieure exclusive sur `createdAt`.                                                                                                                                              |
| `after` | chaîne | non         | Identifiant du rapport. Avec `since`, renvoie également les rapports partageant exactement cette même heure et triés après cet identifiant. Utilisez les deux lorsque `hasMore` est vrai. |

Un rapport qui a été fermé n’est pas dans cette liste, même s’il a été créé après `since`.

```json
{
  "reports": [
    {
      "id": "…",
      "kind": "bug",
      "status": "open",
      "message": "The price shows as zero.",
      "pageUrl": "https://tradecatalog.app/s/northgate/products",
      "tenantSlug": "northgate",
      "userId": "…",
      "role": "Owner",
      "email": "owner@example.com",
      "userAgent": "…",
      "viewport": "1440x900",
      "createdAt": "2026-10-15T12:00:00.000Z",
      "hasScreenshot": true,
      "screenshotUrl": "https://tradecatalog.app/api/feedback-reports/…/screenshot",
      "autoReplyText": null,
      "autoReplySentAt": null,
      "resolvedReplyText": null,
      "resolvedReplySentAt": null,
      "adminUrl": "https://tradecatalog.app/admin?section=reports&report=…"
    }
  ],
  "hasMore": false
}
```

Stockez `createdAt` et `id` du dernier rapport que vous avez conservé. La prochaine requête utilise cette date comme `since`. Si la page était pleine (`hasMore` est vrai), transmettez également cet identifiant comme `after` et conservez le même `since`, afin qu’un rapport enregistré dans la même milliseconde ne soit pas sauté.

## Capture d’écran

**GET** `/api/feedback-reports/{id}/screenshot`

Le même jeton porteur. La réponse est l’image, ou `404` si ce rapport n’a pas de capture d’écran. L’identifiant est l’identifiant du rapport de la liste. Ce n’est pas une clé d’objet.

Les administrateurs de la plateforme peuvent également ouvrir la capture d’écran en étant connectés sur `/admin/feedback-reports/{id}`, et résoudre un rapport sous **Support → Rapports**.

## Réponse automatique

En enregistrant un rapport, un courriel est envoyé à la personne connectée avec une courte note à son adresse. En résolvant le rapport, elle reçoit un autre courriel pour indiquer qu’il est réparé et en ligne. Chacun de ces courriels est envoyé au maximum une fois par rapport.

`autoReplyText` et `autoReplySentAt` sont cette première note. `resolvedReplyText` et `resolvedReplySentAt` sont la note résolue. Ils restent nuls jusqu’à ce que le courriel ait été envoyé.

Définissez la variable Worker `FEEDBACK_AUTO_REPLY` sur `off` pour arrêter les deux. `AUTO_REPLY_BCC` est un secret : l’adresse copiée sur ces courriels. Laissez-le vide et rien n’est copié. Le texte est rédigé avec l’IA des Workers. Si ce brouillon échoue à un test, un message fixe est envoyé à la place.

Chaque rapport devient également un ticket numéroté. La résolution de ce ticket envoie le même courriel fixe et en ligne une seule fois. Les courriels envoyés à support@ ou info@tradecatalog.app sont transférés vers `SUPPORT_FORWARD_TO` avant d’être lus, puis archivés de la même manière. Si cette adresse est absente, ou si le transfert échoue, le message est rejeté afin que l’expéditeur puisse réessayer. Il est attaché à un compte existant uniquement lorsque `Authentication-Results` indique un passage DMARC, ou les deux DKIM et SPF lorsqu’il n’y a pas de DMARC. Sinon, le ticket reste non lié et aucun accusé de réception n’est envoyé.
