58 KiB
Raw Blame History

@ocelot-social/ui - Projektdokumentation

Dieses Dokument dient als zentrale Planungs- und Statusübersicht für das UI-Library Subprojekt. Es ermöglicht das Pausieren und Wiederaufnehmen der Arbeit zu jedem Zeitpunkt.


1. Projektziel & Vision

Kurzbeschreibung: Neue Vue 3 Komponentenbibliothek aufbauen, die später die Vue 2 Komponenten in der Webapp ersetzen soll.

Hintergrund:

  • Bestehendes Projekt nutzt Vue 2.6 mit Nuxt 2 (Upgrade auf Vue 2.7 erforderlich)
  • Existierender styleguide Ordner als Git-Submodul (Vue 2, Vue CLI 3)
  • Design-Token-System mit Theo vorhanden
  • Branding erfolgt über SCSS-Dateien mit Variablen-Overrides
  • Problem: Viele doppelte Komponenten, inkonsistente Styles, nicht konsequent genutztes Design-System

Vision: Ein stark definiertes und flexibles Design-System, das den Branding-Anforderungen von ocelot.social gerecht wird und eine saubere, schrittweise Migration von Vue 2 nach Vue 3 ermöglicht.

Geplanter Ansatz: Migration vorbereiten - schrittweise neue Komponenten in Vue 3 entwickeln, die das bestehende Design-System respektieren und flexible Branding-Optionen bieten.


2. Tech-Stack

Komponente Entscheidung Notizen
Framework Vue 3 + Vite Schnellstes Setup, modernes Tooling
Build-Tool Vite Schnelles HMR, einfache Konfiguration
Dokumentation Histoire Vite-native Storybook-Alternative
Styling Tailwind CSS Mit CSS Custom Properties für Branding
Testing Vitest Vite-nativ, Jest-kompatible API
Paket-Name @ocelot-social/ui Unter ocelot-social npm Org
Komponenten-Prefix Os OsButton, OsCard, etc.
Vue 2 Kompatibilität vue-demi Library funktioniert in Vue 2 und Vue 3
Linting eslint-config-it4c Enthält: TypeScript, Vue, Prettier, weitere Regeln
Release release-please Automatische Versionen und Changelogs
Icons Hybrid-Architektur System-Icons in Library, Feature-Icons in App (siehe Abschnitt 15)
Browser-Support Modern only Chrome, Firefox, Safari, Edge (letzte 2 Versionen)
SSR Ja Nuxt-kompatibel
Dark Mode Ja, von Anfang an Alle Komponenten mit Light/Dark Varianten
Lizenz Apache 2.0 Permissiv mit Patent-Schutz
Repository Monorepo Ocelot-Social/packages/ui/

Konventionen

Aspekt Entscheidung Notizen
Vue API <script setup> Composition API mit script setup (erfordert Vue 2.7+)
Sprache Englisch Code, Comments, Dokumentation
Package Manager npm Bereits im Projekt verwendet
Test Coverage 100% Vollständige Testabdeckung
Dateinamen PascalCase OsButton.vue, OsCard.vue
i18n Nur Props Keine Default-Texte in Komponenten
Breakpoints Tailwind Standard sm:640, md:768, lg:1024, xl:1280, 2xl:1536
TypeScript strict: true Strikte Typisierung

3. Build & Distribution

Dual-Build Strategie

Die Library bietet zwei Nutzungsmöglichkeiten:

@ocelot-social/ui
├── dist/
│   ├── index.js              # Vue Komponenten
│   ├── styles.css            # Vorkompilierte Styles (für Nicht-Tailwind)
│   └── tailwind.preset.js    # Tailwind Preset (für Tailwind-Nutzer)

Nutzung MIT Tailwind

// tailwind.config.js
import ocelotPreset from '@ocelot-social/ui/tailwind.preset'
export default { presets: [ocelotPreset] }

// main.js
import { OsButton } from '@ocelot-social/ui'

Nutzung OHNE Tailwind

// main.js
import { OsButton } from '@ocelot-social/ui'
import '@ocelot-social/ui/styles.css'

Branding (funktioniert für beide)

/* branding.css */
:root {
  --color-primary: rgb(110, 139, 135);
  --button-primary-bg: var(--color-secondary);
}

Beide Varianten nutzen CSS Custom Properties - Branding ist identisch.

Webapp-Integration (Entwicklung)

Lokale Entwicklung mit Nuxt Alias:

// webapp/nuxt.config.js
export default {
  alias: {
    '@ocelot-social/ui': process.env.LOCAL_UI
      ? path.resolve(__dirname, '../packages/ui/src')
      : '@ocelot-social/ui'
  }
}

Entwickler startet mit:

LOCAL_UI=true yarn dev

Release-Check: Bei Ocelot-Release wird geprüft, ob packages/ui unreleased Änderungen hat:

# Commits seit letztem ui-Tag?
git log --oneline $(git describe --tags --match "ui-v*" --abbrev=0)..HEAD -- packages/ui/

→ Wenn Output vorhanden: UI muss zuerst released werden.


4. CI/CD & Release-Automatisierung

Release-Workflow (release-please)

Manifest-Modus für Monorepo:

  • Nur Commits in packages/ui/ werden betrachtet
  • Eigene Versionierung unabhängig vom Hauptrepo
  • Automatischer Changelog nur für dieses Paket
┌─────────────────────────────────────────────────────────────────┐
│                    RELEASE WORKFLOW                             │
├─────────────────────────────────────────────────────────────────┤
│  1. Commit mit Conventional Commits Format                      │
│  2. release-please erstellt Release-PR                          │
│  3. PR merge → Version bump + Changelog                         │
│  4. Automatisch: npm publish + Histoire deploy                  │
└─────────────────────────────────────────────────────────────────┘

Konfigurationsdateien:

  • .release-please-manifest.json - Versionen
  • release-please-config.json - Paket-Konfiguration

GitHub Workflows

Workflow Trigger Beschreibung
Lint Push/PR eslint-config-it4c (TypeScript + Vue + Prettier)
Test Push/PR Vitest Unit-Tests
Build Push/PR Vite Build verifizieren
Release Push to main release-please PR erstellen
Publish Release created npm publish + Histoire deploy

Qualitätssicherung bei PRs

PR erstellt
    ↓
┌─────────────┐
│   Lint      │──→ eslint-config-it4c (TS + Vue + Prettier)
├─────────────┤
│   Tests     │──→ Vitest
├─────────────┤
│   Build     │──→ Vite
└─────────────┘
    ↓
Alle grün → Merge erlaubt

Automatische Deployments

Event Aktion
Release erstellt npm publish
Release erstellt Histoire build + deploy auf Server

