Oder: Warten auf Godot, aber mit 3.791 Zeilen Code
So, jetzt bin ich an dem Punkt angekommen, an dem sich jeder Schritt anfühlt wie „Warten auf Godot“. Ich sehe, dass etwas passiert, aber ich habe mich in diesem Experiment bewusst aus dem aktiven Entwicklungsprozess herausgezogen.
Was ich beim Code‑Review sehe, sieht gut aus. Für die Statistik: Aktuell liegen 3.791 Zeilen Code im Repo – das sind bereits deutlich mehr Zeilen, als die Hauptfiguren bei Beckett überhaupt sprechen.
Ich bleibe gespannt, vor allem auf das erste „Hands‑on“, und stelle mir die bange Frage: Wie groß wird am Ende die Ernüchterung sein – oder die Überraschung?
In dieser Runde: Prompt 9.
Der Auftrag: Prompt 9
JSON‑LD + Content Negotiation + OpenAPI
Implementiere gemäß SPEC.md:
- JSON‑LD Serializer
EmployeeJsonLdSerializerSkillJsonLdSerializerEvidenceJsonLdSerializer- URN‑IDs gemäß SPEC (
urn:employee:*,urn:skill:*,urn:evidence:*) @context: https://schema.org
- Content Negotiation
Accept: application/json→ normale DTOsAccept: application/ld+json→ JSON‑LD Serializer- Middleware:
ContentNegotiationMiddleware
- OpenAPI 3.1
openapi/openapi.yamlerstellen- alle Endpunkte aus SPEC.md dokumentieren
- schema.org‑Begriffe als Referenz nutzen, aber keine externen Schemas einbinden
- /docs
- statische OpenAPI‑UI unter
public/docs - Nginx‑Route sicherstellen
- statische OpenAPI‑UI unter
Vorgabe: Erzeuge ausschließlich Code, der SPEC.md exakt entspricht.
Was Codex daraus gebaut hat
JSON‑LD‑Serializer
Codex ergänzt drei Serializer:
EmployeeJsonLdSerializerSkillJsonLdSerializerEvidenceJsonLdSerializer
Alle mit:
@context: https://schema.org- URN‑basierten
@id‑Werten gemäß SPEC:urn:employee:*urn:skill:*urn:evidence:*
Listen werden als JSON‑LD‑ItemList ausgegeben.
Content Negotiation
Die neue ContentNegotiationMiddleware:
- akzeptiert:
application/jsonapplication/ld+json*/*oder leer → Default: JSON
- liefert bei anderen
Accept‑Headern:406 Not Acceptable- als RFC7807 Problem‑Details (
application/problem+json)
Die API‑Pipeline in public/api.php wird erweitert:
- Middleware‑Reihenfolge: ContentNegotiation → Auth → Scope
EmployeeApiController und SkillEvidenceGraphController werden umgestellt:
application/json→ normale DTOsapplication/ld+json→ JSON‑LD‑Serializer- Listen als JSON‑LD‑
ItemList
OpenAPI 3.1 & /docs
Codex baut eine neue openapi/openapi.yaml:
- OpenAPI 3.1
- dokumentierte Endpunktgruppen:
- Auth
- Employee CRUD
- Skills/Evidence
- Graph
- Export/Erase
- Audit
- Health
- Metrics
- Accept‑Negotiation und ProblemDetails‑Schema sind enthalten
- schema.org‑Begriffe werden referenziert, aber nicht extern eingebunden
Unter public/docs entsteht:
- eine statische OpenAPI‑UI (
index.html, Swagger UI) - eine Kopie der Spezifikation unter
/docs/openapi.yaml
Nginx routet /docs auf diese UI.
Testing & Commit
Syntax‑Checks:
php -l app/Infrastructure/JsonLd/EmployeeJsonLdSerializer.php &&
php -l app/Infrastructure/JsonLd/SkillJsonLdSerializer.php &&
php -l app/Infrastructure/JsonLd/EvidenceJsonLdSerializer.php &&
php -l app/Http/Middleware/ContentNegotiationMiddleware.php &&
php -l app/Http/Controller/EmployeeApiController.php &&
php -l app/Http/Controller/SkillEvidenceGraphController.php &&
php -l public/api.php &&
php -l app/Http/bootstrap.phpZusätzlich:
- lokaler PHP‑Server für
/docsgestartet - Commit: “Add JSON-LD serialization, content negotiation, and OpenAPI docs”
- PR via
make_prerstellt
Review & Spec‑Abgleich zu Prompt 9
Der nächste Schritt: Spec‑Abgleich.
Prüffragen:
- JSON‑LD‑Ausgabe korrekt?
- URN‑IDs korrekt aufgebaut?
- Content Negotiation korrekt implementiert?
openapi.yamlvollständig und valide?/docskorrekt erreichbar?
Gefundene Abweichungen & Fixes
1. Content Negotiation Priorität
Problem: application/json wurde vor application/ld+json geprüft. Bei gemischten Accept‑Headern konnte dadurch fälschlich JSON statt JSON‑LD gewählt werden.
Fix: Reihenfolge angepasst:
application/ld+jsonapplication/json*/*oder leer → JSON‑Default
Jetzt ist die Präferenz deterministisch und spec‑konform.
2. OpenAPI 3.1 Validität
Problem: In openapi/openapi.yaml waren noch nullable: true‑Einträge vorhanden – OpenAPI‑3.0‑Stil, nicht JSON‑Schema‑konform für 3.1.
Fix:
nullable: trueentfernt- durch Typ‑Unionen ersetzt, z.B.:
type: [string, 'null'] - sowohl in der kanonischen Datei als auch in der statischen Docs‑Kopie (
public/docs/openapi.yaml)
Ergebnis des Spec‑Abgleichs
- JSON‑LD‑Ausgabe korrekt? Ja, bereits spec‑konform, unverändert belassen.
- URN‑IDs korrekt aufgebaut? Ja,
urn:employee:*,urn:skill:*,urn:evidence:*– unverändert. - Content Negotiation korrekt? Nach Fix: Ja, mit korrekter Präferenz für
application/ld+json. - OpenAPI.yaml vollständig & valide? Vollständigkeit wie im vorherigen PR, Validitätsproblem (nullable) behoben.
- /docs erreichbar? Nginx‑Routing korrekt,
/docsund/docs/openapi.yamlliefern 200.
Testing im Spec‑Abgleich
php -l app/Http/Middleware/ContentNegotiationMiddleware.php
ruby -e "require 'yaml'; YAML.load_file('openapi/openapi.yaml'); YAML.load_file('public/docs/openapi.yaml'); puts 'yaml ok'"
rg -n "nullable:" openapi/openapi.yaml public/docs/openapi.yaml # keine Treffer
curl -s -o /tmp/docs.html -w "%{http_code}" http://127.0.0.1:8000/docs/ # 200
curl -s -o /tmp/openapi.yml -w "%{http_code}" http://127.0.0.1:8000/docs/openapi.yaml # 200Korrekturen committed, PR aktualisiert.
Fazit
Wir sind jetzt an einem Punkt, an dem das System:
- JSON‑LD spricht,
- Content Negotiation beherrscht,
- eine vollständige OpenAPI 3.1 hat
- und eine Docs‑UI unter
/docsausliefert.
Und ich sitze davor, schaue auf 3.791 Zeilen KI‑generierten Code und frage mich:
Wird das erste Hands‑on ein Desaster – oder eine positive Zumutung?