feat: Frontend im Produktionsbetrieb ausliefern, TTFT bei OpenRouter

npm start baute web/dist, aber niemand lieferte es aus — der Server stellte
nur die API bereit. Jetzt registriert er @fastify/static, wenn ein Build
vorliegt, und die App läuft komplett unter :8788. Ohne web/dist bleibt alles
wie bisher (Vite übernimmt im Dev-Betrieb); der Start sagt, welcher Fall
vorliegt. /api und /ws behalten Vorrang, unbekannte /api-Pfade antworten
weiterhin mit JSON statt mit index.html.

OpenRouter, beim Verifizieren gegen ein Gratis-Modell gefunden:
- ttftMs wurde nie gesetzt — evalMs wurde aus firstTokenAt gerechnet, das
  Feld selbst blieb null
- die Zeitmessung startete erst nach dem fetch und ließ damit die Wartezeit
  auf den Anbieter aus. Startet jetzt davor, wie bei Ollama

Geprüft im Produktionsmodus: /, /assets/*.js, SPA-Fallback, JSON-404 auf
/api, WebSocket aus Origin :8788 und :5174 verbunden, fremde Origin 403.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015AUP4R3rgq4XwVs4bVf7uh
This commit is contained in:
Jeuner 2026-08-28 14:59:35 +02:00
parent ed3c01303b
commit da1d8be426
5 changed files with 309 additions and 9 deletions

View file

@ -26,7 +26,8 @@ npm-Workspace mit zwei Paketen:
| `web/` | React 18 + Vite Frontend, Markdown-Rendering, Voice-Recording |
Der Chat läuft über einen WebSocket (`/ws`), alles andere über REST. Chats,
Nachrichten, Anhänge und Gedächtnis liegen in `server/data.sqlite`.
Nachrichten, Anhänge und Gedächtnis liegen in `server/data.sqlite`. Im
Produktionsbetrieb liefert der Server das gebaute Frontend gleich mit aus.
## Voraussetzungen
@ -364,14 +365,16 @@ läuft die App unter `http://localhost:5174` aus einer Herkunft.
## Produktion
```bash
npm start # baut web/dist und startet den Server
npm start # baut web/dist und startet den Server auf :8788
```
**Hinweis:** Der Server liefert das gebaute Frontend derzeit *nicht* aus — er
stellt nur die API auf `:8788` bereit, `web/dist` bleibt liegen. Für einen
Produktivbetrieb braucht es einen statischen Server davor, der `web/dist`
ausliefert und `/api` sowie `/ws` an `127.0.0.1:8788` weiterreicht. Für den
Alltagsbetrieb auf dem eigenen Rechner ist `npm run dev` der vorgesehene Weg.
Der Server liefert das gebaute Frontend mit aus — die App läuft dann
vollständig unter `http://localhost:8788`, ohne zweiten Prozess. Fehlt
`web/dist`, stellt er nur die API bereit und sagt das beim Start; das ist der
Normalfall im Entwicklungsbetrieb, wo Vite das Frontend übernimmt.
`/api` und `/ws` behalten Vorrang vor den statischen Dateien. Unbekannte
`/api`-Pfade antworten mit JSON-404, alles andere bekommt `index.html`.
Der Server bindet ausschließlich an `127.0.0.1`; zum Aussetzen ins Netz siehe
[Sicherheit](#sicherheit).