Histoire Deploy (Webhook):

  1. GitHub sendet Webhook bei Release-Event
  2. Server empfängt Webhook
  3. Server führt scripts/deploy-histoire.sh aus (Teil des Repos)
  4. Script: git pull → npm ci → histoire build → copy to webroot

GitHub Workflows (vollständige Liste)

Workflow Trigger Tool Beschreibung
lint Push/PR eslint-config-it4c Code-Stil prüfen
typecheck Push/PR TypeScript Typ-Fehler finden
test Push/PR Vitest Unit-Tests
test-a11y Push/PR axe-core Accessibility-Tests
test-visual Push/PR Playwright Visual Regression Screenshots
build Push/PR Vite Build verifizieren
build-histoire Push/PR Histoire Dokumentation bauen
size-check Push/PR size-limit Bundle-Größe prüfen
release Push main release-please Release-PR erstellen
publish Release npm Auf npm veröffentlichen
deploy-docs Release Webhook Histoire auf Server deployen
check-ui-release Ocelot Release Git Prüft unreleased UI-Änderungen

Erweiterte Qualitätssicherung

Maßnahme Tool Beschreibung
Visual Regression Playwright Screenshot-Vergleiche bei Änderungen
Accessibility axe-core + vitest-axe Automatische A11y-Prüfung aller Komponenten
Bundle Size size-limit Warnung wenn Library-Größe Schwellwert überschreitet

Migrations-Absicherung

Feature Parity Checklist (pro Komponente):

┌─────────────────────────────────────────────────────────┐
│  KOMPONENTE: [Name]                                     │
├─────────────────────────────────────────────────────────┤
│  [ ] Alle Props der alten Komponente übernommen         │
│  [ ] Alle Events identisch                              │
│  [ ] Alle Slots vorhanden                               │
│  [ ] Default-Werte identisch                            │
│  [ ] Visuell identisch (Screenshot-Vergleich)           │
│  [ ] A11y mindestens gleich gut                         │
│  [ ] Dokumentation vollständig                          │
└─────────────────────────────────────────────────────────┘

Deprecation Warnings: Nach erfolgreicher Migration einer Komponente werden in der Vue 2 Webapp Warnungen eingebaut:

// In alter Komponente
if (process.env.NODE_ENV === 'development') {
  console.warn('[DEPRECATED] Button: Bitte @ocelot-social/ui verwenden')
}

5. Dokumentation & Developer Experience

Histoire als Komponenten-Dokumentation

Die Komponenten werden über Histoire dokumentiert und auf einer öffentlichen Webseite für Entwickler zugänglich gemacht.

Features für Entwickler:

  • Interaktive Playgrounds zum Ausprobieren
  • Alle Varianten und Zustände auf einen Blick
  • Copy-paste-fertige Code-Snippets
  • Suchfunktion
  • Props-Dokumentation mit Typen und Defaults

Hosting:

  • Eigener Server (öffentlich zugänglich)
  • Static Build via histoire build
  • Deployment bei jedem Release

Workflow:

Komponente entwickeln → Histoire Story schreiben → Build → Deploy auf Server

6. Design-Token & Branding-Architektur

3-Stufen Token-System

┌─────────────────────────────────────────────────────────┐
│  1. BASE TOKENS (Rohwerte)                              │
│     --color-green: rgb(23, 181, 63);                    │
│     --color-teal: rgb(110, 139, 135);                   │
│     --space-small: 16px;                                │
└────────────────────────┬────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────┐
│  2. SEMANTIC TOKENS (Bedeutung)                         │
│     --color-primary: var(--color-green);                │
│     --color-secondary: var(--color-teal);               │
│     --text-color-base: var(--color-neutral-20);         │
└────────────────────────┬────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────┐
│  3. COMPONENT TOKENS (Komponenten-spezifisch)           │
│     --button-primary-bg: var(--color-primary);          │
│     --button-primary-text: var(--color-primary-inverse);│
│     --card-bg: var(--background-color-base);            │
└─────────────────────────────────────────────────────────┘

Branding-Flexibilität

Jedes Branding kann auf jeder Ebene eingreifen:

/* Standard */
:root {
  --button-primary-bg: var(--color-primary);
}

/* Yunite-Branding: Button nutzt Secondary statt Primary */
:root {
  --button-primary-bg: var(--color-secondary);
}

Kompatibilität mit bestehendem System

  • Bestehende SCSS-Variablen ($color-primary) → CSS Custom Properties (--color-primary)
  • Theo bleibt als Token-Quelle, generiert zusätzlich CSS Variables
  • Tailwind Theme nutzt CSS Variables: bg-primaryvar(--color-primary)

7. Migrationsstrategie

Grundprinzipien

┌─────────────────────────────────────────────────────────────────┐
│                    MIGRATIONSSTRATEGIE                          │
├─────────────────────────────────────────────────────────────────┤
│  1. Library vollständig in Vue 3 schreiben                      │
│  2. vue-demi für Vue 2 Kompatibilität                           │
│  3. Komponente für Komponente migrieren                         │
│  4. Jede Komponente: vollständig getestet + in Histoire         │
│  5. Nach Migration: Duplikate entfernen, Varianten konsolidieren│
└─────────────────────────────────────────────────────────────────┘

Ablauf pro Komponente

┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│   ANALYSE    │ →  │    SPEC      │ →  │   DEVELOP    │ →  │     QA       │ →  │  INTEGRATE   │
├──────────────┤    ├──────────────┤    ├──────────────┤    ├──────────────┤    ├──────────────┤
│ Bestehende   │    │ Props        │    │ Vue 3 Code   │    │ Alle Tests   │    │ In Vue 2     │
│ Varianten    │    │ Varianten    │    │ Unit Tests   │    │ grün         │    │ Projekt      │
│ identifiz.   │    │ Zustände     │    │ Histoire     │    │ Visual Regr. │    │ einbinden    │
│ Duplikate    │    │ A11y         │    │ Stories      │    │ A11y Check   │    │              │
│ finden       │    │ Tokens       │    │              │    │ Review       │    │ Alte Komp.   │
│              │    │              │    │              │    │              │    │ entfernen    │
└──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘

Komponenten-Protokoll

Pro Komponente wird eine Dokumentationsdatei geführt:

packages/ui/docs/components/OsButton.md

Inhalt:

  • Ursprung (Webapp/Styleguide/Beide)
  • Zusammengeführte Komponenten (falls vorhanden)
  • Entscheidungen und Begründungen
  • Abweichungen von Original
  • Migration History

Qualitätsanforderungen pro Komponente

