---
name: verifier-web
description: Verifieer een UI-wijziging in Notary.AI end-to-end — productiebuild starten, via de echte import-JSON-flow een dossier aanmaken en met Playwright screenshots als bewijs vastleggen. Gebruik dit voor elke wijziging aan app/ of components/ vóór het committen.
---

# Notary.AI end-to-end verifiëren (web)

Werkend recept (getest 2026-07). Bespaart de koude start: build, launch,
dossier-aanmaak en screenshotcapture staan hieronder letterlijk.

## 1. Bouwen en starten

```bash
npx next build            # moet al slagen vóór je verifieert
(npx next start -p 3100 > /tmp/next-start.log 2>&1 &)
sleep 4 && curl -s -o /dev/null -w "%{http_code}" http://localhost:3100/dossier   # verwacht: 200
```

Poort 3100 om botsingen met een eventuele dev-server te vermijden. Stoppen:
`pkill -f "next start -p 3100"` — let op: draai dit als LAATSTE losse opdracht,
niet vooraan een `&&`-keten (pkill kan de eigen procesgroep raken).

## 2. Playwright (zonder browser-download)

Chromium staat voorgeïnstalleerd; installeer enkel playwright-core in een
scratch-map (NIET in de repo):

```bash
cd <scratchpad> && npm init -y && npm install playwright-core --no-audit
```

```js
import { chromium } from "playwright-core";
const browser = await chromium.launch({ executablePath: "/opt/pw-browsers/chromium-1194/chrome-linux/chrome" });
// bestaat dat pad niet: ls /opt/pw-browsers/ en neem de chromium-*-map
const page = await browser.newPage({ viewport: { width: 1280, height: 1000 } });
const fouten = [];
page.on("pageerror", (e) => fouten.push(String(e)));
page.on("console", (m) => { if (m.type() === "error") fouten.push(m.text()); });
```

## 3. Dossier aanmaken via de echte flow (IndexedDB, dus via de UI)

De app bewaart dossiers client-side; maak ze aan via de import-JSON-flow op
`/dossier` (dit is ook het pad dat een echte agent gebruikt):

```js
await page.goto("http://localhost:3100/dossier", { waitUntil: "networkidle" });
await page.locator("textarea").last().fill("```json\n" + JSON.stringify(INTAKE) + "\n```");
await page.getByRole("button", { name: "Inlezen" }).click();
await page.getByRole("button", { name: "Dossier aanmaken →" }).click();
await page.locator('a[href^="/dossier/dossier-"]').first().click();
await page.waitForURL(/\/dossier\/dossier-/);
```

Een volledig, realistisch INTAKE-object (verkoop-met-krediet, schema
`dossier-intake/v2`) staat in `lib/dossier/gouden-pad-compromis.test.ts`
(`COMPROMIS_JSON`) — kopieer en pas aan. De statusselect op de detailpagina is
`page.locator("select").first()`.

## 4. Bewijs en rapport

- Assereer op `await page.locator("body").innerText()` (Nederlandstalige
  UI-teksten) en maak `page.screenshot({ fullPage: true })` per toestand.
- Meld console-/paginafouten (`fouten`) altijd in het rapport.
- Stuur de screenshots naar de gebruiker (SendUserFile) — een pad alleen is
  geen bewijs.

## Valkuilen

- `npm install` in de repo-root voor Playwright vervuilt package.json — altijd
  de scratchpad gebruiken.
- De pagina herberekent het werkdossier client-side; geef de UI na een
  statuswijziging ~800 ms (`page.waitForTimeout(800)`).
- Geen `page.waitForTimeout` vervangen door networkidle na de import-klik: de
  opslag is lokaal (IndexedDB), er is geen netwerkverkeer om op te wachten.
