shinkan-jinkendo/docs/architecture/BASELINE_SNAPSHOT.md
Lars e09a2284e9
All checks were successful
Deploy Development / deploy (push) Successful in 42s
Test Suite / pytest-backend (push) Successful in 36s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m8s
chore(version): update version and changelog for release 0.8.131
- Bumped APP_VERSION to 0.8.131 and updated the changelog to reflect recent changes.
- Added the TrainingPlanningUnitFormModal component to the TrainingPlanningPage for enhanced training unit management.
- Refactored frameworkLineageText utility function for better code organization and reusability in the training planning context.
- Updated BASELINE_SNAPSHOT documentation to include new metrics and logging details for k6 health checks.
2026-05-14 16:02:54 +02:00

122 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 0 Performance-Baseline (Shinkan Jinkendo)
**Zweck:** Reproduzierbarer Startpunkt **vor** Phase 2 (Backend-Lesepfade, Summary-API).
**Stand:** 2026-05-13 · Backend-App-Version laut `backend/version.py`: **0.8.110**
Nach grösseren Deployments oder Schema-Änderungen: Bundle-Abschnitt neu erfassen (`npm run build`); API-/k6-Werte bei Bedarf aktualisieren.
---
## 1. Frontend-Bundle (`npm run build`)
Messung: Repo-Root → `cd frontend && npm run build` (Vite Production).
**Hinweis:** Dateinamen mit Hash (`index-*.js`) ändern sich pro Build; relevant sind Grössenordnungen und gzip.
### 1.1 Einstieg & globale Vendor-Chunks (Auszug letzter Lauf CI-lokal)
| Asset (Muster) | raw kB | gzip kB | Rolle |
|----------------|--------|---------|--------|
| `index.html` | 1.84 | 0.73 | Einstieg |
| `index-*.css` | 127.55 | 21.58 | Globale Styles |
| `index-*.js` (App-Shell / Router) | 64.83 | 17.45 | Haupteinstieg nach Code-Splitting |
| `vendor-react-*.js` | 142.42 | 45.67 | React + DOM |
| `vendor-router-*.js` | 65.94 | 22.51 | react-router |
| `vendor-markdown-*.js` | 161.54 | 49.31 | Markdown-Stack (wird mit Routen geladen) |
| `vendor-pdf-*.js` | 390.80 | 128.98 | jsPDF (Route-bezogen) |
### 1.2 Schwerste Route-Chunks (lazy, nach Route)
| Bereich | typ. Chunk-Grösse (raw / gzip) | Datei-Muster (Beispiel) |
|---------|-------------------------------|-------------------------|
| Trainingsplanung | 71.81 kB / 18.67 kB | `TrainingPlanningPage-*.js` |
| Übung bearbeiten | 91.31 kB / 22.49 kB | `ExerciseFormPage-*.js` |
| Medienbibliothek | 59.42 kB / 13.69 kB | `MediaLibraryPage-*.js` |
| Dashboard | 19.97 kB / 5.93 kB | `Dashboard-*.js` |
**Abnahme Phase 0 (Bundle):** Zahlen dokumentiert; Re-Run: `npm run build` und Tabelle abgleichen.
---
## 2. API-Latenz (p95) Top-Routen
**Messung** erfolgt auf **Zielumgebung** (z.B. dev.shinkan / prod) mit gleicher Topologie wie Nutzer (HTTPS, Proxy). Nicht aus dem leeren Arbeitsverzeichnis ohne laufendes Backend messbar.
### 2.1 Vorgehen (empfohlen)
- **Access-Logs** des Reverse-Proxy (Request-Zeit), oder
- **APM** / OpenTelemetry, oder
- **k6** mit authentifizierten Szenarien (Token aus Testaccount; Header `X-Auth-Token`, ggf. `X-Active-Club-Id`), oder
- manuell: wiederholte `curl -w '%{time_total}\n'` mit gleichem Token
### 2.2 Vorlage (aus Umgebung ausfüllen)
| Route (Beispiel) | Methode | p95 (ms) | Datum / Umgebung | Bemerkung |
|------------------|---------|----------|------------------|-----------|
| `/api/profiles/me` | GET | *—* | *nach Messung* | |
| `/api/exercises` (Liste, typ. Query) | GET | *—* | *nach Messung* | |
| `/api/training-units` (Liste, typ. Query) | GET | *—* | *nach Messung* | |
| `/api/media-assets` (Liste) | GET | *—* | *nach Messung* | |
| `/health` | GET | *—* | *nach Messung* | k6: siehe `scripts/load/` |
**Abnahme Phase 0 (API):** Verfahren steht; Tabelle mindestens für **`/health`** nach erstem k6-Lauf befüllbar; übrige Zeilen bei nächstem Monitoring-Export.
---
## 3. Lasttestszenario
### 3.1 E2E-Smoke (fachlicher Pfad)
- **Befehl:** Repository-Root, `npm run test:e2e` (setzt `PLAYWRIGHT_BASE_URL`, Testuser per Env, siehe `.gitea/workflows/test.yml`).
- **Abdeckung:** Login, Dashboard, Navigation u.a. entspricht grob „Login → Dashboard → weitere Screens“.
- **Baseline notieren:** Dauer eines vollen Laufs, Anzahl passed (z.B. 26 Tests), Datum.
| Messung | Wert | Datum |
|---------|------|-------|
| Playwright Gesamtlauf (lokal/CI) | *—* | *nach Messung* |
| passed / total | 26 / 26 (Ziel) | |
### 3.2 EXPLAIN (Phase 2 Lesepfade)
- **Datei:** **`scripts/load/explain-readpaths.sql`** — repräsentative Statements für `list_exercises` / Stufenfilter / `training_units`; auf der Ziel-DB mit `EXPLAIN (ANALYZE, BUFFERS)` ausführen (Token/Tenant nicht im Skript; wie bei echten API-Queries filtern).
### 3.3 k6 parallele /health
- **Skript:** `scripts/load/k6-health-baseline.js`
- **CI:** Läuft **automatisch** im Gitea-Workflow im Job **`k6-health-baseline`** (eigenständig, ohne Playwright; `.gitea/workflows/test.yml`). Parallel dazu **Playwright** im Job **`playwright-tests`**.
- **Lokal:** siehe `scripts/load/README.md`
- **Baseline notieren:** k6-Ausgabe `http_req_duration` p(95), Checks succeeded.
| Szenario | p95 / Fehlerquote | Datum / BASE_URL |
|----------|-------------------|------------------|
| 10 VUs, 30 s `/health` | *—* | *nach Messung* |
### 3.4 Aus dem Deployment-/CI-Log übernehmen (k6 `k6-health-baseline`)
Das Skript `scripts/load/k6-health-baseline.js` nutzt **10 VUs**, **30 s**, Ziel **`GET {BASE_URL}/health`** (siehe Workflow-Env für `BASE_URL`).
**In die Tabelle oben (Abschnitt 3.3) eintragen — aus der k6-Zusammenfassung am Ende des Jobs:**
| Feld in BASELINE_SNAPSHOT | Wo im k6-Log (typisch) |
|---------------------------|-------------------------|
| **p95** (Latenz ms) | Zeile **`http_req_duration`** → Wert **`p(95)=…`** (ganze Zahl oder ms mit Einheit wie `12.34ms`) |
| **Fehlerquote** | Zeile **`http_req_failed`** → z.B. `0.00%` bzw. `✓ 0%` — oder kurz „0 %“ notieren |
| **Checks** (optional) | Zeile **`checks`** → Anteil **`✓`** (soll **100 %** sein, sonst Hinweis) |
| **Datum / BASE_URL** | Deploy-Datum + die **öffentliche** Basis-URL des Laufs (wie im Workflow gesetzt, z.B. `https://dev.shinkan.jinkendo.de`) |
| **App-Version** (optional) | dieselbe wie im Deploy (`backend/version.py` / Release), damit M2-Vergleich ressortfähig bleibt |
**Zusätzlich (Abschnitt 2.2):** nur die Zeile **`/health` GET`** mit dem **gleichen** p95 befüllen, wenn ihr dort noch Platzhalter habt — echte API-Routen (`/api/...`) kommen weiter aus Monitoring/k6 mit Auth, nicht aus diesem Job.
---
## 4. Nächster Schritt (Roadmap)
- **Phase 0** ist für den Pipeline-Teil **abgeschlossen**: Bundle dokumentiert; **k6** läuft in CI nach jedem relevanten Deploy (mit Test-Suite); API-p95-Tabellen kann das Team aus Monitoring weiter befüllen (optional, kein Deploy-Blocker).
- **Phase 2** (Backend Lesepfade) ist **abgeschlossen** — siehe [UMSETZUNGSPLAN_ROADMAP.md](./UMSETZUNGSPLAN_ROADMAP.md); nach Deploy **p95 erneut messen** und mit den Werten aus Abschnitt 2 dieser Datei vergleichen (**Meilenstein M2**).
---
## Verweise
- Roadmap: [UMSETZUNGSPLAN_ROADMAP.md](./UMSETZUNGSPLAN_ROADMAP.md)
- k6: [scripts/load/README.md](../../scripts/load/README.md)