Anforderung Beschreibung
Vollständig getestet Unit-Tests für alle Props, Varianten, Edge-Cases
Histoire Stories Alle Varianten und Zustände dokumentiert
Detaillierte Spec Props, Events, Slots, A11y vor Implementierung definiert
Token-basiert Nutzt ausschließlich Design Tokens, keine hardcoded Werte
Vue 2 kompatibel Funktioniert via vue-demi im bestehenden Projekt
A11y geprüft axe-core Tests bestanden
Visual Regression Screenshot-Baseline erstellt
Feature Parity Checkliste abgehakt (alle Props, Events, Slots)

Konsolidierungsziele

Bei der Migration werden:

  • Duplikate eliminiert - nur eine kanonische Version pro Komponente
  • Unnötige Varianten entfernt - nur tatsächlich genutzte Varianten
  • Zusammenführbare Komponenten vereint - z.B. verschiedene Button-Typen → ein Button mit Props
  • Inkonsistenzen bereinigt - einheitliche API, Naming, Patterns

8. Meilensteine

Phase 0: Analyse & Katalogisierung

  • Vollständige Katalogisierung Webapp-Komponenten (139 Komponenten)
  • Vollständige Katalogisierung Styleguide-Komponenten (38 Komponenten)
  • Duplikate identifizieren und dokumentieren (5 direkte + 3 Familien)
  • Inkonsistenzen und Probleme erfassen (Button/Modal/Menu analysiert)
  • Konsolidierungsplan erstellen (Token-Liste)
  • Priorisierung der zu migrierenden Komponenten (15 Komponenten in 4 Tiers)

Phase 1: Vue 2.7 Upgrade

  • Vue 2.6 → Vue 2.7 Upgrade in Webapp (2.6.14 → 2.7.16)
  • Abhängigkeiten aktualisieren:
    • vue-template-compiler entfernt (in Vue 2.7 eingebaut)
    • @vue/composition-api entfernt (in Vue 2.7 eingebaut)
    • @nuxtjs/composition-api entfernt (nicht mehr nötig)
    • vue-server-renderer auf 2.7.16 aktualisiert
  • Tests durchführen: 157 Suites, 979 passed, 87 Snapshots
  • Regressionstests (yarn dev und manuelle Prüfung)

Phase 2: Projekt-Setup

  • Vite + Vue 3 Projekt initialisieren
  • vue-demi einrichten für Vue 2 Kompatibilität
  • Tailwind CSS einrichten
  • Dual-Build konfigurieren (Tailwind Preset + vorkompilierte CSS)
  • System-Icons einrichten (Hybrid-Architektur, ~10 Icons)
  • CSS Custom Properties Token-System aufsetzen
  • Dark Mode Grundstruktur
  • Histoire für Dokumentation einrichten
  • Vitest konfigurieren (mit Vue 2/3 Matrix)
  • eslint-config-it4c einrichten (inkl. TypeScript, Vue, Prettier, JSDoc) ⚠️ BLOCKED: siehe §18
  • npm Package-Struktur (@ocelot-social/ui) mit korrekten exports
  • Build-Pipeline für Vue 2/3 Dual-Support
  • GitHub Workflows einrichten (Lint, Test, Build)
  • Visual Regression Tests einrichten (Playwright)
  • Accessibility Tests einrichten (axe-core)
  • Bundle Size Check einrichten (size-limit)
  • Package-Validierung einrichten (publint, arethetypeswrong)
  • Example Apps erstellen (vue3-tailwind, vue3-css, vue2-tailwind, vue2-css)
  • Kompatibilitätstest-Workflow einrichten (siehe §19)
  • release-please Manifest-Konfiguration
  • npm Publish Workflow
  • Histoire Deploy Workflow
  • LICENSE Datei (Apache 2.0)
  • README.md Grundgerüst (Installation, Quick Start, Struktur)
  • CONTRIBUTING.md
  • Docs-Generierung einrichten (vue-component-meta)
  • CI docs-check Workflow

Phase 3: Token-System & Basis

  • Base Tokens definieren (Farben, Spacing, Typography)
  • Semantic Tokens definieren
  • Component Tokens definieren
  • Branding-System implementieren (CSS Variables)
  • Beispiel-Branding erstellen (Standard + Yunite)
  • Token-Dokumentation in Histoire

Phase 4: Komponenten-Migration

  • Komponenten werden nach Analyse-Ergebnis priorisiert
  • Für jede Komponente: Spec → Develop → Test → Integrate
  • Liste wird in Phase 0 erstellt

Phase 5: Finalisierung

  • Alle Komponenten migriert und getestet
  • Alte Komponenten aus Vue 2 Projekt entfernt
  • Build als npm Library verifiziert
  • README.md finalisieren (alle Sektionen vollständig)
  • ARCHITECTURE.md erstellen (aus PROJEKT.md §2, §6, §11, §15, §16)
  • PROJEKT.md und KATALOG.md archivieren (docs/archive/)
  • Dokumentation vollständig und CI-geprüft

9. Fortschritt

Gesamtprojekt

Phase 0: ██████████ 100% (6/6 Aufgaben) ✅
Phase 1: ██████████ 100% (6/6 Aufgaben) ✅
Phase 2: ░░░░░░░░░░   0% (0/26 Aufgaben)
Phase 3: ░░░░░░░░░░   0% (0/6 Aufgaben)
Phase 4: ░░░░░░░░░░   0% (0/15 Komponenten)
Phase 5: ░░░░░░░░░░   0% (0/7 Aufgaben)
───────────────────────────────────────
Gesamt:  ██░░░░░░░░  ~15%

Katalogisierung (Details in KATALOG.md)

Webapp:     ██████████ 100% (139 Komponenten erfasst)
Styleguide: ██████████ 100% (38 Komponenten erfasst)
Analyse:    ██████████ 100% (Button, Modal, Menu detailiert)

Komponenten-Migration (Priorisiert: 15)

Analysiert:   3 Familien (Button, Modal, Menu)
Spezifiziert: 0
Entwickelt:   0
QA bestanden: 0
Integriert:   0

10. Aktueller Stand

Letzte Aktualisierung: 2026-02-04

Aktuelle Phase: Phase 2 (Projekt-Setup) - Bereit zum Start

