feat(files): Zeichnen und Mindmaps mit Excalidraw
Eine Zeichnung ist eine Datei, kein neues Ding – das ist die ganze Entscheidung dahinter. .excalidraw ist JSON; damit erbt sie Ordner, Gruppenordner, Papierkorb, Versionen, Freigabelinks, interne Freigaben und die Suche. Keine neue Tabelle, kein zweites Rechtemodell. Gespeichert wird über denselben Upload wie alles andere, wie beim Text-Editor in der Vorschau. Drei Sorgen, alle nachgemessen statt gehofft: Das Hauptbündel wächst von 484,11 auf 485,22 kB – das Zeichenbrett ist ein eigenes Stück (584 kB + 142 kB CSS) und wird nachgeladen wie der PDF-Betrachter. Wer nie zeichnet, holt es nie. Die Schriften: Die Richtlinie ist default-src 'self' ohne font-src, Excalidraw hätte seine handgezeichneten Schriften von aussen geladen und still eine Ersatzschrift gezeigt. Sie werden jetzt beim Bauen kopiert und über window.EXCALIDRAW_ASSET_PATH gefunden – gesetzt im Modul, nicht per Inline-Skript, das wäre von derselben Richtlinie blockiert. Xiaolai bleibt draussen: 13 der 14 MB für die chinesische Schrift. Die Reihenfolge der Dateiarten: .excalidraw wird vor code und text geprüft, sonst öffnete eine Zeichnung im Texteditor als Zahlenkolonne (json steht in codeExt). Kein gleichzeitiges Arbeiten. Die Komponente könnte es, aber den Transport bringt sie nicht mit – das wäre ein zweiter Dienst neben Aether. Solange es ihn nicht gibt, überschreibt der Zweite den Ersten. Zwei Dinge fangen das ab: Vor dem Speichern wird geprüft, ob sich die Fassung geändert hat, und dann gefragt statt überschrieben. Und Zeichnungen behalten ihre Fassungen von der ersten Minute an. Der zweite Punkt ist erst durch den Selbsttest aufgefallen: Versionierung ist sonst bewusst aus (Migration 000006), damit der Speicher nicht vollläuft. Für Zeichnungen stimmt die Rechnung nicht – sie werden in sich immer wieder bearbeitet und sind ein paar Kilobyte gross. Ohne sie wäre die Warnung im Editor ein Versprechen ohne Deckung gewesen. Neuer Selbsttest mit 12 Prüfungen: Er prüft die These nach, auf der alles beruht – wenn eine Zeichnung wirklich eine Datei ist, muss sie können, was Dateien können. Nebenbei: db-tests.sh liess je Lauf ein anonymes Postgres-Volume liegen (rund 49 MB). `docker rm -v` nimmt es jetzt mit; zehn verwaiste entfernt. Geprüft: go build/vet sauber, alle 15 Go-Pakete grün, 255 Prüfungen der acht Selbsttest-Suiten grün, 48 Vitest-Tests, tsc sauber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
662c0ebdc1
commit
6fc157bc07
14 files changed
+3700
-19
No files matched your search
+85
@@ -1562,6 +1562,91 @@ bleibt `node` (schnell); wer ein DOM braucht, schreibt
|
||||
|
||||
---
|
||||
|
||||
## Zeichnen und Mindmaps (27.09.2026)
|
||||
|
||||
Auf Excalidraw (MIT). **Eine Zeichnung ist eine Datei, kein neues Ding** – das
|
||||
ist die ganze Entscheidung dahinter. `.excalidraw` ist JSON; damit erbt sie
|
||||
alles, was Aether fuer Dateien schon kann: Ordner, Gruppenordner, Papierkorb,
|
||||
Versionen, Freigabelinks, interne Freigaben, Suche. Keine neue Tabelle, kein
|
||||
zweites Rechtemodell.
|
||||
|
||||
Gespeichert wird ueber denselben Upload wie alles andere – gleicher Name,
|
||||
gleicher Ordner, wie beim Text-Editor in der Vorschau.
|
||||
|
||||
### Drei Sorgen, alle nachgemessen
|
||||
|
||||
**Das Hauptbuendel darf nicht wachsen.** Wer nie zeichnet, soll den Brocken nie
|
||||
holen. Nachgeladen wie der PDF-Betrachter:
|
||||
|
||||
| | vorher | nachher |
|
||||
|---|---:|---:|
|
||||
| Hauptbuendel `index-*.js` | 484,11 kB | **485,22 kB** |
|
||||
| Zeichenbrett (eigenes Stueck) | – | 584 kB + 142 kB CSS |
|
||||
|
||||
**Schriften.** Die Sicherheitsrichtlinie ist `default-src 'self'` ohne eigenes
|
||||
`font-src` – Excalidraw haette seine handgezeichneten Schriften von aussen
|
||||
geladen und still eine Ersatzschrift gezeigt. Sie werden jetzt beim Bauen ins
|
||||
`public/`-Verzeichnis kopiert (`vite.config.ts`) und ueber
|
||||
`window.EXCALIDRAW_ASSET_PATH` gefunden.
|
||||
|
||||
> Der Pfad wird **im Modul** gesetzt, nicht per Inline-Skript in `index.html`:
|
||||
> Das waere von derselben Richtlinie blockiert (`script-src 'self'`).
|
||||
|
||||
> **Xiaolai bleibt draussen.** Die chinesische Schrift ist 13 der 14 MB; alles
|
||||
> andere zusammen 512 KB. Wer Chinesisch in eine Zeichnung tippt, bekommt eine
|
||||
> Ersatzschrift – der Preis dafuer, das Abbild nicht um 13 MB aufzublaehen.
|
||||
|
||||
**Reihenfolge der Dateiarten.** `.excalidraw` wird **vor** `code` und `text`
|
||||
geprueft: `json` steht in `codeExt`, und stuende die Pruefung spaeter, oeffnete
|
||||
eine Zeichnung im Texteditor als Zahlenkolonne.
|
||||
|
||||
### Kein gleichzeitiges Arbeiten – und was das kostet
|
||||
|
||||
Die Komponente koennte es (`isCollaborating`), aber den Transport bringt sie
|
||||
nicht mit: Excalidraw betreibt dafuer einen eigenen WebSocket-Dienst, Nextcloud
|
||||
hat fuer seine Whiteboard-App ein eigenes Node-Backend gebaut. Das waere ein
|
||||
zweiter Container neben Aether, so wie Euro-Office einer ist – eine eigene
|
||||
Entscheidung, kein Nebenprodukt.
|
||||
|
||||
Solange es den nicht gibt, gilt: **Zwei Leute speichern nacheinander, der
|
||||
Zweite ueberschreibt den Ersten.** Zwei Dinge fangen das ab:
|
||||
|
||||
1. Vor dem Speichern wird geprueft, ob sich die Fassung geaendert hat. Wenn ja,
|
||||
wird **gefragt** statt ueberschrieben.
|
||||
2. Zeichnungen behalten ihre Fassungen **von der ersten Minute an**.
|
||||
|
||||
Punkt 2 ist erst durch den Selbsttest aufgefallen: Versionierung ist sonst
|
||||
bewusst abgeschaltet (Migration 000006), damit der Speicher nicht volllaeuft.
|
||||
Fuer Zeichnungen stimmt die Rechnung nicht – sie werden in sich immer wieder
|
||||
bearbeitet und sind ein paar Kilobyte gross. **Ohne sie waere die Warnung im
|
||||
Editor ein Versprechen ohne Deckung** gewesen.
|
||||
|
||||
### Selbsttest
|
||||
|
||||
`scripts/zeichnung-selbsttest.py`, 12 Pruefungen. Er prueft genau die These
|
||||
nach, auf der die Umsetzung beruht: Wenn eine Zeichnung wirklich eine Datei
|
||||
ist, muss sie koennen, was Dateien koennen.
|
||||
|
||||
- [x] Anlegen, Pruefsumme, Inhalt kommt unveraendert zurueck
|
||||
- [x] Aendern erzeugt eine Fassung in der Historie
|
||||
- [x] Jede Speicherung hebt die Fassungsnummer – darauf beruht der Abgleich
|
||||
- [x] Freigabelink darauf, oeffentlich abrufbar
|
||||
- [x] Zeichnung im Gruppenordner
|
||||
- [x] Excalifont wird vom eigenen Server ausgeliefert
|
||||
|
||||
### Von Hand zu pruefen
|
||||
|
||||
- [ ] `+ Drawing` legt eine Zeichnung an und oeffnet sie 🔎
|
||||
- [ ] Zeichnen, Rechteck, Text darin, Pfeil andocken – Block verschieben, der
|
||||
Pfeil folgt (das ist der Mindmap-Fall)
|
||||
- [ ] Die Schrift sieht handgezeichnet aus, nicht nach Arial
|
||||
- [ ] Speichern -> Punkt neben dem Namen verschwindet, Meldung erscheint
|
||||
- [ ] Schliessen mit ungespeicherten Aenderungen -> Rueckfrage
|
||||
- [ ] Zurueck-Geste im Zeichenbrett -> schliesst es, nicht die App
|
||||
- [ ] Am Telefon: Geht es mit dem Finger?
|
||||
- [ ] In zwei Browsern oeffnen, in beiden etwas zeichnen, nacheinander
|
||||
speichern -> der Zweite bekommt die Rueckfrage
|
||||
|
||||
## Der Abgleich bekommt eine Notbremse (26.09.2026)
|
||||
|
||||
`internal/rescan` ist das einzige Stueck Aether, das **hart** loescht:
|
||||
|
||||
Reference in new issue
Block a user