# Probleemrapporten

> Hoe een automatisering open probleemrapporten toont die zijn verzonden vanaf ingelogde TradeCatalog-pagina's.

Ongemodereerde leveranciers en kopers kunnen een fout of feedback vanaf elke pagina in de app verzenden. Elke rapportage wordt opgeslagen met status open en per e-mail naar Happy Webs gestuurd.

Deze pagina is voor de automatisering die deze rapportages oppakt. Het is geen werkruimte API-sleutel, en staat niet in het OpenAPI-document.

## Authenticeer

De aanvraag gebruikt een bearer token. Het token is de Worker secret `FEEDBACK_REPORTS_TOKEN`.

Stel het eenmaal in, buiten git:

```bash
wrangler secret put FEEDBACK_REPORTS_TOKEN
```

Voor lokale ontwikkeling, zet dezelfde naam in `.dev.vars`. Commit de waarde niet.

Stuur het op elke aanvraag:

```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"
```

Als de geheime sleutel ontbreekt, of de header ontbreekt of verkeerd is, is het antwoord `401` met `WWW-Authenticate: Bearer realm="feedback-reports"`. Er is geen cookie, geen werkruimte API-sleutel, en geen CORS.

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

## Open rapportages tonen

`since` is vereist. Het is een ISO-8601-tijd of een Unix-tijd in milliseconden. De lijst bevat open rapportages die **na** die tijd zijn gemaakt, oudste eerst, maximaal 100.

| Naam    | Type   | Vereist | Beschrijving                                                                                                                            |
| ------- | ------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `since` | string | ja      | Exclusieve ondergrens op `createdAt`.                                                                                                   |
| `after` | string | nee     | Rapport id. Met `since`, retourneert ook rapporten die dezelfde tijd delen en daarna sorteren. Gebruik beide wanneer `hasMore` waar is. |

Een rapport dat is gesloten is niet in deze lijst, zelfs als het na `since` is gemaakt.

```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
}
```

Sla de `createdAt` en `id` van het laatste rapport dat u hebt bewaard op. De volgende poll gebruikt die tijd als `since`. Als de pagina vol was (`hasMore` is waar), geef ook dat id als `after` en houd hetzelfde `since`, zodat een rapport dat in dezelfde milliseconde is opgeslagen niet wordt overgeslagen.

## Screenshot

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

Hetzelfde bearer token. Het antwoord is de afbeelding, of `404` wanneer dat rapport geen screenshot heeft. Het id is het rapport id uit de lijst. Het is geen object sleutel.

Platformbeheerders kunnen ook een schermopname openen terwijl ze ingelogd zijn op `/admin/feedback-reports/{id}` en een rapport oplossen onder **Ondersteuning → Rapporten**.

## Automatische reactie

Het opslaan van een rapport stuurt een korte notitie naar de ingelogde persoon op hun eigen adres. Het oplossen ervan stuurt hen nogmaals een bericht dat het is opgelost en live is. Elke van deze berichten wordt maximaal één keer per rapport gestuurd.

`autoReplyText` en `autoReplySentAt` zijn die eerste notitie. `resolvedReplyText` en `resolvedReplySentAt` zijn de opgeloste notitie. Ze blijven leeg tot het e-mailbericht is verstuurd.

Stel de werkervariabele `FEEDBACK_AUTO_REPLY` in op `off` om beide te stoppen. `AUTO_REPLY_BCC` is een geheim: het adres dat op die e-mails wordt gekopieerd. Laat het ongezet en er wordt niets gekopieerd. De tekst is opgesteld met Werker AI. Als die concept niet door een controle komt, wordt er een vast bericht gestuurd in plaats daarvan.

Elk rapport wordt ook een genummerd ticket. Het oplossen van dat ticket stuurt hetzelfde vast en live e-mailbericht één keer. E-mail naar support@ of info@tradecatalog.app wordt doorgestuurd naar `SUPPORT_FORWARD_TO` voordat het wordt gelezen, en vervolgens op dezelfde manier opgeslagen. Als dat adres ontbreekt, of de doorsturing mislukt, wordt het bericht afgewezen zodat de verzender het opnieuw kan proberen. Het wordt alleen aan een bestaand account gekoppeld wanneer `Authentication-Results` een DMARC-positief resultaat toont, of zowel DKIM als SPF wanneer DMARC ontbreekt. Anders blijft het ticket ongekoppeld en wordt er geen bevestiging gestuurd.