Zuletzt abgeschlossen:

  • Projektordner erstellt
  • Planungsdokument erstellt
  • Tech-Stack entschieden
  • Branding-Architektur definiert
  • Migrationsstrategie definiert
  • Phase 0: Komponenten-Analyse (177 Komponenten katalogisiert)
  • Button-Familie detailiert analysiert (Props, Styles, Konsolidierung)
  • Modal-Familie detailiert analysiert (Architektur erkannt)
  • Menu-Familie detailiert analysiert (3 Patterns identifiziert)
  • Priorisierung erstellt (15 Komponenten in 4 Tiers)
  • Konsolidierungsplan finalisiert
  • Phase 1: Vue 2.7 Upgrade
    • Vue 2.6.14 → 2.7.16
    • vue-template-compiler entfernt
    • @vue/composition-api entfernt
    • @nuxtjs/composition-api entfernt
    • Webpack-Alias für @vue/composition-api → vue
    • Webpack-Regel für ESM .mjs Module
    • Unit-Tests: 157 Suites, 979 passed, 87 Snapshots
    • Integrationstests: bestanden

Aktuell in Arbeit:

  • Nichts - Bereit für Phase 2

Nächste Schritte:

  1. Phase 0: Komponenten-Analyse
  2. Phase 1: Vue 2.7 Upgrade
  3. Phase 2: Projekt-Setup (Vite + Vue 3 + Histoire)

11. Entscheidungen

# Frage Entscheidung Begründung
1 Hauptziel Migration vorbereiten Schrittweise Vue 2 → Vue 3
2 Framework Vue 3 + Vite Modern, schnell, gute DX
3 Dokumentation Histoire Vite-nativ, schneller als Storybook
4 Styling Tailwind + CSS Variables Modern + Branding-kompatibel
5 Token-System 3-Stufen (Base/Semantic/Component) Maximale Branding-Flexibilität
6 Testing Vitest Vite-nativ, Jest-kompatibel
7 Komponenten-Reihenfolge Nach Bedarf Flexibel, Token-System zuerst
8 Paket-Format npm Library Wiederverwendbar
9 Vue 2 Kompatibilität vue-demi Library funktioniert in beiden Vue-Versionen
10 Migrations-Ablauf Komponente für Komponente Kontrolliert, schrittweise
11 Vor-Analyse Vollständige Analyse Duplikate/Probleme vor Migration identifizieren
12 Spezifikation Detailliert vor Implementierung Props, Varianten, A11y vorher definieren
13 Doku-Hosting Eigener Server Öffentlich zugängliche Komponenten-Doku
14 Doku-Zugang Öffentlich Für alle Entwickler frei zugänglich
15 Release-Tool release-please (Manifest) Monorepo-kompatibel, nur styleguide-vue3 Änderungen
16 Linting eslint-config-it4c TypeScript + Vue + Prettier + weitere Regeln
17 CI Workflows Lint, Test, Build Qualitätssicherung bei jedem PR
18 npm Publish Automatisch bei Release Nach release-please PR merge
19 Doku-Deploy Automatisch bei Release Histoire build + deploy
20 Visual Regression Playwright Screenshots Visueller Vergleich bei Änderungen
21 Accessibility axe-core + vitest-axe Automatische A11y-Prüfung
22 Bundle Size size-limit Warnung bei Größenüberschreitung
23 Feature Parity Checkliste pro Komponente Sicherstellen dass alle Features migriert
24 Deprecation Warnings Console Warnings Hinweise in alter Codebase
25 Paket-Name @ocelot-social/ui Unter ocelot-social npm Org
26 Komponenten-Prefix Os OsButton, OsCard, etc.
27 Browser-Support Modern only Letzte 2 Versionen von Chrome, Firefox, Safari, Edge
28 SSR Ja Nuxt-kompatibel
29 Dark Mode Ja, von Anfang an Alle Komponenten mit Light/Dark
30 Icons Hybrid-Architektur System-Icons in Library, Feature-Icons in App
31 Build-Strategie Dual-Build Tailwind Preset + Vorkompilierte CSS
32 Lizenz Apache 2.0 Permissiv mit Patent-Schutz
33 Repository Monorepo Ocelot-Social/packages/ui/
34 Vue API <script setup> Composition API mit script setup
35 Sprache Englisch Code, Comments, Docs
36 Package Manager npm Bereits im Projekt verwendet
37 Test Coverage 100% Vollständige Testabdeckung
38 Dateinamen PascalCase OsButton.vue, OsCard.vue
39 i18n Nur Props Keine Default-Texte in Komponenten
40 Breakpoints Tailwind Standard sm, md, lg, xl, 2xl
41 TypeScript strict: true Strikte Typisierung
42 Ordnerstruktur packages/ui Monorepo-Standard, erweiterbar
43 Vue 2 Minimum Vue 2.7 Erforderlich für <script setup> Support
44 Dev-Linking Nuxt Alias LOCAL_UI=true für lokale Library
45 Release-Check Git-basiert Prüft unreleased UI-Änderungen vor Ocelot-Release
46 Histoire Deploy Webhook + Script Server zieht und baut bei Release
47 Komponenten-Protokoll Markdown pro Komponente docs/components/OsButton.md
48 Katalogisierung KATALOG.md Unterbrechbar, Webapp + Styleguide
49 Fortschritt Berechenbar Pro Phase und Gesamt
50 GitHub Workflows 12 Workflows Vollständige CI/CD Pipeline
51 Icon-Architektur Hybrid ~10 System-Icons in Library, Rest in App (siehe §15)
52 Docs-Generierung vue-component-meta Komponenten-Tabelle aus Code generiert
53 Docs CI-Check GitHub Workflow Prüft JSDoc-Coverage und README-Aktualität
54 Nach Migration ARCHITECTURE.md PROJEKT.md → ARCHITECTURE.md, KATALOG.md archivieren
55 Komponenten-Abgrenzung Entscheidungsbaum Library: präsentational, Webapp: Business-Logik (siehe §17)
56 Externe Abhängigkeiten Dokumentiert in §18 eslint-config-it4c muss modularisiert werden
57 Kompatibilitätstests 4er-Matrix + CI Vue 2/3 × Tailwind/CSS (siehe §19)

12. Arbeitsprotokoll

