Merge PR #322: QA-05 (Connect): Abnahme-Pruefung Connect
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
This commit is contained in:
commit
f86484db6b
1 file changed
+263
@@ -0,0 +1,263 @@
|
||||
# QA-05 – Abnahme-Prüfung Connect: Prüfprotokoll
|
||||
|
||||
Datum: 2026-10-16. Host 192.168.1.204, frischer Klon von
|
||||
`gitea.perlbach24.de/scripte/nexarch.git` nach
|
||||
`/root/qa-05-connect-work-1792161903`, Branch
|
||||
`feature/qa-05-05-abnahme-pruefung-connect` von `main`
|
||||
(`dac7fff504ba65bad7bec64d06cfe062845d3e09`, 2026-10-15) abgezweigt.
|
||||
Eigene Wegwerf-Postgres-Rolle/DB `qa05_connect_test` (Passwort generiert,
|
||||
nur in `/root/.qa05_connect_env` auf Host 204, root-only, nicht Teil des
|
||||
Commits). `archivdms` nicht berührt. Alle Testdaten synthetisch.
|
||||
|
||||
Diese Kachel ist, wie im Ticket festgelegt, eine Zusammenfassungs- und
|
||||
Abnahme-Kachel – kein Code-Integrationsticket. Sie baut keinen neuen
|
||||
Produktcode, der alle sechs Vorgänger-Branches gleichzeitig voraussetzt,
|
||||
sondern (1) liest die sechs realen Prüfprotokolle direkt aus den
|
||||
jeweiligen offenen PR-Branches (ohne Merge), (2) führt einen echten,
|
||||
frischen Gesamttestlauf gegen den tatsächlich in `main` bereits
|
||||
zusammengeführten Connect-Bestand durch, und (3) trifft auf dieser
|
||||
Grundlage eine begründete Freigabeentscheidung.
|
||||
|
||||
## Ausgangslage: Merge-Status der sechs Vorgänger-Gates
|
||||
|
||||
Keines der sechs Prüfgates ist zum Prüfzeitpunkt in `main` gemergt. Alle
|
||||
liegen als offene PRs vor:
|
||||
|
||||
| Gate | PR | Branch | Basis |
|
||||
|---|---|---|---|
|
||||
| QA-02 | #315 | `feature/qa-02-02-pruefgate-connector-engine` | `main` |
|
||||
| QA-03 | #317 | `feature/qa-03-03-pruefgate-erp-datev-m365` | `main` |
|
||||
| QA-04 | #320 | `feature/qa-04-04-sicherheitspruefung-drittsystem-credentials` | `feature/eng-07-...` (unmerged ENG-07) |
|
||||
| QA-06 | #319 | `feature/qa-06-schnittstellen-vertragstests-connect` | `feature/api-03-...` (unmerged API-03) |
|
||||
| QA-07 | #314 | `feature/qa-07-last-leistungstest-connect` | `main` |
|
||||
| QA-08 | #321 | `feature/qa-08-barrierefreiheits-audit-connect` | `feature/api-01-...` (unmerged API-01) |
|
||||
|
||||
Jeder Branch wurde per `git fetch origin <branch>` lokal referenziert und
|
||||
sein `connect/docs/<CODE>-PRUEFPROTOKOLL.md` per `git show <branch>:...`
|
||||
gelesen – kein Merge, keine Änderung an diesen Branches.
|
||||
|
||||
## AC1 – Alle vorgelagerten Prüfgates abgeschlossen und protokolliert
|
||||
|
||||
Alle sechs Protokolle liegen vollständig vor und schließen jeweils mit
|
||||
einem nachvollziehbaren Ergebnis, belegt durch echte Testläufe (nicht nur
|
||||
Behauptungen):
|
||||
|
||||
| Gate | Ergebnis laut eigenem Protokoll | Zentrale reale Befunde |
|
||||
|---|---|---|
|
||||
| QA-02 (Connector-Engine) | Bestanden | Echte, netzwerkseitige Fehlerinjektion (lokaler HTTP-Server, 2× echtes 503, danach 200) treibt Retry+Backoff und wird nach Erholung vollständig im Audit-Trail nachgeliefert. 3-fach wiederholt, keine Flakiness. |
|
||||
| QA-03 (ERP/DATEV/M365 + DMS2) | Bestanden | Erstmals echte Testläufe gegen den QA-01-Referenzkorpus (statt Ad-hoc-Mocks) ergänzt; dabei ein **echter Frontend-Fehler** in `web/datev-export` gefunden (doppelte React-Kopie durch fehlenden Resolve-Alias) und behoben. |
|
||||
| QA-04 (Credential-Sicherheit) | Bestanden nach Fix | Verschlüsselung/Zugriffskontrolle bestanden. **Echter, kritischer Befund:** Tenant-KEK-Rotation machte vor dem Fix alle Bestands-Credentials dauerhaft unlesbar (empirisch nachgewiesen, dann durch `RewrapDEK`/`RewrapTenantKEK` behoben, analog DMS/FDN-09). Offen: keine End-User-RBAC-Permission für Credential-Zugriff (noch kein Endpunkt, der das bräuchte). |
|
||||
| QA-06 (Vertragstests Webhook) | Bestanden, mit offen benannter Einschränkung | 8/8 Vertragstests grün, inkl. echtem Breaking-Change-Beweis (Signatur-Header real umbenannt → Tests schlagen exakt wie erwartet fehl). **Einschränkung:** Core besitzt keinen HTTP-Endpunkt für die Webhook-Abonnement-Verwaltung (API-07 nur als Go-Paket, nicht verdrahtet) – der Abonnement-Vertrag ist nur einseitig (Connect-Konsument) geprüft, nicht gegen eine echte Core-Instanz. |
|
||||
| QA-07 (Last/Leistung) | Bestanden | Alle drei Lasttests (Credential-Abruf, Sync-Job-Queue, Rate-Limiting) mit realen Messwerten weit innerhalb der Zielwerte, gegen echte Postgres-Testdatenbank, 0 Fehler. |
|
||||
| QA-08 (Barrierefreiheit) | Bestanden mit offenem AC2 | 0 axe-Verstöße über 4 Oberflächen, vollständige Maus-freie Kernabläufe real durchgeführt. **AC2 nicht erfüllt:** kein Bildschirmleser (NVDA/VoiceOru/Orca) auf Testhost/Entwicklungsmaschine installierbar – dieselbe organisatorische Lücke wie `UX-06` (DMS) und `UX-07` (Mail), dort mit Frist 2026-10-31 verfolgt. |
|
||||
|
||||
**Bewertung AC1:** Erfüllt. Alle sechs Protokolle liegen vor, sind in
|
||||
sich stimmig, durch echte Messungen belegt und benennen ihre jeweils
|
||||
eigenen Restrisiken selbst und unverharmlost.
|
||||
|
||||
## AC2 – Zusammenspiel aller Connectoren im Gesamttest geprüft
|
||||
|
||||
### Einschränkung (siehe Auftrag)
|
||||
|
||||
Ein Gesamttest, der alle sechs offenen PR-Branches gleichzeitig im
|
||||
selben Checkout voraussetzt (insbesondere QA-04 auf ENG-07, QA-08 auf
|
||||
API-01, QA-06 auf API-03 – drei voneinander unabhängige, noch nicht
|
||||
gegeneinander abgestimmte Feature-Branches), wurde **bewusst nicht**
|
||||
durch einen Mehrfach-Merge versucht. Das Risiko realer Merge-Konflikte
|
||||
und unbeabsichtigter Interaktionseffekte zwischen noch nicht final
|
||||
abgestimmten Features wäre höher als der Erkenntnisgewinn gegenüber den
|
||||
bereits vorliegenden Einzelprotokollen. Diese Prüfung ist daher in zwei
|
||||
real durchgeführte Teile zerlegt:
|
||||
|
||||
### Teil 1: Echter Gesamttestlauf gegen den tatsächlich in `main` bereits zusammengeführten Connect-Bestand
|
||||
|
||||
`main` enthält bereits ENG-01–06, ENG-08, ENG-10, ERP-01–04, DAT-01–03,
|
||||
M365-01–03, DMS2-01–03 und API-02 – also die überwiegende Mehrheit aller
|
||||
Connectoren und der Connector-Engine, real im selben Checkout vereint.
|
||||
Frischer Testlauf auf dieser Grundlage:
|
||||
|
||||
```
|
||||
cd connect
|
||||
go build ./... -> clean
|
||||
go vet ./... -> clean
|
||||
go test ./... -count=1 -p 1 -> 27/27 testbare Pakete ok, 0 FAIL, 0 SKIP
|
||||
bash scripts/check-security-test-coverage.sh -> "Merge-Gate bestanden"
|
||||
```
|
||||
|
||||
Betroffene Pakete (Auszug, vollständige Liste im Rohlog): `registry`,
|
||||
`credential`, `crypto`, `httpclient`, `syncjob`, `fieldmapping`,
|
||||
`auditclient`, `audittrail`, `erpconnector`, `erpexport`, `crmconnector`,
|
||||
`datevtransfer`, `datevexport`, `datevapi`, `m365connector`,
|
||||
`m365calsync`, `m365docsync`, `dms2import`, `dms2importapi`,
|
||||
`backupconnector`, `masterdatasync`, `dmsexchange`, `thirdpartyrate`,
|
||||
`statusapi`, `killswitch`, `policyclient`, `archiveclient`,
|
||||
`testcorpus`. Alle Connector-Typen (ERP, CRM, DATEV, M365, DMS2/Backup)
|
||||
liefen damit real **gemeinsam in einem Lauf**, nicht nur einzeln.
|
||||
|
||||
Frontend-Gesamttest (alle auf `main` vorhandenen Connect-Oberflächen):
|
||||
|
||||
```
|
||||
web/connect-status -> npm install (kein Lockfile im Paket) + vitest run: 5/5 Tests grün, tsc sauber
|
||||
web/dms2-import -> npm ci + vitest run: 3/3 Tests grün, tsc sauber
|
||||
web/datev-export -> npm ci + vitest run: 4/4 Tests FEHLGESCHLAGEN (siehe Befund unten), tsc sauber
|
||||
```
|
||||
|
||||
**Eigener, unabhängig reproduzierter Befund:** Der in QA-03 gefundene und
|
||||
dort behobene Fehler (`web/datev-export`: fehlender React-Resolve-Alias
|
||||
in `vitest.config.ts`, führt zu einer zweiten React-Kopie und
|
||||
`Cannot read properties of null (reading 'useState')`) wurde in dieser
|
||||
Sitzung **unabhängig erneut real reproduziert** – weil der Fix nur auf
|
||||
dem QA-03-Branch existiert, nicht in `main`. Das bestätigt zwei Dinge:
|
||||
(a) QA-03s Befund war real und ist korrekt behoben, (b) `main` ist
|
||||
heute, vor Merge von PR #317, für `web/datev-export` tatsächlich rot.
|
||||
Dies ist kein neuer Fehler, sondern der sichtbare Beweis, dass der
|
||||
Gesamttest gegen den ungemergten `main`-Stand ehrlich und ungeschönt
|
||||
durchgeführt wurde, statt die Behauptung aus dem QA-03-Protokoll
|
||||
unkritisch zu übernehmen.
|
||||
|
||||
`gofmt -l .` listet zusätzlich 10 vorbestehende, nicht von dieser Kachel
|
||||
verursachte unformatierte Dateien (`datevapi`, `datevexport`,
|
||||
`dms2import`, `dms2importapi`, `erpexport`, `testcorpus`) – rein
|
||||
kosmetisch, bereits in QA-02 als Befund vermerkt, hier nicht behoben
|
||||
(außerhalb des Ticketumfangs).
|
||||
|
||||
### Teil 2: Zusammenspiel mit Core-Webhook-Registry (Prüfung 2 des Tickets)
|
||||
|
||||
Core besitzt auf `main` bereits `internal/webhook` (Registrierung,
|
||||
Zustellung mit Retry/Backoff, HMAC-Signatur) – aber, bestätigt per
|
||||
`grep` über den gesamten Checkout, **keinen HTTP-Handler**, der dieses
|
||||
Paket für ein physisch getrenntes Modul wie Connect erreichbar macht
|
||||
(an keinem `cmd/`-Binary verdrahtet). Die Connect-seitigen
|
||||
Konsument-Pakete (`webhooksub`, `webhookclient`) existieren auf `main`
|
||||
überhaupt nicht – nur auf den unmerged Branches API-03/QA-06.
|
||||
|
||||
Ein echter Zusammenspiel-Test auf `main` selbst ist damit zum
|
||||
Prüfzeitpunkt nicht möglich – nicht wegen eines Connect-Fehlers, sondern
|
||||
weil die Gegenstelle (Core-HTTP-Wrapper für API-07) schlicht noch nicht
|
||||
existiert. Ersatzweise wurde der bereits in QA-06 gebaute
|
||||
Vertragstest-Korpus in einem isolierten `git worktree` auf dem
|
||||
`qa06`-Branch (= API-03 + QA-06, nicht gemergt, nicht verändert) frisch
|
||||
erneut ausgeführt, als unabhängige Momentaufnahme:
|
||||
|
||||
```
|
||||
cd /root/qa05-webhook-spotcheck/connect
|
||||
go build ./... -> clean
|
||||
go test ./internal/contracttest/... -v -> 8/8 PASS (erneuter, unabhaengiger Lauf):
|
||||
TestContract_SubscribeRequest_SentFieldsMatchDocumentedCorpus
|
||||
TestContract_SubscribeRequest_DetectsBreakingChange_RenamedField
|
||||
TestContract_SubscribeResponse_RealStructMarshalsDocumentedFields
|
||||
TestContract_SubscribeResponse_DetectsBreakingChange_RemovedField
|
||||
TestContract_UnsubscribeRequest_MethodPathAndQueryMatchDocumentedCorpus
|
||||
TestContract_DeliverySignatureHeader_MatchesDocumentedName
|
||||
TestContract_DeliveryEndToEnd_DocumentedSignature_Succeeds
|
||||
TestContract_DeliveryEndToEnd_DetectsBreakingChange_RenamedSignatureHeader
|
||||
```
|
||||
|
||||
Worktree danach wieder entfernt (`git worktree remove --force`), keine
|
||||
Änderung an `qa06` vorgenommen, kein Push von dort.
|
||||
|
||||
**Bewertung AC2:** Teilweise erfüllt, mit offen benannter Einschränkung.
|
||||
Das Zusammenspiel **aller bereits in `main` zusammengeführten
|
||||
Connectoren** (ERP, CRM, DATEV, M365, DMS2/Backup, Sync-Engine) wurde
|
||||
real in einem gemeinsamen Testlauf nachgewiesen – kein Mock-only-Beweis,
|
||||
echte Postgres-Testdatenbank, echte HTTP-Wege. Das Zusammenspiel mit der
|
||||
Core-Webhook-Registry ist dagegen, wie von QA-06 selbst bereits benannt,
|
||||
nur einseitig (Connect-Konsument) und nur auf einem noch nicht gemergten
|
||||
Branch nachweisbar – ein beidseitiger Nachweis gegen eine laufende
|
||||
Core-Instanz mit echtem HTTP-Endpunkt ist strukturell erst möglich,
|
||||
sobald der Core-seitige Wrapper existiert (core-kanban-Board, außerhalb
|
||||
dieser Kachel und außerhalb von Connect insgesamt).
|
||||
|
||||
## AC3 – Abnahmeprotokoll abgelegt und nachlesbar
|
||||
|
||||
Dieses Dokument: `connect/docs/QA-05-PRUEFPROTOKOLL.md`. Erfüllt.
|
||||
|
||||
## Freigabeentscheidung
|
||||
|
||||
**Bedingte Freigabe.** Nexarch Connect ist fachlich und technisch auf
|
||||
einem belastbaren Stand – alle sechs Prüfgates sind mit echten
|
||||
Messungen bestanden (teils nach einem real gefundenen und behobenen
|
||||
Fehler), kein Gate behauptet etwas ohne Protokoll, und der eigene
|
||||
Gesamttest in dieser Kachel bestätigt die Engine- und
|
||||
Connector-Robustheit unabhängig erneut. Eine uneingeschränkte Freigabe
|
||||
ist aber nicht gerechtfertigt, weil mehrere konkrete, benannte
|
||||
Restrisiken offen sind und weil der geprüfte Gesamtbestand aktuell nur
|
||||
als Summe einzelner, nicht gegeneinander abgestimmter Branches
|
||||
existiert – nicht als ein einziger, gemeinsam getesteter Integrations-
|
||||
stand. Die Freigabe gilt unter folgenden Bedingungen:
|
||||
|
||||
1. **Vor jeder produktiven Nutzung durch andere Module:** Alle sechs
|
||||
PRs (sowie ihre eigenen Abhängigkeiten ENG-07, API-01, API-03) müssen
|
||||
gemergt und danach ein frischer Gesamttestlauf auf dem tatsächlich
|
||||
integrierten `main`-Stand wiederholt werden. Der in dieser Kachel
|
||||
durchgeführte Gesamttest deckt nur den bereits gemergten Teilbestand
|
||||
ab; das volle Feature-Set wurde noch nie gemeinsam in einem Checkout
|
||||
ausgeführt.
|
||||
2. **Vor Freischaltung von Webhook-Abonnements:** Core muss den
|
||||
HTTP-Wrapper für API-07 (Webhook-Registry) liefern. Bis dahin ist der
|
||||
Abonnement-Verwaltungsvertrag nur ein von Connect veröffentlichter,
|
||||
nicht beidseitig bestätigter Pact (core-kanban-Board, außerhalb
|
||||
dieser Kachel).
|
||||
3. **Vor Freischaltung von API-01 (Connect-Konfigurationsoberfläche):**
|
||||
Es existiert noch keine End-User-RBAC-Permission für
|
||||
Credential-Zugriff (`connect.credential.*`) und keinen dafür
|
||||
verdrahteten HTTP-Endpunkt – API-01 darf nicht ohne eine nach dem
|
||||
`statusapi`-Muster (`requireIdentity`+`requirePermission`)
|
||||
implementierte Zugriffskontrolle live gehen (bereits in QA-04 als
|
||||
Empfehlung vermerkt, hier bekräftigt).
|
||||
4. **Vor dem ersten echten Tenant-KEK-Rotations-Ereignis in Produktion:**
|
||||
Es existiert jetzt eine Rewrap-Fähigkeit (`RewrapTenantKEK`), aber
|
||||
kein automatischer Trigger/Runbook, der sie aufruft. Ein Runbook muss
|
||||
vor der ersten echten Rotation vorliegen.
|
||||
5. **`web/datev-export`:** PR #317 (QA-03) muss gemergt werden, bevor der
|
||||
Frontend-Testbestand auf `main` wieder grün ist – aktuell real
|
||||
reproduziert rot (siehe oben).
|
||||
6. **Bildschirmleser-Durchlauf (AC2 aus QA-08):** bleibt offen, verfolgt
|
||||
unter der projektweiten Frist aus `UX-06` (2026-10-31) – kein
|
||||
Connect-spezifischer Blocker, aber Teil der Gesamtzusage zur
|
||||
Barrierefreiheit.
|
||||
|
||||
Keines der gefundenen Risiken deutet auf einen grundlegenden
|
||||
Architektur- oder Engine-Mangel hin – jedes ist entweder bereits
|
||||
behoben (KEK-Rotation, DATEV-Export-Frontend-Fehler, jeweils mit
|
||||
Protokoll) oder ein sauber benannter, noch offener Abhängigkeits-/
|
||||
Organisationspunkt mit klarem Verantwortlichen. Eine "keine Freigabe"
|
||||
wäre angesichts der Qualität und Dichte der bereits real durchgeführten
|
||||
Prüfungen nicht angemessen; eine uneingeschränkte "volle Freigabe" würde
|
||||
die oben genannten, konkreten und teils sicherheitsrelevanten (RBAC,
|
||||
Webhook-Core-Lücke) Punkte verharmlosen.
|
||||
|
||||
## DSGVO
|
||||
|
||||
Keine echten Kunden-/Mandantendaten verwendet. Eigene Wegwerf-DB
|
||||
`qa05_connect_test` mit ausschließlich synthetischen Daten aus den
|
||||
bereits vorhandenen Testfixtures/-korpora der geprüften Branches.
|
||||
Zugangsdaten (`TEST_ADMIN_DSN`/`TEST_TENANT_DSN`) ausschließlich als
|
||||
Variablennamen referenziert, kein Wert in diesem Protokoll oder im
|
||||
Commit.
|
||||
|
||||
## Entscheidungen/Ermessen in dieser Sitzung
|
||||
|
||||
- **Kein Mehrfach-Merge:** bewusst unterlassen, Begründung siehe AC2.
|
||||
Stattdessen Gesamttest gegen den echten `main`-Bestand plus isolierter
|
||||
Worktree-Spotcheck für die Webhook-Vertragstests, ohne einen der
|
||||
Branches zu verändern.
|
||||
- **Reproduktion statt Übernahme des datev-export-Befunds:** Der
|
||||
QA-03-Fehlerbefund wurde nicht als gegeben übernommen, sondern
|
||||
unabhängig erneut real ausgelöst (Testlauf gegen unverändertes
|
||||
`main`), um die eigene Prüfungspflicht dieser Kachel ernst zu nehmen.
|
||||
- **Eigene Wegwerf-DB statt Wiederverwendung** einer der bereits
|
||||
laufenden Test-DBs auf Host 204, um Kollisionen mit parallelen
|
||||
Testläufen zu vermeiden.
|
||||
- 0 von 20 Iterationen für Unklarheiten gebraucht.
|
||||
|
||||
## Gesamtergebnis
|
||||
|
||||
**Bedingte Freigabe** von NEXARCH Connect zur Nutzung durch andere
|
||||
Module – siehe Bedingungen 1–6 oben. AC1 und AC3 vollständig erfüllt,
|
||||
AC2 für den bereits gemergten Connector-Bestand real nachgewiesen, für
|
||||
das Zusammenspiel mit der Core-Webhook-Registry nur einseitig und nur
|
||||
auf unmerged Branches nachweisbar (strukturelle Abhängigkeit von
|
||||
core-kanban, nicht von dieser Kachel behebbar).
|
||||
|
||||
Kein Merge, kein Deploy.
|
||||
Reference in new issue
Block a user