Ausgangsfrage: Ist die Migration der Projektpartner-User aus dem Neos-Altsystem (Export unter temp/) samt anhängender Dokumente bereits funktional? Antwort: die User-, Profil- und Suchagenten-Migrationen waren implementiert und getestet — aber die Dokumente-Übernahme hätte kein einziges File kopiert.
Ursache: Der Process-Plugin neos_private_documents erwartet einen Datei-Pfad in der Neos-DB-Spalte relativepublicationpath — die ist im echten Dump für alle 100.931 User-Dokumente leer (per SQL verifiziert). Neos legt private Dateien content-adressiert unter ihrem SHA1-Hash ab (Resources/<s0>/<s1>/<s2>/<s3>/<sha1>); der Publikationspfad wird nur für öffentliche Dateien befüllt. Jedes Dokument wäre still übersprungen worden — die Kernel-Tests waren grün, weil ihre Fixtures den Pfad befüllen.
Fix: Der Source-Plugin NeosProjektpartnerProfile löst leere Pfade jetzt über den mitgelesenen SHA1 auf (subdivided Layout zuerst, flaches Layout als Fallback). Der Basis-Pfad ist maschinen-spezifisch und lebt als Setting solcom_projektpartner.neos_resources_path in settings.local.php — gleiches Muster wie die Neos-DB-Connection, dokumentiert in web/sites/example.settings.local.php. Schlägt die Auflösung fehl oder fehlt das Setting, wird jetzt geloggt statt still übersprungen.
Testabdeckung: Neuer Kernel-Test reproduziert den Bug (rot ohne Fix, per temporärem Patch-Revert bewiesen) und pinnt die SHA1-Auflösung; ein Negativ-Test sichert das Verhalten bei fehlendem Setting ab. NeosSqlSourceTest: 5 Tests, 39 Assertions, grün. PHPCS (Drupal + DrupalPractice) und PHPStan (Level 6, CI-Konfiguration): 0 Findings.
156 Dateien nach private://ppp/<ppp_id>/ kopiert, file_managed-Einträge vorhanden; SHA1-Prüfsumme der kopierten Dateien matcht die Neos-DB (≥3 Stichproben).
Resolution-Rate
500 von 500 gesampelten Dokumenten lösen auf existierende Dateien im Export auf — alle über das subdivided SHA1-Layout, 0 Misses.
Feld-Qualität
Skills werden zu Taxonomie-Term-Referenzen aufgelöst (Stichprobe: Term „PMO“ korrekt); 293 unbekannte Skill-Labels im State-Bucket solcom_projektpartner.neos_unknown_skills zur Nacharbeit erfasst.
Vorbestehende Test-Fails
Volle Modul-Suite: 100 Tests, 3 Errors + 2 Failures — alle fünf vorbestehend auf develop (fehlender Entity-Type project_offer_alert, Login-Redirect-Drift, Webform-Config-Drift) und ohne Berührung der geänderten Dateien.
Neue Befunde aus dem E2E-Lauf
Befund
Risiko
Suchagenten-Migration zeigt auf nicht existente Tabelle.solcom_projektpartner_alert_neos war auf neos_search_agent konfiguriert; die echte Quelle ist contenance_solcom_domain_model_projectalert (13.053 User-Alerts). Behoben in diesem Branch (Commits 9e708f7d + 0e146c2a): Source-Rewrite, neuer Process-Plugin neos_alert_nested_array für die verschachtelten Serialisierungen (alter Pfad hätte 0 Skills migriert), Entity um Location remote + field_excluded_skills erweitert. Proof-Run: 21 Alerts migriert, 0 failed.
Behoben
Aktivierungs-Command via Drush defekt.solcom-ppp:activate-bestandsnutzer scheiterte bei der Command-Discovery: Drushs Autowire-Container konnte ProjektpartnerMailManager nicht auflösen (Service nur unter Custom-ID registriert, kein Autowire-Alias). Behoben in diesem Branch (Commit 2480b896): FQCN-Alias in der services.yml + Kernel-Repro-Test; --dry-run läuft durch („Project partners found: 52“).
Behoben
Rollback nicht idempotent.migrate:rollback der Profil-Migration lässt File-Entities und physische Dateien verwaist zurück; ein Re-Import dupliziert sie anschließend (156 Duplikate mit _0-Suffix im Test). Vor produktiven Wiederholungsläufen braucht es Datei-Cleanup beim Rollback oder Replace-Semantik.
Mittel
Datenqualität field_languages. 15 von 56 Profilen tragen den literalen PHP-Serialisierungs-String s:0:""; als Sprachwert — der neos_doctrine_array-Plugin reicht leere Quellwerte ungefiltert durch; würde im UI literal rendern.
Mittel
Skills-Abdeckung 29/56. Konsistent mit spärlichen Quelldaten plus 293 nicht aufgelösten Labels; kein Auflösungs-Bug erkennbar, aber vor dem Voll-Import lohnt eine Alias-Erweiterung für die häufigsten unbekannten Labels.
Niedrig
Offene Entscheidungen
DSGVO
Die Migration importiert derzeit alle 37.664 Neos-Accounts ohne Consent-/Aktivitätsfilter. Die Quellspalte policyoption existiert; ob nur eingewilligte/aktive Accounts migriert werden, ist eine Business-Entscheidung (Datenschutz/Vertrieb). Der Filter selbst ist eine kleine Ergänzung im Source-Query, sobald entschieden.
Follow-up
Befunde 1+2 (Suchagenten-Tabelle, Aktivierungs-Command) wurden nachträglich im selben Branch behoben — inklusive der zwei damit verbundenen Datenverlust-Risiken (Location remote: 1.835 aktive Alerts; Skill-Ausschlüsse notags: 1.441 aktive Alerts). Bewusst nicht migriert: D0–D9-Postleitzonen-Präferenzen (1.022 Alerts, kein Zielfeld). Offen bleiben Befunde 3–5: Rollback-Semantik vor produktiven Re-Runs, field_languages-Datenqualität, Skills-Alias-Abdeckung.