Datum Beschreibung Ergebnis
2026-02-04 Projektstart Ordner und Planungsdokument erstellt
2026-02-04 Tech-Stack Entscheidungen Alle Kernentscheidungen getroffen
2026-02-04 Migrationsstrategie vue-demi, Komponente-für-Komponente, Analyse-First
2026-02-04 Dokumentation Histoire auf eigenem Server, öffentlich zugänglich
2026-02-04 CI/CD & Release release-please, GitHub Workflows, automatisches npm publish
2026-02-04 Erweiterte QA Visual Regression, A11y Tests, Bundle Size Check
2026-02-04 Migrations-Absicherung Feature Parity Checklist, Deprecation Warnings
2026-02-04 Naming & Paket @ocelot-social/ui, Os-Prefix
2026-02-04 Plattform Modern Browsers, SSR-kompatibel, Dark Mode
2026-02-04 Build & Icons Dual-Build (Tailwind + CSS), unplugin-icons
2026-02-04 Organisatorisch Apache 2.0, bleibt im Monorepo
2026-02-04 Konventionen script setup, Englisch, npm, 100% Coverage, PascalCase
2026-02-04 Weitere Nur Props (kein i18n), Tailwind Breakpoints, strict TS
2026-02-04 Ordnerstruktur packages/ui statt styleguide-vue3
2026-02-04 Konfliktanalyse Vue 2.7 Upgrade als Voraussetzung für script setup
2026-02-04 Webapp-Integration Nuxt Alias für lokale Entwicklung, Git-basierter Release-Check
2026-02-04 Prozesse QA-Schritt pro Komponente, Komponenten-Protokoll, KATALOG.md
2026-02-04 Fortschritt Berechenbar für Gesamt und Einzelschritte
2026-02-04 Phase 1 abgeschlossen Vue 2.7 Upgrade erfolgreich, alle Tests bestanden
2026-02-04 Icon-Architektur Hybrid-Ansatz: ~10 System-Icons in Library, Feature-Icons in App
2026-02-04 Dokumentationsstrategie Hybrid: Generiert (vue-component-meta) + Manuell, CI-geprüft
2026-02-04 Abgrenzung Library/Webapp Entscheidungsbaum + Checkliste für Komponenten-Zuordnung
2026-02-04 Externe Abhängigkeit eslint-config-it4c blockiert Linting-Setup, Workaround dokumentiert
2026-02-04 Kompatibilitätstests 4er-Matrix (Vue 2/3 × Tailwind/CSS), Example Apps, Playwright E2E
2026-02-04 Phasen umbenannt 0.5→1, 1→2, 2→3, 3→4, 4→5 (nur ganzzahlige Phasen)

13. Komponenten-Katalog

Detaillierte Katalogisierung in separater Datei: KATALOG.md

Zusammenfassung (wird automatisch aus KATALOG.md übernommen)

Quelle Gesamt Analysiert Duplikate Zu migrieren
Webapp ~60+ 0 0 ?
Styleguide ~15 0 0 ?
Gesamt ~75+ 0 0 ?

Projekt:

Tracking:

  • Katalogisierung: ./KATALOG.md
  • Komponenten-Docs: ./docs/components/

Dokumentation:


15. Icon-Architektur

Entscheidung: Hybrid-Ansatz

Die Library verwendet eine Hybrid-Architektur für Icons:

┌─────────────────────────────────────────────────────────────┐
│  @ocelot-social/ui (Library)                                │
├─────────────────────────────────────────────────────────────┤
│  icons/system/           # ~10 System-Icons                 │
│  ├── close.svg           # Modal, Chip, Dialoge             │
│  ├── check.svg           # Modal confirm, Checkboxen        │
│  ├── chevron-down.svg    # Select, Dropdown                 │
│  ├── chevron-up.svg      # Select, Accordion                │
│  ├── spinner.svg         # Loading-States                   │
│  ├── bars.svg            # Hamburger-Menu                   │
│  ├── copy.svg            # CopyField                        │
│  ├── eye.svg             # Password-Toggle                  │
│  ├── eye-slash.svg       # Password-Toggle, Anonym          │
│  └── search.svg          # Search-Input                     │
└─────────────────────────────────────────────────────────────┘
                            ↓
┌─────────────────────────────────────────────────────────────┐
│  Webapp / Konsumierendes Projekt                            │
├─────────────────────────────────────────────────────────────┤
│  assets/icons/           # Feature-Icons (beliebig viele)   │
│  ├── user.svg            │
│  ├── bell.svg            │
│  ├── heart.svg           │
│  ├── settings.svg        │
│  └── ...                 │
└─────────────────────────────────────────────────────────────┘

Begründung

  1. Library muss standalone funktionieren - Ein OsModal braucht einen Close-Button ohne zusätzliche Konfiguration
  2. 616 Icons sind zu viel - Der Styleguide hat 616 Icons, die meisten werden nie gebraucht
  3. Feature-Icons gehören zur App - Icons wie user, bell, heart sind Business-Logik
  4. Branding-Flexibilität - Verschiedene Ocelot-Instanzen können unterschiedliche Icon-Sets verwenden

System-Icons (in Library enthalten)

Icon Verwendung in Komponenten
close OsModal, OsChip, OsDialog, OsAlert
check OsModal (confirm), OsCheckbox
chevron-down OsSelect, OsDropdown, OsAccordion
chevron-up OsSelect, OsAccordion
spinner OsButton (loading), OsSpinner
bars OsPage (mobile menu)
copy OsCopyField
eye OsInput (password toggle)
eye-slash OsInput (password toggle), OsAvatar (anonym)
search OsInput (search variant)

API-Design

// OsIcon akzeptiert verschiedene Formate:

// 1. System-Icon (String) - aus Library
<OsIcon name="close" />

// 2. Vue-Komponente - für App-Icons
<OsIcon :icon="UserIcon" />

// 3. In Komponenten mit icon-Prop
<OsButton icon="close" />           // System-Icon
<OsButton :icon="CustomIcon" />     // Komponente

Webapp-Integration

// webapp/plugins/icons.ts
import { provideIcons } from '@ocelot-social/ui'
import * as appIcons from '~/assets/icons'

export default defineNuxtPlugin((nuxtApp) => {
  // App-Icons global registrieren
  provideIcons(appIcons)
})
<!-- Dann in der Webapp nutzbar -->
<OsButton :icon="icons.user" />
<OsIcon :icon="icons.bell" />

Aktuelle Icon-Statistik

Quelle Anzahl Status
Styleguide (_all) 616 Nicht übernehmen (FontAwesome 4 komplett)
Webapp (svgs) 238 Feature-Icons, bleiben in Webapp
Library (system) ~10 Nur essenzielle System-Icons

16. Dokumentationsstrategie

Übersicht

┌─────────────────────────────────────────────────────────────┐
│  GENERIERT (aus Code) - Single Source of Truth              │
├─────────────────────────────────────────────────────────────┤
│  • README.md Komponenten-Tabelle                            │
│  • Props/Events/Slots Dokumentation                         │
│  • TypeScript-Typen                                         │
└─────────────────────────────────────────────────────────────┘
                            +
┌─────────────────────────────────────────────────────────────┐
│  MANUELL                                                    │
├─────────────────────────────────────────────────────────────┤
│  • README.md Installation, Quick Start, Theming             │
│  • Histoire Stories (interaktive Beispiele)                 │
│  • ARCHITECTURE.md (Entscheidungen)                         │
│  • Best Practices, Patterns                                 │
└─────────────────────────────────────────────────────────────┘

