Files
archivmail/features/PROJ-79-dependency-major-upgrades.md
T
sysopsandClaude Sonnet 5 a2e45b950b chore(PROJ-79): lucide-react Major-Upgrade + npm audit fix + Deploy-Warn-Gate
lucide-react 0.562.0 auf 1.28.0 (kein Codeumbau nötig, alle genutzten
Icon-Namen kanonisch unverändert). npm audit fix behebt alle 6 gefundenen
Vulnerabilities ohne Breaking Change (next minor 16.2.9->16.3.0 im
bestehenden ^16.1.1-Range). caniuse-lite/Browserslist-DB aktualisiert
(war 8 Monate alt).

update.sh: npm audit --audit-level=high läuft jetzt als nicht-blockierendes
Warn-Gate nach npm ci. Bewusst kein Auto-Fix während des laufenden Deploys
— ein npm audit fix live auf dem Produktivsystem könnte unbemerkt Versionen
ändern, ohne vorherige Verifikation. Bei Fund wird gewarnt und auf lokales
audit fix + Test + Commit verwiesen.

Restliche PROJ-79-Schritte (eslint, @types/node, tailwindcss v4 +
tailwind-merge v3, typescript) bleiben offen, siehe Feature-Spec.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019j28kGcaJAhBnrYX34hGdt
2026-08-05 17:37:40 +02:00

5.9 KiB

id, title, status, created
id title status created
PROJ-79 Frontend-Dependency-Major-Upgrades (eslint, lucide-react, tailwindcss+tailwind-merge, typescript, @types/node) In Progress 2026-08-05

Problem

npm outdated zeigt mehrere Major-Version-Sprünge im Frontend, die nicht blind gezogen werden sollten (Build-/Runtime-Bruchrisiko):

Paket Aktuell Ziel Risiko
eslint 9.39.2 10.8.0 Config-Format
typescript 5.9.3 7.0.2 2 Majors auf einmal
tailwindcss 3.4.19 4.3.3 Komplett neue Config-Architektur
lucide-react 0.562.0 1.28.0 Icon-API-Änderungen
tailwind-merge 2.6.0 3.6.0 Hart an tailwindcss v4 gekoppelt
@types/node 20.19.28 26.1.2 Typen sollten zur echten Node-Version auf 131/132 passen

Wichtiger Befund während der Umsetzung: tailwind-merge v3 setzt laut offizieller README Tailwind CSS v4 voraus ("if you use Tailwind v3, use tailwind-merge v2.6.0"). Ein isoliertes Upgrade von tailwind-merge allein wäre eine offiziell unsupported Kombination — heute laut Messung (283.556 paarweise Klassen-Merges aus dem echten Codebestand verglichen, 0 Abweichungen) verhaltensneutral, aber *-opacity-*-Klassen (z.B. bg-opacity-50) würden künftig lautlos falsch gemerged statt einen Build-Fehler zu werfen.

Lösung (Vorschlag, priorisierte Reihenfolge)

  1. lucide-react 0.562.0 → 1.28.0 — unabhängig, grep -rn "from \"lucide-react\"" src/ für Impact-Fläche, danach Upgrade + tsc --noEmit (fängt umbenannte Icons als Compile-Fehler ab).
  2. eslint 9 → 10 + eslint-config-next (aktuell 16.1.1) nachziehen, Flat-Config-Breaking-Changes prüfen, npm run lint danach.
  3. @types/node 20 → 26 — vorher node -v auf 131 und 132 prüfen, Typen dürfen nicht vor der tatsächlichen Node-Laufzeit-Version liegen.
  4. tailwindcss v3→v4 + tailwind-merge v2→v3 zusammen (gekoppeltes Paar, nicht einzeln):
    • npx @tailwindcss/upgrade (offizielles Migrationstool)
    • tailwind-merge@3 im selben Schritt
    • shadcn/ui-Komponenten-Kompatibilität mit Tailwind 4 vorab prüfen
    • Lint-Regel gegen *-opacity-*-Klassen ergänzen (bg-/text-/border-/ring-/divide-/placeholder-opacity) — Absicherung gegen stummen Styling-Bruch, da diese Klassen in v4 vom Merge verschluckt werden ohne Fehler
    • Voller visueller Regressionstest (größter Einzelschritt im gesamten Upgrade-Batch)
  5. typescript 5 → 6 → 7 — stufenweise, nicht direkt springen, nach jedem Schritt tsc --noEmit komplett grün vor dem nächsten.

