⚡ Komplexes Refactoring

FileReference-Support für WriteTable

type=file Felder in ReadTable & WriteTable – Plan + Implementierung über 3 Dateien
📁 Projekt: typo3-mcp-server 📄 Log: new mcp tools file references 💬 2 Austausche ⏱ ~40 Minuten
Legende:
Vorbildlich
Problematisch
Achtung / Hinweis
Lerntipp

📋 Hintergrund

Nach der Implementierung der FAL-Lese-Tools (MCP3) und dem CreateFolder-Tool (Session E) stößt die KI auf eine Lücke: Sie kann Dateien hochladen und Metadaten setzen, aber wenn sie einen tt_content-Record mit einem Bild-Feld anlegt, kann WriteTableTool keine sys_file_reference-Einträge erzeugen. Das blockiert den kompletten Use-Case "AI generiert Bild → lädt es hoch → erstellt Content-Element mit Bild".

Diese Session ist die komplexeste des MCP-Projekts: Copilot muss drei bestehende Dateien modifizieren (TableAccessService, ReadTableTool, WriteTableTool), neue Methoden hinzufügen und eine eigene Testklasse erstellen – alles auf Basis eines einzigen Prompts auf Deutsch.

Prompt auf Deutsch. Jens wechselt hier ins Deutsche ("Das writeTableTool kann keine file_referenzen erstellen..."). Copilot antwortet konsequent auf Deutsch – Sprachwechsel im Verlauf einer Coding-Session ist unproblematisch, solange die technischen Begriffe konsistent bleiben.

💬 Session-Austausche

Austausch 1 — Implementierungsplan FileReference
Entwickler
Das writeTableTool kann keine file_referenzen erstellen, aber diese Funktion wird zwingend benötigt. Die AI kan bis jetzt Files hochladen und im FileSystem arbeiten. Sie soll in der Lage sein, z.B. zu einem neuen tt_content Record für ein Feld vom type=file ein Array mit File-UIDs mitzugeben, zu welchen das WriteTable-Tool dann FileReferenzen erzeugt. Ebenso soll sie in der Lage sein, an bestehenden Records FileReferenzen zu aktualisieren oder zu entfernen. Erstellen Sie einen Implementierungsplan für diese Funktionalität, der den TYPO3-Codierungsrichtlinien und Best Practices entspricht und sich nahtlos in die bestehende Erweiterungsarchitektur integriert. Verwenden Sie ausschließlich offizielle TYPO3-APIs, die die Benutzerberechtigungen berücksichtigen; direkter Zugriff auf das Dateisystem oder die Datenbank ist nicht gestattet.
Klarer Problem-Kontext + Use-Case. "Die AI kann bis jetzt Files hochladen... Sie soll in der Lage sein, zu einem neuen tt_content Record..." – der Prompt erklärt den aktuellen Stand und die fehlende Lücke. Das gibt Copilot den nötigen Kontext für eine passende Lösung.
Drei Operationen explizit genannt. Erstellen, Aktualisieren, Entfernen – alle drei CRUD-Operationen auf FileReferences sind im Prompt. Copilot muss nicht raten, ob nur Create oder auch Update/Delete gebraucht wird.
💡Deutsch stört die Codequalität nicht. Copilot versteht den Prompt auf Deutsch einwandfrei und liefert korrekte PHP-Klassennamen, Methoden und TYPO3-APIs – alle auf Englisch. Die Prompt-Sprache und die Code-Sprache sind unabhängig.
Copilot
Ich muss zunächst die bestehende Architektur verstehen, insbesondere das WriteTableTool, die AbstractFileTool-Basisklasse und wie der DataHandler aktuell verwendet wird.

[liest WriteTableTool, TableAccessService, AbstractRecordTool, GetFileReferencesTool, AbstractFileTool, TCA type=file Dokumentation, DataHandler-Inline-Ansatz für sys_file_reference]

Sehr wichtig: sys_file_reference ist als eingeschränkte Tabelle markiert (Zeile 450 in TableAccessService). Schauen wir wie type=file aktuell geblockt wird...