README.md Struktur

# @ocelot-social/ui

## Übersicht
- Was ist die Library?
- Link zu Histoire (Live-Dokumentation)

## Installation
- npm install
- Peer Dependencies (vue, vue-demi)

## Quick Start
- Minimal-Beispiel (Import + Nutzung)
- Mit Tailwind / Ohne Tailwind

## Theming / Branding
- CSS Custom Properties überschreiben
- Beispiel-Branding

## Icon-System
- System-Icons (enthalten)
- Eigene Icons registrieren

## Vue 2 / Vue 3
- vue-demi Erklärung
- Kompatibilitätshinweise

## Komponenten                    ← GENERIERT
- Tabelle aller Komponenten
- Link zu Histoire für Details

## Contributing
- Link zu CONTRIBUTING.md

## License
- Apache 2.0

Generierung mit vue-component-meta

Tool: vue-component-meta (offizielles Vue-Tool)

// scripts/generate-docs.ts
import { createComponentMetaChecker } from 'vue-component-meta'

// Extrahiert aus .vue Dateien:
{
  name: "OsButton",
  description: "Primary button component for user actions",
  props: [
    {
      name: "variant",
      type: "'primary' | 'secondary' | 'danger'",
      default: "'primary'",
      required: false,
      description: "Visual style variant"
    }
  ],
  events: [{ name: "click", type: "(event: MouseEvent) => void" }],
  slots: [{ name: "default", description: "Button content" }]
}

Generierte Komponenten-Tabelle:

| Komponente | Beschreibung | Props | Events | Slots |
|------------|--------------|-------|--------|-------|
| OsButton | Primary button for actions | 8 | 1 | 2 |
| OsCard | Container with header/footer | 5 | 0 | 3 |
| ... | ... | ... | ... | ... |

CI-Workflow: docs-check

# .github/workflows/docs-check.yml
name: Documentation Check

on: [push, pull_request]

jobs:
  docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generate docs from components
        run: npm run docs:generate

      - name: Check for undocumented props
        run: npm run docs:check-coverage
        # Fails if props/events/slots missing JSDoc

      - name: Verify README is up-to-date
        run: npm run docs:verify
        # Compares generated table with README
        # Fails if differences found

Scripts in package.json:

{
  "scripts": {
    "docs:generate": "tsx scripts/generate-docs.ts",
    "docs:check-coverage": "tsx scripts/check-doc-coverage.ts",
    "docs:verify": "tsx scripts/verify-readme.ts",
    "docs:update": "npm run docs:generate && npm run docs:inject-readme"
  }
}

ESLint-Regeln für Dokumentation

// eslint.config.js
{
  rules: {
    // Erzwingt JSDoc für exportierte Funktionen/Komponenten
    "jsdoc/require-jsdoc": ["error", {
      require: {
        FunctionDeclaration: true,
        ClassDeclaration: true
      }
    }],
    "jsdoc/require-description": "error",
    "jsdoc/require-param-description": "error"
  }
}

Dokumentations-Phasen

Phase Dokumentation Status
Phase 2 README.md Grundgerüst (Installation, Setup) Manuell
Phase 2 CONTRIBUTING.md Manuell
Phase 2 docs:generate Script einrichten Automatisiert
Phase 2 CI docs-check Workflow Automatisiert
Phase 4 Histoire Stories pro Komponente Manuell
Phase 4 JSDoc in Komponenten Im Code
Phase 4 README Komponenten-Tabelle Generiert
Phase 5 ARCHITECTURE.md (aus PROJEKT.md) Manuell
Phase 4 README Finalisierung Manuell

Nach der Migration: Datei-Transformation

Während Migration:
├── PROJEKT.md          # Planungs- und Statusdokument
├── KATALOG.md          # Komponenten-Tracking

Nach Phase 5 (Migration abgeschlossen):
├── README.md           # Nutzer-Dokumentation (teilweise generiert)
├── CONTRIBUTING.md     # Beitragende
├── CHANGELOG.md        # Automatisch via release-please
├── docs/
│   ├── ARCHITECTURE.md # Entscheidungen aus PROJEKT.md §2, §6, §11, §15
│   └── archive/        # Historische Referenz (optional)
│       ├── PROJEKT.md
│       └── KATALOG.md

Was wird übernommen nach ARCHITECTURE.md:

  • §2 Tech-Stack (gekürzt)
  • §6 Token-System (Design-Token-Architektur)
  • §11 Entscheidungen (relevante, nicht Prozess-bezogene)
  • §15 Icon-Architektur
  • §16 Dokumentationsstrategie (gekürzt)
  • §17 Abgrenzung Library vs. Webapp

Was wird archiviert/gelöscht:

  • §8 Meilensteine → erledigt
  • §9 Fortschritt → erledigt
  • §10 Aktueller Stand → erledigt
  • §12 Arbeitsprotokoll → historisch interessant, archivieren
  • KATALOG.md → nur für Migration relevant, archivieren

17. Abgrenzung: Library vs. Webapp

Grundprinzip

┌─────────────────────────────────────────────────────────────┐
│  @ocelot-social/ui (Library)                                │
├─────────────────────────────────────────────────────────────┤
│  • Rein präsentational                                      │
│  • Keine Business-Logik                                     │
│  • Keine API-Calls                                          │
│  • Kein App-State                                           │
│  • Wiederverwendbar in jedem Vue-Projekt                    │
└─────────────────────────────────────────────────────────────┘
                            ▲
                            │ nutzt
┌─────────────────────────────────────────────────────────────┐
│  Webapp (Ocelot)                                            │
├─────────────────────────────────────────────────────────────┤
│  • Business-Logik (GraphQL, Auth, etc.)                     │
│  • App-State (Vuex/Pinia)                                   │
│  • i18n Texte                                               │
│  • Routing-Logik                                            │
│  • Ocelot-spezifische Features                              │
└─────────────────────────────────────────────────────────────┘

Entscheidungs-Checkliste

Kriterium Library Webapp
Business-Logik Keine Hat GraphQL/API-Calls
App-State Kein Vuex/Pinia Braucht Store
i18n Nur via Props Nutzt $t() direkt
Routing Nur via Props (to) Nutzt $router direkt
Wiederverwendbar In jedem Vue-Projekt Nur in Ocelot
Abhängigkeiten Nur Vue + vue-demi Ocelot-spezifisch
Styling Design-Tokens App-spezifische Styles
Daten Erhält via Props Fetcht selbst

Entscheidungsbaum

Komponente X
    │
    ▼
