FlorianEisenmenger 5 дней назад
Родитель
Сommit
c203f8cfd6
1 измененных файлов: 12 добавлений и 5 удалений
  1. +12
    -5
      CLAUDE.md

+ 12
- 5
CLAUDE.md Просмотреть файл

@@ -298,12 +298,12 @@ Serverseitige Logik: `ReportController` ermittelt via `TimeEntryRepository::find

## Statistiken

Arbeitszeit-Statistik als gestapeltes Balkendiagramm (Chart.js), erreichbar über den Statistik-Button im Report-Header. Tab-Navigation zwischen „Zeiten" und „Statistiken".
Arbeitszeit-Statistik als gestapeltes Balkendiagramm (Chart.js) + drei Donut-Charts (Kunden, Projekte, Leistungen), erreichbar über den Statistik-Button im Report-Header. Tab-Navigation zwischen „Zeiten" und „Statistiken".

### Architektur

- **Backend**: `ReportController::statistics()` (Seite) + `ReportController::statisticsData()` (API)
- **Frontend**: `assets/scripts/statistics.js` (eigener Webpack-Entry), nutzt Chart.js (tree-shaked: nur `BarController`, `BarElement`, `CategoryScale`, `LinearScale`, `Tooltip`)
- **Frontend**: `assets/scripts/statistics.js` (eigener Webpack-Entry), nutzt Chart.js (tree-shaked: `BarController`, `BarElement`, `DoughnutController`, `ArcElement`, `CategoryScale`, `LinearScale`, `Tooltip`)
- **Styles**: `assets/styles/sections/_statistics.scss`
- **Template**: `templates/report/statistics.html.twig`

@@ -313,23 +313,30 @@ Arbeitszeit-Statistik als gestapeltes Balkendiagramm (Chart.js), erreichbar übe
|--------------------|--------|-------------------------------------------------------|
| `/api/statistics` | GET | Aggregierte Zeitdaten: `?range={12months|6months|4weeks}&userId={id}` |

Rückgabe enthält zwei Bereiche:
- **Balkendiagramm**: `labels`, `billable`, `nonBillable`, `billableRevenue`, `nonBillableRevenue`, `groupBy`
- **Verteilung**: `distribution.clients`, `distribution.projects`, `distribution.services` — jeweils Arrays mit `{name, hours, revenue}`

### Daten-Aggregation

`TimeEntryRepository::getStatisticsData()` aggregiert Zeiteinträge in Buckets:
**Balkendiagramm** — `TimeEntryRepository::getStatisticsData()` aggregiert Zeiteinträge in Buckets:
- **12months**: Monats-Buckets (`Y-m`), letztes Jahr
- **6months**: Wochen-Buckets (`o-W`), letztes halbes Jahr
- **4weeks**: Tages-Buckets (`Y-m-d`), letzte 4 Wochen

Rückgabe: `labels`, `billable`, `nonBillable`, `billableRevenue`, `nonBillableRevenue`, `groupBy`. Billable/Non-Billable Trennung via `Service.billable`. Revenue-Berechnung nutzt die Stundensatz-Kaskade.
Billable/Non-Billable Trennung via `Service.billable`. Revenue-Berechnung nutzt die Stundensatz-Kaskade.

**Donut-Charts** — `TimeEntryRepository::getDistributionData()` aggregiert für denselben Zeitraum/User nach Kunden, Projekten und Leistungen (jeweils `SUM(duration)` und `SUM(rate * duration / 60)`). Einträge < 5% werden clientseitig zu „Rest" zusammengefasst.

### Frontend-Features

- **Metrik-Umschalter**: Stunden oder Umsatz (clientseitig, kein neuer API-Call)
- **Metrik-Umschalter**: Stunden oder Umsatz — gilt für Bar-Chart und Donuts (clientseitig, kein neuer API-Call)
- **User-Filter**: Admins/Members können nach einzelnem User filtern oder alle sehen (Account-Name als „Alle")
- **Tracker**: sieht nur eigene Daten (serverseitig erzwungen)
- **Tages-Ansicht**: Alternierende Wochen-Bänder als visuelle Hilfe (Custom Chart.js Plugin `weekBands`)
- **Tooltip**: Zeigt formatierte Stunden (`h:mm`) oder Umsatz (`€`) je nach Metrik
- **Brand-Farbe**: Billable-Balken nutzen `--color-primary`, Non-Billable grau
- **Donut-Charts**: Drei nebeneinander (3-Spalten-Grid, responsive 1-Spalte), eigene Legende mit Farb-Dot, Name, Wert und Prozent. 8-Farben-Palette, „Rest" in Grau

## TenantConnectionMiddleware



Загрузка…
Отмена
Сохранить