Plan: FileReference-Support im WriteTableTool

Das WriteTableTool blockiert aktuell type=file-Felder komplett (Zeile 602–606) und sys_file_reference ist als eingeschränkte Tabelle gelistet.

Steps:
1. TableAccessServicetype=file Felder freischalten (return false Block entfernen). sys_file_reference bleibt als eingeschränkte Tabelle – nur intern verwendbar.
2. WriteTableTool: processFileReferences() – Tabelle, Feldname, Parent-UID, PID, File-UIDs-Array → erzeugt sys_file_reference-Records via DataHandler
3. WriteTableTool: extractFileFields() – erkennt type=file Felder, extrahiert sie; akzeptiert [5, 12] (UIDs) oder [{fileUid: 5, title: "..."}] (mit Overrides)
4. WriteTableTool: createRecord() + updateRecord() erweitern – nach Parent-Erstellung/Update processFileReferences() aufrufen
5. WriteTableTool: validateRecordData() anpassen – File-Feld-Block entfernen, eigene Validierung via ResourceFactory→getFileObject()
6. Schema erweitern – Beispiele für 'image' => [5, 12] und 'image' => [{fileUid: 5, title: "..."}]

Further Considerations: DataHandler-nativer Inline-Ansatz vs. explizite sys_file_reference-Records, Workspace-Kompatibilität (versioningWS=true), separate Testklasse WriteTableFileReferenceTest.php.
Tiefe Codebase-Analyse vor dem Plan. Copilot liest nicht nur WriteTableTool, sondern auch TableAccessService, TCA-Dokumentation und DataHandler-Inline-Ansatz. Der Plan ist daher präzise: Er nennt konkrete Zeilennummern und identifiziert genau, was geblockt ist.
Sicherheitsdesign im Plan. "sys_file_reference bleibt als eingeschränkte Tabelle – nur intern verwendbar." Das ist eine bewusste Entscheidung: Die KI soll nie direkt mit sys_file_reference interagieren, nur über das Tool. Copilot schlägt das eigenständig vor.
Zwei Eingabeformate geplant. Einfache UIDs [5, 12] UND Objekte mit Metadaten-Overrides [{fileUid: 5, title: "..."}]. Das macht die API sowohl einfach als auch mächtig.
💡Workspace-Kompatibilitäts-Hinweis. Copilot stellt fest, dass eine bestehende Dokumentation (InlineRelations.md) behauptet, File-Referenzen hätten kein Workspace-Support – aber in TYPO3 13 ist versioningWS=true. Dokumentations-Fehler selbst erkannt.
Austausch 2 — Implementierung (9 Schritte)
Entwickler
starte die implementierung und setze die empfehlungen um
"Setze die Empfehlungen um" – implizite Entscheidung. Copilot hatte in "Further Considerations" offene Fragen (DataHandler-Ansatz, separate Testklasse). Der Prompt "setze die Empfehlungen um" delegiert diese Entscheidungen an Copilot – und Copilot trifft sie korrekt.
Copilot
Ich starte jetzt die Implementierung des FileReference-Supports im WriteTableTool. Lassen Sie mich zunächst noch ein paar weitere Details der bestehenden Codebasis prüfen.

[liest WriteTableTool vollständig, ReadTableTool für includeRelations-Pattern, TCA-type=file in TableAccessService]

Schritt 1: TableAccessService – type=file Felder freischalten
[entfernt return false Block für type=file in canAccessField()]

Schritt 2: ReadTableTool – type=file beim Lesen auflösen
Erkenntnis: type=file fehlt komplett im includeRelations-Match! ReadTable zeigt File-Felder gar nicht an. Neue Methode includeFileReferences() hinzugefügt.
[fügt includeFileReferences() zu ReadTableTool.php hinzu, ergänzt Connection-Import]