┌─────────────────────────────────────┐
│ Hat sie Business-Logik?             │
│ (API-Calls, Mutations, Auth-Check)  │
└─────────────────────────────────────┘
    │
    ├── JA ──► WEBAPP
    │
    ▼ NEIN
┌─────────────────────────────────────┐
│ Braucht sie App-State?              │
│ (Vuex, Pinia, globaler State)       │
└─────────────────────────────────────┘
    │
    ├── JA ──► WEBAPP
    │
    ▼ NEIN
┌─────────────────────────────────────┐
│ Nutzt sie $t() oder $router direkt? │
└─────────────────────────────────────┘
    │
    ├── JA ──► WEBAPP (oder refactoren)
    │
    ▼ NEIN
┌─────────────────────────────────────┐
│ Ist sie generisch wiederverwendbar? │
│ (Könnte in anderem Projekt helfen)  │
└─────────────────────────────────────┘
    │
    ├── NEIN ──► WEBAPP
    │
    ▼ JA

    ══► LIBRARY

Quantitative Regel

Wenn ≥2 Kriterien auf "Webapp" zeigen → Webapp Wenn alle Kriterien auf "Library" zeigen → Library

Konkrete Beispiele

Komponente Entscheidung Begründung
OsButton Library Rein präsentational, keine Logik
OsModal Library UI-Container, Logik via Events
OsInput Library Generisches Form-Element
OsAvatar Library Nur Bild + Fallback-Initialen
OsCard Library Layout-Container
OsDropdown Library Popover-Mechanik
FollowButton Webapp GraphQL Mutation, User-State
PostTeaser Webapp Ocelot-Datenstruktur, Links
CommentForm Webapp API-Call, Auth-Check
ConfirmModal Webapp Nutzt OsModal + Callbacks
LoginForm Webapp Auth-Logik, Routing, i18n
UserAvatar Webapp Nutzt OsAvatar + User-Daten
NotificationMenu Webapp GraphQL, Store, i18n

Composition Pattern für Grenzfälle

Wenn eine Komponente UI- und Business-Anteile hat: Aufteilen

┌─────────────────────────────────────────────────────────────┐
│  LIBRARY: OsModal                                           │
│  - Overlay, Animation, Backdrop                             │
│  - close/confirm Events                                     │
│  - Slots für Content                                        │
│  - Props: title, confirmLabel, cancelLabel                  │
└─────────────────────────────────────────────────────────────┘
                        ▲
                        │ nutzt
┌─────────────────────────────────────────────────────────────┐
│  WEBAPP: DeleteUserModal                                    │
│  - Wraps OsModal                                            │
│  - GraphQL Mutation                                         │
│  - i18n Texte via $t()                                      │
│  - Redirect nach Löschung                                   │
└─────────────────────────────────────────────────────────────┘

Beispiel-Code:

<!-- Webapp: DeleteUserModal.vue -->
<template>
  <OsModal
    :title="$t('user.delete.title')"
    :confirm-label="$t('common.delete')"
    confirm-variant="danger"
    @confirm="handleDelete"
    @cancel="$emit('close')"
  >
    <p>{{ $t('user.delete.warning', { name: user.name }) }}</p>
  </OsModal>
</template>

<script setup>
import { OsModal } from '@ocelot-social/ui'
import { useDeleteUserMutation } from '~/graphql/mutations'
import { useRouter } from 'vue-router'

const props = defineProps(['user'])
const emit = defineEmits(['close'])
const router = useRouter()
const { mutate: deleteUser } = useDeleteUserMutation()

const handleDelete = async () => {
  await deleteUser({ id: props.user.id })
  emit('close')
  router.push('/')
}
</script>

Checkliste bei neuer Komponente

Vor dem Erstellen einer Komponente diese Fragen beantworten:

[ ] Wo gehört die Komponente hin? (Entscheidungsbaum durchlaufen)
[ ] Falls Library: Sind alle Texte via Props?
[ ] Falls Library: Keine direkten Store/Router Imports?
[ ] Falls Webapp: Welche Library-Komponenten werden genutzt?
[ ] Falls Grenzfall: Kann sie aufgeteilt werden?

18. Externe Abhängigkeiten

Übersicht

Einige Aufgaben in diesem Projekt sind von externen Projekten abhängig, die zuerst angepasst werden müssen.

Abhängigkeit Status Blockiert Beschreibung
eslint-config-it4c ⚠️ Offen Phase 2: Linting Paket muss modularer werden

eslint-config-it4c

Repository: it4c/eslint-config-it4c (vermutlich)

Problem: Das Paket ist aktuell nicht modular genug, um in der UI-Library eingesetzt zu werden. Es muss angepasst werden, um:

  • Einzelne Regelsets separat importierbar zu machen (TypeScript, Vue, Prettier, JSDoc)
  • Flexible Konfiguration für verschiedene Projekttypen zu ermöglichen
  • Kompatibel mit dem Flat Config Format (ESLint 9+) zu sein

Erforderliche Änderungen im externen Projekt:

eslint-config-it4c/
├── base.js           # Basis-Regeln
├── typescript.js     # TypeScript-Regeln (optional)
├── vue.js            # Vue-Regeln (optional)
├── prettier.js       # Prettier-Integration (optional)
├── jsdoc.js          # JSDoc-Regeln (optional)
└── index.js          # Alles kombiniert (Vollversion)

Gewünschte Nutzung in @ocelot-social/ui:

// eslint.config.js
import baseConfig from 'eslint-config-it4c/base'
import typescriptConfig from 'eslint-config-it4c/typescript'
import vueConfig from 'eslint-config-it4c/vue'
import prettierConfig from 'eslint-config-it4c/prettier'
import jsdocConfig from 'eslint-config-it4c/jsdoc'

export default [
  ...baseConfig,
  ...typescriptConfig,
  ...vueConfig,
  ...prettierConfig,
  ...jsdocConfig,
  {
    // Projekt-spezifische Overrides
  }
]

Workaround bis Abhängigkeit erfüllt:

  • Temporär eigene ESLint-Konfiguration in packages/ui erstellen
  • Nach Modularisierung von eslint-config-it4c migrieren

Tracking:

  • Issue in eslint-config-it4c erstellen
  • Modulare Struktur implementieren
  • Neue Version releasen
  • In @ocelot-social/ui einbinden

19. Kompatibilitätstests (Vue 2/3 + Tailwind/CSS)

Testmatrix

Die Library muss in 4 Kombinationen funktionieren:

                    │  Tailwind         │  CSS (vorkompiliert)
────────────────────┼───────────────────┼──────────────────────
Vue 3.4+            │  ✓ Muss testen    │  ✓ Muss testen
Vue 2.7             │  ✓ Muss testen    │  ✓ Muss testen

