feat(composer): die Admin-Fläche, mit der der Editor spricht - #186
Merged
Conversation
Vier Routen: Entwurf lesen, Entwurf schreiben, veröffentlichen, verwerfen. Jede nennt die
Berechtigung, die sie verlangt, und genau daran hängt die Entwurfs-Garantie aus dem
Core-Vertrag: Zwei getrennte Methoden statt einer mit Schalter nützen nichts, wenn die eine
ungeschützt im Netz steht. Der öffentliche Renderpfad ruft GetPublishedAsync auf einem
anderen Vertrag und kommt hier nie an; der einzige Weg zum Entwurf liegt hinter
composer.layout.read.
VERÖFFENTLICHEN IST NICHT SCHREIBEN
Eigene Berechtigung. Ein Entwurf ist noch niemandes Entscheidung — er darf falsch,
halbfertig oder ein Versuch sein. Veröffentlichen stellt ihn vor Besucher, und die beiden
sind verschieden genug, dass jemand vernünftigerweise das eine dürfen kann und das andere
nicht. Verwerfen zählt zum Veröffentlichen: Beide entscheiden über den Unterschied zwischen
dem, was jemand gebaut hat, und dem, was Besucher sehen — nur in verschiedene Richtungen.
Ein veralteter Änderungsstempel beim Speichern antwortet 409, nicht 200. Das ist der
Unterschied zwischen einem Editor, der jemandem sagt, dass seine Arbeit kollidiert ist, und
einem, der still die Hälfte davon wegwirft. Was der andere geschrieben hat, steht NICHT in
der Antwort: Das lüde dazu ein, im Client zu mischen, und genau dort verschwindet Arbeit.
Wer veröffentlicht hat, kommt aus der Host-Anfrage, nie aus dem Body — sonst wäre es eine
Behauptung.
Zehn Tests, davon sieben über die Routen selbst statt über ihr Verhalten: dass jede eine
Berechtigung nennt, dass Veröffentlichen eine andere verlangt als Schreiben, dass jede
verlangte Berechtigung auch im Katalog des Hosts steht — sonst könnte niemand sie jemandem
geben. Die Gegenprobe belegt, dass eine Route ohne Berechtigung auffliegt.
Ein Fund beim Testen: Der Save-Handler nahm {"document": 5} entgegen. Syntaktisch gültiges
JSON, kein Layout — und ohne Prüfung landete es in der Datenbank, wo erst der Renderer
darüber fiele, bei einem Besucher. Jetzt muss das Dokument ein Objekt sein.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. Why is this change necessary?
#183 hat das Plugin gebaut, das Layouts besitzt — aber niemanden, der mit ihm spricht. Das ist die
Fläche, über die der Editor den Entwurf holt, speichert, veröffentlicht und verwirft.
2. What does this change do, exactly?
Vier Routen, jede mit der Berechtigung, die sie verlangt:
GET layouts/{layoutKey}/draftcomposer.layout.readPUT layouts/{layoutKey}/draftcomposer.layout.writePOST layouts/{layoutKey}/publishcomposer.layout.publishPOST layouts/{layoutKey}/discardcomposer.layout.publishDaran hängt die Entwurfs-Garantie. Zwei getrennte Methoden statt einer mit Schalter nützen
nichts, wenn die eine ungeschützt im Netz steht. Der öffentliche Renderpfad ruft
GetPublishedAsyncauf einem anderen Vertrag und kommt hier nie an; der einzige Weg zum Entwurfliegt hinter einer Operator-Berechtigung.
Veröffentlichen ist nicht Schreiben. Ein Entwurf ist noch niemandes Entscheidung — er darf
falsch, halbfertig oder ein Versuch sein. Veröffentlichen stellt ihn vor Besucher, und die beiden
sind verschieden genug, dass jemand vernünftigerweise das eine dürfen kann und das andere nicht.
Verwerfen zählt zum Veröffentlichen: Beide entscheiden über den Unterschied zwischen dem, was
jemand gebaut hat, und dem, was Besucher sehen — nur in verschiedene Richtungen.
Ein veralteter Änderungsstempel beim Speichern antwortet 409, nicht 200. Das ist der
Unterschied zwischen einem Editor, der jemandem sagt, dass seine Arbeit kollidiert ist, und einem,
der still die Hälfte davon wegwirft. Was der andere geschrieben hat, steht nicht in der
Antwort: Das lüde dazu ein, im Client zu mischen, und genau dort verschwindet Arbeit.
Wer veröffentlicht hat, kommt aus der Host-Anfrage, nie aus dem Body — sonst wäre es eine
Behauptung.
3. Describe each step to reproduce the issue or behaviour.
Zehn Tests, davon sieben über die Routen selbst statt über ihr Verhalten: dass jede eine
Berechtigung nennt, dass Veröffentlichen eine andere verlangt als Schreiben, dass jede verlangte
Berechtigung auch im Katalog des Hosts steht — sonst könnte niemand sie jemandem geben.
Gegenprobe: Nimmt man der Entwurfs-Route ihre Berechtigung, wird
EveryRouteDeclaresAPermissionrot.
4. Please link to the relevant issues (if any).
Setzt §7.3 (Entwurfs-Garantie an ihrer Aufrufstelle) und den zweiten Teil von §8 Baustein 7 um.
Was die Tests gefunden haben
Der Save-Handler nahm
{"document": 5}entgegen. Syntaktisch gültiges JSON, kein Layout — undohne Prüfung landete es in der Datenbank, wo erst der Renderer darüber fiele, bei einem Besucher.
Jetzt muss das Dokument ein Objekt sein.
Zahlen
11 Dateien. .NET 1971 + 29 Analyzer, zweimal wiederholt grün.
Noch nicht drin
Der Canvas selbst — die Vue-Oberfläche, in der jemand Blöcke zieht. Dafür fehlen noch die
beiden verbliebenen Bedingungen aus §7.6: Theme-Tokens und Sektions-CSS in den Canvas scopen.