# Unified Skills Hub — Plan ## Anforderungsanalyse **Was:** Die zwei getrennten Skill-Seiten (`/analytics/skills` = SkillsAnalytics, `/analytics/skill-marketplace` = SkillMarketplace) zu **einer einzigen, nutzerfreundlichen Skills-Hub-Seite** zusammenfuehren. **Problem heute:** - **SkillsAnalytics** (496 LOC): Skill-Tabelle mit Filtern, People Finder (AND/OR Suche), XLSX Export, Skill Distribution Chart, Skill Gap Alerts - **SkillMarketplace** (346 LOC): Skill-Suche mit Verfuegbarkeitsfilter, Skill Gap Heat Map (Supply vs Demand), Skill Distribution Chart (dupliziert!) - **Ueberlappung:** Beide haben `ProficiencyBadge`, `PROFICIENCY_CLASSES`, `SkillDistributionChart`, aehnliche Tabellen - **Verwirrung:** User muss zwei Seiten besuchen fuer zusammenhaengende Informationen - **Inkonsistenz:** Analytics hat kein Dark-Theme auf manchen Elementen, Marketplace hat es **Ziel:** Eine Seite `/analytics/skills` mit Tab-basiertem Layout: ``` +-------------------------------------------------------------+ | Skills Hub [Export] | | 125 resources . 47 distinct skills | +----------+----------+----------+-------------+--------------+ | Overview | Search | Gaps | People | Distribution | +----------+----------+----------+-------------+--------------+ | | | [Tab content area] | | | +--------------------------------------------------------------+ ``` ### Betroffene Pakete & Dateien | Paket | Dateien | Art der Aenderung | |-------|---------|------------------| | `apps/web` | `src/components/analytics/SkillsHub.tsx` | **create** — neue unified component | | `apps/web` | `src/components/analytics/skills/OverviewTab.tsx` | **create** — KPI cards + distribution chart | | `apps/web` | `src/components/analytics/skills/SearchTab.tsx` | **create** — skill search + availability (from Marketplace) | | `apps/web` | `src/components/analytics/skills/GapsTab.tsx` | **create** — supply/demand gap analysis (from Marketplace) | | `apps/web` | `src/components/analytics/skills/PeopleFinderTab.tsx` | **create** — AND/OR skill search (from Analytics) | | `apps/web` | `src/components/analytics/skills/shared.tsx` | **create** — ProficiencyBadge, GapIndicator, constants | | `apps/web` | `src/app/(app)/analytics/skills/page.tsx` | **edit** — render SkillsHub statt SkillsAnalytics | | `apps/web` | `src/app/(app)/analytics/skill-marketplace/page.tsx` | **edit** — redirect to /analytics/skills | | `apps/web` | `src/components/layout/AppShell.tsx` | **edit** — remove "Skill Marketplace" nav link | | `packages/api` | `src/router/resource.ts` | **edit** — add unified getSkillsHub query | ### Task-Liste - [ ] **Task 1:** Shared utilities extrahieren -> `skills/shared.tsx` - `ProficiencyBadge`, `GapIndicator`, `PROFICIENCY_CLASSES`, `PROFICIENCY_LABELS`, `proficiencyClasses()` - Einmal definieren, ueberall nutzen - [ ] **Task 2:** API: neuen `getSkillsHub` Query -> `resource.ts` - Kombiniert alle Daten in einem Call: - `aggregated` (from getSkillsAnalytics) - `searchResults` (from getSkillMarketplace) - `gapData` (from getSkillMarketplace) - `distribution` (from both, dedupliziert) - `totalResources`, `totalSkillEntries` - Alte Queries behalten (AI Assistant nutzt sie) - [ ] **Task 3:** OverviewTab bauen -> `skills/OverviewTab.tsx` - KPI Cards: Total Resources, Total Skills, Avg Proficiency, Skill Gaps Count - Top 10 Skills Tabelle (sortierbar) - Skill Distribution Chart (lazy-loaded) - Quick filters: Category, Min Count - [ ] **Task 4:** SearchTab bauen -> `skills/SearchTab.tsx` - Skill name Suche (debounced) - Min Proficiency Filter (1-5 Buttons) - "Available in 30 days" Toggle - Ergebnis-Tabelle: Resource, Chapter, Skill, Proficiency, Utilization, Available From - Links zu `/resources/[id]` - [ ] **Task 5:** GapsTab bauen -> `skills/GapsTab.tsx` - Supply vs Demand Tabelle - Supply/Demand Bar Visualisierung - Gap Indicator (shortage/surplus/balanced) - Sortierbar nach groesstem Gap - Click auf Skill -> fuellt Search Tab - [ ] **Task 6:** PeopleFinderTab bauen -> `skills/PeopleFinderTab.tsx` - Multi-rule Builder: Skill + Min Proficiency pro Regel - AND/OR Operator Toggle - Chapter Filter - Ergebnis-Tabelle mit Match Score - XLSX Export Button - [ ] **Task 7:** SkillsHub zusammenfuegen -> `SkillsHub.tsx` - Tab Navigation (Overview, Search, Gaps, People Finder) - Header mit KPI Summary + Export Button - Tab State via URL search params - Lazy-load Tabs fuer Performance - [ ] **Task 8:** Routing + Navigation aktualisieren - `/analytics/skills/page.tsx` -> rendert `` - `/analytics/skill-marketplace/page.tsx` -> redirect zu `/analytics/skills?tab=search` - AppShell: "Skill Marketplace" entfernen, "Skills Analytics" umbenennen zu "Skills Hub" - [ ] **Task 9:** Dark Theme durchgaengig - Alle Elemente mit `dark:` Varianten - Konsistenz mit dem Rest der App ### Abhaengigkeiten - Task 1 muss zuerst (shared utilities fuer alle Tabs) - Task 2 kann parallel zu Task 1 (API aendern) - Tasks 3-6 koennen parallel nach Task 1 (4 Tabs, unabhaengige Dateien) - Task 7 benoetigt Tasks 3-6 (importiert alle Tabs) - Task 8 benoetigt Task 7 (Routing zeigt auf neue Komponente) - Task 9 kann parallel zu Task 8 ### Akzeptanzkriterien - [ ] `pnpm --filter @planarchy/web exec tsc --noEmit` — keine neuen Errors - [ ] `/analytics/skills` zeigt die vereinte Seite mit 4 Tabs - [ ] `/analytics/skill-marketplace` redirected zu `/analytics/skills?tab=search` - [ ] Alle Features beider Seiten sind auf der neuen Seite verfuegbar - [ ] Dark Theme funktioniert durchgehend - [ ] Sidebar zeigt nur noch "Skills Hub" statt zwei Links - [ ] XLSX Export funktioniert weiterhin - [ ] People Finder AND/OR Suche funktioniert - [ ] Skill Gap Heat Map mit Supply/Demand funktioniert - [ ] Availability Filter (30 Tage) funktioniert ### Risiken & offene Fragen - **API Performance:** Ein kombinierter Query koennte langsamer sein -> Loesung: Lazy-load per Tab, Query nur wenn Tab aktiv - **URL State:** Aktiver Tab via `?tab=search` Query Param persistiert - **Export:** Nur aktiver Tab exportierbar - **Backwards-Kompatibilitaet:** AI Assistant Tools nutzen alte Queries -> behalten