Werkzeuge & Strategien

1. vue-demi (Code-Ebene)

Abstrahiert Vue 2/3 API-Unterschiede:

// Komponente importiert von vue-demi, nicht vue
import { ref, computed, defineComponent } from 'vue-demi'

2. Unit Tests mit Vitest (Vue 2/3 Matrix)

// vitest.config.ts
export default defineConfig({
  test: {
    alias: {
      'vue': process.env.VUE_VERSION === '2'
        ? 'vue2.7'
        : 'vue'
    }
  }
})

3. Example Apps (4 Kombinationen)

packages/ui/
├── examples/
│   ├── vue3-tailwind/     # Vite + Vue 3 + Tailwind Preset
│   │   ├── package.json
│   │   ├── vite.config.ts
│   │   ├── tailwind.config.js  # Nutzt @ocelot-social/ui/tailwind.preset
│   │   └── src/App.vue         # Importiert alle Komponenten
│   │
│   ├── vue3-css/          # Vite + Vue 3 + styles.css
│   │   ├── package.json
│   │   ├── vite.config.ts
│   │   └── src/
│   │       ├── main.ts         # import '@ocelot-social/ui/styles.css'
│   │       └── App.vue
│   │
│   ├── vue2-tailwind/     # Vue CLI / Nuxt 2 + Tailwind
│   │   └── ...
│   │
│   └── vue2-css/          # Vue CLI / Nuxt 2 + styles.css
│       └── ...

Jede Example App:

  • Importiert @ocelot-social/ui via Workspace-Link
  • Rendert alle exportierten Komponenten
  • Kann lokal gestartet werden (npm run dev)
  • Wird in CI gebaut und getestet

4. Playwright E2E Tests

// e2e/compatibility.spec.ts
import { test, expect } from '@playwright/test'

const examples = [
  { name: 'vue3-tailwind', port: 3001 },
  { name: 'vue3-css', port: 3002 },
  { name: 'vue2-tailwind', port: 3003 },
  { name: 'vue2-css', port: 3004 },
]

for (const example of examples) {
  test.describe(example.name, () => {
    test('all components render', async ({ page }) => {
      await page.goto(`http://localhost:${example.port}`)

      // Prüfe dass alle Komponenten sichtbar sind
      await expect(page.locator('[data-testid="os-button"]')).toBeVisible()
      await expect(page.locator('[data-testid="os-card"]')).toBeVisible()
      await expect(page.locator('[data-testid="os-modal"]')).toBeVisible()
    })

    test('styles are applied correctly', async ({ page }) => {
      await page.goto(`http://localhost:${example.port}`)
      const button = page.locator('[data-testid="os-button-primary"]')

      // Prüfe dass CSS korrekt angewendet wird
      await expect(button).toHaveCSS('background-color', /rgb/)
    })

    test('visual regression', async ({ page }) => {
      await page.goto(`http://localhost:${example.port}`)
      await expect(page).toHaveScreenshot(`${example.name}.png`)
    })
  })
}

5. Package Validation

Tool Zweck
publint Prüft package.json auf Export-Fehler
arethetypeswrong Prüft TypeScript-Typen für alle Entry Points
{
  "scripts": {
    "check:exports": "publint && attw --pack .",
    "prepublishOnly": "npm run check:exports"
  }
}

6. package.json Exports (korrekte Struktur)

{
  "name": "@ocelot-social/ui",
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    },
    "./styles.css": "./dist/styles.css",
    "./tailwind.preset": {
      "import": "./dist/tailwind.preset.mjs",
      "require": "./dist/tailwind.preset.cjs",
      "types": "./dist/tailwind.preset.d.ts"
    }
  },
  "peerDependencies": {
    "vue": "^2.7.0 || ^3.0.0"
  },
  "peerDependenciesMeta": {
    "tailwindcss": {
      "optional": true
    }
  }
}

CI Workflow: Compatibility Matrix

# .github/workflows/compatibility.yml
name: Compatibility Tests

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: packages/ui/dist

  test-unit:
    needs: build
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        vue-version: ['2.7', '3.4']
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: packages/ui/dist
      - run: npm ci
      - run: npm test
        env:
          VUE_VERSION: ${{ matrix.vue-version }}

  test-e2e:
    needs: build
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        example: ['vue3-tailwind', 'vue3-css', 'vue2-tailwind', 'vue2-css']
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: packages/ui/dist

      - name: Setup example app
        working-directory: packages/ui/examples/${{ matrix.example }}
        run: |
          npm ci
          npm run build

      - name: Start preview server
        working-directory: packages/ui/examples/${{ matrix.example }}
        run: npm run preview &

      - name: Wait for server
        run: npx wait-on http://localhost:4173 --timeout 30000

      - name: Run Playwright tests
        working-directory: packages/ui
        run: npx playwright test --grep "${{ matrix.example }}"

      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report-${{ matrix.example }}
          path: packages/ui/playwright-report/

  validate-package:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: packages/ui/dist
      - run: npm ci
      - name: Validate exports
        run: |
          npx publint packages/ui
          npx @arethetypeswrong/cli packages/ui

Werkzeug-Übersicht

Werkzeug Zweck Phase
vue-demi Vue 2/3 API-Kompatibilität im Code Phase 2
Vitest + Matrix Unit Tests für Vue 2.7 und Vue 3.4 Phase 2
Example Apps (4x) Echte Projekte für jede Kombination Phase 2
Playwright E2E + Visual Regression für alle 4 Phase 2
publint Package.json Export-Validierung Phase 2
arethetypeswrong TypeScript Entry Points Check Phase 2
pkg-pr-new Preview-Releases in PRs (optional) Optional

Checkliste für neue Komponenten

[ ] Unit Tests laufen mit VUE_VERSION=2.7
[ ] Unit Tests laufen mit VUE_VERSION=3.4
[ ] Komponente in allen 4 Example Apps hinzugefügt
[ ] E2E Tests für Komponente geschrieben
[ ] Visual Regression Baseline erstellt
[ ] Keine Vue 3-only APIs verwendet (oder via vue-demi abstrahiert)

Wie dieses Dokument verwendet wird

Zum Fortsetzen der Arbeit:

"Lass uns am @ocelot-social/ui Projekt weiterarbeiten" (packages/ui)

Nach jeder Session aktualisieren:

  • Abschnitt 9: "Fortschritt"
  • Abschnitt 10: "Aktueller Stand"
  • Abschnitt 12: "Arbeitsprotokoll"
  • KATALOG.md (ab Phase 0)
  • Meilenstein-Checklisten in Abschnitt 8