feat: das Dashboard -- und die eine Regel steht im Code, nicht im Vorsatz
Schritt 4. React 18, TypeScript, Vite 5, Tailwind 4 (CSS-first), Lucide, Zustand; kein Konsta. Quelle in server/ui, Build nach server/web (gitignored), im Abbild von einer eigenen Docker-Stufe gebaut. JEDER KNOPF GIBT RUECKMELDUNG -- und zwar erzwungen, nicht vorgenommen: - api.ts haelt den EINZIGEN fetch und GENAU EINE Fehlerklasse. Der Fivemanage-Fehler war, zwei zu haben: geworfen wurde `new Error`, geprueft auf `instanceof ApiError`, und damit verschwand jeder Fehlschlag lautlos. - store.ts haelt run(): Aktion rein, Erfolgstext rein, und es meldet bei Erfolg diesen und bei Fehlschlag den Text DES DIENSTES. Wer darueber geht, kann keinen stillen Knopf bauen. - Jeder wartende Knopf ist gesperrt und zeigt einen Kreisel. Der zweite Klick eine Sekunde spaeter war der Weg zu neunzehn gleichnamigen Organisationen. - Fehlermeldungen bleiben stehen, bis jemand sie wegklickt. Ein Fehler, der von allein verschwindet, ist einer, den niemand gelesen hat. @vitejs/plugin-react ist auf ^4 festgenagelt: die 6 verlangt vite ^8. In den peerDependencies nachgesehen -- Vite 5.4.21 liegt in der Schnittmenge von plugin-react@4 und @tailwindcss/vite@4. Am laufenden Container nachgemessen: / kommt als text/html, assets/*.js als text/javascript, *.css als text/css (die MIME-Falle aus Schritt 1 traegt), und /tokens, /speicher, /konto liefern dieselbe index.html -- die SPA-Rueckfall- route tut, wofuer sie gebaut wurde. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+69
-11
@@ -338,19 +338,77 @@ wird freigestellt, landet auf der Platte und liegt Sekunden später unter einer
|
||||
vorhersagbaren Adresse — ohne Fivemanage, ohne PostgreSQL, ohne MinIO, ohne
|
||||
einen einzigen Handgriff von Hand dazwischen.
|
||||
|
||||
### ✅ Fertig — Schritt 4, das Dashboard
|
||||
|
||||
Liegt in `server/ui`, gebaut nach `server/web` (gitignored), im Abbild von
|
||||
einer eigenen Docker-Stufe. React 18, TypeScript, Vite 5, Tailwind 4
|
||||
(CSS-first), Lucide, Zustand — **kein Konsta**, wie geplant.
|
||||
|
||||
Anmeldung · Galerie mit Vorschau, Suche, Mehrfachauswahl, Blättern · Einzel-
|
||||
und Sammellöschung mit Nachfrage, die die Pfade zeigt · Speicherverbrauch nach
|
||||
Ordnern · Token-Verwaltung mit Klartext genau einmal · Passwortwechsel.
|
||||
|
||||
> **Vite 5 bleibt, aber `@vitejs/plugin-react` ist auf `^4` festgenagelt.**
|
||||
> Die 6 verlangt `vite ^8`. In den `peerDependencies` nachgesehen, nicht
|
||||
> geraten: `@tailwindcss/vite@4` nimmt `^5.2 || ^6 || ^7 || ^8`, und
|
||||
> `plugin-react@4` nimmt `^4.2 || ^5 || ^6 || ^7`. Vite 5.4.21 liegt in beiden
|
||||
> Schnittmengen.
|
||||
|
||||
**Wie die eine Regel durchgesetzt wird, und nicht nur gemeint ist.** In
|
||||
`api.ts` steht der einzige `fetch` und genau eine Fehlerklasse — der
|
||||
Fivemanage-Fehler war, zwei zu haben (`new Error` geworfen, `instanceof
|
||||
ApiError` geprüft, jeder Fehlschlag verschluckt). In `store.ts` steht `run()`:
|
||||
es nimmt die Aktion und den Erfolgstext, meldet bei Erfolg diesen und bei
|
||||
Fehlschlag den Text **des Dienstes**. Wer darüber geht, kann keinen stillen
|
||||
Knopf bauen. Jeder Knopf, der wartet, zeigt einen Kreisel und ist gesperrt —
|
||||
der zweite Klick eine Sekunde später war der Weg zu neunzehn gleichnamigen
|
||||
Organisationen.
|
||||
|
||||
Nachgemessen am laufenden Container: `/` liefert die Oberfläche als
|
||||
`text/html`, `assets/*.js` als `text/javascript`, `assets/*.css` als
|
||||
`text/css` (die MIME-Falle aus Schritt 1 trägt also), und `/tokens`,
|
||||
`/speicher`, `/konto` geben dieselbe `index.html` zurück — die
|
||||
SPA-Rückfallroute tut, wofür sie gebaut wurde.
|
||||
|
||||
### ⚠️ Der Proxy hält Bilder fest — 30 Minuten lang
|
||||
|
||||
**Beim Nachmessen der Zwischenspeicher-Kopfzeilen gefunden, und es trifft
|
||||
genau den Fotostudio-Ablauf.** NPMs `assets.conf` greift über eine Regex auf
|
||||
*jede* URL, die auf `.css .js .png .webp …` endet — also auch auf
|
||||
`/f/vehicles/adder.webp`. Sie setzt `proxy_cache public-cache`,
|
||||
`proxy_cache_valid any 30m` und wirft unsere Kopfzeilen weg
|
||||
(`proxy_ignore_headers Cache-Control`, `proxy_hide_header Cache-Control`).
|
||||
|
||||
Reproduziert, nicht vermutet:
|
||||
|
||||
```
|
||||
Bild hochladen → abrufen: "ERSTE-FASSUNG"
|
||||
dieselbe Datei neu → abrufen über NPM: "ERSTE-FASSUNG" ← alt
|
||||
abrufen am Dienst: "ZWEITE-FASSUNG" ← neu
|
||||
```
|
||||
|
||||
**Ein neu fotografiertes Fahrzeug sieht bis zu 30 Minuten lang aus wie das
|
||||
alte**, obwohl Upload, Protokoll und Datenbank alle „fertig" sagen. Das ist
|
||||
die Sorte Fehler, die man drei Ebenen tiefer sucht.
|
||||
|
||||
Der Gegenschnipsel gehört in NPM, Proxy Host `fivemanage.d4rkst3r.de` →
|
||||
*Advanced*:
|
||||
|
||||
```nginx
|
||||
# Dateien nicht zwischenspeichern -- sie koennen sich unter derselben
|
||||
# Adresse aendern. Das ^~ ist der ganze Trick: eine gewoehnliche
|
||||
# Praefix-Location VERLIERT gegen die Regex aus assets.conf.
|
||||
location ^~ /f/ {
|
||||
proxy_cache off;
|
||||
include conf.d/include/proxy.conf;
|
||||
}
|
||||
```
|
||||
|
||||
Dass `^~` nötig ist und ein blankes `location /f/` nicht reicht, ist in einem
|
||||
Wegwerf-nginx nachgemessen: ohne `^~` gewinnt die Regex, mit `^~` das Präfix.
|
||||
|
||||
### ⬜ Als Nächstes
|
||||
|
||||
**4 · Dashboard.** React 18, TypeScript, Vite 5, Tailwind 4 (CSS-first),
|
||||
Lucide, Zustand. **Kein Konsta** — das ist für die Handy-Oberfläche richtig,
|
||||
für ein Dashboard am Monitor nicht.
|
||||
|
||||
Anmeldung · Galerie mit Vorschau, Suche, Mehrfachauswahl · Löschen ·
|
||||
Speicherverbrauch nach Ordnern · Token-Verwaltung, Klartext genau einmal.
|
||||
|
||||
> **Die eine Regel:** jeder Knopf gibt Rückmeldung, auch der erfolgreiche.
|
||||
> Das ist der Fehler, an dem wir bei Fivemanage einen Nachmittag verloren
|
||||
> haben, und er ist billig zu vermeiden.
|
||||
|
||||
**5 · Umzug.** Root-`docker-compose.yml` wird unsere; die Fivemanage-Dateien
|
||||
wandern nach `legacy/`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user