Files
proxmox-selfservice/qa-tool/README.MD
Sven Steinert fce31ebcd7 Viel neues
2026-04-30 12:06:00 +02:00

461 lines
15 KiB
Markdown
Raw 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.
# oByte QA TestprotokollTool (Full README)
**Stand:** 2025-09-04
**Stack:** PHP 8.3 ( Apache ), JS (Vanilla), MariaDB, Docker & Compose, Portainer
Dieses Repository enthält ein vollwertiges QATool mit Login (OIDC), GitLabTemplateLoader, DocBeePosting, PDFErzeugung im Browser und persistenter Speicherung (DB + PDFAblage). Diese README basiert ausschließlich auf dem mitgelieferten Projektstand.
---
## Inhaltsverzeichnis
1. [Überblick](#überblick)
2. [Architektur & Verzeichnisstruktur](#architektur--verzeichnisstruktur)
3. [Funktionen](#funktionen)
4. [UIBedienung (Kurzüberblick)](#ui-bedienung-kurzüberblick)
5. [Datenmodell (DB)](#datenmodell-db)
6. [APIEndpunkte](#api-endpunkte)
7. [Konfiguration per Umgebungsvariablen (.env)](#konfiguration-per-umgebungsvariablen-env)
8. [Lokale Entwicklung](#lokale-entwicklung)
9. [Deployment mit Docker Compose](#deployment-mit-docker-compose)
10. [Deployment mit Portainer (Stack)](#deployment-mit-portainer-stack)
11. [GitLabVorlagen](#gitlab-vorlagen)
12. [DocBeeIntegration](#docbee-integration)
13. [PDFExport](#pdf-export)
14. [Troubleshooting](#troubleshooting)
15. [Sicherheitshinweise](#sicherheitshinweise)
16. [Lizenz / Nutzung](#lizenz--nutzung)
---
## Überblick
- **Ziel:** Manuelle QATestläufe effizient vorbereiten, durchführen und revisionssicher exportieren.
- **Workflow:** Vorlage laden → Metadaten eintragen (inkl. **OLMNummer**) → Schritte bearbeiten (Gruppen, Status, Evidenzen) → **Exportieren (DocBee, DB, PDF)**.
- **Login:** OpenID Connect (konfigurierbar), optional **bypassbar** über `AUTH_DISABLED=true` für lokale Tests.
- **Persistenz:** Reports (Metadaten & Steps) in MariaDB, PDFs serverseitig abgelegt.
- **Integrationen:** GitLab (YAMLVorlagen), DocBee (Login + NotizErzeugung via REST).
---
## Architektur & Verzeichnisstruktur
```
o-byte-qa-tool/
├─ compose/
│ ├─ Dockerfile # PHP 8.3 + Apache, Composer
│ └─ docker-compose.yml # app, mariadb, schema-loader, phpmyadmin, fix-pdf-perms
└─ htdocs/ # Webroot
├─ index.php # App-Entry, Token-Bootstrap für DocBee, UI
├─ app.js # UI-Logik, Exporte, DocBee-Push, GitLab-Loader
├─ style.css # Styles
├─ api/
│ ├─ export.php # Report+Steps in DB speichern, PDF entgegennehmen
│ ├─ echo.php # einfache Echo-Route (Debug)
│ └─ health.php # HealthCheck (DB/PDFPfad)
├─ config/config.php # ENVKonfiguration (OIDC, DocBee, DB, APP_BASE_URL, …)
├─ login.php # OIDCStart
├─ callback.php # OIDCCallback, SessionBootstrap
├─ logout.php # Session reset (OLM beibehalten)
├─ logo.png / logo_light.png
├─ favicon.ico
├─ vendor/ # Composer (z.B. jumbojett/openid-connect-php, phpseclib, …)
└─ oidc/ # phpseclib Assets (lokal eingebunden)
```
---
## Funktionen
### Vorlagen & Schritte
- **Vorlagen laden**: YAML/JSON (lokal per Datei **oder** aus **GitLab**Repo/Pfad/Ref).
- **Gruppen**: Gruppenzeilen, ein-/ausklappbar; Schritte via DragHandle verschiebbar (innerhalb und zwischen Gruppen).
- **Automatische NeuNummerierung** der Steps bei Änderungen/Verschieben.
- **Pflichtschritte** (📌) werden geprüft Export blockiert, wenn offen.
- **Gruppenstatus setzen** auf *pass/fail/skip/blocked*, inkl. **Warnung** bei Überschreiben bestehender Stati.
- **Kommentare & Evidenzen** (Freitext + URL).
### Metadaten
- **Module**, **ModulVersion**, **PBXVersion**, **Tester** (aus Session), **DocBeeTicketURL**, **OLMNummer** (`olm_nummer`).
### Exporte
- **Exportieren (DocBee, DB, PDF)** per **einem** Button:
1. DocBeeNotiz erstellen (falls Token vorhanden) → TicketURL ggf. aktualisiert.
2. **PDF** im Browser generieren (jsPDF+AutoTable).
3. **/api/export.php**: JSON (Run) + PDF (multipart) an Server → DBSpeicherung + PDFAblage.
4. Server sendet `report_id` und `pdf_path` zurück.
- **Lauf speichern / laden** als JSON (Zwischenspeichern/Weiterarbeiten).
- **Template als YAML exportieren** (inkl. `olm_nummer`, Gruppen & Steps).
> Hinweis: Dedizierte Buttons für CSV/MD/PDF wurden in dieser Version **konsolidiert** CSV/MDFunktionen existieren noch im Code, UIseitig aber nicht exponiert.
---
## UIBedienung (Kurzüberblick)
- **GitLab Vorlage**: Dropdown befüllen (`GitLab: …` Tag zeigt Status), Datei wählen → Vorlage wird geladen.
- **Metadaten**: Felder ausfüllen (**OLMNummer** nicht vergessen).
- **Steps**: `+ Step` / `+ Gruppe`, per Griff `⋮⋮` ziehen, Status setzen, Kommentare/Evidenzen pflegen.
- **Exportieren (DocBee, DB, PDF)**: Startet kompletten LaufExport. Ergebnisdialog zeigt Ticket/PDFPfad/ReportID.
---
## Datenmodell (DB)
Beim Export werden folgende Tabellen (idempotent) angelegt/aktualisiert:
**reports**
- `id` BIGINT (PK)
- `created_at` TIMESTAMP (Default `CURRENT_TIMESTAMP`)
- `module` VARCHAR(255)
- `module_version` VARCHAR(100)
- `pbx_version` VARCHAR(100)
- `olm_nummer` VARCHAR(100)
- `tester` VARCHAR(255)
- `docbee_url` TEXT
- `summary` VARCHAR(255)  → z.B. `12/15 pass, 2 fail, 1 skip`
- `pdf_path` TEXT
**steps**
- `id` BIGINT (PK)
- `report_id` BIGINT (FK → reports.id, ON DELETE CASCADE)
- `step_index` INT
- `step_id` VARCHAR(50)
- `title` TEXT
- `expected` TEXT
- `status` ENUM('pass','fail','skip','na','')
- `comment` TEXT
- `evidence` TEXT
- `group_title` VARCHAR(255)
- `group_index` INT
Der **schemaloader** Service in `docker-compose.yml` erstellt die Tabellen automatisch beim ersten Start.
---
## APIEndpunkte
- `GET /api/health.php`
- Prüft PDO / MariaDBErreichbarkeit, Schreibrechte des PDFOrdners.
- `POST /api/export.php` (multipart/form-data)
- **Felder:**
- `run` JSON mit Metadaten (`module`, `module_version`, `pbx_version`, `olm_nummer`, `tester`, `docbee_url`, `ts`, `steps`[…])
- `pdf` erzeugte PDFDatei (optional; Export läuft auch ohne PDF durch)
- **Antwort:** `{{"ok":true,"report_id":<int>,"pdf_path":"…","summary":"…"}}`
- `POST /api/echo.php`
- Debug/Echo.
---
## Konfiguration per Umgebungsvariablen (.env)
Beispiel **.env** (für Compose/Portainer):
```env
# App
APP_PORT=8009
APP_BASE_URL=http://localhost:8009
AUTH_DISABLED=false # true = Login-BYPASS (nur lokal verwenden)
# OpenID Connect (Login)
OIDC_PROVIDER=https://auth.o-byte.com/realms/o-byte.com
OIDC_CLIENT=qa-tool
OIDC_SECRET=<client-secret>
# MariaDB
DB_HOST=mariadb
DB_PORT=3306
DB_NAME=qa_tool
DB_USER=qa
DB_PASS=change_me
DB_ROOT_PASS=change_me_root
# Persistenz
PDF_STORAGE_DIR=/var/reports
# DocBee
DOCBEE_BASEURL=https://obyte.docbee.com
DOCBEE_USER=OBYTE/service
DOCBEE_PASS=<password>
DOCBEE_TIME=1440 # Minuten Token-Gültigkeit
# GitLab Templates
GITLAB_HOST=https://git.steinert.cc
GITLAB_PROJECT_ID=qa/templates # oder numerische ID
GITLAB_REF=main
GITLAB_PATH=templates
GITLAB_TOKEN= # optional (PRIVATE-TOKEN)
# Container-User (Dateirechte)
APP_UID=0
APP_GID=0
# phpMyAdmin Port (optional)
PHPMYADMIN_PORT=8010
```
> **Wichtig:** Keine Secrets in Repos commiten. Für Produktion Token/Passwörter über PortainerUI/Secrets setzen.
---
## Lokale Entwicklung
1. **ComposerAbhängigkeiten** sind bereits im Repo (`vendor/`). Falls nötig:
```bash
cd htdocs && composer install
```
2. **PHPBuiltin** (nur für schnellen Test, ohne DB/PDFAblage):
```bash
php -S 127.0.0.1:8009 -t htdocs
```
3. **LoginBypass** lokal aktivieren:
```bash
export AUTH_DISABLED=true
```
4. Browser: `http://127.0.0.1:8009`
---
## Deployment mit Docker Compose
Im Ordner `compose/` befindet sich ein funktionsfähiges Setup mit:
- **app** (Apache+PHP 8.3), bindmountet `htdocs` und nutzt `PDF_STORAGE_DIR` Volume
- **mariadb** (11.x)
- **schema-loader** (initialisiert Tabellen)
- **phpmyadmin** (optional)
- **fix-pdf-perms** (setzt 0777 auf PDFVolume)
**Starten:**
```bash
cd compose
cp ../.env .env # eigene Werte setzen
docker compose up -d
```
**Zugriff:** `http://<host>:${APP_PORT:-8009}`
**phpMyAdmin:** `http://<host>:${PHPMYADMIN_PORT:-8010}`
---
## Deployment mit Portainer (Stack)
1. **Stack → Add Stack**
2. **Environment Vars** nach obiger `.env` setzen (oder Datei hochladen).
3. **Compose** verwenden (aus `compose/docker-compose.yml`), z.B.:
```yaml
version: "3.8"
services:
app:
image: thecodingmachine/php:8.3-v4-apache
user: "${APP_UID:-0}:${APP_GID:-0}"
ports:
- "${APP_PORT:-8009}:80"
environment:
PHP_EXTENSION_PDO_MYSQL: "1"
APP_BASE_URL: ${APP_BASE_URL}
AUTH_DISABLED: ${AUTH_DISABLED}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASS: ${DB_PASS}
PDF_STORAGE_DIR: ${PDF_STORAGE_DIR}
OIDC_PROVIDER: ${OIDC_PROVIDER}
OIDC_CLIENT: ${OIDC_CLIENT}
OIDC_SECRET: ${OIDC_SECRET}
DOCBEE_BASEURL: ${DOCBEE_BASEURL}
DOCBEE_USER: ${DOCBEE_USER}
DOCBEE_PASS: ${DOCBEE_PASS}
DOCBEE_TIME: ${DOCBEE_TIME}
GITLAB_HOST: ${GITLAB_HOST}
GITLAB_PROJECT_ID: ${GITLAB_PROJECT_ID}
GITLAB_REF: ${GITLAB_REF}
GITLAB_PATH: ${GITLAB_PATH}
GITLAB_TOKEN: ${GITLAB_TOKEN}
volumes:
- ${APP_HTDOCS_HOST:-/opt/qa-tool/htdocs}:/var/www/html
- pdf_storage:/var/reports
depends_on:
mariadb:
condition: service_healthy
fix-pdf-perms:
condition: service_completed_successfully
restart: unless-stopped
mariadb:
image: mariadb:11
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASS}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mariadb-admin", "ping", "-h", "127.0.0.1", "-p${DB_PASS}"]
interval: 10s
timeout: 5s
retries: 30
start_period: 20s
restart: unless-stopped
schema-loader:
image: mariadb:11
depends_on:
mariadb:
condition: service_healthy
environment:
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASS: ${DB_PASS}
command: >
sh -lc "
echo 'Waiting for DB…'; sleep 3;
mysql -h $DB_HOST -P $DB_PORT -u$DB_USER -p$DB_PASS $DB_NAME <<SQL
CREATE TABLE IF NOT EXISTS reports (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
module VARCHAR(255),
module_version VARCHAR(100),
pbx_version VARCHAR(100),
olm_nummer VARCHAR(100),
tester VARCHAR(255),
docbee_url TEXT,
summary VARCHAR(255),
pdf_path TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS steps (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
report_id BIGINT NOT NULL,
step_index INT,
step_id VARCHAR(50),
title TEXT,
expected TEXT,
status ENUM('pass','fail','skip','na','') DEFAULT '',
comment TEXT,
evidence TEXT,
group_title VARCHAR(255),
group_index INT,
CONSTRAINT fk_steps_report FOREIGN KEY (report_id) REFERENCES reports(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
SQL
"
restart: "no"
fix-pdf-perms:
image: busybox:1.36
volumes:
- pdf_storage:/target
command: |
sh -lc '
set +e
mkdir -p /target
chmod -R 0777 /target 2>/dev/null || true
chown -R 0:0 /target 2>/dev/null || true
exit 0
'
restart: "no"
phpmyadmin:
image: phpmyadmin:5
ports:
- "${PHPMYADMIN_PORT:-8010}:80"
environment:
PMA_HOST: mariadb
PMA_USER: ${DB_USER}
PMA_PASSWORD: ${DB_PASS}
depends_on:
mariadb:
condition: service_healthy
restart: unless-stopped
volumes:
db_data:
pdf_storage:
```
4. **Deploy Stack** → öffnen: `http://<host>:${APP_PORT}`.
---
## GitLabVorlagen
- Konfiguration via ENV (`GITLAB_HOST`, `GITLAB_PROJECT_ID`, `GITLAB_REF`, `GITLAB_PATH`, `GITLAB_TOKEN`).
- UI lädt per GitLab API die Liste der YAMLDateien aus `GITLAB_PATH` (nur `.yaml`/`.yml`).
- Parser akzeptiert **YAML** und **JSON** (Fallback).
---
## DocBeeIntegration
- Beim Laden von `index.php` wird via `DOCBEE_BASEURL/restApi/login` ein Token geholt und **clientseitig** als `window.DOCBEE_TOKEN` bereitgestellt.
- Exportablauf:
1. **postToDocBee** erstellt eine Notiz im angegebenen **Ticket** (aus `DocBee TicketURL`).
2. Bei Erfolg wird die URL im Lauf aktualisiert.
3. Danach erfolgt ServerExport (DB + optional PDF).
**Erforderliche ENV:** `DOCBEE_BASEURL`, `DOCBEE_USER`, `DOCBEE_PASS`, `DOCBEE_TIME` (Minuten).
---
## PDFExport
- Erzeugung **im Browser** via **jsPDF** + **AutoTable** (CDNFallbacks vorhanden).
- **Logo** `logo_light.png` wird proportional (max 26×12 mm) **rechtsbündig** im Kopf platziert.
- Fallback: Falls Libraries fehlen, wird ein TextPDF erzeugt.
- Server speichert PDFs in `PDF_STORAGE_DIR` (Default `/var/reports`).
---
## YAMLVorlage (Beispiel inkl. OLM)
```yaml
name: "Modul XYZ BasisTests"
module: "Modul XYZ"
module_version: "1.2.3"
pbx_version: "8.1"
olm_nummer: "OLM-12345"
steps:
- type: "group"
title: "Telefonie Basis"
- type: "step"
id: "s1"
title: "Anruf initiieren"
expected: "Ruf wird erfolgreich aufgebaut"
required: true
- type: "step"
id: "s2"
title: "Rufumleitung"
expected: "Ruf wird korrekt umgeleitet"
required: false
```
---
## Troubleshooting
- **LoginLoop / 401:** OIDCKonfiguration prüfen (`OIDC_PROVIDER`, RedirectURL `/callback.php`). Lokal ggf. `AUTH_DISABLED=true`.
- **DocBee 401/403:** `DOCBEE_USER/DOCBEE_PASS/DOCBEE_BASEURL/DOCBEE_TIME` prüfen.
- **DBFehler (PDO not loaded):** Image/Extension prüfen (`PHP_EXTENSION_PDO_MYSQL=1` gesetzt? Compose).
- **Keine Schreibrechte PDF:** Volume/`fix-pdf-perms` prüfen; `PDF_STORAGE_DIR` existiert/schreibbar? `/api/health.php` ansehen.
- **GitLabListe leer:** Pfad/Ref/Token prüfen; nur `.yaml/.yml` werden angezeigt.
- **Export blockiert:** Pflichtschritte haben keinen Status (📌).
---
## Sicherheitshinweise
- **AUTH_DISABLED** ausschließlich in Dev/Stage verwenden.
- DocBeeToken wird **clientseitig** verwendet nur in internen Netzen nutzen oder alternative ServerProxyVariante vorsehen.
- Secrets per PortainerSecrets/ENV setzen, nicht im Repo.
- DBBackups/Retention für `reports`/`steps` einplanen; PDFAblage regelmäßig bereinigen/archivieren.
---
## Lizenz / Nutzung
Interne Nutzung innerhalb oByte / Kundenprojekten. Anpassungen willkommen.