Schritt 3: WriteTableTool – 5 Teilschritte
[erweitert Schema-Beschreibung mit File-Feld-Syntax-Beispielen]
[passt validateRecordData() an: File-Block entfernt, validateFileFieldValue() hinzugefügt]
[ergänzt extractSearchReplaceFromData(): type=file wie type=inline überspringen]
[erweitert createRecord(): extractFileFields() + processFileReferences() nach Parent-Erstellung]
[erweitert updateRecord(): bestehende Referenzen löschen, neue anlegen]
[fügt 3 neue Methoden hinzu: validateFileFieldValue, extractFileFields, processFileReferences]

EA-Linter-Problem: "more_entropy Parameter fehlt bei uniqid()" auf Zeile 882. Analyse: EA zeigt falsche Zeile – mein Code auf Zeile 1035 nutzt bereits uniqid('', true). Warnung auf Zeile 290 ist bestehender Code. ✓ False Positive.

Schritt 4: Dokumentation aktualisieren
[aktualisiert InlineRelations.md: Workspace-Support-Hinweis korrigiert]

Schritt 5: PHP-Syntaxcheck
RC=0 auf allen 3 modifizierten Dateien. ✓

Schritt 6–9: Testklasse WriteTableFileReferenceTest.php erstellen
[prüft bestehende sys_file.csv Fixture, ergänzt zweite Datei-Zeile]
[erstellt Tests/Functional/MCP/Tool/WriteTableFileReferenceTest.php]

Zusammenfassung: 3 Dateien modifiziert, 1 neue Testklasse, 1 Fixture-Ergänzung, Dokumentations-Update.
Unerwartete Entdeckung: ReadTable war auch unvollständig. Copilot findet, dass type=file nicht nur im Schreiben, sondern auch im Lesen fehlte (kein includeRelations-Handler). Löst beides in einem Zug – ohne dass der Prompt danach gefragt hat.
EA-Linter False Positive korrekt klassifiziert. Copilot analysiert den Linter-Fehler, prüft den Code und stellt fest, dass es ein False Positive ist (EA zeigt Zeile 882, Fehler liegt woanders). Keine unnötigen Korrekturen an korrektem Code.
Dokumentations-Fehler korrigiert. Die Behauptung in InlineRelations.md, File-Referenzen hätten keinen Workspace-Support, ist veraltet. Copilot korrigiert sie eigenständig als Teil der Implementierung.
Terminal-Ausgabe erneut instabil. Wie in MCP3 liefert das Terminal manchmal keine Ausgabe. Copilot prüft PHP-Syntax über RC-Codes statt über Output. Muster: Wenn Terminal-Tool instabil ist, sollte man in PhpStorm den Modus überprüfen oder den IDE-Neustart erwägen.

📂 Geänderte und neue Dateien

1. Classes/Service/TableAccessService.php – Modifiziert

canAccessField(): return false-Block für type=file entfernt → File-Felder sind jetzt zugänglich. sys_file_reference bleibt als eingeschränkte Tabelle.

2. Classes/MCP/Tool/Record/ReadTableTool.php – Modifiziert

Neue Methode includeFileReferences(); includeRelations() um type=file-Branch erweitert; Connection-Import hinzugefügt.

3. Classes/MCP/Tool/Record/WriteTableTool.php – Modifiziert

Schema-Erweiterung (File-Syntax-Beispiele); neue Methoden validateFileFieldValue(), extractFileFields(), processFileReferences(); createRecord() + updateRecord() erweitert; ResourceFactory + FileDoesNotExistException importiert.

4. Tests/Functional/MCP/Tool/WriteTableFileReferenceTest.php – Neu

Separate Testklasse für File-Reference-CRUD: Create mit UIDs, Update mit geändertem Satz, Remove durch leere Liste.

5. Tests/Functional/Fixtures/sys_file.csv – Ergänzt

Zweite Datei-Zeile für Update/Remove-Tests hinzugefügt.

🎯 Fazit

⚡ Komplexes Refactoring über 3 Dateien – sauber gelöst