Jeder Schritt: eigener Commit, erst auf 132 build+visuell testen, dann 131.

Implementation Notes

  • 2026-08-05: tailwind-merge-Einzelupgrade gestoppt nach Entdeckung der v4-Kopplung (siehe Problem-Abschnitt). Kein Code geändert, git status war danach sauber. Reihenfolge oben entsprechend revidiert — Punkt 4 bündelt beide Pakete statt sie getrennt zu behandeln.

lucide-react Upgrade (Punkt 1) — 2026-08-05

  • lucide-react 0.562.0 → 1.28.0 (npm install lucide-react@^1). Geändert wurden nur package.json / package-lock.jsonkein Anwendungscode musste angepasst werden.
  • Impact-Fläche: 19 Dateien unter src/, alle Imports einzeilig, insgesamt 20 verschiedene Icons: Bookmark, BookmarkPlus, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Circle, FileText, Info, Lock, MailPlus, Moon, MoreHorizontal, PanelLeft, Search, Server, Sun, Trash2, X.
  • Keine Icon-Umbenennungen nötig: alle 20 Namen existieren unverändert in den v1-Typdeklarationen (node_modules/lucide-react/dist/lucide-react.d.ts) — es handelt sich durchweg um kanonische Namen, keine veralteten Aliase, die beim 0.x→1.x-Sprung entfallen wären.
  • Verifikation: npx tsc --noEmit0 Fehler; npm run builderfolgreich, alle 14 Routen generiert.
  • Kein Live-Browser-Test durchgeführt (laut Spec-Auftrag nicht nötig, da fehlende Icon-Exporte vollständig als Compile-Fehler auftreten würden).
  • Offen: Verifikation auf 132, danach 131-Deploy.

npm audit fix + Browserslist-Refresh — 2026-08-05

Anlass: beim 131-Deploy meldete npm ci 26 Vulnerabilities (1 low, 6 moderate, 19 high) sowie eine 8 Monate alte caniuse-lite-Datenbank (Browserslist). Lokal (nach dem lucide-react-Upgrade) zeigte npm audit nur 6 Vulnerabilities (@babel/core low, brace-expansion/js-yaml/ next/postcss/sharp high) — Differenz vermutlich Lock-Datei-Drift zwischen Workstation und 131 zum Zeitpunkt des Checks.

  • npm audit fix (ohne --force, da alle 6 Funde fixAvailable: true ohne SemVer-Major-Flag waren) → 0 Vulnerabilities. next wanderte dabei minor von 16.2.9 auf 16.3.0 (im ^16.1.1-Range, kein Breaking Change).
  • npx update-browserslist-db@latestcaniuse-lite aktualisiert (1.0.30001763 → 1.0.30001806), keine Target-Browser-Änderung.
  • Verifikation: npx tsc --noEmit 0 Fehler, npm run build erfolgreich, alle 14 Routen generiert.
  • update.sh erweitert: nach npm ci läuft jetzt npm audit --audit-level=high als Warn-Gate (nicht blockierend, kein Auto-Fix während des laufenden Deploys — Breaking-Change-Risiko live auf Produktivsystem wäre inakzeptabel). Bei Fund: Warnung mit Verweis auf /tmp/npm-audit-report.txt und Hinweis, npm audit fix lokal auszuführen/zu testen/zu committen statt es automatisch im Deploy zu fahren.

Acceptance Criteria

  • lucide-react auf 1.x, tsc --noEmit + npm run build grün.
  • eslint auf 10.x + eslint-config-next kompatibel, npm run lint grün.
  • @types/node auf zur Server-Node-Version passende Major-Version.
  • tailwindcss v4 + tailwind-merge v3 gemeinsam umgesetzt, Lint-Regel gegen *-opacity-*-Klassen aktiv, visueller Regressionstest durchgeführt.
  • typescript schrittweise auf 7.x, tsc --noEmit bei jedem Zwischenschritt grün.
  • Jeder Schritt einzeln auf 132 verifiziert vor 131-Deploy.