15 KiB
o‑Byte QA – Testprotokoll‑Tool (Full README)
Stand: 2025-09-04
Stack: PHP 8.3 ( Apache ), JS (Vanilla), MariaDB, Docker & Compose, Portainer
Dieses Repository enthält ein vollwertiges QA‑Tool mit Login (OIDC), GitLab‑Template‑Loader, DocBee‑Posting, PDF‑Erzeugung im Browser und persistenter Speicherung (DB + PDF‑Ablage). Diese README basiert ausschließlich auf dem mitgelieferten Projektstand.
Inhaltsverzeichnis
- Überblick
- Architektur & Verzeichnisstruktur
- Funktionen
- UI‑Bedienung (Kurzüberblick)
- Datenmodell (DB)
- API‑Endpunkte
- Konfiguration per Umgebungsvariablen (.env)
- Lokale Entwicklung
- Deployment mit Docker Compose
- Deployment mit Portainer (Stack)
- GitLab‑Vorlagen
- DocBee‑Integration
- PDF‑Export
- Troubleshooting
- Sicherheitshinweise
- Lizenz / Nutzung
Überblick
- Ziel: Manuelle QA‑Testläufe effizient vorbereiten, durchführen und revisionssicher exportieren.
- Workflow: Vorlage laden → Metadaten eintragen (inkl. OLM‑Nummer) → Schritte bearbeiten (Gruppen, Status, Evidenzen) → Exportieren (DocBee, DB, PDF).
- Login: OpenID Connect (konfigurierbar), optional bypassbar über
AUTH_DISABLED=truefür lokale Tests. - Persistenz: Reports (Metadaten & Steps) in MariaDB, PDFs serverseitig abgelegt.
- Integrationen: GitLab (YAML‑Vorlagen), DocBee (Login + Notiz‑Erzeugung 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 # Health‑Check (DB/PDF‑Pfad)
├─ config/config.php # ENV‑Konfiguration (OIDC, DocBee, DB, APP_BASE_URL, …)
├─ login.php # OIDC‑Start
├─ callback.php # OIDC‑Callback, Session‑Bootstrap
├─ 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 Drag‑Handle verschiebbar (innerhalb und zwischen Gruppen).
- Automatische Neu‑Nummerierung 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, Modul‑Version, PBX‑Version, Tester (aus Session), DocBee‑Ticket‑URL, OLM‑Nummer (
olm_nummer).
Exporte
- Exportieren (DocBee, DB, PDF) per einem Button:
- DocBee‑Notiz erstellen (falls Token vorhanden) → Ticket‑URL ggf. aktualisiert.
- PDF im Browser generieren (jsPDF+AutoTable).
- /api/export.php: JSON (Run) + PDF (multipart) an Server → DB‑Speicherung + PDF‑Ablage.
- Server sendet
report_idundpdf_pathzurü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/MD‑Funktionen existieren noch im Code, UI‑seitig aber nicht exponiert.
UI‑Bedienung (Kurzüberblick)
- GitLab Vorlage: Dropdown befüllen (
GitLab: …Tag zeigt Status), Datei wählen → Vorlage wird geladen. - Metadaten: Felder ausfüllen (OLM‑Nummer nicht vergessen).
- Steps:
+ Step/+ Gruppe, per Griff⋮⋮ziehen, Status setzen, Kommentare/Evidenzen pflegen. - Exportieren (DocBee, DB, PDF): Startet kompletten Lauf‑Export. Ergebnisdialog zeigt Ticket/PDF‑Pfad/Report‑ID.
Datenmodell (DB)
Beim Export werden folgende Tabellen (idempotent) angelegt/aktualisiert:
reports
idBIGINT (PK)created_atTIMESTAMP (DefaultCURRENT_TIMESTAMP)moduleVARCHAR(255)module_versionVARCHAR(100)pbx_versionVARCHAR(100)olm_nummerVARCHAR(100)testerVARCHAR(255)docbee_urlTEXTsummaryVARCHAR(255) → z. B.12/15 pass, 2 fail, 1 skippdf_pathTEXT
steps
idBIGINT (PK)report_idBIGINT (FK → reports.id, ON DELETE CASCADE)step_indexINTstep_idVARCHAR(50)titleTEXTexpectedTEXTstatusENUM('pass','fail','skip','na','')commentTEXTevidenceTEXTgroup_titleVARCHAR(255)group_indexINT
Der schema‑loader Service in docker-compose.yml erstellt die Tabellen automatisch beim ersten Start.
API‑Endpunkte
GET /api/health.php- Prüft PDO / MariaDB‑Erreichbarkeit, Schreibrechte des PDF‑Ordners.
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 PDF‑Datei (optional; Export läuft auch ohne PDF durch)
- Antwort:
{{"ok":true,"report_id":<int>,"pdf_path":"…","summary":"…"}}
- Felder:
POST /api/echo.php- Debug/Echo.
Konfiguration per Umgebungsvariablen (.env)
Beispiel .env (für Compose/Portainer):
# 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 Portainer‑UI/Secrets setzen.
Lokale Entwicklung
- Composer‑Abhängigkeiten sind bereits im Repo (
vendor/). Falls nötig:cd htdocs && composer install - PHP‑Built‑in (nur für schnellen Test, ohne DB/PDF‑Ablage):
php -S 127.0.0.1:8009 -t htdocs - Login‑Bypass lokal aktivieren:
export AUTH_DISABLED=true - 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), bind‑mountet
htdocsund nutztPDF_STORAGE_DIRVolume - mariadb (11.x)
- schema-loader (initialisiert Tabellen)
- phpmyadmin (optional)
- fix-pdf-perms (setzt 0777 auf PDF‑Volume)
Starten:
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)
- Stack → Add Stack
- Environment Vars nach obiger
.envsetzen (oder Datei hochladen). - Compose verwenden (aus
compose/docker-compose.yml), z. B.:
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:
- Deploy Stack → öffnen:
http://<host>:${APP_PORT}.
GitLab‑Vorlagen
- Konfiguration via ENV (
GITLAB_HOST,GITLAB_PROJECT_ID,GITLAB_REF,GITLAB_PATH,GITLAB_TOKEN). - UI lädt per GitLab API die Liste der YAML‑Dateien aus
GITLAB_PATH(nur.yaml/.yml). - Parser akzeptiert YAML und JSON (Fallback).
DocBee‑Integration
- Beim Laden von
index.phpwird viaDOCBEE_BASEURL/restApi/loginein Token geholt und clientseitig alswindow.DOCBEE_TOKENbereitgestellt. - Exportablauf:
- postToDocBee erstellt eine Notiz im angegebenen Ticket (aus
DocBee Ticket‑URL). - Bei Erfolg wird die URL im Lauf aktualisiert.
- Danach erfolgt Server‑Export (DB + optional PDF).
- postToDocBee erstellt eine Notiz im angegebenen Ticket (aus
Erforderliche ENV: DOCBEE_BASEURL, DOCBEE_USER, DOCBEE_PASS, DOCBEE_TIME (Minuten).
PDF‑Export
- Erzeugung im Browser via jsPDF + AutoTable (CDN‑Fallbacks vorhanden).
- Logo
logo_light.pngwird proportional (max 26×12 mm) rechtsbündig im Kopf platziert. - Fallback: Falls Libraries fehlen, wird ein Text‑PDF erzeugt.
- Server speichert PDFs in
PDF_STORAGE_DIR(Default/var/reports).
YAML‑Vorlage (Beispiel inkl. OLM)
name: "Modul XYZ – Basis‑Tests"
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
- Login‑Loop / 401: OIDC‑Konfiguration prüfen (
OIDC_PROVIDER, Redirect‑URL/callback.php). Lokal ggf.AUTH_DISABLED=true. - DocBee 401/403:
DOCBEE_USER/DOCBEE_PASS/DOCBEE_BASEURL/DOCBEE_TIMEprüfen. - DB‑Fehler (PDO not loaded): Image/Extension prüfen (
PHP_EXTENSION_PDO_MYSQL=1gesetzt? Compose). - Keine Schreibrechte PDF: Volume/
fix-pdf-permsprüfen;PDF_STORAGE_DIRexistiert/schreibbar?/api/health.phpansehen. - GitLab‑Liste leer: Pfad/Ref/Token prüfen; nur
.yaml/.ymlwerden angezeigt. - Export blockiert: Pflichtschritte haben keinen Status (📌).
Sicherheitshinweise
- AUTH_DISABLED ausschließlich in Dev/Stage verwenden.
- DocBee‑Token wird clientseitig verwendet – nur in internen Netzen nutzen oder alternative Server‑Proxy‑Variante vorsehen.
- Secrets per Portainer‑Secrets/ENV setzen, nicht im Repo.
- DB‑Backups/Retention für
reports/stepseinplanen; PDF‑Ablage regelmäßig bereinigen/archivieren.
Lizenz / Nutzung
Interne Nutzung innerhalb o‑Byte / Kundenprojekten. Anpassungen willkommen.