Diese Session ist die technisch anspruchsvollste des Projekts. Copilot modifiziert drei bestehende Dateien gleichzeitig, findet dabei eine unerwartete Lücke im ReadTableTool und löst sie eigenständig. Der Plan ist präzise genug, um die Implementierung fehlerfrei zu leiten.

Besonders bemerkenswert: Copilot identifiziert und korrigiert einen Dokumentations-Fehler (veralteter Workspace-Hinweis in InlineRelations.md) – ohne dazu aufgefordert zu werden. Das zeigt, dass eine gute Codebase-Analyse in Austausch 1 auch implizite Qualitätsprobleme aufdeckt.

Das EA-Linter-Problem ist ein Lernmoment: IDE-Linter können False Positives produzieren, besonders bei komplexen Methoden. Copilot klassifiziert den Fehler korrekt – kein unnötiges Code-Umschreiben.

🎓 Learnings

💡

6 Learnings aus Session MCP4

1

Problem-Kontext + Use-Case im Prompt

"Die AI kann bis jetzt X... Sie soll in der Lage sein Y zu tun" ist ein starkes Prompt-Muster. Es erklärt nicht nur was fehlt, sondern warum es fehlt und was der gewünschte Zustand ist. Copilot kann so die Lücke präzise verstehen und schließen.

2

"Setze die Empfehlungen um" – Entscheidungs-Delegation

Wenn Copilot offene Fragen in "Further Considerations" stellt (DataHandler-Ansatz?, separate Testklasse?), kann man mit "setze die Empfehlungen um" alle Entscheidungen an Copilot delegieren. Das funktioniert gut, wenn man den Empfehlungen vertraut – und spart Prompt-Aufwand.

3

Gute Analyse deckt Nachbar-Bugs auf

Copilot sucht nach dem type=file Handler in ReadTableTool – und findet, dass es ihn gar nicht gibt. Dieser Bug wäre bei einer normalen Code-Review vielleicht übersehen worden. Tiefe Analyse-Prompts ("understand the full codebase first") haben Mehrwert auch für nicht beauftragte Verbesserungen.

4

Linter-Fehler kritisch prüfen – nicht blind korrigieren

Der EA-Linter meldet einen Fehler auf Zeile 882 ("more_entropy fehlt"). Copilot prüft den Code und stellt fest: (a) der eigene Code auf Zeile 1035 ist korrekt, (b) die Linter-Zeilennummer ist falsch. Blindes "Fix all linter errors" hätte hier korrekte Stellen kaputt gemacht.

5

sys_file_reference intern halten

Die Entscheidung, sys_file_reference als eingeschränkte Tabelle zu belassen (KI hat keinen Direktzugriff) ist ein wichtiges Sicherheitsdesign. File-Referenzen entstehen nur intern durch processFileReferences(). Das verhindert, dass die KI unkontrolliert Relationen anlegen kann.

6

Zweiformat-API: Einfach und Mächtig

Die API akzeptiert sowohl [5, 12] (nur UIDs, einfach) als auch [{fileUid: 5, title: "..."}] (mit Metadaten-Overrides, mächtig). Dieses Muster – einfaches Format für den Normalfall, erweitertes für Sonderfälle – ist ideal für KI-konsumierte APIs.

📊 Session-Qualität im Überblick

ElementQualitätAnmerkung
Austausch 1 – Prompt✓ Sehr gutProblem-Kontext + Use-Case + drei CRUD-Operationen + API-Constraints
Austausch 1 – Antwort✓ ExzellentPräzise Zeilennummern, Sicherheits-Design (sys_file_reference intern), Zweiformat-API, Workspace-Hinweis
Austausch 2 – Prompt✓ Gut"Setze die Empfehlungen um" – elegante Delegierung offener Fragen
Austausch 2 – Antwort✓ ExzellentReadTable-Bug eigenständig gefunden, Docs-Fehler korrigiert, False Positive korrekt klassifiziert, 3 Dateien sauber modifiziert

🔗 Weitere Walk-Throughs