CHANGELOG.md
Rama main · réplica de lectura del repositorio original.
# Changelog
## 3.8.3 – Oktober 2026
### Sicherheit
- 🔒 **Zugriff ohne Portfreigabe: stumme Verbindungen gehen wieder zu.**
Ein Gerät, das sich über den Vermittler meldet, aber den verschlüsselten
Handschlag nicht schickt, hielt bisher seinen Platz, solange es wollte.
Weil der Vermittler je Instanz nur acht Geräte gleichzeitig zulässt,
konnte so jemand alle Plätze besetzen, und die eigenen Geräte kamen nicht
mehr hinein. Jetzt schließt Nupplo jede Verbindung, die nach zehn Sekunden
noch keinen Handschlag hat. Gekoppelte Geräte merken davon nichts, ihr
Handschlag dauert Millisekunden.
## 3.8.2 – Oktober 2026
### Geändert
- 🔒 **Der Figurenkatalog kommt verschlüsselt.** Die Beschreibungen, mit
denen die Suche Figuren nach ihrem Aussehen findet, standen bisher als
Klartext in `katalog/index.ndjson` – und damit unter der MIT-Lizenz des
Repos, also für jeden frei nehmbar. Sie sind aber eigene Arbeit des
Projekts und sollen nur in Nupplo genutzt werden. Jetzt lädt Nupplo
`katalog/index.nupplo`, Zeile für Zeile verschlüsselt, und der Ordner
`katalog/` hat eine eigene Lizenz (`katalog/LIZENZ.md`): Nutzung nur in
Nupplo. Der Schlüssel steht in Nupplo selbst – jede Installation bekommt
den Katalog weiter ohne Anmeldung und ohne Hub. Die Verschlüsselung ist
bewusst ein Schild, keine Festung: Wer sie umgeht, weiß, dass der Inhalt
nicht für ihn bestimmt ist. Ein paar Kontrollzeilen machen eine Kopie
erkennbar; Nupplo übergeht sie. Das Format steht in
`docs/KATALOG-FORMAT.md`.
- 📣 **Ältere Fassungen bitten ums Update.** An der alten Stelle liegt nur
noch ein Hinweis. Wer nicht aktualisiert, findet bei der Suche nach
Aussehen statt Figuren die Bitte, Nupplo zu aktualisieren – mit dem
Grund dafür. Nach dem Update verschwinden diese Hinweise von selbst, und
jede Beschreibung kommt aus der neuen Datei zurück. Wer die alte Adresse
als Katalogquelle eingetragen hatte, wird still auf die neue umgelenkt.
- 🇩🇪 **Beschreibungen werden beim Abruf eingedeutscht**, nicht nur einmal
beim Start. Sonst wären alle Beschreibungen, die nach dem Hinweis neu
kommen, englisch geblieben, und „gelber Kopf“ fände nichts mehr.
Sonst ändert sich nichts – dieses Update bringt nur die neue Katalogdatei
und ihren Schlüssel.
## 3.8.1 – Oktober 2026
### Geändert
- 📘 **Der Verweis auf die Bauanleitungen steht nicht mehr in der
Hauptansicht.** Beim Set in der Sammlung liegt er im Steckbrief unter
**Mehr → Nachschlagen**, neben Preisverlauf und BrickLink; im
Katalogfenster hinter **Mehr ▾** neben „Bei BrickLink ansehen“. Das 📘
neben den Sets einer Figur ist weg – wer die Anleitung sucht, öffnet das
Set und findet sie dort unter „Mehr“.
## 3.8.0 – Oktober 2026
### Neu
- 📘 **Verweis auf die Bauanleitungen bei LEGO.** Bei Sets – in der
Sammlung und im Katalog – und bei Figuren in der Liste „in Sets“ führt
ein Verweis zu LEGOs Seite mit den Bauanleitungen zur Setnummer.
**Optional und ausgeschaltet voreingestellt:** Unter *Mehr → 📘
Bauanleitungen* wählst du, ob er nur in der Browseransicht, nur in der
Handyansicht oder in beiden erscheint. Artikelseiten verlinken wir
nicht – die gibt es bei LEGO nur für Sets, die gerade verkauft werden.
## 3.7.4 – Oktober 2026
### Behoben
- 🔎 **„Badehose Stormtrooper" findet den Stormtrooper in Badehose.** Für
diese Anfrage hatte sich die Instanz früher eine Übersetzung vom Modell
gemerkt (`stormtrooper helmet`), und die ging der Liste vor – auch
nachdem die Liste „Badehose" kannte. Jetzt stehen die Fassungen der
Liste vorn, das Gelernte dahinter, und gesucht wird mit allen.
- 🔎 **Die eigene Sammlung findet auch über die Bildbeschreibung.** Bisher
verglich der zweite Anlauf dort nur Namen. Eine Figur, deren Badehose
nur in der Beschreibung steht, fand die Katalogsuche, die eigene
Sammlung aber nicht.
## 3.7.3 – Oktober 2026
### Behoben
- 🔎 **„Badehose" findet etwas.** Das Wort fehlte im mitgelieferten
Wörterbuch, und ein unbekanntes Wort zählt als Pflichtwort – die Suche
lief leer, obwohl eine Figur in Badehose im Katalog steht. Ergänzt sind
Badehose, Whirlpool, Bademantel, Schlafanzug, Trainingsanzug, Laborkittel,
Fliege, Schlittschuhe, Rettungsring und weitere Alltagswörter rund um
Kleidung und Freizeit.
- 🔎 **Ein unbekannter Wortteil leert die Suche nicht mehr.** Kennt die
Liste den vorderen Teil eines zusammengesetzten Worts nicht, gilt
wenigstens der hintere – eine „Quatschhose" ist eine Hose. Namen wie
Skywalker oder Dumbledore bleiben unangetastet.
## 3.7.2 – Oktober 2026
### Geändert
- 📣 **„Meine Mitteilungen vom Hub-Admin“ erscheint nur, wenn etwas drin
ist.** Bisher stand der Kasten im Tausch-Tab auch leer da – obwohl man den
Hub-Admin von dort gar nicht anschreiben kann. Sind alle Mitteilungen
gelöscht, verschwindet er.
## 3.7.1 – Oktober 2026
### Sicherheit (externer Zugriff ohne Portfreigabe)
- 🔒 **Gelöschte Benutzer nehmen ihre gekoppelten Geräte mit.** Bisher
blieben die Geräte stehen und kamen weiter bis zur Anmeldeseite. Jetzt
verschwinden sie samt offenen Kopplungscodes, und bestehende Verbindungen
werden sofort getrennt.
- 🔒 **Eine kaputte Nachricht trifft nur ihre eigene Verbindung.** Ein
gekoppeltes Gerät konnte mit einer fehlerhaften Nachricht die Leitung für
alle Geräte kurz abreißen lassen. Außerdem sind Anfragen je Verbindung auf
160 MB begrenzt; darüber gibt es „413“.
- 🔒 **Die Herkunft kommt nie aus Kopfzeilen des Geräts.** Fehlte die
Adresse vom Vermittler, zählte die Bremse gegen Passwortraten nach der
vom Gerät gesetzten Absender-Kopfzeile. Solche Kopfzeilen werden jetzt
verworfen; ohne Adresse zählt eine feste Kennung je Gerät.
## 3.7.0 – Oktober 2026
### Neu
- 🗑 **Mitteilungen vom Hub-Admin löschen.** Unter „Meine Mitteilungen vom
Hub-Admin“ hat jeder Eintrag jetzt „Löschen“. Die Mitteilung verschwindet
nur bei dir und gilt als gelesen; der Hub-Admin behält sie in seinem
Verlauf. Braucht Hub 1.27.0.
## 3.6.0 – Oktober 2026
### Neu
- 🚫 **Zur Sperre selbst Stellung nehmen.** Im Kasten „Zugang gesperrt“
stand bisher nur, dass und warum gesperrt ist – widersprechen ließ sich
nicht. Jetzt steht darunter „Stellung nehmen“ (bis 2000 Zeichen, nur der
Hub-Admin liest es; erneutes Senden ersetzt die frühere Stellungnahme).
- 🚫 **Auch ohne Mitgliedskonto.** Lehnt der Hub schon den Beitritt ab, weil
die Installation gesperrt ist, sagt das jetzt *Mehr → Tausch-Netzwerk*
samt Grund – und bietet dieselbe Stellungnahme an. Dann spricht die
Installation mit ihrer Kennung statt mit einem Konto. Braucht Hub 1.26.0.
## 3.5.0 – Oktober 2026
### Neu
- 📣 **Zu einer Mitteilung des Hub-Admins Stellung nehmen.** Bisher blieb
eine Verwarnung ohne Gegenrede im Verlauf stehen – man konnte sie nur mit
„Verstanden“ wegdrücken. Jetzt steht daneben „Stellung nehmen“: ein Feld
für bis zu 2000 Zeichen, das nur der Hub-Admin liest. Erneutes Senden
ersetzt die frühere Stellungnahme. Braucht Hub 1.25.0.
- 📣 **Meine Mitteilungen vom Hub-Admin.** Im Tausch-Tab stehen alle
Mitteilungen an dich, auch bestätigte, mit deiner Stellungnahme.
Zurückgenommene bleiben durchgestrichen mit Datum und Begründung stehen.
- 🚫 **Auch gesperrt kann man Stellung nehmen.** Der Hub beantwortet die
eigenen Mitteilungen auch während einer Sperre; die Liste ist dann gleich
aufgeklappt. Das Lesen hebt den Sperrhinweis nicht auf – bisher galt jede
erfolgreiche Antwort des Hubs als Freischaltung.
## 3.4.4 – Oktober 2026
### Behoben
- 🎨 **„rote Beine" findet jetzt, was der Name sagt.** Die Farbsuche schaute
bisher nur in die Farbliste der Bildanalyse. Nannte der BrickLink-Name
„… Red Legs", fehlte Rot aber in der Liste, fiel die Figur heraus – und
umgekehrt kam „Red Torso, Blue Legs" herein, weil Rot irgendwo stand.
Jetzt liest Nupplo SE aus dem Namen, welches Teil welche Farbe hat
(`backend/namensfarben.py`): Fragt jemand nach einem Teil, entscheidet
der Name; ohne Teil holt er eine Figur nur noch herein, hinter die
Treffer der Farbliste („roter Droide" bleibt R-3PO).
- Gelesen wird nur „<Farbe> <Teil>" – Details wie „Short Red Stripes"
machen weiter keinen roten Droiden. Und es bleibt **lokal**: Die Namen
holt jede Instanz über ihren eigenen BrickLink-Zugang, weitergegeben
wird nichts.
## 3.4.3 – Oktober 2026
### Geändert
- 📚 **Der Katalog-Abzug hat eine eigene Karte.** Bisher stand er samt
Stand („… Figuren und … Sets · zuletzt geholt am …“) unten in der Karte
„Lokale KI für die Suche“ – dort sucht ihn niemand. Jetzt unter
**Mehr → 📚 Katalog-Abzug**. Die Zahlen im Erklärtext stimmen wieder
(gut 19.000 Figuren, gut 6 MB).
### Neu
- 🔄 **Beim Öffnen der App wird der Katalog-Abzug nachgesehen** – wie bei
den übrigen Nupplo-Oberflächen, statt bis zu zwölf Stunden auf den
nächsten Hintergrundlauf zu warten. Geholt wird nur, was sich geändert
hat, höchstens alle 15 Minuten, ohne BrickLink-Kontingent (die Namen
schlägt weiter der Hintergrundlauf nach). Die Karte zeigt dazu
„Zuletzt nachgesehen: …“.
## 3.4.2 – Oktober 2026
### Behoben
- 🐞 **Fehlerliste: kopierter Text und Issue nennen jetzt auch die jüngste
Fassung.** Bisher stand dort nur die Version vom ersten Auftreten – ein
heute wieder aufgetretener Fehler sah so aus, als käme er von einer Seite,
die seit Tagen nicht neu geladen wurde. Jetzt steht dort wie in der Karte
„2.92.0 → 3.4.0 (zuerst → zuletzt)“.
## 3.4.1 – Oktober 2026
### Behoben
- 🤝 **Angebote ziehen nach dem Abgleich selbst nach.** Wurde eine im
Tausch-Netzwerk angebotene Figur über externen Zugriff verkauft oder
geändert, stand das alte Angebot weiter im Netz – neu veröffentlichen
durfte nur ein Admin. Jetzt veröffentlicht die Instanz nach so einem
Abgleich im Hintergrund neu, wie nach einem Tausch (nur, wenn schon einmal
veröffentlicht wurde).
## 3.4.0 – Oktober 2026
### Neu
- 🤝 **Verkaufslisten im Tausch-Netzwerk.** Unter einer Verkaufsliste steht
„🤝 Im Netz anbieten“: Die offenen Artikel erscheinen im Netzwerk als
Verkauf, so viele Stück wie auf der Liste, **mit Preis je Stück** (aus dem
Preisfeld der Liste, sonst Ø-Marktwert). „Aus dem Netz nehmen“ zieht sie
zurück; angebotene Artikel tragen „🤝 im Netz“.
- **Liste und Netzwerk wissen voneinander:** Auf der Liste als verkauft
abgehakt → raus aus dem Angebot. Über das Netzwerk verkauft und
ausgetragen → die Liste hakt den Artikel von selbst ab, ohne die Sammlung
ein zweites Mal anzufassen.
- 💶 **Preise an Angeboten.** Wer mit Preis anbietet, bei dem steht er an
der Karte – unter Angebote, in Entdecken und im Profil. Braucht Hub 1.24.0.
## 3.3.3 – Oktober 2026
### Behoben
- ↩︎ **Rückgängig bei Verkäufen aus der App.** Was in der iOS-App verkauft
wurde, trägt keinen Schnappschuss des alten Stands. „Rückgängig“ in der
Web-App setzte dann nur den Haken zurück, die Stücke fehlten weiter in
der Sammlung. Jetzt sagt sie „In der App verkauft – bitte dort
zurücknehmen“ und lässt alles, wie es ist.
## 3.3.2 – Oktober 2026
### Behoben
- 🏷️ **„ab … €“ passt zum Zustand.** Die Angebotsmarke in Einkaufs- und
Verkaufslisten (und bei den Doppelten) zeigte immer den billigsten
**gebrauchten** Preis, auch bei Artikeln im Zustand Neu. Jetzt steht dort
„ab … neu“ bzw. „ab … gebraucht“, passend zum Artikel. Weiterhin eine
Abfrage je Zeile – das BrickLink-Tageslimit wird nicht stärker belastet.
## 3.3.1 – Oktober 2026
### Verbessert
- 💰 **Gesamterlös auf Verkaufslisten.** „💰 Gesamtpreis“ verteilt einen
Betrag anteilig nach Marktwert auf die offenen Artikel – auf einer
Verkaufsliste heißt das Feld jetzt „Gesamterlös“, und der Vorschlag ist
der volle Marktwert statt des Angebots-Anteils (60 %), der fürs Einkaufen
gedacht ist.
## 3.3.0 – Oktober 2026
### Neu
- 💰 **Verkaufslisten.** Über den Stift ✏️ an einer Liste lässt sich jetzt
auch die Art wählen: Einkaufs- oder Verkaufsliste. Eine Verkaufsliste tut
beim Abhaken das Gegenteil – **„✔ Verkauft – raus aus der Sammlung“**
nimmt die Stücke aus der Sammlung, das Kaufbuch geht mit, und die letzten
Stücke nehmen die Zeile mit. Im Preisfeld steht der Erlös; er zählt nicht
als Einkauf. „Rückgängig“ legt Menge, Kaufbuch und Notiz genau zurück.
- Das Listen-PDF schlägt für Verkaufslisten gleich die Verkaufsfassung vor.
### Geändert
- Der Stift an einer Liste öffnet jetzt einen Dialog mit Name und Art statt
einer Zeile nur zum Umbenennen.
## 3.2.1 – Oktober 2026
### Verbessert
- 📄 **Listen-PDF kommt fertig vom Server.** Bisher lief es über den
Druckdialog des Browsers – am iPhone ohne „Als PDF sichern“, mit Rändern
und Skalierung nach Gutdünken. Jetzt baut die Instanz das PDF selbst
(gleiches Aussehen überall, Nunito wie in der App, Seitenzahlen). Am
Handy geht danach das Teilen-Menü auf (In Dateien sichern, AirDrop,
Mail), am Rechner wird die Datei heruntergeladen – als
„Verkaufsliste ‹Name›.pdf“ bzw. „Einkaufsliste ‹Name›.pdf“.
### Für Betreiber
- Neue Abhängigkeit **fpdf2** (reines Python). Wer das Image zieht oder
mit `update.sh` baut, muss nichts tun.
## 3.2.0 – Oktober 2026
### Neu
- 📄 **Listen als PDF.** Unter jeder Einkaufsliste steht „📄 PDF“, zur
Auswahl in zwei Fassungen:
- **🛒 Einkaufsliste** – alle Artikel mit Bild, Zustand, Menge, Ø-Preis,
Summe, eingetragenen Einkaufspreisen und einem Kästchen zum Abhaken.
- **💰 Verkaufsliste** – für den Käufer: nur die offenen Artikel, ein
Preis je Stück (auf Wunsch ein Anteil vom Marktwert, z. B. 90 %) und
die Summe – **ohne** eigene Einkaufspreise.
Oben Wortmarke, Listenname und Eckdaten; gedruckt bzw. gesichert über den
Druckdialog des Browsers („Als PDF sichern“).
## 3.1.3 – Oktober 2026
### Neu
- 🎬 **Neues Startbild.** Die Wortmarke steht größer da, die
Steine fallen von weit oben ein und federn nach, „Nupp“ und „o“ gleiten
weiter heran. Darunter steigen ein **Gruß zur Tageszeit** („Guten
Morgen, Mia!“, ohne Anmeldung schlicht „Guten Morgen!“) und der Spruch
auf. Der Name der Sammlung steht dort nicht mehr – er bleibt bei der
Anmeldung.
- Der Gruß in der Kopfleiste spricht jetzt genauso wie das Startbild:
„Guten Morgen“ bis 11 Uhr, „Hallo“ bis 18 Uhr, „Guten Abend“ bis 23 Uhr,
danach „Noch wach?“.
## 3.1.2 – Oktober 2026
### Neu
- 🔐 **„Nur mit zweitem Faktor“** für den Zugriff ohne Portfreigabe
(*Mehr → Nach außen*, Admin). Dann kommt über den Vermittler nur herein,
wer die Zwei-Faktor-Anmeldung eingerichtet hat; im Heimnetz ändert sich
nichts.
### Warum
- Gemeldet: Über den Vermittler kam keine Code-Abfrage. Das Konto hatte
keinen zweiten Faktor – gefragt hatte bisher Cloudflare Access vor der
Web-App, und dieser Weg führt nicht durch Access.
- **Geprüft wird bei jeder Anfrage, nicht nur beim Anmelden.** Ein Gerät
meldet sich zu Hause oft direkt an und geht erst unterwegs über den
Vermittler; eine Prüfung nur beim Anmelden hätte diese Sitzung
durchgelassen.
## 3.1.1 – Oktober 2026
### Neu
- 🧱 **„Jede Noppe zählt.“** – der neue Spruch unter der Wortmarke im
Startbild und bei der Anmeldung (englisch „Every stud counts.“). Nupplo
kommt von „Noppe“.
### Doku
- Neue Bildschirmfotos in der README: Scannen, Sammlung, Einkaufsliste,
Statistik, eigene Fotos und Sicherung – mit der Nupplo-Kopfleiste und
erfundenen Beispieldaten.
## 3.1.0 – Oktober 2026
### Neu
- 📡 **Zugriff ohne Portfreigabe.** Nupplo SE kann von sich aus eine
Verbindung zu einem Vermittler (`connect.nupplo.com`) aufbauen und offen
halten. Externe Geräte erreichen die Instanz darüber, ohne dass am Router
etwas freigegeben wird – ohne Domain, ohne Tunnel, ohne zweiten
Container. Aus, bis ein Admin es unter *Mehr → Nach außen* einschaltet.
**Im Aufbau:** Der Vermittler nimmt vorerst nur freigeschaltete
Instanzen an.
- 🔐 **Ende zu Ende verschlüsselt** mit dem Noise-Protokoll (IK). Der
Vermittler reicht nur durch und kann nichts lesen. Geprüft gegen die
offiziellen Testvektoren.
- 📱 **Geräte koppeln per QR-Code** im Profil: Einmalcode, zehn Minuten
gültig. **Nur gekoppelte Geräte kommen durch** – ein fremdes Gerät sieht
nicht einmal die Anmeldeseite. Entkoppeln beendet auch eine gerade offene
Verbindung. Angemeldet wird danach wie immer.
- „Von außen genutzt“ in den Einstellungen zum zweiten Faktor kennt den
neuen Weg und meldet ihn nicht als „ohne Zugangsschutz“.
### Warum so gebaut
- **Anfragen gehen im Prozess an den Server**, nicht über eine
HTTP-Bibliothek an 127.0.0.1. Im Probelauf hängte eine solche Bibliothek
von sich aus `Accept-Encoding: gzip` an, und Fotos kamen gepackt an,
obwohl niemand danach gefragt hatte. Kopfzeilen gehen jetzt unverändert
durch; ein Test hält das fest.
- **Die Absenderadresse des Geräts** gibt der Verbinder als Client-Adresse
weiter. Sonst hätte die Sperre gegen Passwortraten („je Herkunft“) alle
Geräte gemeinsam gebremst.
- **Die Anmeldung beim Vermittler trägt eine Zufallszahl.** Ed25519
unterschreibt gleichen Inhalt immer gleich; eine Instanz, die sich in
derselben Sekunde neu verbindet, wäre sonst als Wiederholung abgewiesen
worden (beim Bau bemerkt).
- Der Schlüssel liegt als `connect.key` neben dem Geheimnis, nicht in der
Datenbank – Sicherungen wandern herum.
## 3.0.1 – Oktober 2026
**Das Repository heißt jetzt [Melle79/nupplo](https://github.com/Melle79/nupplo).**
Die alte Adresse leitet weiter – Links, `git`, `update.sh` und die
Katalogdatei kommen dort weiter an.
### Neu
- 👋 **Gruß in der Kopfleiste** statt des Namens über der Wortmarke:
„Guten Morgen“, „Guten Abend“ … mit dem eigenen Benutzernamen, passend
zur Tageszeit. Der Name der Sammlung steht weiter im Startbild und bei
der Anmeldung.
### Behoben
- **Update-Hinweis nach dem Umzug.** Die Prüfung liest, wohin
`…/releases/latest` weiterleitet. Seit dem Umzug steht davor eine zweite
Weiterleitung – vom alten auf den neuen Namen –, und der folgte sie
nicht. Jetzt folgt sie bis zu drei Sprüngen, nur innerhalb von GitHub.
**Wer 3.0.0 oder älter betreibt, bekommt den Hinweis auf diese Fassung
deshalb nicht angezeigt** und aktualisiert einmal von Hand.
- Fehler melden legt die Issues im neuen Repository an; ein noch auf
`Melle79/brickfolio` gesetztes `GITHUB_REPO` gilt als der neue Name.
## 3.0.0 – Oktober 2026
**Brickfolio heißt jetzt Nupplo SE** – SE steht für *Server Edition*, die
Fassung, die man selbst betreibt. Gleiche App, neuer Name – bestehende
Installationen laufen ohne Umstellung weiter.
### Neu
- 🧱 **Neuer Name und neues Logo.** Die Wortmarke „Nupplo“, deren l ein Turm
aus vier Steinen ist – oben gelb, dann rot, blau, unten grün. Sie steht im
Startbild, bei der Anmeldung und in der Kopfleiste, mit einem kleinen
„SE“ daneben, und nimmt die Farben jedes Designs an.
- 🎬 **Startbild:** Der Turm baut sich Stein für Stein auf, dann gleiten die
Buchstaben heran. Wer „Bewegung reduzieren“ eingestellt hat, sieht alles
sofort.
- 📲 **Neues App-Symbol:** der Steinturm auf Gelb, mit dem Namen der Instanz
darüber, wenn einer eingestellt ist. Auf dem Startbildschirm erscheint es
beim nächsten Hinzufügen.
- 🔔 Nach dem Update sagt ein einmaliger Hinweis, dass Brickfolio jetzt
Nupplo SE heißt.
### Für Betreiber
- **Nichts umstellen nötig.** Datenbank (`data/brickfolio.db`), tägliche
Sicherungen und JSON-Sicherungen behalten ihre Namen und ihr Format –
Sicherungen lassen sich weiter in ältere Instanzen einspielen.
- **Docker-Image:** Neu ist `ghcr.io/melle79/nupplo` (und `melle79/nupplo`
auf Docker Hub). Das bisherige `…/brickfolio` bekommt während eines
Übergangs von etwa drei Monaten dieselben Fassungen; wer es in seiner
`docker-compose.yml` stehen hat, muss nichts tun, sollte aber bei
Gelegenheit auf `nupplo` wechseln.
- Die Umgebungsvariable für den Anzeigenamen heißt jetzt `NUPPLO_NAME`;
`BRICKFOLIO_NAME` gilt weiter.
- Die Verbindung zum Tausch-Netzwerk und dessen Verschlüsselung bleiben
unverändert.
## 2.92.1 – September 2026
### Verbessert
- 🔎 **Das Suchwörterbuch kennt jetzt auch die Wörter der Setnamen** – rund
450 neue Stichwörter quer durch alle Themen: City, Friends, Ninjago,
Harry Potter, Castle, Pirates, Technic, Creator, Duplo, Disney,
Marvel/DC, Minecraft, Jurassic World, Super Mario, Botanicals. Gemessen
worden war bisher nur an Figurennamen; dort deckte die Liste 80 % der
Wörter, in den 21.669 Setnamen aber nur 37 %. „Bahnhof", „Bagger",
„Garage", „Tempel" oder „Adventskalender" (allein 1.931 Sets) fanden
nichts. Jetzt sind es 59 % – der Rest sind Eigennamen und Marken, die man
so tippt, wie sie im Katalog stehen.
- **Häufige Zusammensetzungen mit eigenem Eintrag.** Zerlegt wurde
„Feuerwache" zu `fire` + `guard` und traf Wachen aller Art; jetzt ist es
`fire station`. Ebenso „Polizeiwache", „Feuerwehrauto", „Todesstern".
- **Deutsche Namen, die anders lauten:** „Schneewittchen", „Aschenputtel",
„Dornröschen", „Arielle", „Todesstern", „Sternzerstörer",
„Kopfgeldjäger", „Besen", „Zaubertrank" und andere.
- Aufgenommen ist nur, was im Katalog auch vorkommt – ein Ziel, das in
keinem Namen steht, fände nichts.
### Behoben
- **Fehlende Bedeutungen:** „Pony" war nur die Frisur (jetzt auch das
Tier), „Motorrad" zerfiel in `motor` + `wheel`, „Anhänger" war nur der
Schmuck (jetzt auch der Anhänger am Auto), „Steine" nur Edelsteine, „See"
nur das Meer. Die bisherige Bedeutung bleibt jeweils vorn.
## 2.92.0 – September 2026
### Neu
- 📚 **Der Katalog für externen Zugriff** (`/api/sync/katalog`). Wer die
Sammlung mit eigener Datenbank führt, soll auch dann nachschlagen können,
wenn die Instanz gerade nicht erreichbar ist – nach Name, Nummer oder
Beschreibung. Dafür gibt die Instanz ihren Katalog heraus: Figuren und
Sets mit Bild, Jahr und Beschreibung, dazu Kategorien, Setinhalte und die
BrickLink-Nummern.
- **Mit den Namen, ohne die Schlüssel.** Der öffentliche Abzug hat keine
Namen; jede Instanz trägt sie über ihren eigenen BrickLink-Zugang nach.
Wer den Katalog von hier holt, bekommt sie mit. Die BrickLink-Schlüssel
verlassen die Instanz dabei nicht.
- Geholt wird nur, was sich seit dem letzten Mal geändert hat, in Seiten zu
5.000 Einträgen und gepackt: Der ganze Figurenkatalog (gut 19.000) ist
rund 1 MB.
## 2.91.0 – September 2026
### Neu
- 🔄 **Abgleich für externen Zugriff mit eigener Datenbank.** Wer von
außen zugreift und seine Daten selbst mitführt, kann jetzt holen, was sich
seit seinem letzten Stand geändert hat, und schicken, was bei ihm geändert
wurde (`/api/sync/info`, `/pull`, `/push`). Das betrifft Sammlung,
Kaufbuch, Wunschliste, Einkaufslisten und Preisverlauf. Konflikte
entscheidet die neueste Änderung je Eintrag. Doppelt erfasste Artikel
werden zusammengeführt, statt dass einer verloren geht.
- Dafür bekommt jede dieser Zeilen eine feste Kennung und einen Stand.
**Nachgezogen wird über Trigger in der Datenbank**, nicht an den rund 90
Stellen, an denen die Instanz schreibt: So zählt jeder Schreibweg mit,
auch einer, der später dazukommt. Gelöschtes hinterlässt einen Vermerk,
sonst käme es beim nächsten Abgleich wieder zurück.
### Rechte wie in der Web-App
- **Kaufpreise und Kaufbuch nur für Sammlerprofis.** Standard-Konten bekommen
sie beim Abholen nicht, und was sie schicken, wird dort ignoriert.
- **Einkaufslisten** anlegen und ändern nur Profis. Standard-Konten dürfen
Artikel verbuchen. Das Archiv gibt es für sie auch im Abgleich nicht.
- Werte werden geprüft wie in der Web-App: kein `1e999` als Preis, keine
unbekannten Zustände.
### Geändert
- ↩️ **Nach dem Zurückspielen einer Sicherung** (JSON oder Tagesstand)
beginnt jeder externe Zugriff mit eigener Datenbank von vorn. Mit einem
Tagesstand kommt auch der alte Zählerstand zurück, und wer schon weiter
war, hätte sonst Änderungen übersehen.
## 2.90.22 – September 2026
### Neu
- 🔎 **Steckbriefe in der Tauschbörse.** Ein Tipp auf Name oder Nummer eines
Artikels öffnet seinen Steckbrief – in Angeboten, Entdecken, „Ich biete
an“, im Profil eines anderen, im Anfrage-Fenster und im Kopf eines
Gesprächs. Die Knöpfe behalten ihre Aufgabe.
- 🎨 **Kopf des Tausch-Netzwerks als eigene Karte:** größeres Bild, Name
fett, „Mein Profil“ und „Freund einladen“ als Knöpfe; die freien
Einladungen stehen als Zahl im Einladen-Knopf.
- 👑 **Hub-Admins laden ohne Kontingent ein** (mit Hub 1.23.0).
### Geändert
- 👤 **„Benutzername ändern“** statt „Anzeigename ändern“ im Profil – das
Feld ändert den Anmeldenamen.
- 🔒 **Nummern übernehmen, doppelte Nummern zusammenführen und Themen
nachladen** dürfen nur noch Admins und Sammlerprofis. Standard-Konten
sehen den Hinweis weiter, ohne die Knöpfe.
- 💬 **Rückfragen im eigenen Fenster** statt der Browser-Kästen
(`confirm`/`alert`); Löschen und Entfernen mit rotem Knopf.
- 🔢 **Sortierung „Nummer“** zählt Zahlen als Zahlen: 3001 vor 10179-1.
- 🌍 **Englisch:** die übrigen Absätze in den Einstellungen (Jedipedia,
Katalog-Abzug, Gelernte Begriffe, Tausch-Netzwerk, Diagnose, Quellen &
Rechtliches) und die restlichen Texte aus dem Code übersetzt.
### Behoben
- 🐞 **Ausfälle von BrickLink & Co. landen nicht mehr als Fehler** mit
großem Hinweis und Push – die App hat sie abgefangen und sagt es.
- 📉 **„Größte Wertverluste“** zählt keine Artikel ohne Marktpreis mehr.
- 💬 **Dialoge schließen nicht mehr bei falscher Eingabe** („Weiterer Kauf“
mit Buchstaben, zu kurzes Passwort) – sie sagen, was fehlt.
- 🧾 **Kaufbuch** zeigt den Betrag des Postens statt des gerundeten
Stückpreises („2× 9,99 €“ statt „2× 5,00 €“).
- ✏️ **Kleinigkeiten:** das × in Suchfeldern stimmt auch nach „Filter
zurücksetzen“; der Stift in der Bezahlt-Kachel wird nicht abgeschnitten;
Listen-Reiter und Fußzeile einzeilig; Schilder über mehrere Zeilen stoßen
nicht an die Rundung; das Preis-Protokoll ist am Handy lesbar; der
Zwei-Faktor-Schlüssel bricht nur zwischen den Vierergruppen um;
„Fehlerbericht öffnen“ springt an den Anfang der Karte; der Listenpreis
lässt sich leeren; der Minus-Knopf wechselt nach einem Kauf sein Zeichen;
der Steckbrief nimmt Preise von Wunsch- und Einkaufsliste; „Modelle
laden“ ohne Adresse sagt es; „Nichts zu tun“ nur, wenn wirklich nichts
offen ist; „Alle auf die Wunschliste“ verschwindet, wenn schon alle
gemerkt sind; Netzwerkfehler als Satz statt Python-Meldung; nach dem
Abmelden keine Abfragen mehr; der Hinweistitel wechselt mit der Sprache;
die Hilfe verweist auf „Manuell erfassen“ statt auf eine Suche, die es
dort nicht gibt.
- 🤝 **Tausch-Netzwerk:** Der Ungelesen-Zähler verpasst keine Antwort mehr
in derselben Sekunde; „Ich biete an“ gleicht Nummer *und* Zustand ab;
der Stand einer Meldung kommt nach dem Absenden sofort.
- 🛡️ **Schnittstelle:** Die Anmeldebremse glaubt Proxy-Kopfzeilen nur aus
dem eigenen Netz; die Ersteinrichtung legt auch bei gleichzeitigen
Aufrufen nur einen Admin an; eine neue Nummer verwirft die alten Preise;
eine CSV-Datei mit offenem Anführungszeichen meldet die Zeile.
## 2.90.21 – September 2026
Ergebnis eines Gesamttests: alle 181 Schnittstellen, die ganze Oberfläche
(Handy und Desktop, drei Designs, Deutsch und Englisch) und das
Tausch-Netzwerk mit zwei Instanzen und einem örtlichen Hub.
### Behoben – Sammlung, Listen, Kaufpreise
- 💥 **Ein unendlicher Preis legte die App lahm.** `1e999` als Kaufpreis
wurde angenommen; danach gaben Sammlung, Statistik und Sicherung nur noch
Fehler. Unendlich und NaN werden jetzt überall abgelehnt, auch im
CSV-Import.
- ↩️ **„Rückgängig“ in der Einkaufsliste nimmt den Wareneingang zurück** –
Menge und Kaufposten. Bisher blieb beides stehen, und wer den Artikel noch
einmal annahm, hatte ihn doppelt. Nach „Ersetzen“ bleibt es beim Hinweis,
die Sammlung von Hand anzupassen.
- 🔒 **Kaufpreise nur für Sammlerprofis – auch in der Schnittstelle.** Die
Oberfläche blendete sie für Standard-Benutzer aus, geliefert und
angenommen wurden sie trotzdem (Sammlung, Kaufbuch, Statistik, Listen).
- 📉 **Weniger Stück heißt weniger bezahlt.** Menge verringern ließ den
ganzen Kaufpreis an der Zeile stehen; jetzt geht das Kaufbuch mit.
- 🧹 **Gelöschter Kaufpreis bleibt gelöscht.** Nach dem Neuladen war er
wieder da.
- ☑️ **Haken in der Katalogliste entfernen löscht keine Einträge mit
Kaufpreis mehr** – und räumt Kaufbuch und Fotos mit auf.
- 🔢 **Neue Nummer übernehmen** führt zusammen, wenn es die Nummer schon
gibt, statt mit einem Serverfehler abzubrechen.
- 👤 **Benutzer löschen** klappt auch, wenn er ein Foto angehängt hat.
- 🤝 **„Doppelte übernehmen“ bietet nur den Überschuss an** – nicht mehr das
Exemplar zum Behalten und die Figuren aus eigenen Sets.
- ⭐ **Wunschliste:** Besitz neu *und* gebraucht wird zusammengezählt.
- 📈 **Wertverlauf** berücksichtigt beide Zustände einer Figur.
- 💶 **Gesamtangebot:** kein Anteil mehr mit −0,01 €.
- 📄 **CSV:** Der Export enthält Thema und (für Profis) Bezahlt, der Import
liest beides und versteht „1,234.56“ wie „1.234,56“.
- 🔐 **Falsches Passwort beim Einrichten der Zwei-Faktor-Anmeldung meldet
nicht mehr ab.**
- 🤖 **Der Ollama-Test fragt wirklich das Modell** – vorher antwortete das
eingebaute Wörterbuch, und der Test meldete „verbunden“ ohne Dienst.
- 🧩 **Steckbrief:** „Steckt in diesen Sets“ zeigt wieder Name und Anzahl
statt „…|2“.
- 🛒 **Manuell erfassen → Liste** übernimmt den Einkaufspreis.
- 🔁 **Zustand im Karten-Fenster umstellen** aktualisiert Wert und Gewinn
sofort.
- Kleinigkeiten: Katalog ohne Abzug meldet „noch nicht geladen“,
„Lukas' Brickfolio“ statt „Lukas's“, „1 Figur fehlt“, keine doppelten
Fehlergründe, sichere Suche mit `%` und `_`, Push-Geräte ohne Schlüssel
werden abgewiesen, Sicherungen mit kaputtem Aufbau bekommen eine klare
Meldung, 422-Antworten wiederholen keine Eingaben (auch keine
Passwörter), der Update-Vergleich versteht Anhänge wie `-rc1`.
### Behoben – Tausch-Netzwerk
- 📨 **Nachrichten an ein gesperrtes Gegenüber gehen raus** (und kommen nach
der Freischaltung an), statt mit „Mitglied nicht gefunden“ zu scheitern.
- 📦 **Löscht das Gegenüber ein schon angenommenes Gespräch, bleibt es
buchbar.**
- 🗂 **Nach Abmelden und Wiederbeitritt** stehen alte Gespräche als
„frühere Mitgliedschaft“ da, nicht als „vom Gegenüber gelöscht“.
- 🔁 **Dasselbe Angebot lässt sich nach einem abgeschlossenen Tausch wieder
anfragen**; der Zustand (neu/gebraucht) zählt dabei.
- 🚦 **Statuswechsel werden geprüft** – die eigene Anfrage annehmen oder ein
abgeschlossenes Gespräch wieder öffnen geht nicht mehr.
- 🚪 **Zweimal beitreten** legt kein zweites Mitglied mehr an.
- 🔌 **Vom Hub-Admin entfernt?** Die App sagt es und zeigt den Weg zum
Neubeitritt, statt überall „Token ungültig“ zu melden.
- 🐞 **Absagen des Hubs sind keine Fehler mehr.** Sperre, Kontingent,
benutzte Einladung landeten als 502 im Fehlerbericht.
- ⚖️ **Gleichzeitiges Austragen** bucht Menge und Kaufbuch sauber
nacheinander.
- Kleinigkeiten: „nicht mehr angeboten“ nur, solange nichts zugesagt ist;
der Sperrhinweis sagt nicht „bis auf Weiteres“ neben einem Enddatum;
„Freund einladen“ verschwindet bei Sperre; leere Nachrichten werden
abgewiesen.
### Geändert – Darstellung
- 📱 **Sammlung am Handy:** Die Suche hat eine eigene Zeile, „Alle Typen“
und „Zuletzt erfasst“ werden nicht mehr abgeschnitten.
- 📱 **Kacheln am Handy:** Große Beträge passen nebeneinander, auch in der
Wunschliste.
- 🎨 **Galaxy und Nova:** Ausgewählte Zustands-Pillen und das
Wunschlisten-Schild haben dunkle Schrift auf Gelb bzw. Hellblau.
- 🌍 **Englisch:** gut 60 fehlende Übersetzungen im Tausch-Netzwerk
(Entdecken, Profil, Einstieg) ergänzt.
## 2.90.20 – September 2026
### Behoben
- 🔌 **Vereinzelte „502“ mitten im Betrieb.** Hinter einem Tunnel wie
Cloudflare schloss der Server ruhende Verbindungen schon nach 5 Sekunden,
der Tunnel hielt sie aber bis zu 90 Sekunden für die nächste Anfrage
bereit. Traf eine Anfrage genau diesen Moment, kam sie mit „502“ zurück –
ohne dass der Server neu startete. Er hält Verbindungen jetzt 120 Sekunden
offen. Wirkt nach dem Update, weil der Startbefehl im Image steckt.
## 2.90.19 – September 2026
### Behoben
- 💰 **„Gesamtangebot“ in Einkaufslisten geht wieder.** Seit die Knöpfe
einer Liste in der eigenen Fußzeile stehen (2.88.37), suchte der Knopf
noch den alten Rahmen, fand ihn nicht und brach ohne Meldung ab – es
passierte einfach nichts.
- 📱 **Tausch-Netzwerk am Handy aufgeräumt.** Unter dem eigenen Namen stehen
„Mein Profil“, „Freund einladen“ und die freien Einladungen jetzt in einer
eigenen, eingerückten Zeile, statt links unter das Bild zu rutschen.
- 📱 **„Ich biete an“:** „Entfernen“ sitzt jetzt klein unten rechts neben der
Menge. Bisher nahm der Knopf neben dem Titel fast die halbe Breite ein und
quetschte lange Namen auf fünf Zeilen.
- 🎨 **Keine blaue Schrift mehr auf dem iPhone.** Safari färbt Knöpfe und
Auswahllisten ohne eigene Farbe systemblau – betroffen waren etwa die
Reiter im Tausch-Netzwerk und die Mengenauswahl. Sie übernehmen jetzt die
Textfarbe des Themas. In den dunklen Themen ist die Schrift auf gelb
bzw. blau hinterlegten, ausgewählten Reitern und Umschaltern wieder dunkel.
## 2.90.18 – September 2026
### Geändert
- 📱 **Preiszeilen brechen sauber um.** Das gelbe Schild steht links, alles
andere in einer eigenen Spalte daneben – was umbricht, bleibt unter dem
Preis eingerückt. Bisher rutschte „· 13× verkauft 🇩🇪“ auf dem Handy an
den linken Rand unter das Schild. Ist die Zeile schmal (Handy,
Katalogfenster), steht die Verkaufszahl grundsätzlich in einer eigenen,
eingerückten Zeile; ist sie breit, bleibt alles in einer. Angaben wie
„1× verkauft 🇩🇪“ werden nie mehr mittendrin getrennt.
## 2.90.17 – September 2026
### Geändert
- 💶 **Das Katalogfenster zeigt jetzt auch Preise** – wie der Steckbrief,
mit Spanne, Verkaufszahl, Gebietsfahne und den Angebotspreisen, wenn
eingeschaltet. Bisher standen dort nur Bild, Name und die Knöpfe. Das
Fenster ist dafür etwas breiter geworden.
- Die Gebietsfahne hängt an der Angabe davor und rutscht nicht mehr allein
in die nächste Zeile.
## 2.90.16 – September 2026
### Geändert
- 💶 **Auch das Info-Fenster aus Listen, Sets und Katalog zeigt die Preise
wie der Steckbrief** – mit Spanne, Verkaufszahl, Gebietsfahne und den
Angebotspreisen, wenn eingeschaltet. Wie beim Suchtreffer (2.90.15) steht
die Kurzzeile sofort da, die vollen Angaben folgen.
## 2.90.15 – September 2026
### Geändert
- 💶 **Das Infofenster eines Suchtreffers zeigt die Preise wie der
Steckbrief.** Bisher stand dort nur „Ø neu … · Ø gebr. …“. Jetzt kommen
neu und gebraucht mit Spanne, Verkaufszahl und Gebietsfahne, darunter die
Angebotspreise, wenn eingeschaltet. Die Kurzzeile steht sofort da, die
vollen Angaben folgen einen Moment später.
## 2.90.14 – September 2026
### Neu
- ✉️ **Meine Einladungen.** Unter „Freund einladen“ stehen die eigenen
Einladungen: offene mit ihrem Code – noch einmal kopieren, teilen oder
zurückziehen –, eingelöste mit Name und Datum (vier Wochen lang). Bisher
war ein Code nach dem Schließen des Fensters weg, obwohl die Einladung
verbraucht war, und ob er eingelöst wurde, sah man nirgends. Den Code
merkt sich die eigene Instanz, der Hub kennt nur seine Prüfsumme. Braucht
Hub 1.22.0.
## Hub 1.22.0 – September 2026
### Neu
- `GET /v1/invites` liefert die eigenen Einladungen mit Stand (Prüfsumme als
Kennung, ohne Code), `DELETE /v1/invites/:prüfsumme` zieht eine offene
zurück.
### Behoben
- Abgelaufene, nie eingelöste Einladungen zählten für immer gegen das
Kontingent. Jetzt zählen nur noch offene und eingelöste.
## 2.90.13 – September 2026
### Geändert
- ✉️ **Einladen mit eigenem Fenster.** Der Code stand bisher als rohe
Zeile unter dem Zähler. Jetzt öffnet „Freund einladen“ ein Fenster mit dem
Code in groß, „Kopieren“ und – wo das Gerät es kann – „Teilen“, dazu drei
Schritte, was der Freund damit macht. Wie viele Einladungen noch frei
sind, steht als kleine Marke direkt am Knopf.
- 📝 README und Handbuch: Der Tausch-Abschnitt sagt jetzt gleich oben, dass
das Netzwerk von Haus aus aus ist und nur geteilt wird, was man
ausdrücklich auswählt. Die Flaggen-Beschreibung passt zu 2.90.12.
## 2.90.12 – September 2026
### Geändert
- 🇩🇪 **Jede Preiszeile im Steckbrief zeigt ihr Gebiet.** Bisher stand die
Fahne nur, wenn die App auf ein größeres Gebiet ausweichen musste. Dann
sah man etwa bei „Gebraucht“ die EU-Fahne und bei „Neu“ nichts. Jetzt
steht auch die Fahne des eingestellten Gebiets dahinter, bei Verkaufs-
wie Angebotspreisen, und der Tooltip sagt, woher der Preis kommt. Die
kurze Zeile auf der Karte bleibt, wie sie war.
## Hub 1.21.0 – September 2026
### Neu
- **Instanz ganz entfernen:** `DELETE /v1/admin/instances/:id` löscht die
Instanz samt aller Konten, die je darüber beigetreten sind, und allem, was
an ihnen hängt. Für Testinstanzen und verwaiste Installationen – wer nur
nicht zurücksoll, bekommt weiter „Neubeitritt sperren“. Instanzen mit
Admin-Konto bleiben stehen. In der Konsole unter *Instanzen → Entfernen*.
## 2.90.11 – September 2026
### Neu
- 💬 **Rückfragen zu Meldungen.** Der Hub-Admin kann beim Meldenden
nachfragen. Die Frage steht unter der Meldung im Gespräch, es kommt ein
Hinweis, und man antwortet gleich dort.
- 📣 **Maßnahmen, die der Betroffene sieht.** Hinweis und Verwarnung des
Hub-Admins stehen oben im Tausch-Tab, bis man „Verstanden“ drückt. Der
Sperrhinweis nennt Grund und Ende einer Sperre. Wer gemeldet hat, steht
nirgends.
- ✔ **Der Meldende sieht, was aus seiner Meldung wurde** – die Maßnahme,
wenn der Admin sie freigibt, sonst nur „bearbeitet“.
Braucht Hub 1.20.0.
## Hub 1.20.0 – September 2026
### Neu
- **Rückfragen:** `report_messages`; der Admin schreibt über
`POST /v1/admin/reports/:id/messages`, der Meldende über
`POST /v1/reports/:id/messages` (öffnet eine erledigte Meldung wieder).
Beide Seiten bekommen den Austausch mit den Meldungen geliefert.
- **Maßnahmen beim Erledigen:** `massnahme` (`keine`, `hinweis`,
`verwarnung`, `sperre_zeit` mit `tage`, `sperre`), Text an den
Gemeldeten, `ergebnis_sichtbar` für den Meldenden. Hinweise landen in
`member_notices` und über `/v1/me` beim Betroffenen, bestätigt mit
`POST /v1/notices/:id/ack`. Sperren setzen `blocked_until`/`block_reason`,
befristete heben sich beim nächsten Besuch nach Ablauf selbst auf. Der
403 einer Sperre nennt Grund und Ende.
- **Archiv:** erledigte Meldungen und entschiedene Einladungsanfragen lassen
sich archivieren (`POST …/archive`, Liste mit `?archiv=1`) oder löschen.
- Die Meldungsliste der Verwaltung nennt beim Gemeldeten, wie oft er schon
gemeldet wurde und welche Maßnahmen es gab. Die Mitgliederliste zeigt
Meldungen, Maßnahmen und Sperrgrund.
## 2.90.10 – September 2026
### Neu
- ⚑ **Die eigene Meldung bleibt sichtbar.** Bisher kam nach dem Melden nur
eine kurze Bestätigung, danach fand man die Meldung nirgends wieder. Jetzt
steht im Gespräch, wann man gemeldet hat und ob mit Verlauf, in der
Gesprächsliste die Marke „⚑ gemeldet“. Hat ein Hub-Admin die Meldung
erledigt, steht das dort ebenfalls, und es kommt ein Hinweis. Braucht
Hub 1.19.0.
## Hub 1.19.0 – September 2026
### Neu
- `POST /v1/reports` gibt die Nummer der Meldung zurück, `GET /v1/reports`
liefert die eigenen Meldungen mit Stand (`open`/`handled`) und Datum. Die
Notiz des Admins und der offengelegte Verlauf gehen dabei nicht mit.
## 2.90.9 – September 2026
### Behoben
- ✉️ **„Freund einladen“ war kaum zu finden.** Der Knopf stand im Reiter
„Angebote“ neben „Aktualisieren“. Seit „Entdecken“ der Startreiter ist,
sah man ihn gar nicht mehr. Jetzt steht er oben im Tausch-Tab neben „Mein
Profil“, samt Einladungszähler, und ist von jedem Reiter aus erreichbar.
## 2.90.8 – September 2026
### Behoben
- 🧱 **Kompakte Ansicht nach Thema sortiert zeigte Riesenkacheln.** Auf
breiten Bildschirmen standen statt der kleinen Kacheln drei 400 px breite
Kästen je Reihe. Schuld war die Spaltenregel der Listenansicht: Sie
traf auch die kompakte Ansicht und stand später in der Datei. Jetzt gilt
sie nur noch für die Liste, und ein Test hält das fest.
## 2.90.7 – September 2026
### Neu
- ↕️ **Nach Kaufpreis und Gewinn sortieren** (nur Sammlerprofis):
„Bezahlt (hoch → niedrig)“, „Gewinn (hoch → niedrig)“ und „Gewinn
(niedrig → hoch)“ – letztere zeigt die Verluste zuerst. „Wert“ bleibt der
Marktwert. Einträge ohne Kaufpreis stehen am Ende. Für alle anderen
bleiben die Sortierungen unsichtbar und greifen auch nicht, denn schon
die Reihenfolge verriete, was bezahlt wurde.
## 2.90.6 – September 2026
### Behoben
- 📒 **Ein leer gelassenes „Bezahlt (optional)“ wurde als 0 € gebucht.**
Beim Übernehmen eines Tauschs landete damit „0 € bezahlt“ im Kaufbuch
statt „kein Preis“, und der Gewinn der Zeile stimmte nicht. Leer heißt
jetzt wieder: keine Angabe.
## 2.90.5 – September 2026
### Behoben
- 🔁 **Ein Neustart beim Ausrollen ging manchmal als Fehler in die Liste.**
Nach einem 502 fragte die App genau einmal nach 20 Sekunden, ob der
Server frisch gestartet ist. Dauerte der Austausch länger, lief die
Nachfrage ins Leere, und „502 bei GET /api/update/status“ landete als
Fehler im Bericht. Jetzt fragt sie bis zu zwei Minuten lang nach.
Gemeldet wird nur, wenn der Server schon lange läuft oder nach zwei
Minuten immer noch weg ist.
## 2.90.4 – September 2026
### Behoben
- 📬 **Neue Nachrichten erschienen erst nach bis zu einer Minute.**
Außerhalb eines Gesprächs sah die App nur einmal pro Minute beim Hub
nach. Wer vorher neu lud, sah die Nachricht sofort und hielt das
Nachladen für kaputt. Jetzt alle 20 Sekunden (in der Nachrichtenliste
alle 15, im offenen Gespräch weiter alle 8) und zusätzlich sofort, wenn
man in den Tab oder ins Fenster zurückkommt.
## 2.90.3 – September 2026
### Behoben
- Eine Nachricht an jemanden, der das Netzwerk verlassen hat, scheiterte
mit „502 – Mitglied nicht gefunden“. Jetzt heißt es gleich „Das Gegenüber
hat das Tausch-Netzwerk verlassen“. In der Oberfläche war das Eingabefeld
dort schon ausgeblendet, es betraf nur den direkten Aufruf.
## 2.90.2 – September 2026
### Neu
- 🚪 **Hinweis, wenn das Gegenüber das Netzwerk verlassen hat.** Bisher
konnte man in so ein Gespräch weiterschreiben, aber es kam nie etwas an.
Jetzt steht im Gespräch „hat das Tausch-Netzwerk verlassen", das
Eingabefeld verschwindet, und der Verlauf bleibt lesbar. Ist das
Gegenüber gesperrt, sagt ein Hinweis, dass Nachrichten erst nach einer
Freischaltung ankommen.
### Geändert
- 📝 Der Text zum Tausch-Netzwerk unter *Mehr* stammte noch aus der Zeit,
als nur Abgebbares geteilt wurde. Jetzt sagt er, was wirklich geteilt
wird: Angebote, Profil und, wenn man will, die Wunschliste.
Braucht Hub 1.18.0.
## Hub 1.18.0 – September 2026
### Neu
- `/v1/trades` liefert `from_status`/`to_status` (`active`, `left`,
`disabled`, `gone` für gelöschte Mitglieder). Nachrichten an Abgemeldete
lehnt der Hub mit 410 ab – sie würden nie abgeholt.
### Geändert
- Beim Abmelden geht auch das Profil (Über mich, Gegend, Themen). Es
bleiben nur Name und Eckdaten, damit die Verwaltung den Austritt sieht
und die Gegenseite ihre Gespräche behält.
## 2.90.1 – September 2026
### Neu
- 🚪 **Abmelden heißt jetzt auch abmelden.** Bisher vergaß beim Trennen nur
die eigene Instanz die Verbindung. Im Hub blieben Angebote und Wünsche
stehen, andere fragten bei jemandem an, der nie antworten würde. Jetzt
meldet sich die App beim Hub ab, der nimmt alles heraus, und in der
Verwaltung steht „abgemeldet am …". Der Knopf heißt „Aus dem Netzwerk
abmelden", und die Rückfrage sagt, was passiert.
- ⏸ **Pause bei Inaktivität.** Wer länger nicht im Netzwerk war (Standard
30 Tage), dessen Angebote und Wünsche blendet der Hub aus, bis er
wiederkommt. Dann sind sie von selbst zurück, und die App sagt, von wann
bis wann sie pausiert waren – als Hinweis und zwei Wochen lang im
Tausch-Tab.
### Behoben
- 📒 **Austragen nach einem Tausch ließ das Kaufbuch stehen.** Es sank nur
die Stückzahl, und bei einer Figur standen danach „10,37 € für 5 Stück"
bei nur noch 4 in der Sammlung. Einkauf und Gewinn der Zeile stimmten
nicht mehr. Jetzt gehen die weggegebenen Stücke im Buch mit hinaus, vom
jüngsten Kauf her, denn abgegeben wird meist der zuletzt dazugekommene
Doppelte.
Braucht Hub 1.17.0.
## Hub 1.17.0 – September 2026
### Neu
- `POST /v1/leave`: Das Mitglied bekommt `status = 'left'` und `left_at`,
Angebote und Wünsche werden gelöscht, der Token gilt nicht mehr. Der Name
ist danach wieder frei.
- **Pause bei Inaktivität:** `hub_settings.inaktiv_tage` (Standard 30, 0 =
aus, über `GET/PUT /v1/admin/settings`). Angebote und Wünsche von
Mitgliedern, deren letzter Besuch länger zurückliegt, fehlen in
`/v1/offers` und `/v1/wants`, ihr Profil trägt `pausiert`. Kommt jemand
zurück, hält der Hub `pause_von`/`pause_bis` fest, und `/v1/me` meldet sie
zusammen mit `inaktiv_tage`.
- Verwaltung: `/v1/admin/overview` zählt `paused` und `left`,
`/v1/admin/members` liefert `left_at`, `paused_since`, `pause_von` und
`pause_bis`.
## 2.90.0 – September 2026
### Neu
- 🏷 **Angebotspreise: was die Figur gerade *kostet*.** Bisher stand überall
der Ø-Verkaufspreis – was zuletzt tatsächlich bezahlt wurde, also was die
Figur *wert* ist. Neu daneben: **ab wie viel sie zu haben ist**. Zwei
verschiedene Fragen, und für den Flohmarkt ist die zweite oft die
nützlichere.
- In der **Detailansicht** unter dem Verkaufspreis, für neu und gebraucht,
mit der Zahl der angebotenen Stücke.
- In **Wunsch- und Einkaufslisten** als kleine Marke an der Zeile
(„ab 6,70 € gebraucht").
- **Zuschaltbar unter *Mehr → Angebotspreise*, voreingestellt aus.** Die
gewohnte Ansicht bleibt, wie sie war, und die zusätzlichen
BrickLink-Abrufe zahlt niemand ungefragt.
- Dieselbe Schnittstelle, dieselben Zugangsdaten – nur ein anderer
Parameter. Keine neue Quelle.
- **Angebote werden nicht gespeichert.** Was heute zu haben ist, ist morgen
weg; der Wert deiner Sammlung beruht weiter auf Verkäufen.
### Intern
- Listen holen ihre Angebote in **einem** Abruf statt einem je Zeile
(höchstens 60 Nummern; der 20-Minuten-Speicher fängt Wiederholungen ab).
Fällt eine Figur aus, reißt sie die anderen nicht mit.
- Beim Rückfall auf ein breiteres Preisgebiet entscheidet bei Angeboten die
**Stückzahl**, nicht der Durchschnitt: BrickLink meldet in einem leeren
Gebiet `0.0000` statt nichts.
## 2.89.4 – September 2026
### Neu
- 🏁 **Tausche schließen sich selbst ab.** Bisher blieb ein fertiger Tausch
für immer auf „angenommen". Jetzt meldet jede Seite ihre Buchung
(ausgetragen bzw. übernommen) an den Hub, und sobald beide gebucht haben,
steht er auf „abgeschlossen". Die Schrittleiste endet mit „🏁
Abgeschlossen". Wer seinen Teil noch nicht gebucht hat, behält den Knopf.
Schon gebuchte Tausche schließen sich beim nächsten Abgleich nach.
### Behoben
- 🆕 **Bei „🤝 Anbieten" wurde „gebraucht" vorgeschlagen, auch für neue
Stücke.** Der Zustand ging nicht mit. Jetzt schickt die abgebende Seite
ihn mit, und die bekommende übernimmt ihn als Vorschlag. Beim Austragen
ist das Stück im passenden Zustand vorgewählt.
Braucht Hub 1.16.0.
## Hub 1.16.0 – September 2026
### Neu
- `given_at` und `taken_at` an `trades`: `POST /v1/trades/:id/progress`
kennt dafür die Schritte `given` (abgebende Seite) und `taken`
(bekommende). Stehen beide, setzt der Hub den Status auf `closed`. Gebucht
werden darf auch nach dem Abschluss noch.
- `trades.condition` (`new`/`used`) – beim Anlegen mitgeschickt, in der
Vorgangsliste zurück.
## 2.89.3 – September 2026
### Neu
- 📦 **Verschickt → angekommen → übernehmen.** Nach dem Annehmen ging es
bisher direkt ans Buchen, ob das Päckchen schon unterwegs oder da war,
stand nirgends. Jetzt führt das Gespräch durch Schritte, sichtbar als
Leiste: Wer abgibt, meldet **„verschickt / übergeben"** (mit einer
vorbelegten Nachricht, gern samt Sendungsnummer) und trägt danach aus.
Wer bekommt, bestätigt **„angekommen"** und übernimmt dann in die
Sammlung. Gebucht wird erst nach dem eigenen Schritt. Von Hand zu Hand
geht die Ankunft auch ohne „verschickt". In der Gesprächsliste steht, was
ansteht. Braucht Hub 1.15.0; ältere App-Fassungen merken davon nichts.
## Hub 1.15.0 – September 2026
### Neu
- **Tauschschritte** `shipped_at` und `arrived_at` samt
`POST /v1/trades/:id/progress` (`step`: `shipped` oder `arrived`).
„Verschickt" darf nur die abgebende Seite melden, „angekommen" nur die
bekommende, beides nur bei angenommenem Tausch. Der Status bleibt
`accepted`.
## 2.89.2 – September 2026
### Behoben
- 🤫 **Die Mahnung beim Betreiber-Feld ist wieder weg.** 2.89.0 meldete
„BrickLink ist eingerichtet, aber es steht keine Kontaktadresse da" –
jeder Instanz, immer. Für die allermeisten ist das Unsinn: Wenn außer
der eigenen Familie niemand die Instanz benutzt, gibt es keine Fremden,
die jemanden erreichen müssten. Eine Auflage, die im Regelfall ins Leere
läuft, gehört nicht als Dauerhinweis in die Einstellungen. Das Feld
bleibt, die Mahnung geht.
- 📝 **Und der Hinweis sagt jetzt, wann man es überhaupt braucht:** bei
einem Zugang für jemanden außerhalb des Haushalts oder einer öffentlich
erreichbaren Instanz. Sonst: leer lassen.
## 2.89.1 – September 2026
### Behoben
- 📝 **Der Hinweis beim Betreiber-Feld sagte nicht, wofür die Adresse da
ist.** Die naheliegende Rückfrage lautet: „Meine Adresse liegt BrickLink
doch aus der Registrierung vor, und das Feld wird gar nicht dorthin
übertragen – wozu dann?" Beides stimmt, nur geht die Auflage in eine
andere Richtung: Die Adresse ist **nicht für BrickLink**, sondern für
**Dritte, die deine Instanz benutzen**. Sie soll angezeigt werden, nicht
gesendet. Steht jetzt so dort – und in beiden Handbüchern.
- 💬 Ein neues Gespräch zeigte bis zum ersten Abgleich „an ?" statt des
Namens, und eine nie zugestellte Nachricht in einem gelöschten Gespräch
stand ewig auf „unterwegs …".
## 2.89.0 – September 2026
BrickLinks Nutzungsbedingungen einmal gelesen statt überflogen – und dabei
drei Stellen gefunden, an denen Brickfolio sie nicht erfüllte.
### Neu
- 🔑 **Kontaktadresse des Betreibers** unter *Mehr → API-Schlüssel*.
BrickLink verlangt eine sichtbare Kontaktadresse in der Anwendung.
Gemeint ist die des **Betreibers**: Die Zugangsdaten registriert jede
Instanz selbst, damit ist auch jeder Betreiber selbst der „Developer" im
Sinne dieser Bedingungen – eine feste Projektadresse wäre dort schlicht
falsch. Das Feld ist nicht maskiert, leeren heißt löschen, und ohne
BrickLink-Zugang bleibt es ohne Wirkung.
- ⚖️ **Der vorgeschriebene BrickLink-Hinweis** steht jetzt unter
*Mehr → Rechtliches* – im Wortlaut, wie verlangt, und auf Englisch auch
in der deutschen Oberfläche. Er erscheint nur, wenn diese Instanz die
API überhaupt benutzt. Ein Test vergleicht ihn Zeichen für Zeichen und
ein zweiter stellt sicher, dass der Übersetzungslauf ihn nicht anfasst.
### Behoben
- 📄 **„Ein kostenloses Konto genügt" stimmte nicht.** Die Store-API steht
nur Verkäufern offen: Im BrickLink-Konto muss einmal ein Shop eröffnet
sein, der aber leer bleiben darf. Das Handbuch sagte es längst, die
Projektseite nicht – dort stand es an drei Stellen falsch.
### Intern
- Die neue Einstellung ist als personenbezogen eingestuft und wird aus
Fehlerberichten entfernt. Sichtbar in der eigenen Instanz heißt nicht
sichtbar in einem öffentlichen Issue.
## 2.88.56 – September 2026
Gefunden beim Durchspielen von vier Tauschgesprächen zwischen zwei
Testinstanzen und einer echten.
### Behoben
- 🧹 **Nach einem Tausch blieb Veraltetes stehen.**
- Wer ein Stück übernahm, behielt es auf der Wunschliste. Das Netzwerk
zeigte deshalb weiter an, wer es hätte, und anderen, dass man es sucht.
Jetzt verschwindet der Wunsch beim Übernehmen in die Sammlung (auf eine
Einkaufsliste bleibt er stehen).
- Wer ein Stück austrug, bot es im Netzwerk weiter in alter Stückzahl an,
bis von Hand neu veröffentlicht wurde. Jetzt zieht die App die Angebote
im Hintergrund nach – aber nur, wer schon einmal veröffentlicht hat.
- 🖼 **Ein erhaltenes Angebot kam ohne Bild in die Sammlung.** Der Hub
liefert dem Empfänger kein Bild mit. Jetzt kommt es von der Wunschliste
oder als Standardbild von BrickLink.
- 👻 **Vom Gegenüber gelöschte Gespräche standen ewig als „offen" da.**
Antworten liefen ins Leere. Jetzt heißen sie „vom Gegenüber gelöscht",
bleiben lesbar, und das Eingabefeld verschwindet.
- **Annehmen und Ablehnen** standen auch beim Fragenden, der so seine eigene
Anfrage „annehmen" konnte. Jetzt sieht die Knöpfe nur, wer gefragt wurde,
und nur, solange das Gespräch offen ist.
## 2.88.55 – September 2026
### Behoben
- 🤝 **Wer jemandem etwas anbietet, das er sucht**, bekam im Gespräch
„⚠ Dieser Artikel wird nicht mehr angeboten" zu sehen: Der Hub suchte den
Artikel in den Angeboten des *Gegenübers*, wo er nie stand. Gespräche
tragen jetzt ihre Art – Anfrage oder Angebot. Die Warnung gibt es nur
noch bei Anfragen, und nach dem Annehmen stimmt auch die Richtung: Wer
angeboten hat, trägt aus, wer das Angebot bekommt, übernimmt. Bisher war
es genau verkehrt herum. Braucht Hub 1.14.0.
## Hub 1.14.0 – September 2026
### Neu
- **Vorgänge tragen ihre Art** (`trades.kind`: `anfrage` oder `angebot`).
Ältere App-Fassungen schicken nichts, das gilt als Anfrage. Bei einem
Angebot meldet der Hub den Artikel immer als verfügbar. Bestehende
Vorgänge, deren Empfänger den Artikel sucht und nicht selbst anbietet,
stellt die Migration auf „angebot" um.
## Hub 1.13.0 – September 2026
### Neu
- 💶 **Angebote tragen ihre Art**: Tausch, Verkauf oder beides (neue Spalte
`offers.deal`). Fehlt sie – bei älteren App-Fassungen –, gilt das Angebot
als Tausch.
## Hub 1.12.0 – September 2026
### Neu
- 🧭 **Profile und freiwillig gezeigte Wunschlisten.** Zwei neue Tabellen
(`member_profiles`, `wants`) und sechs Endpunkte: eigenes Profil lesen und
speichern, fremdes Profil samt Tauschbilanz, Profilliste, eigene Wünsche
ersetzen, gezeigte Wünsche der anderen. Wünsche nimmt der Hub nur an,
solange „Wunschliste zeigen" gesetzt ist; beim Abschalten löscht er sie
sofort. Die Sammlungsgröße speichert er gerundet und zeigt sie nur, wenn
sie freigegeben ist. Beim Löschen eines Mitglieds gehen Profil und
Wünsche mit.
- Ältere App-Fassungen fragen diese Wege nicht an und merken nichts davon.
## Hub 1.11.0 – September 2026
### Geändert
- 📚 **Nachtrag zur Beschreibung des Katalogwegs.** Der Eintrag zu Hub 1.8.0
(weiter unten) beschreibt die Technik von damals; wie der Katalog *heute*
entsteht, stand nirgends zusammenhängend. Deshalb hier in drei Schritten:
1. **Angelegt und vervollständigt wird der Katalog im Katalogdienst** —
Nummern der Reihe nach, dazu die Beschreibung des Katalogfotos. Dort
liegen die BrickLink-Schlüssel dafür, und nur dort.
2. **Ausgerollt wird über GitHub** — als Datei mit Nummer und
Beschreibung, **ohne Namen**.
3. **Die Namen holt sich jede Instanz selbst** über ihren eigenen
BrickLink-Zugang, oder in Sekunden aus der Katalogdatei.
Am 05.09.2026 nachgetragen, weil das Handbuch an zwei Stellen
Verschiedenes sagte.
## Hub 1.8.0 – August 2026
### Neu
- 📚 **Der Katalogabzug liegt jetzt im Hub.** Bisher baute ihn jede Instanz
selbst: Nummern der Reihe nach bei BrickLink abklappern (Tage, eigenes
Kontingent) und danach jedes Bild von einem Sehmodell beschreiben lassen
(rund 24 Stunden Grafikeinheit für 9.741 Figuren). Dieselbe Arbeit für
dasselbe Ergebnis — der Katalog beschreibt BrickLinks Fotos, nicht die
Sammlung von irgendwem.
`POST /v1/katalog` nimmt Stapel zu 500 Zeilen entgegen, `GET /v1/katalog?seit=…`
liefert nur, was sich seit dem eigenen Stand geändert hat. Im Normalbetrieb
sind das null Zeilen — der Katalog ändert sich in der Größenordnung eines
Dutzend Namen im Monat.
**Schreiben braucht ein eigenes Recht (`can_katalog`), lesen nicht.** Das
Recht hängt am Hub und nicht in der App, denn die Instanzen sind selbst
gehostet: Wer seinen Container betreibt, kann dessen Code ändern, und eine
Absprache wäre damit keine Regel, sondern eine Bitte. Der Schaden wäre auch
nicht Unordnung, sondern Verschlechterung — eine schwächere Bildanalyse
überschreibt eine bessere, und man sieht es der Beschreibung nicht an.
Jede Zeile vermerkt, welches **Modell** die Beschreibung erzeugt hat. Ohne
das wäre ein Modellwechsel ein stilles Umschreiben aller Zeilen, und
niemand könnte zwei Beschreibungen daraufhin ansehen, ob sie überhaupt
vergleichbar sind.
## 2.88.54 – September 2026
### Neu
- 💶 **Zum Tausch, zum Verkauf oder beides.** Unter „Ich biete an" wählst du
je Artikel, wozu er angeboten wird; anfangs steht alles auf Tausch. Beim
Gegenüber steht die Art an der Karte, unter „Angebote" lässt sich danach
filtern, und bei reinem Verkauf schlägt die Anfrage einen Kauf vor statt
eines Tauschs. Braucht Hub 1.13.0.
### Geändert
- Die Reiter im Tausch-Tab heißen jetzt **„💬 Nachrichten"** und **„📤 Ich
biete an"**, der Knopf zum Veröffentlichen **„📤 Im Netzwerk anbieten"**.
## 2.88.53 – September 2026
### Neu
- 🧭 **Entdecken im Tausch-Netzwerk.** Der Tausch-Tab öffnet mit einem neuen
Reiter und drei Abschnitten, alle auf der eigenen Instanz ausgerechnet:
**„Hat, was du suchst"** (Angebote anderer, die auf deiner Wunschliste
stehen – deine Wunschliste verlässt dafür die Instanz nicht), **„Sucht, was
du übrig hast"** (gezeigte Wunschlisten anderer gegen deine Doppelten und
Angebote, mit „🤝 Anbieten") und **„Passt zu dir"** (gleiche
Lieblingsthemen).
- 👤 **Profile.** Ein Tipp auf einen Namen öffnet das Profil: Über mich,
Gegend, Lieblingsthemen, Tauschbilanz, freiwillig die gerundete
Sammlungsgröße, dazu was das Mitglied anbietet und – falls gezeigt – sucht.
Was davon zu dir passt, ist gelb umrandet.
- ✏️ **Mein Profil** oben im Tab, ganz freiwillig. Zwei Schalter stehen
anfangs auf aus: **„Meine Wunschliste im Netzwerk zeigen"** (wird bei jeder
Änderung nachgezogen, beim Abschalten oder Trennen im Hub gelöscht) und
**„Sammlungsgröße zeigen"**.
- 🤝 **Einrichtungsplaner nach dem Beitritt.** Sechs Schritte – Beitreten,
Über dich, Themen, Sichtbarkeit, Angebote, Los –, jeder überspringbar,
gespeichert nach jedem Schritt.
- Beitreten geht weiterhin nur mit Einladung, und ohne Beitritt bleibt der
Tab verborgen.
### Geändert
- Die Reiter heißen kürzer: „💬 Vorgänge" und „📤 Auswahl", damit vier
nebeneinander aufs Telefon passen.
## 2.88.52 – September 2026
### Intern
- 🤝 **Das Tausch-Netzwerk hat eigene Dateien.** Die 26 Endpunkte standen
mitten in `main.py`, der Tausch-Tab mitten in `app.js`. Jetzt liegen sie in
`backend/community.py` (als eigener Router) und `frontend/community.js`.
`main.py` ist damit gut 700 Zeilen kürzer, `app.js` gut 800. Am Verhalten
ändert sich nichts – die angemeldeten Routen sind vorher wie nachher
dieselben 171. Grundlage für den Ausbau zur Community (Profile,
Entdecken).
- Beitreten geht weiterhin **nur mit Einladungscode**, und ohne Beitritt
bleibt der Tausch-Tab verborgen; ein Test hält beides fest.
## 2.88.51 – September 2026
### Geändert
- Im Zwei-Faktor-Abschnitt fällt der feste Satz „Empfehlenswert, sobald die
App von außen erreichbar ist" weg, sobald die App weiß, wie sie genutzt
wird. Direkt unter „nötig ist sie nicht" widersprach er sonst.
## 2.88.50 – September 2026
### Neu
- 🌐 **Die App merkt, ob sie von außen genutzt wird – und ob etwas davor
steht.** Nicht durch einen Test von außen (dafür kennt sie ihre öffentliche
Adresse nicht, und ein Aufruf aus dem eigenen Netz beweist nichts), sondern
an den angemeldeten Anfragen selbst: Über Cloudflare kommen eigene
Kopfzeilen mit, über Cloudflare Access zusätzlich dessen Anmeldenachweis,
über einen Reverse Proxy mit Portfreigabe eine öffentliche Absenderadresse.
Im Zwei-Faktor-Abschnitt steht dann „nur aus dem Heimnetz", „von außen,
geschützt durch Cloudflare Access" oder „von außen – ohne Zugangsschutz
davor".
- 🔔 **Im letzten Fall ein Hinweis für Admins ohne Zwei-Faktor** – einmal,
mit „Zwei-Faktor einschalten". Mit Access davor drängt nichts: Dort steht
mit dem Code per E-Mail schon ein zweiter Faktor vor der App.
### Behoben
- Hinweise auf dem Startbildschirm erscheinen jetzt auch auf Englisch
übersetzt, wo es eine Übersetzung gibt.
## 2.88.49 – September 2026
### Behoben
- 🔐 **Rettungscodes ließen sich auf dem Handy nicht eintippen.** Das
Code-Feld beim Anmelden holt den Ziffernblock – die Rettungscodes haben
aber Buchstaben (a–f). Unter dem Feld steht jetzt **„Rettungscode
eingeben"**, das die volle Tastatur holt. Außerdem gilt ein Rettungscode
auch **ohne Bindestriche**; vorher hieß „3f9a0b12c7de" „Code stimmt
nicht".
## 2.88.48 – September 2026
### Neu
- 🔐 **Zwei-Faktor schon bei der ersten Einrichtung.** Der Assistent hat
einen Schritt „Absichern mit Zwei-Faktor" vor dem Abschluss (jetzt acht
Schritte). Das Passwort vom Anlegen des Kontos ist schon eingetragen –
QR-Code scannen, Code eintippen, Rettungscodes sichern, weiter. Es ist
derselbe Block wie im Profil, nicht ein zweiter Nachbau; das Passwort
liegt nur im Speicher der Seite und wird beim Ende des Assistenten
vergessen. Überspringen geht wie bei jedem Schritt.
### Geändert
- Als Beispiel für den Anzeigenamen im Tausch-Netzwerk steht „Steinesammler"
statt eines echten Vornamens.
## 2.88.47 – September 2026
### Behoben
- 🔐 **Der QR-Code für die Zwei-Faktor-Anmeldung ließ sich nicht scannen.**
Er kam mit fester Größe (265 px) und ohne `viewBox`; die Oberfläche zeigt
ihn in 200 px, und ein solches Bild wird dabei nicht verkleinert, sondern
abgeschnitten – rechts und unten fehlte ein Drittel. Keine
Authenticator-App konnte ihn lesen (gemeldet mit dem Google
Authenticator). Jetzt skaliert er, hat den Rand, den die Norm verlangt,
und einen weißen Grund im Bild selbst. Nachgeprüft mit der
QR-Erkennung von macOS: der alte nicht lesbar, der neue fehlerfrei.
### Geändert
- 🔐 **Einschalten der Zwei-Faktor-Anmeldung beendet alle anderen
Sitzungen.** Ein Gerät, das schon angemeldet war, blieb es bis zu 90 Tage
– ohne je nach dem Code gefragt zu werden. Jetzt muss es sich neu
anmelden; das Gerät, auf dem man einschaltet, bleibt angemeldet.
## 2.88.46 – September 2026
### Geändert
- 🛒 **„Verkaufsliste (Doppelte)" und „Fehlende Set-Figuren" stehen über dem
Anlegen.** Das Feld für eine neue Einkaufsliste steht jetzt direkt über den
Listen, zu denen sie gehört; die beiden Auswertungen rücken nach oben, und
ihre Kästen klappen gleich unter den Knöpfen auf.
- **Feld und „Anlegen" in einer Zeile.** Vorher stand „Anlegen" als eigener
grüner Balken über die volle Breite darunter. Der Platzhalter heißt dafür
kürzer „Neue Liste, z. B. Flohmarkt" – der alte hätte auf dem Telefon
292 px gebraucht, neben dem Knopf bleiben 210.
## 2.88.44 – September 2026
### Behoben
- ⭐ **Die Wunschliste frischt sich auf wie die Einkaufslisten.** Was ein
anderes Gerät oder der Live-Scanner auf eine Einkaufsliste legte, erschien
nach wenigen Sekunden von selbst – was er merkte oder wieder von der
Wunschliste nahm, erst nach dem nächsten Neuladen. Die App verglich auf
dem Listen-Tab nur den Stand der Einkaufslisten; jetzt zählt die
Wunschliste mit.
## 2.88.43 – September 2026
### Geändert
- ⬆️ **Die Update-Prüfung fragt nicht mehr die GitHub-API.** Die erlaubt
ohne Anmeldung nur 60 Abfragen je Stunde – für den ganzen
Internetanschluss, geteilt mit jedem anderen Gerät dahinter. War das
aufgebraucht, stand unter Mehr „GitHub gerade nicht erreichbar", und der
Hinweis auf eine neue Fassung blieb aus. Jetzt liest die App die neueste
Fassung aus der Weiterleitung der Release-Seite; die zählt nicht mit.
- Ein Fehlschlag wird eine halbe Stunde gemerkt. Vorher fragte jeder
Aufruf des Mehr-Tabs erneut bei GitHub nach. „Jetzt prüfen" fragt
weiterhin sofort.
## 2.88.42 – September 2026
### Geändert
- ✏️ **Die Suchvorschläge beim manuellen Erfassen in der neuen Handschrift.**
Jeder Treffer trug vier gleich große Knöpfe – „✔ Übernehmen", „☆ Merken",
„🛒 Liste", „BrickLink ↗". Jetzt derselbe Aufbau wie die Trefferkarte beim
Scannen: **„✔ Übernehmen" breit und grün**, ☆ und 🛒 als Zeichen daneben,
„Bei BrickLink ansehen ↗" als Verweis darunter.
- ⭐ **Der Stern ist gefüllt, wenn der Artikel schon auf der Wunschliste
steht** – beim Scannen wie beim Suchen. Vorher erfuhr man das erst nach
dem Tippen, als Zuruf „Steht schon auf der Wunschliste".
- „✔ Übernehmen" ist jetzt auch auf Englisch übersetzt.
## 2.88.41 – September 2026
### Geändert
- ✅ **„Da! Ab in die Sammlung" bestätigt sichtbar.** Bisher verschwand der
Artikel einfach aus der Einkaufsliste, und die Meldung erschien unten am
Rand – wer auf den Artikel schaute, bekam keine Rückmeldung. Jetzt bleibt
die Zeile kurz stehen, links grün markiert und mit dem Schild
„✔ In der Sammlung · Gebraucht" (beim Dazulegen „· jetzt 3×"), dasselbe
Grün wie „schon in der Sammlung" auf der Wunschliste. Erst danach rückt
sie zu den erledigten. Die Meldung unten nennt dazu den Namen.
### Behoben
- 🗓 **Das Jahr steht in den Suchvorschlägen nur noch einmal.** Beim
manuellen Erfassen hieß es „sw0815 · 2017 · 2017 · Ø neu …": Der eigene
Katalog gibt das Jahr gleich mit, und die Preisabfrage hängte es ein
zweites Mal an.
- Beim Dazulegen hieß die Meldung noch „Einkaufspreis gemittelt" – seit
2.88.40 wird addiert, wie es sich für ein Kaufbuch gehört.
## 2.88.40 – September 2026
### Behoben
- 🧾 **Käufe von der Einkaufsliste stehen jetzt im Kaufbuch.** „✔ Da! Ab in
die Sammlung" schrieb den Preis direkt an den Eintrag, aber keinen Posten
ins Kaufbuch – und der bezahlte Betrag ist die Summe dieser Posten. Kam
danach ein weiteres Exemplar mit Preis dazu, wurde die Summe aus dem Buch
neu gerechnet, und der Listenkauf fiel heraus: 5 € von der Liste plus 2 €
gescannt ergaben 2 €. Beim nächsten Neustart zog die App fehlende Posten
zwar nach, bis dahin aber stimmte die Summe nicht. Aufgefallen beim Test
einer frisch aufgesetzten Instanz.
Dabei auch behoben: „zusätzlich" **mittelte** den alten und den neuen
Preis, statt sie zu addieren, und „überschreiben" ließ die alten Posten im
Buch stehen. Im Kaufbuch steht als Herkunft jetzt der Name der Liste.
## 2.88.39 – September 2026
### Behoben
- ✅ **„✔ Da! Ab in die Sammlung" fragt nicht mehr alles noch einmal ab.**
Für Profis öffnete der Knopf eine eigene Zeile mit „Preis [..] € – leer =
BrickLink-Ø" und „✔ Gebraucht übernehmen" – dabei stehen Einkaufspreis und
Zustand direkt darüber in derselben Karte. Jetzt nimmt ein Tipp, was dort
steht: den Zustand aus der Pille, den Preis aus dem Einkaufsfeld (auch
wenn er noch nicht mit ✓ gespeichert ist – man sieht ihn ja). Leer heißt
wie bisher: BrickLink-Durchschnitt; das steht jetzt als Erklärung am Feld.
Gefragt wird nur noch, wenn es wirklich etwas zu entscheiden gibt: Steht
die Figur schon in diesem Zustand in der Sammlung, heißt es „zusätzlich
oder überschreiben?" – mit rotem ✕ wie überall.
## 2.88.38 – September 2026
### Geändert
- 🧩 **Fehlende Set-Figuren ohne Knopfzeile.** Je Figur standen zwei gleich
große Knöpfe, „☆ Merken" und „BrickLink ↗", bei gemerkten Figuren dazu ein
gelbes Schild – bei 40 fehlenden Figuren viel Höhe für wenig. Jetzt wie im
Katalog: **der Stern als Zeichen rechts an der Zeile**, gefüllt und gelb,
wenn die Figur schon auf der Wunschliste steht; BrickLink als Verweis in
der Nummernzeile. Im Fuß ist „☆ Alle auf die Wunschliste" die breite
Hauptsache, CSV und Drucken stehen daneben.
### Behoben
- 🔄 **Ein Neustart erzeugte Fehlerberichte.** Beim Ausrollen ist die
Instanz ein paar Sekunden weg; Cloudflared antwortet dann mit seiner
eigenen HTML-Seite, und die Hintergrundabfragen (Tauschbörse jede Minute,
Update-Wache) laufen genau hinein. So kam am 24.09. ein „502 bei POST
/api/hub/trades/sync" an – das Tunnelprotokoll zeigte 17 Sekunden
Neustart und mittendrin genau diese Anfrage.
Verschwiegen wird so ein Fehler trotzdem nicht: Die App fragt nach 20
Sekunden `/api/laufzeit`, seit wann der Server läuft. Ist er um den Fehler
herum frisch gestartet, war es der Neustart; läuft er schon länger, war es
ein echter Ausfall, und der wird gemeldet. Fehler der App selbst gehen wie
bisher sofort ins Protokoll.
## 2.88.37 – September 2026
### Geändert
- 🧾 **Wunschliste, Einkaufsliste und „Auf eine Liste legen" sprechen
dieselbe Sprache wie der Scan.** Überall dasselbe Muster: eine breite
Hauptsache, Löschen und Abbrechen als rotes Zeichen, die Wege nach
draußen als Verweise, eine Wahl als Pille.
- **Wunschliste:** `[✔ Gekauft!] [🗑]` statt vier gleich großer Knöpfe
im Raster; Preisverlauf und BrickLink als Verweise darunter. „Gekauft
als" ist die Zeile `[Preis €] [Gebraucht] [Neu] [✕]` – „leer =
BrickLink-Ø" steht als Erklärung am Feld statt als eigene Zeile.
- **Einkaufsliste:** Einkaufspreis mit kleinem ✓ und daneben der Zustand
als Pille – vorher zwei umrandete Zustandsknöpfe, einer gelb, und ein
grüner ✓-Balken über die volle Breite. Im Fuß `[Gesamtangebot]
[Archivieren] [🗑]` statt „Liste löschen" über die volle Breite.
- **Auf eine Liste legen** (Trefferkarte, Suchtreffer, Formular):
Einkaufspreis und Zustand in einer Zeile, die Listen als ruhige Knöpfe
– im Formular war jede Liste ein grüner –, unten `[+ Neue Liste] [✕]`
bzw. `‹`, wenn es zurück zur Listenwahl geht.
- **Figurenliste im Set-Steckbrief:** Das ✕ im Zustands-Schritt war dort
noch schwarz, als einzige Stelle der App.
### Behoben
- 🌐 **Texte, die an der Übersetzung vorbeiliefen.** „+ Zur Sammlung",
„83 % sicher", „Auf welche Liste?", „Flohmarkt 24.09." und die Zurufe
nach dem Aufnehmen standen als deutscher Text im Markup; zwei Zurufe
wurden sogar aus deutschen Teilen zusammengesetzt. Wer die App auf
Englisch nutzt, las dort Deutsch.
## 2.88.36 – September 2026
### Behoben
- 🌫 **Nach jedem Scan wurde die ganze Seite grau.** Der grüne „hier
geschaut"-Rahmen auf dem Foto dunkelt mit einem riesigen Schatten das Foto
um sich herum ab. Der Behälter schnitt aber nicht ab – seit **v1.78.0
(31.07.)** lief der Schatten über die **ganze Seite**. Alles wurde um 28 %
dunkler; nur was eine Ebene höher liegt – Kopfleiste, Trefferkarte – blieb
hell. Das sah aus wie ein grauer Hintergrund, der nach dem Foto auftaucht.
Der Behälter schneidet jetzt ab. Damit das Foto seinen eigenen
Schlagschatten nicht verliert, trägt diesen jetzt der Behälter – dessen
eigener Schatten wird vom Abschneiden nicht erfasst.
### Geändert
- 📏 **Der Zustands-Schritt steht in einer Zeile**, so breit wie die
Knopfreihe, die er ersetzt: `[Bezahlt €] [Gebraucht] [Neu] [✕]`. In
2.88.35 zog sich das Feld auf breiten Karten noch über 650 Pixel. Jetzt
teilen sich die beiden Zustände den Platz, Feld und ✕ bleiben fest – die
Karte springt beim Umschalten nicht. **Abbrechen ist ein rotes ✕**, in
derselben Sprache wie „Letztes Exemplar löschen" in der Sammlung.
- 📝 **„Manuell erfassen" mit eigenen Bauteilen.** Das rohe „Datei
auswählen | Keine Datei ausgewählt" des Systems ist weg: Das Bild ist eine
Kachel mit Vorschau und ✕, daneben „Bild wählen" und „Vom Scan" in
gleicher Größe. **Typ und Zustand sind Pillen** wie im Steckbrief statt
Systemauswahl, die **Anzahl hat Plus und Minus**, und unten stehen die
Knöpfe wie auf der Trefferkarte – ein breiter grüner, ☆ und 🛒 als
Zeichen. Dabei ist auch „Zur Sammlung" endlich überall **grün**; im
Formular war es gelb.
Die alten Auswahlfelder bleiben unsichtbar als Quelle der Wahrheit
stehen: `m-type` wird an elf Stellen gelesen – keine davon musste
angefasst werden. Wo der Code den Wert direkt setzt, zeichnen sich die
Pillen nach; ein Test hält fest, dass kein Setzen ohne das dazukommt.
## 2.88.35 – September 2026
### Geändert
- 🎯 **Die Trefferkarte im Scan hat eine Hauptsache.** Vorher standen dort
vier gleich große Knöpfe mit demselben kräftigen Rahmen – obwohl sie sehr
unterschiedlich wichtig sind: „Zur Sammlung" will man fast immer, „Liste"
fast nie, und BrickLink führt aus der App heraus. Weil sie nicht
nebeneinander passten, brach jede Beschriftung um („+ Zur / Sammlung").
Jetzt derselbe Aufbau wie in der Katalogliste und im Steckbrief: **ein
breiter Knopf** für die Sammlung, **Merken und Liste als Zeichen**
daneben, **BrickLink als Verweis** darunter. Nach dem Merken füllt sich
der Stern und das Zeichen wird gelb, statt dass „⭐ Gemerkt" den kleinen
Knopf sprengt.
- ⚖️ **Der Zustands-Schritt ist ruhiger.** Ein Tipp auf „Gebraucht" oder
„Neu" nimmt die Figur weiter sofort auf – das ist der schnellste Weg in
die Sammlung, ein Zwischenschritt wäre ein Verlust. Geändert hat sich die
Gewichtung: „Abbrechen" war so groß wie das Hinzufügen selbst. Jetzt teilen
sich „Bezahlt" und „Abbrechen" eine Zeile, und Abbrechen ist ein Verweis –
mit derselben Trefferfläche von 44 Pixeln wie jeder Knopf. **324 → 266 px.**
Der Hinweis „wird sofort gespeichert" stand vorher ohne Übersetzung im
Markup; auf Englisch stand dort Deutsch.
## 2.88.34 – September 2026
### Behoben
- 🚨 **Aus dem Scan liess sich nichts mehr aufnehmen.** „+ Zur Sammlung",
„☆ Merken" und „🛒 Liste" taten **gar nichts** – keine Reaktion, keine
Fehlermeldung, nichts im Protokoll. Betroffen seit **2.86.5 (22.09.)**,
also zwei Tage.
Dieselbe Zeile wie in 2.88.32, nur an der zweiten Stelle: `2.86.5` setzte
`enrichSuggestions(items, meta.detailVon || 0)` in **zwei** Funktionen –
in eine, die ein `meta` hat, und in die Scan-Ansicht, die keines hat. Dort
flog die Ausnahme genau **zwischen** dem Zeichnen der Karte und dem
Verdrahten der Knöpfe:
```
enrichSuggestions(items, meta.detailVon || 0); ← hier knallt es
wireWantButtons(…); wireCartButtons(…); ← kommt nie an
…forEach([data-add]) ← kommt nie an
```
Die Karte stand also vollständig da und sah richtig aus – sie war nur
taub. Die Scan-Ergebnisse brauchen kein `meta`: Sie kommen in einem Stück,
es gibt keine zweite Seite.
- 🛡 **Ein Wächter gegen genau diese Art Fehler.** Beide Zeilen sahen
richtig aus – ein Test auf den Wortlaut hätte nichts gefunden. Der neue
prüft den **Geltungsbereich**: Keine Funktion darf ein `meta` benutzen,
das sie nicht hat. Kommentare und Zeichenketten bleiben dabei außen vor,
sonst zählt jedes `<meta>` in einer Vorlage mit.
## 2.88.33 – September 2026
### Dokumentation
- 📖 **Das englische Handbuch war seit 2.87.0 stehen geblieben.** Nachgezogen
sind die Kamera in der App (Livebild, Mediathek daneben, Zoom, der
Sucherausschnitt und warum das Telefon jedes Mal nach der Freigabe fragt)
und der Steckbrief mit Kopf und drei Reitern, samt Zeitspannen und
Ablesen am Preisverlauf.
Ein Kapitel zum Katalog-Durchblättern gibt es dort nicht – `MANUAL.md` ist
eine gekürzte Fassung, kein Spiegel von `HANDBUCH.md`.
## 2.88.32 – September 2026
### Behoben
- 🔢 **Die Suche nach einer BrickLink-Nummer brach ab** (aus der App
gemeldet, 24.09.2026): `Cannot read properties of undefined (reading
'detailVon')`. Fand BrickLink zu einer eingetippten Nummer etwas, stürzte
das Zeichnen der Trefferliste ab – die Treffer waren da, zu sehen war
nichts.
Die Zeichenfunktion nimmt die Treffer und freiwillig ein paar Angaben zur
Seitenzahl. Drei der vier Aufrufer haben diese Angaben nicht; im Rumpf war
eine Stelle darauf vorbereitet, eine zweite nicht. **Seit 2.86.5 drin.**
- 🙈 **Warum es drei Monate niemand bemerkt hat.** Der dritte dieser Wege –
die Nummernsuche beim manuellen Erfassen – steht in einem Fangblock, der
*jede* Ausnahme in einen Hinweistext verwandelt. Dort stand dann „Cannot
read properties of undefined – der Eintrag behält die Rebrickable-Nummer",
und das liest sich wie eine Meldung des Dienstes. Gemeldet wurde nichts.
Ein `TypeError` ist kein Netzwerkfehler: Solche Ausnahmen gehen jetzt auch
dort ins Fehlerprotokoll, statt nur als Text dazustehen.
## 2.88.31 – September 2026
### Geändert
- 🟡 **Die Marke im Kopf sieht aus wie überall sonst.** Die erste Noppe war
dort weiß – als Einzige in der ganzen App. Der Grund war handfest: Die
Kopfleiste ist gelb, eine gelbe Noppe darauf wäre unsichtbar. Der Preis
war die Farbfolge, an der man die Marke erkennt.
Statt die Farbe zu ändern, tragen jetzt **alle vier eine haarfeine
Kante**. Sie hält die gelbe Noppe gegen den gelben Grund und lässt die
anderen drei, wie sie sind – alle vier, weil ein Ring um genau eine von
Nahem auffiele.
- 🌙 **In den dunklen Themen fällt die Ausnahme ganz weg.** Dort ist die
Kopfleiste dunkel; die Noppe ist auch ohne Kante bestens zu sehen. Das
Blaugrau, das da stand, war nur mitkopiert. In Nova nimmt die erste Noppe
jetzt die Akzentfarbe des Themas an – dort ist das ein Blau, und das ist
Absicht des Themas, nicht ein verlorenes Gelb.
## 2.88.30 – September 2026
### Behoben
- 🧩 **Absturz beim Nachladen der Sammlung** (aus der App gemeldet,
24.09.2026): `NotFoundError: Failed to execute 'insertBefore' … not a
child of this node`, aus dem Beobachter heraus.
Die Sammlung lädt blockweise nach und fügt die Karten vor einer
unsichtbaren Marke ein. Zeichnet sich die Liste neu – Suche, Filter,
Sortierung –, wird der Nachschub beendet und die Liste geleert; eine
beim Beobachter **bereits eingereihte Meldung** läuft aber trotzdem noch
durch. Dann zeigt die Marke ins Leere. Nachgestellt und Wort für Wort
derselbe Fehler; der Nachschub hält jetzt an, wenn die Marke nicht mehr
zur Liste gehört.
Nebenbei hätte das auch Karten aus dem **alten** Bestand in die neue
Liste gesetzt, denn Daten und Zählstand gehörten noch zum vorigen Lauf.
- 🔇 **Und der stillere Fehler an derselben Stelle:** Der Beobachter lag in
einer Variablen der Datei, nicht beim einzelnen Lauf. Räumte ein alter
Lauf auf, beendete er damit den Beobachter des **neuen** – die Liste
hörte lautlos auf nachzuladen, ohne Fehlermeldung. Jeder Lauf hat jetzt
seinen eigenen.
## 2.88.29 – September 2026
### Geändert
- 🧱 **Der Platzhalter für fehlende Bilder trägt die heutige Handschrift.**
Er war als Einziger noch im alten Stil: ein flächiger gelber Stein mit
3 px schwarzer Kontur. Die App zeichnet Steine längst anders – weiche
Ecken, keine Kontur, eine dunklere Unterkante als Tiefe. Jetzt sind es
die **vier Steine des Ladezeichens**, in denselben Farben und derselben
Reihenfolge: Gelb, Rot, Blau, Grün. Er steht an sechs Stellen und liest
sich noch bei 28 Pixeln.
## 2.88.28 – September 2026
### Geändert
- 📚 **Die Artikel im Katalog sind endlich auseinanderzuhalten.** Der Name
stand einzeilig in 162 Pixeln – nachgemessen an 80 Zeilen auf einem
Telefon: **74 % abgeschnitten, und 14 Zeilenpaare sahen gleich aus.**
BrickLink-Namen tragen die Identität vorn und das Unterscheidungsmerkmal
hinten, also fiel genau der Teil weg, der zählt:
```
Luke Skywalker - Pilot Suit, … Dark Gray Hips, Yellow Head
Luke Skywalker - Pilot Suit, … Dark Bluish Gray Hips, Yellow Head
beide sichtbar als → „Luke Skywalker - Pilot Suit"
```
In der Mitte zu kürzen half kaum (14 → 13 gleiche Paare) – die Namen
teilen sich Kopf *und* Schwanz. Es half nur Platz:
| | ganz lesbar |
|---|---|
| vorher | 23 % |
| Name darf umbrechen (zwei Zeilen) | 57 % |
| + Merkknopf raus, Namensfeld 196 px | **75 %** |
- ⭐ **Gemerkt wird jetzt im Steckbrief**, nicht mehr am Zeilenende. Dass
eine Figur auf der Wunschliste steht, zeigt ein kleiner **Stern am
Bild** – derselbe wie im Reiter „Wünsche"; der Katalog war die einzige
Stelle mit einem Herz. Der Stern ist nur eine Anzeige, ein Tipp darauf
öffnet den Steckbrief. „Hab ich" bleibt, wo es war: Das braucht man im
Vorbeigehen.
- 🗂 **Die Artikel stehen auf weißen Karten**, je Hunderterblock eine, und
die Blocknummer liegt dazwischen auf der grauen Fläche. Sie gliedert, sie
ist kein Artikel. Bisher lag die ganze Liste ohne eigene Fläche auf dem
Grau, und die weißen Bildchen wirkten darin wie Löcher.
### Behoben
- 🔌 **„Merken" im Steckbrief hätte lautlos aufgehört zu wirken.** Es
schaltete nicht selbst, sondern suchte den passenden Knopf in der
Katalogzeile und klickte ihn. Mit dem Herz wäre dieser Knopf verschwunden
– und die Prüfung `if (knopf)` hätte den Fall kommentarlos verschluckt:
keine Wirkung, keine Fehlermeldung. Beide Wege schalten jetzt über die
Daten, und ein Fehlschlag nimmt die Anzeige wieder zurück.
## 2.88.27 – September 2026
### Geändert
- 🎚 **Die Zoomstufen versprechen nichts mehr über Objektive.** In 2.88.26
hießen sie 1× / 2× / 5×, weil moderne iPhones dort einrasten. Das war
eine Zusage, die die App nicht halten kann: Auf einem Modell **ohne
Teleobjektiv** wäre die 5 rein gerechnet. Und umgekehrt genauso – auf
einem Gerät *mit* 5×-Tele ist ein 3× eine Zwischenstufe. **Es gibt keine
Leiter, die überall auf Rastpunkte trifft.**
Der Grund liegt tiefer: Die Schnittstelle **unterscheidet Optik und
Rechnung nicht**. Sie meldet einen durchgehenden Bereich, in dem der
digitale Zoom mitzählt (beim iPhone bis 25×); welcher Faktor mit Glas
entsteht, steht nirgends. Was sich nicht unterscheiden lässt, darf die
Oberfläche auch nicht andeuten.
Also wieder eine gleichmäßige Leiter **1× / 2× / 3×**, die nur sagt, wie
viel näher es wird – und die Kneifgeste für alles dazwischen und
darüber. Gefiltert wird weiterhin: Was der gemeldete Bereich nicht
hergibt, erscheint nicht.
## 2.88.26 – September 2026
### Geändert
- 🔍 **Die Zoomstufen heißen jetzt 1× / 2× / 5×.** Vorher 1/2/3 – eine
Zahlenreihe, die kein Telefon so hat. Ein iPhone 16 Pro Max rastet bei
1×, 2× und 5× ein; ein 3× gibt es dort **nicht**, das läge zwischen zwei
Objektiven und wäre gerechnet.
Wo ein Gerät den Bereich nicht hergibt – kein Teleobjektiv –, fällt die 5
von selbst weg. Und wo es den Gerätezoom gar nicht gibt, bleibt es bei
1/2/3: Digital wird nur beschnitten, und bei 5× blieben von einem
Sucherausschnitt von 599 Pixeln noch 120 übrig.
**Die Zahlen benennen die Vergrößerung, nicht das Objektiv** – so wie
Apples Beschriftung auch. Welches Glas dafür zum Einsatz kommt,
entscheidet iOS.
> **Warum eine feste Leiter und keine abgefragte:** Das Telefon gibt
> seine Rastpunkte nicht heraus. Der Browser bekommt nur `{min, max,
> step}`, also einen durchgehenden Bereich; die Umschaltpunkte kennt nur
> AVFoundation intern. Aus `max` lässt sich der optische Endpunkt auch
> nicht ablesen, weil dort der digitale Zoom mitzählt (bis 25×).
### Behoben
- 🔢 **Ein Zwischenwert aus der Kneifgeste fand seine Stufe nicht mehr.**
Welche Stufe ihn anzeigt, wurde mit `Math.floor` bestimmt – das setzt
die Reihe 1, 2, 3 voraus. Bei 1/2/5 käme für 3,4× eine 3 heraus, die es
nicht gibt: Keine Stufe trüge den Wert, die Leiste zeigte weiter „2×".
## 2.88.25 – September 2026
### Geändert
- ↩️ **Die Objektivwahl aus 2.88.24 ist wieder raus.** Am Gerät sah man,
warum: iOS bietet dort gar keine einzelnen Objektive an, sondern seine
virtuellen Kombi-Kameras („Rückseitige Triple-Kamera", „Rückseitige
Dual-Weitwinkelkamera") – und die Frontkamera gleich mit. Viel Auswahl,
wenig Gewinn. Die Zoomstufen genügen.
### Behoben
- 🔍 **„1×" hätte am iPhone heraus gezoomt.** Der Gerätezoom wurde gegen
den *kleinsten* Wert gerechnet, den die Kamera meldet. Bei einer
Rückseite, die intern zwischen Ultraweitwinkel, Weitwinkel und Tele
umschaltet, gehört dieser kleinste Wert zum **Ultraweitwinkel** – die
Ansicht beim Öffnen liegt darüber. „1×" hätte also ein weiteres Bild
gezeigt als das, was man gerade sieht, und „2×" wäre kaum mehr als
normal gewesen.
Bezugspunkt ist jetzt, was die Kamera beim Öffnen meldet: **Was du
siehst, ist 1×.** Nachgemessen an einer Attrappe mit dem Verhalten einer
Triple-Kamera (Bereich 1–15, Ausgangslage 2): 2× stellt 4, 3× stellt 6,
und zurück auf 1× stellt wieder 2. Rein optisch, ohne Ausschnitt.
## 2.88.24 – September 2026
### Neu
- 🔭 **Die Objektive des Telefons stehen zur Wahl.** Über den Zoomstufen
liegt jetzt eine Reihe mit den Kameras, die das Gerät hergibt –
Weitwinkel, Ultraweitwinkel, Teleobjektiv. Wer eines davon wählt,
bekommt **echte Optik** statt eines Ausschnitts.
**Warum das nicht der Zoomregler tut:** Auf dem iPhone gibt es die
Zoom-Schnittstelle nicht. WebKit reicht `zoom` in den Fähigkeiten einer
Videospur nicht heraus, und weil alle Browser auf dem iPhone dieselbe
Maschine benutzen, hilft auch kein anderer. Was es seit iOS 16.3 gibt:
Die Rückkameras stehen **einzeln** in der Geräteliste. Über diesen Weg
läuft die Wahl.
Die Namen kommen vom Betriebssystem und sind übersetzt – darum werden
sie angezeigt und nicht durchsucht. Welches Objektiv wofür taugt, weiß
die App nicht: **Ein Teleobjektiv stellt oft erst ab einem halben Meter
scharf** und ist für eine Figur auf dem Tisch womöglich das falsche.
Also wählen lassen, nicht raten. Wo es nur eine Kamera gibt, bleibt die
Reihe weg.
## 2.88.23 – September 2026
### Neu
- 🔍 **Zoom in der Kamera.** Über dem Auslöser stehen **1× / 2× / 3×**, und
Kneifen mit zwei Fingern geht auch – stufenlos. Wo das Gerät es kann,
zoomt der Sensor selbst (echte Details); sonst wird der Ausschnitt
verkleinert. Die Stufen erscheinen nur, wo es etwas zu wählen gibt.
### Behoben
- 📷 **Aufgenommen wurde viel mehr, als der Sucher zeigte.** Das Livebild
füllt den Bildschirm und ist dafür beschnitten – auf einem hochkanten
Telefon sieht man **26 % der Bildbreite**. Das Foto nahm trotzdem das
ganze Sensorbild. Wer eine Figur einrahmte, bekam sie also auf ein
Viertel geschrumpft, und die Erkennung rechnet jedes Bild auf 1024 Pixel
herunter.
Der alte Grund dafür war, dass sonst der Rand fehle, an dem die Figur oft
steht. Der Gedanke stimmt, die Größenordnung nicht: 74 % sind kein Rand.
Jetzt wird der Sucherausschnitt genommen, **plus ein Fünftel
Sicherheitsrand**. Nachgemessen: Die Figur kommt ohne Zoom mit **171
statt 96 Pixeln** bei der Erkennung an, mit 3× mit **427**.
- 🔓 **Nicht mehr bei jedem Foto nach der Kamera fragen.** Bisher endete
der Kamerastrom beim Schließen sofort; das nächste Foto fragte neu. Wer
fünf Figuren hintereinander scannte, wurde fünfmal gefragt. Der Strom
bleibt jetzt eine halbe Minute stehen – beim Tabwechsel und im
Hintergrund endet er sofort, damit die Kameraanzeige des Geräts nicht
ohne Grund leuchtet.
**Das Fragen beim App-Start bleibt.** Für eine Web-App vom
Startbildschirm merkt sich iOS die Kamerafreigabe nicht über den Start
hinaus (WebKit-Fehler 215884) – daran kann keine App etwas ändern.
## 2.88.22 – September 2026
### Behoben
- 📐 **Der Update-Kasten brach mitten durch den Satz.** „Die App startet
gleich / neu – bitte kurz warten." – der Umbruch riss das Verb
auseinander, und in der zweiten Zeile las sich „neu" wie ein neuer
Gedanke. Jetzt bricht er nach „neu –", wo der Satz auch atmet.
### Dokumentation
- 📖 **Handbuch und README beschreiben den Steckbrief, wie er heute
aussieht.** Dort standen noch die vier Abschnitte von 2.69.0 und ein
Themenfeld mit Stift, den es bei Katalogartikeln nicht mehr gibt. Neu
beschrieben sind der Kopf (Bild über die volle Breite, Marken, die drei
Kacheln) und die Reiter Exemplar / Preise / Mehr.
- 📖 **Die Kamera in der App steht jetzt im Handbuch** (Abschnitt 4.1):
Livebild beim Antippen, Mediathek darin daneben, Licht nur wo das Gerät
es kann – und der Hinweis, dass es über `http://` beim Dateidialog
bleibt, weil das Livebild eine gesicherte Verbindung braucht.
- 📖 **Zeitspannen und Ablesen am Preisverlauf** sind beschrieben, samt dem
Punkt, der leicht Fragen aufwirft: Die Spannen filtern im Browser und
kosten keinen Abruf.
## 2.88.21 – September 2026
### Behoben
- 🧱 **Die Ladeanzeige im Katalog klebte unter der Filterleiste** und sagte
nicht, worauf man wartet. Dort standen nur die vier Steine – ohne
Abstand, ohne Beschriftung. Jetzt derselbe Block wie in Sammlung,
Statistik und Tauschbörse: Luft darum und „Katalog wird geladen …"
darunter.
## 2.88.20 – September 2026
### Geändert
- ↩️ **Die Schiebeschalter aus 2.88.17 und 2.88.19 sind zurückgenommen.**
Sie kamen aus der Formensprache der Fenster und wirkten in den Listen
geborgt: Die App lebt von kräftigen Konturen, ein weicher Schalter sieht
darin aus wie aus einer anderen App hineinkopiert. Reiterreihen,
Katalogfilter, Themenwahl und Suchfeld stehen wieder wie zuvor.
Geblieben ist nur, was kein Geschmack ist: die Trefferfläche der Marken
„Hab ich" und „Merken" im Katalog – 44 statt 35 Pixel, das Maß, das
überall sonst gilt. Und die unsichtbare Vorsorge im Katalogkopf gegen das
seitliche Verschieben.
## 2.88.19 – September 2026
### Geändert
- ↩️ **Zurückgenommen mit 2.88.20** – hier nur der Vollständigkeit halber,
weil 2.88.20 darauf verweist: Die Schiebeschalter aus 2.88.17 waren auf
alle Reiterreihen ausgeweitet worden (Wünsche/Einkaufen/Archiv/Katalog,
Katalogfilter, Tauschbörse). Zwei Formensprachen übereinander sahen
schlechter aus als eine, aber die richtige war die alte.
Geblieben ist die Trefferfläche der Marken „Hab ich" und „Merken" im
Katalog: 44 statt 35 Pixel, das Maß, das überall sonst gilt.
## 2.88.18 – September 2026
### Behoben
- 🔁 **„Bilder holen" lief endlos über dieselben Bilder.** Von BrickLink
kommen die meisten Figurenbilder mit **400 Pixeln** – nachgemessen: von
100 frisch geholten waren 91 genau 400 groß und acht 800. Die Ablage
verkleinert nur, sie erfindet keine Pixel; ein solches Bild ist nach dem
Holen genauso klein wie vorher und galt deshalb sofort wieder als offen.
Neben jedem geholten Bild liegt jetzt eine Merkdatei mit der Zielgröße im
Namen. Damit endet der Lauf – und wenn die Zielgröße später steigt, gilt
sie nicht mehr und alles wird noch einmal versucht.
**Was das für die Schärfe heißt:** Das große Bild im Steckbrief wird nur
dort besser, wo BrickLink mehr als 400 Pixel liefert. Bei vielen Figuren
ist 400 schlicht das Original.
- ↩️ **Der Text im Update-Fenster bricht ausgeglichen um.** „bitte kurz /
warten." ließ das letzte Wort allein stehen.
## 2.88.17 – September 2026
### Geändert
- 📚 **Der Katalogkopf spricht dieselbe Sprache wie der Rest.** Die vier
Filter („Alle", „Fehlt mir", „Hab ich", „Gemerkt") waren einzeln
umrandete Knöpfe, einer davon gelb – das sah aus wie vier Aktionen, ist
aber eine Wahl. Jetzt ein Schiebeschalter, dieselbe Form wie
„Gebraucht/Neu" im Steckbrief. „Figuren/Sets" ebenso.
Themenwahl und Suchfeld tragen die ruhige Fassung aus den Fenstern:
weiche Kontur, Fläche statt Kasten, Rand erst beim Hineingehen.
- 🛡 **Dieselbe Vorsorge wie in der Sammlung.** Im Katalogkopf steht
dasselbe Auswahlfeld in derselben Bauweise, an der Safari die Seite
seitlich aufschob – der Kopf schneidet jetzt ab, bevor es dort dazu
kommen kann.
## 2.88.16 – September 2026
### Geändert
- 🪟 **Auch Hilfe und Figuren-Steckbrief fahren jetzt auf.** Sie hängen an
einer anderen Hülle als die übrigen Fenster und blieben deshalb beim
Umbau zurück – sie sprangen herein, während alles daneben aufging. Der
Schleier dahinter ist jetzt ebenfalls weichgezeichnet.
- 🔘 **Die Knöpfe im Katalogfenster haben dieselben Maße wie überall
sonst** – mindestens 44 Pixel hoch, weiche Ecken. Am Telefon trifft man
sie damit sicher.
## 2.88.15 – September 2026
### Geändert
- 🔍 **„Bilder holen" schärft die alten mit.** Bisher holte es nur, was ganz
fehlte; die vor 2.88.0 abgelegten 400er blieben liegen und wurden erst
scharf, wenn jemand den Artikel öffnete. Bei 780 Figuren dauert das seine
Zeit. Sie gelten jetzt als offen und laufen in denselben Häppchen mit,
samt Fortschrittsanzeige.
**Richtigstellung:** In 2.88.3 und 2.88.13 stand, ein Sammellauf ginge
gegen dasselbe BrickLink-Tageskontingent wie die Preise. Das ist falsch.
Bilder kommen von den CDNs (`img.bricklink.com`, `cdn.rebrickable.com`),
das Tageslimit von 5000 gilt für `api.bricklink.com`. Mit diesem falschen
Argument war die bessere Lösung verworfen worden.
- 🪟 **Interesse, Melden und das Gespräch sehen aus wie der Rest.** Der
Steckbrief hatte die ruhigere Sprache bekommen, der Dialog auch – diese
drei blieben zurück und fielen nebeneinander auf. Sie sind gleich gebaut,
also tragen sie jetzt dasselbe Kleid: weiche Felder, Abstand zum Rand,
gleich breite Knöpfe.
- 🐞 **Ein wiederkehrender Fehler behält beides**, den ersten und den
jüngsten Text. Gleichartige Meldungen werden zusammengefasst und behielten
bisher nur den ersten; nach einer Behebung erhöhte ein Wiedersehen bloß
den Zähler, und man sah dem Eintrag nicht an, ob er von vor oder nach der
Änderung stammte. Genau daran ist am 23.09.2026 eine Runde
verlorengegangen.
## 2.88.14 – September 2026
### Behoben
- 📈 **Am Telefon blieb der abgelesene Preis nicht stehen.** Beim Antippen
der Kurve erschienen Datum und beide Preise – und verschwanden beim
Loslassen wieder, also genau in dem Moment, in dem man sie lesen wollte.
Am Zeiger ist das Ausblenden richtig: Die Maus fährt weiter, ein
klebender Wert wäre dort falsch. Am Finger ist es andersherum, denn zum
Ablesen muss man loslassen. Jetzt bleibt der Wert stehen, bis man die
Kurve erneut antippt oder eine andere Zeitspanne wählt.
## 2.88.13 – September 2026
Diese Fassung bündelt alles seit 2.88.2. Die Zwischenschritte 2.88.3 bis
2.88.12 liefen nur auf einer Instanz und stehen unten einzeln – hier das
Wesentliche für alle.
### Geändert
- 🔍 **Zu klein abgelegte Bilder holen sich selbst nach**, sobald jemand die
Figur oder das Set aufruft. Wer durch die Sammlung blättert, löst nichts
aus.
*(Hier stand zunächst, ein Sammellauf ginge gegen dasselbe
BrickLink-Tageskontingent wie die Preise. Das war falsch – siehe 2.88.15.)*
- 🧹 **Die Fehlersuche-Abschnitte sind raus** – sowohl die Überstands-
Messung, die eigens für die Jagd unten gebaut wurde, als auch das
Abschalten einzelner Bausteine aus 2.73.0. Letzteres war für die
Absturzsuche gedacht; die ist abgeschlossen, und was damals gelernt wurde,
steht in den Proben. Wer Bausteine abgeschaltet hatte, bekommt sie damit
automatisch zurück.
### Behoben
- ↔️ **Die Sammlung ließ sich seitlich schieben** – auf dem iPhone, nicht
auf dem Prüfgerät. Der Rahmen um das Sortierfeld ist 98 Pixel breit, sein
Inhalt meldete 175: Safari rechnet die Textbreite der `<option>`-Einträge
in den Überlauf ein, obwohl diese Liste nie gezeichnet wird. Von dort
wanderte es in die Filterleiste und bis zur Seite. Der Rahmen schneidet
jetzt ab, und die Felder dürfen schrumpfen (`min-width: 0`).
Sichtbar verschwindet dadurch nichts: Das Feld klippt seinen Text ohnehin,
und die aufgeklappte Liste zeichnet das Betriebssystem außerhalb des
Kastens.
## 2.88.12 – September 2026
### Geändert
- 🧹 **Die Überstands-Messung ist wieder raus.** Sie war für genau eine
Jagd gebaut (2.88.4 bis 2.88.11) und hat sie erledigt: Ein Fehler, der
sich auf keinem Prüfgerät nachstellen ließ, wurde dort gemessen, wo er
auftrat. Was bleibt, sind die Proben und der Eintrag hier – das Werkzeug
selbst muss niemand mit sich herumtragen.
## 2.88.11 – September 2026
### Behoben
- ↔️ **Das seitliche Schieben in der Sammlung – die Ursache.** Gemessen auf
dem Gerät: Der Rahmen um das Sortierfeld ist 98 Pixel breit, sein Inhalt
meldet 175 – und das Auswahlfeld darin nur 94. Die Differenz kommt von
den `<option>`-Einträgen: Safari rechnet deren Textbreite („Wert (hoch →
niedrig)") in den Überlauf ein, obwohl sie nie gezeichnet werden. Von
dort wanderte sie weiter in die Filterleiste (+27) und bis zur Seite
(+11).
Der Rahmen schneidet jetzt ab. Sichtbar verschwindet dadurch nichts: Das
Feld klippt seinen eigenen Text ohnehin, und die aufgeklappte Liste
zeichnet das Betriebssystem außerhalb des Kastens.
Chromium rechnet die Optionen nicht mit – deshalb war in der Nachbildung
bei vier Bildschirmbreiten, allen Ansichten und 800 Einträgen nie etwas
zu sehen. Gefunden hat es die Messung auf dem Gerät selbst.
## 2.88.10 – September 2026
### Behoben
- 📐 **Alte Überstands-Befunde gaben sich als neu aus.** Der gespeicherte
Text blieb nach einem Update stehen, und die naheliegende Lesart war
„nichts geändert" – zweimal geschehen. Jetzt sagt die Anzeige es, wenn
der Befund aus einer älteren Fassung stammt.
Dasselbe auf der Serverseite: Gleichartige Meldungen werden dort
zusammengefasst und behalten den Text der **ersten**. Ein Wiedersehen
nach einem Fix erhöhte damit nur den Zähler einer alten Zeile. Die
Fassung steht jetzt in der Meldung, also bekommt jede ihre eigene.
## 2.88.9 – September 2026
### Behoben
- ↔️ **Das seitliche Schieben in der Sammlung – der zweite und
wahrscheinlich letzte Grund.** Das Sortier- und das Typ-Feld standen mit
175 Pixeln in einem 98 Pixel breiten Rahmen und schoben die Seite auf.
Ein Flex-Kind schrumpft von sich aus **nicht** unter die Breite seines
Inhalts – bei einem Auswahlfeld ist das die längste Option („Wert (hoch →
niedrig)"). `width: 100%` hilft dagegen nicht, die Mindestgröße gewinnt;
es braucht ausdrücklich `min-width: 0`. Safari hält sich strikt daran,
Chromium schrumpft von selbst – deshalb war davon in der Nachbildung bei
vier Bildschirmbreiten, allen Ansichten und 800 Einträgen nie etwas zu
sehen.
Gefunden hat es die Messung auf dem Gerät selbst. Dasselbe gilt jetzt für
das Suchfeld, das denselben Bau hat.
## 2.88.8 – September 2026
### Behoben
- 📐 **Die Überstands-Messung nennt jetzt den richtigen Kasten.** Zwei
Schwächen: Sie schlug den Scroll-Versatz auch fest positionierten
Elementen auf – dadurch stand die Tab-Leiste als Übeltäter da, obwohl sie
gar nicht mitwandert. Und die Liste „scrollt innen über" war nach innen
sortiert: Ganz innen stehen harmlose Dinge (der Text in einem Auswahlfeld
ist länger als das Feld – das klippt der Browser), während der
interessante Kasten weiter außen liegt.
Jetzt wird eigens ausgewiesen, welcher Kasten **genau den Überstand des
Dokuments** weiterreicht, innerste Quelle zuerst. Das ist der Ort.
## 2.88.7 – September 2026
### Geändert
- 📐 **Der Überstands-Befund geht an den Server** und landet in der
Fehlerliste – mit Zeit, Fassung und Gerät. Ihn in den Einstellungen zu
suchen und abzufotografieren kostete jedes Mal eine Runde, und man sah
ihm nicht an, ob er von heute oder von gestern war. Der Text in den
Einstellungen trägt jetzt ebenfalls Zeitpunkt und Fassung.
- 📐 **Neu in der Messung: „Scrollt innen über".** Steht kein einziges
Element über, ist das Dokument aber breiter, steckt die Ursache in etwas,
das in keiner Elementliste auftaucht – ein `::before`/`::after`, ein Rand,
eine Tabelle. Sichtbar wird sie trotzdem: Jeder Kasten, der sie enthält,
meldet ein größeres `scrollWidth` als `clientWidth`. Die Messung nennt
jetzt den **innersten** davon, und das ist der Ort.
## 2.88.6 – September 2026
### Behoben
- 📐 **Die Überstands-Messung fand bei 11 Pixeln kein einziges Element.**
Zwei Gründe, beide behoben:
`getBoundingClientRect` misst gegen das **Fenster**, nicht gegen das
Dokument – ist die Seite schon seitlich geschoben, rutscht alles nach
links und der Übeltäter versteckt sich hinter dem Rand. Und **Ränder
zählen nicht mit**: Ein `margin-right` steht in keinem Rechteck, macht
das Dokument aber trotzdem breiter. Genau so sehen elf Pixel aus, die
nirgends zu sehen sind.
Außerdem nennt die Messung jetzt immer etwas: Liegt nichts über der
Schwelle, kommen die äußersten Elemente trotzdem in die Liste, dazu alles,
was nach **links** hinausragt. Eine leere Liste hilft niemandem.
## 2.88.5 – September 2026
### Behoben
- 📐 **Die Überstands-Messung konnte gar nichts finden.** Sie maß die
Ansicht, die gerade offen ist – und sobald man in die Einstellungen
wechselt, ist die Sammlung ausgeblendet. Ausgeblendetes steht nicht über:
Die Messung meldete pflichtschuldig „nichts" und hatte dabei recht. Nur
eben nutzlos.
Jetzt schaut eine Wache beim Blättern mit und schreibt den Befund einmal
je Ansicht weg; die Einstellungen zeigen ihn später an. Man blättert also
einfach durch die betroffene Ansicht und sieht danach nach. Der teure
Durchlauf durch alle Elemente passiert nur, wenn wirklich etwas übersteht.
## 2.88.4 – September 2026
### Neu
- 📐 **„Was steht über den Rand?" in der Fehlersuche.** Lässt sich eine
Ansicht seitlich schieben, ist irgendein Element breiter als das Fenster
– welches, hängt an den eigenen Daten und am eigenen Browser. Der Knopf
misst dort, wo es auftritt, und nennt das Element beim Namen, dazu seine
Breite und den Weg nach oben: Ein überstehendes Kind sagt wenig, solange
man nicht weiß, welcher Kasten es nicht halten konnte.
Anlass war das seitliche Schieben in der Sammlung: In der Nachbildung
stand es bei vier Bildschirmbreiten, allen drei Ansichten, allen
Sortierungen und 800 Einträgen nie über – auf dem Gerät schon. Drei
Anläufe gingen so ins Leere. Zu finden unter **Mehr → Einstellungen →
📐 Fehlersuche**.
## 2.88.3 – September 2026
### Geändert
- 🔍 **Zu klein abgelegte Bilder holen sich selbst nach.** Mit 2.88.0 stieg
die Ablagegröße von 400 auf 800 Pixel, damit das Bild im Popup über die
volle Breite scharf bleibt – schon abgelegte Bilder blieben aber klein.
Nachgeholt wird jetzt genau dann, wenn jemand die Figur oder das Set
**aufruft**: beim vollen Bild, nicht beim Daumennagel im Raster. Wer durch
800 Karten blättert, löst nichts aus – sonst stünden bei jedem Blick in
die Sammlung Hunderte Abrufe an.
*(Hier stand zunächst, ein Sammellauf ginge gegen dasselbe
BrickLink-Tageskontingent wie die Preise. Das war falsch – siehe 2.88.15.)*
Der Abruf läuft im Hintergrund; das Fenster wartet nicht darauf. Beim
ersten Öffnen steht noch das alte Bild, ab dem zweiten das scharfe. Die
daraus abgeleiteten Daumennägel werden mitgelöscht, sonst bliebe die
Sammlung ausgefranst.
## 2.88.2 – September 2026
### Behoben
- ↔️ **Die Sammlung ließ sich seitlich schieben.** Die Karten standen in
der rechten Spalte über den Bildschirmrand hinaus, und die ganze Seite
wurde dadurch breiter als das Fenster.
Ursache war eine Zeile, die harmlos aussieht:
`contain-intrinsic-size: auto 236px`. Gemeint war die Höhe, die der
Browser für noch nicht gezeichnete Karten annehmen soll – **ein
einzelner Wert gilt aber für beide Achsen**. Karten außerhalb des
Sichtfelds meldeten damit auch 236 Pixel *Breite*. Weil Rasterfelder von
Haus aus `min-width: auto` haben, konnte `1fr` nicht darunter: Die zwei
Spalten rechneten 260 statt 197 Pixel und standen 126 Pixel über.
Sichtbar war das nur bei vielen Einträgen – wo der Browser nichts
überspringt, gibt es auch keine Ersatzgröße. Mit sieben Karten in der
Probe war nie etwas zu sehen, mit 780 sofort. Die Zeile steht seit
2.73.0 (29.08.2026) im Stylesheet.
Jetzt gilt die Ersatzgröße nur noch für die Höhe. Zusätzlich dürfen
Karten ihre Spalte nicht mehr aufblähen (`min-width: 0`) – falls ein
Browser die genauere Schreibweise nicht kennt.
## 2.88.1 – September 2026
### Neu
- 📷 **Die Kamera geht jetzt in der App auf.** Antippen zeigt das Livebild
mit Auslöser, Sucher-Ecken und – das war der Punkt – einem Knopf zur
**Fotomediathek gleich daneben**. Mit 2.88.0 kam an dieser Stelle noch
die Auswahlliste des Systems: Sie bot die Mediathek zwar an, kostete aber
jedes Foto einen Tipp mehr und sah nicht nach der App aus. Ein Licht
erscheint oben rechts, wo das Gerät es kann.
**Zweigleisig, und das ist wichtig:** Der Kamerazugriff im Browser
(`getUserMedia`) gibt es nur über HTTPS. Über die Cloudflare-Adresse ist
das gegeben. Wer eine Instanz im Heimnetz über `http://` aufruft, bekommt
weiter den Dateidialog – genau wie vorher. Dasselbe gilt, wenn die
Freigabe für die Kamera abgelehnt wird. Es wird also nirgends schlechter,
nur an der einen Stelle besser.
Ein `<input type="file" capture>` war dafür übrigens nie geeignet: Es
reicht nur an das Betriebssystem weiter, und in dessen Kamera gibt es
keinen Weg zur Mediathek.
## 2.88.0 – September 2026
### Geändert
- 🖼 **Das Detail-Popup macht mit dem Bild auf.** Es war eine Briefmarke von
72 Pixeln neben dem Namen; jetzt steht das Bild über die volle Breite auf
weißem Grund. Weiß ist bewusst fest und kommt nicht aus dem Design: Fast
alle Katalogbilder bringen selbst einen weißen Grund mit, und auf Hellgrau
bekam jedes von ihnen einen sichtbaren Kasten. Auch die Bilder in der
Sammlung stehen jetzt auf Weiß.
- 💶 **Drei Kacheln statt fünf gleich lauter Zeilen.** Bezahlt, Wert und
Gewinn stehen zuoberst, direkt unter dem Namen. Vorher standen sie als
Zeilen zwischen „Anzahl" und „Zustand" – gleich laut wie die Bedienung,
obwohl fast immer eine dieser drei Zahlen der Grund ist, das Fenster
überhaupt zu öffnen. Kaufpreis ändern und „weiterer Kauf" sitzen als
kleine Symbole in der Ecke ihrer Kachel.
- 🗂 **Der Rest liegt auf drei Blättern:** Exemplar, Preise, Mehr. Beim
Umbau am 29.08.2026 war Zuklappen verworfen worden, weil es „bei jedem
Öffnen einen Tipper kostet". Das gilt weiter – nur ist es erledigt: Die
drei Zahlen stehen **über** den Reitern und kosten keinen. Ein Blatt ohne
Inhalt bekommt keinen Reiter, und bleibt nur eines übrig, entfällt die
Leiste ganz.
- 📓 **Die Notiz gehört jetzt zum Exemplar**, nicht mehr unter „Einordnung".
Sie beschreibt *dieses* Stück – woher es kam, was ihm fehlt –, nicht seine
Einsortierung. Und sie lag zuletzt so weit unten, dass sie beim Durchsehen
übersehen wurde.
- 🎞 **Die Fenster fahren auf, statt zu erscheinen.** In der App bewegt sich
sonst alles – der Startbildschirm baut sich auf, die Ladeanzeige hüpft –,
nur die meistgeöffneten Fenster sprangen herein. Das war der größte Teil
ihres alten Eindrucks. Der Schließen-Knopf hat dabei seinen schwarzen
Kasten verloren: Umrandet war er das Kräftigste im ganzen Fenster,
ausgerechnet für die Nebensache.
- 🧱 **Vier Noppen auf dem Aufnahme-Knopf.** Zwei einfarbige waren der
letzte Rest der alten Handschrift; inzwischen sind es überall vier bunte
Steine – im Logo, im Startbildschirm, in der Ladeanzeige. Sie sind unten
geschlossen, damit jede als eigener Stein *auf* dem Knopf steht,
unabhängig von dessen Farbe.
- ✍️ **Die Aufschrift des Aufnahme-Knopfes folgt dem Gerät.** Am Telefon
„Figur oder Set fotografieren", am Rechner „Bild hierher ziehen oder
auswählen". Entschieden wird über `hover` – ehrlicher als die
Fensterbreite, denn ein schmales Browserfenster am Rechner bedient man
weiter mit der Maus.
- 🏷 **Kein Stift mehr am Thema von Sets.** Er erschien nur, wo das Thema
nicht feststand – bei Sets lieferte die Ableitung aber grundsätzlich
nichts, weil sie nur Figurennummern kennt. Deshalb stand dort immer einer
für etwas, das längst über BrickLink gefunden war. Bei selbst angelegten
Einträgen und bei Teilen bleibt er: Ein Grundstein hat kein Thema, und
was dort landet, kann danebenliegen.
### Neu
- 🖼 **Bilder aus der Fotomediathek.** Am Datei-Feld stand
`capture="environment"` – das *erzwang* die Kamera, ein Foto, das man
schon hatte, war schlicht nicht scanbar. Jetzt fragt das Telefon selbst:
Mediathek, Foto aufnehmen, Datei. Der Preis ist ein Tipp mehr auf dem Weg
zur Kamera.
- 📅 **Zeitspannen am Preisverlauf** – 1M, 3M, 1J, Alles. Das kostet keine
einzige BrickLink-Abfrage: Die Punkte liegen längst vollständig mit
Zeitstempel vor, gefiltert wird im Browser. Angeboten wird nur, was etwas
zeigt – bei einem Stück von letzter Woche zeichnete „1J" dieselbe Kurve
wie „1M".
- 🔎 **Ablesen im Preisverlauf.** Beim Berühren erscheint eine Linie in der
Spalte, die Punkte werden hervorgehoben, und darunter stehen Datum und
beide Preise. Getroffen werden muss die **Spalte**, nicht der Punkt: Auf
dem Telefon liegen sie dicht beieinander, und der Finger verdeckt genau
den, den man treffen will.
### Behoben
- 🔍 **Das große Bild war ausgefranst.** Zwei Ursachen: Das Popup holte die
Daumennagel-Fassung, und abgelegt wurde ohnehin nur mit 400 Pixeln
(„reicht für Karte und Popup" – das stimmte, solange es eine Briefmarke
war). Jetzt 800 Pixel und die volle Fassung. Bereits abgelegte Bilder
bleiben bei 400, bis sie über „Bild erneuern" neu geholt werden; ein
Sammellauf ginge gegen dasselbe Tageskontingent wie die Preise.
- 🪟 **Dialogfenster standen links statt mittig**, und ihr Schließen-Knopf
schwebte rechts daneben in der Luft. Die Breitenbegrenzung saß am Inhalt
statt am Fenster. Gleichzeitig haben die Dialoge die ruhigere Sprache
bekommen: weiche Felder, gleich breite Knöpfe, Abstand zum Rand.
- 🏷 **Ein Klick auf den Themen-Stift ließ das Thema verschwinden.** Er
blendet die Zeile aus und ein Feld ein – das lag seit den Blättern auf
„Mehr" und war damit unsichtbar. Das Feld steht jetzt direkt neben der
Zeile im Kopf.
- 📏 **Preiszeilen brachen mitten in der Klammer um.** „(717,74 € –" stand
am Ende der einen, „959,66 €)" am Anfang der nächsten Zeile.
## 2.87.1 – September 2026
### Geändert
- 🧱 **Der drehende Klemmbaustein ist überall der hüpfenden Reihe
gewichen.** Mit 2.87.0 kamen die vier Logo-Steine als Lade-Anzeige, aber
zwei Stellen hatten den alten Stein behalten: das Feld, das beim
Herunterziehen zum Aktualisieren oben erscheint, und der Bildschirm
während eines Updates. Dort dreht sich jetzt nichts mehr.
Aus dem runden Feld am oberen Rand ist dafür eine Pille geworden — vier
Steine nebeneinander passten in 42 Pixel Durchmesser nicht hinein. Der
Takt der Geste bleibt: Beim Ziehen stehen die Steine still, gehüpft wird
erst, wenn das Neuladen losgeht.
- 🟢 **Die Schwelle beim Herunterziehen ist ein grüner Ring statt einer
grünen Fläche.** Die Füllung stammte aus der Zeit des einfarbigen
Steins; unter den vier bunten hätte sie ausgerechnet den grünen
verschluckt.
### Behoben
- 📏 **Eine Regel im Stylesheet stand ohne schließende Klammer da** — ein
zu großzügiger Schnitt beim Ausbau der alten Anzeige. Browser werfen so
etwas stillschweigend weg; hier war die Sammlungsansicht betroffen, die
im Raster über beide Spalten mittig stehen soll. Eine neue Probe
(`test_css_wohlgeformt.py`) prüft künftig Klammern und Blöcke mit.
## 2.87.0 – September 2026
### Hinzugefügt
- 🧱 **Ein Startbildschirm, der sich aufbaut.** Beim Aufrufen der Seite
fallen die vier Steine des Logos nacheinander ein und federn leicht,
dann kommen Name, Wortmarke und Unterzeile versetzt hinterher. Nach drei
Sekunden blendet das Bild aus – und **erst danach** fährt der Inhalt
auf; sonst schiene er während des Ausblendens durch, und aus dem
Auftritt würde eine Überblendung.
**Der Name kommt vom Server**, nicht aus JavaScript. Sonst blitzte das
Logo erst ohne Namen auf und spränge dann um. Ohne gesetzten
Anzeigenamen fällt die Zeile weg und das Logo rückt zusammen.
Die Haltedauer steht an **einer** Stelle (`--halt` am `#splash`), und
der Ladebalken hängt an derselben – zwei Zahlen wären zwei
Gelegenheiten, sie auseinanderlaufen zu lassen. Wer Bewegung reduziert
hat, sieht dasselbe Bild ohne Animation.
Ein Notausgang in `theme-boot.js` nimmt das Bild nach sechs Sekunden in
jedem Fall weg. Bricht `app.js` je ab, läge es sonst für immer über
einer App, die man nicht mehr bedienen kann – lieber ohne Startbild als
ausgesperrt.
- 🌊 **Das Ladezeichen passt dazu.** Statt des drehenden Klemmsteins
hüpfen in den Listen jetzt dieselben vier Steine nacheinander, im Takt
des Startbildschirms. Beim **Herunterziehen zum Aktualisieren** bleibt
es beim drehenden Stein: Dort sitzt das Zeichen in einem kleinen runden
Knopf, und das Drehen gehört zur Geste.
### Behoben
- 🌙 **Das dunkle Design blitzte auf dem Anmeldebogen kurz hell auf.**
`theme-boot.js` setzte vor dem ersten Zeichnen korrekt Galaxy – und
`checkSetup()` überschrieb es eine Zehntelsekunde später mit dem
Instanz-Standard. Genau das Aufblitzen, gegen das `theme-boot.js`
überhaupt geschrieben wurde.
Jetzt gilt auch dort, was nach dem Anmelden längst galt: **die eigene
Wahl auf diesem Gerät vor dem Instanz-Standard.** Aufgefallen ist es
erst beim Startbildschirm – mit einem ruhig stehenden Logo wird aus dem
Zucken ein sichtbarer Farbwechsel.
- 🍎 **Die iOS-Kachel hieß „'s Brickfolio".** Derselbe Genitiv-Fehler wie
in 2.85.0, nur an einer Stelle übersehen: Die Vorlage trug
`__OWNER__'s Brickfolio`, und ohne gesetzten Namen klebte das s an einer
leeren Zeichenkette. Wer die App aufs Handy legte, hatte das auf dem
Startbildschirm stehen.
## 2.86.5 – September 2026
### Behoben
- 💶 **Ab dem sechsten Treffer fehlten Jahr und Preis.** Zwei Grenzen
passten nicht zusammen: Die Oberfläche schickte **acht** Nummern zum
teuren Abruf, der Server bediente davon **fünf** (`[:5]`). Die drei
dazwischen bekamen den Hinweis „lade Jahr & Preise …", nie Daten – und
am Ende räumte die Oberfläche den Hinweis wortlos wieder weg.
Beide stehen jetzt auf **zehn**, so viele wie eine Seite zeigt. Und beim
Blättern wandert das Fenster mit: Bisher wurden immer wieder dieselben
ersten Treffer angereichert, seit 2.86.3 konnte man aber bis Treffer 200
blättern.
Gemessen am Beispiel „gelber Umhang": vorher fünf Karten mit
Preis und fünf ohne, jetzt alle zehn – und nach einem Klick auf
„Weitere Ergebnisse laden" auch die beiden nächsten.
### Hinzugefügt
- 🏷 **„keine Preisdaten bei BrickLink"** steht jetzt dort, wo bisher
einfach nichts stand. Manche Einträge haben im Preisfenster **null
Verkäufe** – `cas123`, eine Castle-Figur von 1987, ist so ein Fall;
BrickLink führt sie dort sogar ohne Namen („Castle") und ohne Jahr.
Neben ihren Nachbarn sah so eine Karte aus, als sei etwas kaputt.
Gesagt wird es **nur, wo wirklich nachgefragt wurde**. Bei allem anderen
hieße „kein Preis" bloß „noch nicht gefragt", und das als Auskunft
hinzustellen wäre schlimmer als zu schweigen.
## 2.86.3 – September 2026
### Geändert
- 🔍 **Bei Figuren antwortet nur noch der eigene Katalogabzug.** Aufgefallen
war, dass die Trefferliste zwei Quellen mit denselben Figuren mischt –
und das stimmte: `dis080 · Donald Duck - Jester` und
`fig-012635 · Donald Duck, Jester` sind dieselbe Figur.
Die Entdoppelung konnte das nicht fangen. Sie vergleicht Nummer plus Typ,
und die Nummern gehören zwei verschiedenen Katalogen. Über die Namen
ginge es auch nicht, die sind nur gleichbedeutend („Qui-Gon Jinn (Yellow
Head)" gegen „Qui-Gon Jinn, Yellow Skin"). Und eine Brücke gibt es nicht:
**Rebrickable liefert für Figuren keine BrickLink-Nummer** – weder in der
Suche noch im Einzelabruf, für Teile dagegen schon.
Dazu kam, dass die zweite Hälfte die schlechtere war: ohne Preis, ohne
Set-Zugehörigkeit, ohne BrickLink-Nummer – also ohne alles, woran hier
die Bewertung hängt.
Rebrickable springt bei Figuren jetzt nur noch ein, wenn der eigene Abzug
**nichts** findet. Für **Sets und Teile** bleibt alles wie es war; dort
ist es oft die einzige Quelle, und bei Teilen liefert es sogar die
BrickLink-Nummer mit.
- 📜 **Mehr Treffer, und das Blättern geht ohne Nachfragen.** Der Abzug war
auf 20 Treffer gedeckelt – das war der eigentliche Grund, warum
Rebrickable überhaupt etwas beitragen konnte. Er gibt jetzt heraus, was
er hat: „Stormtrooper" sind **69** statt 20, „Darth Vader" 35 statt 20.
Angezeigt werden weiterhin zehn; **Weitere Ergebnisse laden** blättert
durch das, was schon geholt wurde, und löst keine neue Anfrage aus.
Nachgemessen: 10 von 45 → ein Klick → 20 von 45, ohne einen einzigen
Netzzugriff.
Die Schwelle für den Farb-Rückfall bleibt dabei bei 20. Wäre sie
mitgewandert, liefe die Verbreiterung praktisch immer – und „gold" hieße
wieder „yellow", was 9.231 Figuren hereinzöge.
## 2.86.2 – September 2026
### Behoben
- ⚡ **Die erste Suche nach einem Neustart dauerte fünf Sekunden.** Danach
war alles schnell, und niemand konnte sich erklären, warum ausgerechnet
die eine Anfrage hing.
Die Suche rechnet aus den Daten selbst aus, welche Wörter in fast jeder
Bildbeschreibung stehen (`torso`, `legs`, `yellow` …) – sonst fände
„gelb" zwei Drittel des Katalogs. Dafür liest sie **alle** Beschreibungen
und zerlegt sie: bei 19.267 Figuren gemessene **5,1 s** auf der NAS. Das
Ergebnis lag bisher nur im Arbeitsspeicher, war also nach jedem
Containerstart weg – und der nächste Suchende zahlte es.
Jetzt steht es auch in den Einstellungen, mit der Zeilenzahl als
Schlüssel: Ändert sich der Abzug, wird neu gezählt, sonst gelesen.
Zusätzlich wärmt der Start es im Hintergrund vor, damit auch der erste
Lauf nach einem neuen Abzug nicht vor dem Suchfeld stattfindet.
Gemessen auf einer Instanz: erster Lauf **5,1 s → 0,2 s**, jeder weitere
war schon vorher 0,2 s.
## 2.86.1 – September 2026
### Behoben
- 🔍 **„Figur mit blauem Hut" fand nichts.** Das Wörterbuch machte daraus
`figure blue hat`, und weil die Suche **alle** Wörter verlangt, blieb sie
leer: `figure` steht in 1.268 von 40.936 Katalogzeilen, fast nur bei
Duplo. Dabei ist „Figur" in dieser Frage gar kein Merkmal, sondern ein
Füllwort – gemeint ist „eine Figur, die einen blauen Hut hat", gesucht
ist der Hut. Welche Gattung gemeint ist, sagt ohnehin schon die
Typ-Auswahl über dem Feld.
„Figur", „Figuren", „Minifigur" und „Minifiguren" zählen jetzt zu den
Füllwörtern. Gemessen an **79 echten Anfragen** aus der Instanz plus neun
Mustern: **sieben besser, keine schlechter, 82 unverändert.**
| Anfrage | vorher | nachher |
|---|---|---|
| Figur mit blauem Hut | 0 | **20** |
| Figur mit blauem Hut, roten Beinen und grünem Torso | 0 | **4** |
| Figur mit gelbem Kopf | 2 | **20** |
| Figur mit Kopf und Arm | 0 | **6** |
| Figuren mit Umhang | 14 | **20** |
Zwei der besseren Fälle standen so im echten Anfragen-Protokoll – das
Muster wurde also wirklich getippt und lief wirklich ins Leere.
**Eine Anfrage wird dabei nie zu nichts.** Wer nur „Figur" tippt, hat ein
Füllwort getippt und sonst nichts; dann bleiben die Füllwörter stehen.
Ohne diese Rückfallebene wäre genau diese eine Anfrage schlechter
geworden – der einzige Rückschritt in der ersten Messung, und vermeidbar.
## 2.86.0 – September 2026
### Hinzugefügt
- 📈 **Pfeile im Preis-Protokoll.** Neben jedem Betrag steht jetzt ein
grünes **↑** oder ein rotes **↓** – je nachdem, wohin der Preis seit dem
vorherigen Punkt desselben Artikels gegangen ist. Eine Zahl allein sagt
nämlich nicht, ob sie gut ist: „Ø 4,55 €" liest sich gleich, ob der Preis
gestiegen oder gefallen ist. Der Hinweis unter der Maus nennt den alten
Wert und die Veränderung („vorher 620,00 € · −14,50 €"). Neu und
gebraucht haben je einen eigenen Pfeil; sie laufen nicht immer in
dieselbe Richtung.
**Kein Pfeil heißt: nichts zu zeigen** – erster Punkt eines Artikels,
oder der Betrag ist derselbe geblieben. Verglichen wird **auf Cent**,
also genau das, was in der Zeile steht: BrickLink liefert vier
Nachkommastellen, und ein Pfeil für eine Bewegung, die im angezeigten
Betrag nicht zu sehen ist, wäre nur verwirrend.
Der Endpunkt liefert den Vorgänger über eine Fensterfunktion (`LAG`) mit.
Der Fallstrick steckte im `LIMIT`: Das Protokoll zeigt die jüngsten 50
Zeilen, aber der vorherige Punkt eines Artikels liegt fast immer weiter
zurück. Das Fenster läuft deshalb über den **ganzen** Verlauf und wird
erst danach begrenzt – dafür gibt es eine eigene Probe.
## 2.85.1 – September 2026
### Geändert
- ⏱ **Die Namen des Katalogabzugs kommen schneller – ohne das Kontingent zu
reißen.** Der Stapel je Lauf war fest auf 1.500 gesetzt. Die Zahl stammte
aus einer Zeit mit 9.700 Namen; bei inzwischen **19.267** wären das
sechseinhalb Tage, in denen eine frische Instanz nur über die
Bildbeschreibungen sucht.
Einfach hochsetzen ging nicht: BrickLink lässt 5.000 Abrufe am Tag zu, und
am Preis-Deckel ist das bereits ausgeschöpft. Nur trifft dieser Deckel
genau die Instanzen, die den Namenslauf **längst hinter sich haben** – wer
gerade erst installiert hat, hat eine leere Sammlung, und die Preise
brauchen fast nichts. Deshalb wird der Stapel jetzt gerechnet statt
gesetzt: Was nach den Preisen vom Tagesbudget übrig bleibt, gehört den
Namen.
| Sammlung | Namen je Tag | 19.267 Namen in |
|---|---|---|
| leer (Neuinstallation) | 3.620 | **5,3 Tagen** (vorher 6,4) |
| 900 Artikel | 3.456 | 5,6 Tagen |
| 3.000 Artikel | 2.708 | 7,1 Tagen |
| 9.000 Artikel | 2.180 | 8,8 Tagen |
Bei großen Sammlungen ist das **langsamer** als die festen 1.500 – und
genau richtig so: Dort war die feste Zahl ein Überzug aufs Kontingent.
Sieben Proben halten fest, dass die Summe aus Preisen und Namen das
Tagesbudget in keinem Fall überschreitet.
## 2.85.0 – September 2026
### Behoben
- 🏷 **Ohne Anzeigenamen hieß die App „'s Brickfolio" – und das Logo
trug einen fremden Vornamen.** Auf **jeder** frischen Installation,
bevor jemand einen Namen setzt. Die Vorlage trug `__OWNER__'s Brickfolio`, und der Server setzte
nur den nackten Namen ein: Das Genitiv-s klebte an einer leeren
Zeichenkette. Das Logo blieb beim Platzhalter, weil `applyOwnerName` bei
leerem Namen mit einem frühen `return` ausstieg.
Jetzt setzt der Server denselben `_app_title()` ein, den das Manifest
längst richtig benutzt („Dein Brickfolio"), der Name kommt ebenfalls von
dort, und eine leere Namenszeile blendet sich aus. Auch der
Einrichtungsassistent nennt nicht mehr einen festen Vornamen als Beispiel,
sondern zeigt den fertigen Titel als Vorschau.
- 🔍 **„Nichts gefunden" stand über zehn sichtbaren Treffern.** Nicht die
Suche war schuld, sondern der Übersetzungs-Zusatzversuch: Er läuft auch
dann, wenn nur der *eigene* Abzug leer blieb – und auf einer neuen
Instanz ist das der Normalfall, weil die Namen darin erst nach und nach
bei BrickLink nachgeschlagen werden. Fand die Übersetzung nichts, schrieb
sie ihr „Nichts gefunden" über die Treffer, die schon dastanden.
Der Versuch weiß jetzt, ob schon etwas zu sehen ist: Dann heißt es
währenddessen „Suche zusätzlich nach der Übersetzung …", und ein
Misserfolg endet still, statt zu widersprechen.
### Geändert
- 🔒 **`Permissions-Policy` ergänzt.** Sie fehlte als einzige der üblichen
Kopfzeilen. Gesperrt sind jetzt Mikrofon, Standort, Zahlung, USB, MIDI und
Seriell; die Kamera bleibt für die eigene Seite erlaubt. Gescannt wird
zwar über ein Dateifeld mit `capture`, das die Regel gar nicht betrifft –
ein `camera=()` wäre aber eine Falle für den Tag, an dem jemand auf
`getUserMedia` umstellt.
- 📘 **Das Handbuch sagt jetzt, dass die Sicherung die API-Schlüssel im
Klartext trägt.** Genannt waren bisher nur die Passwort-Hashes. In der
Oberfläche erscheinen die Schlüssel maskiert (`…41c7`), in der Sicherung
vollständig – anders ließe sich eine Instanz nicht wiederherstellen. Die
Datei ist damit so vertraulich wie die Datenbank selbst.
- 🧹 **Drei Dateien entfernt, die niemand mehr abrief:**
`frontend/icons/icon-180.png` (das Apple-Touch-Symbol wird je Instanz
erzeugt), `frontend/manifest.webmanifest` (wird erzeugt, seit der Name aus
den Einstellungen kommt – die feste Fassung war obendrein veraltet) und
`docs/screenshots/start.png` (seit Juli in keiner Doku eingebunden).
Ebenfalls aufgeräumt, aber ohne Wirkung auf die App: Projektseite,
Katalogdienst, Tausch-Hub und Hub-Konsole liegen jetzt in eigenen,
nicht öffentlichen Repos. Hier bleibt das Programm.
## 2.84.1 – September 2026
### Behoben
- 📘 **Eine Dublette im Handbuch wieder entfernt.** 2.84.0 hat einen
Abschnitt 9.1 „Wie der Gesamtwert gerechnet wird" angelegt, weil ein
Suchlauf die vorhandene Erklärung nicht fand – gesucht wurde nach
„bereinigt", im Handbuch steht „**B**ereinigt" am Satzanfang. Die Regel
stand also längst in Kapitel 13, und das Handbuch erklärte sie danach
zweimal mit verschiedenen Worten. 9.1 ist wieder raus, Kapitel 9 verweist
nur noch auf 13, und die Hilfe verlinkt dorthin.
*Diese Fassung sollte man 2.84.0 vorziehen.*
## 2.84.0 – September 2026
### Geändert
- 📖 **Die Hilfe ist auf die Hälfte geschrumpft.** Sie war über die Jahre
zu acht Textwänden gewachsen: **934 Wörter**, davon 340 allein für „Wie
der Wert berechnet wird", und in sechs von acht Abschnitten keine
einzige Aufzählung. Wer auf dem Handy eine schnelle Antwort suchte, las
einen Aufsatz.
Jetzt hat jeder Abschnitt dieselbe Form: **ein Leitsatz, dann kurze
Punkte**. Aus 934 Wörtern wurden **560** – und das mit einem Abschnitt
*mehr*. Der längste Abschnitt hat jetzt 91 statt 340 Wörter.
- 🗣 **Eine Anrede statt zwei.** Die App duzte und ihrzte gleichzeitig: in
der Oberfläche 32× „du" gegen 13× „ihr", in den Meldungen aus dem Code
13× „ihr" gegen 12× „du", und innerhalb der Hilfe 9× „ihr" gegen 2× „du".
Mal hieß es „in eurer Sammlung", zwei Zeilen weiter „deine Sammlung".
Jetzt sagt alles **„du"**: Oberfläche, Meldungen, Hilfe und Handbuch.
Betroffen waren 27 Stellen im Code und rund 100 im Handbuch; die
englischen Schlüssel sind mitgewandert, sonst wäre die englische Fassung
an 13 Stellen ins Deutsche zurückgefallen.
### Hinzugefügt
- 🔍 **Ein eigener Abschnitt „Suchen".** Dass die Suche seit 2.80.0 Deutsch
versteht, stand in der Hilfe nirgends – ausgerechnet die Neuerung, nach
der man dort suchen würde. Vier Zeilen: beide Sprachen, Merkmale
kombinieren, reine Nummern, und dass ein *kürzerer* Begriff mehr bringt
als ein längerer.
- 🔗 **Die Hilfe verlinkt das Handbuch abschnittsweise.** Was beim Kürzen
wegfiel, ist nicht verloren – „Wie der Wert berechnet wird" zeigt jetzt
auf [Kapitel 13](docs/HANDBUCH.md#13-die-preis-automatik-im-detail), wo
die Rechnung seit jeher ausführlich steht.
## 2.83.0 – September 2026
### Geändert
- 🐢 **Das Modell ist jetzt das letzte Mittel, nicht der zweite Reflex.**
Bisher genügte **ein** unbekanntes Wort in der Anfrage, um die lokale KI
zu bemühen – und bei Star-Wars-Figuren ist ein unbekannter Eigenname der
Normalfall, nicht die Ausnahme. „Jedi mit gelbem Kopf und braunem
Umhang" ging deshalb ans Modell, obwohl das Wörterbuch `jedi yellow head
brown cape` liefert und damit auf Anhieb die richtigen Figuren findet.
Jetzt wird **erst gesucht und dann gefragt**: Die Oberfläche versucht es
mit dem, was das Wörterbuch hergibt, und holt das Modell nur, wenn dabei
nichts herauskommt. Gemessen an 103 echten Anfragen: 97 beantwortet das
Wörterbuch vollständig, und von den übrigen sechs war eine („Jedi mit …")
schon vorher richtig übersetzt.
Für „Bademantel", „Dirndl" oder „Trachtenhut" bleibt das Modell die
einzige Hilfe – `bathrobe` steht in keiner Liste, die aus Katalogwörtern
gebaut ist.
## 2.82.0 – September 2026
### Neu
- 🔎 **Deutsch suchen, ohne lokale KI.** Die Katalognamen sind englisch;
„Ritter" fand bisher nur etwas, wenn ein Sprachmodell eingerichtet war.
Die App bringt jetzt ein Wörterbuch mit: rund 1.400 deutsche Stichwörter,
dazu Endungen abstreifen und zusammengesetzte Wörter zerlegen
(„Protokolldroide" → `protocol droid`, „Sturmtruppler" → `storm trooper`).
Gewonnen wurde es aus der Worthäufigkeit des Katalogs selbst: 19.267
Figurennamen bestehen aus 7.016 verschiedenen Wörtern, aber die
häufigsten 300 decken 77 % aller Vorkommen – Farben, Kleidung,
Körperteile. Der Rest sind Eigennamen, die man ohnehin so tippt.
Die KI bleibt nützlich: Sie springt ein, wenn das Wörterbuch eine Anfrage
nicht **vollständig** kennt. Von Hand Gepflegtes schlägt weiterhin beides.
### Behoben
- 🔤 **Umlaute waren Trennzeichen.** „Mütze" zerfiel in „m" + „tze",
„König" in „k" + „nig", „Fußball" in „fu" + „ball" – und weil einzelne
Buchstaben wegfallen, blieb ein Wortfetzen übrig. Zwölf von zwölf
gescheiterten Anfragen im ersten Trainingslauf hatten einen Umlaut.
- 👑 **„king" fand gar nichts.** Der gespeicherte Suchtext klebt alle Wörter
aneinander, `LIKE '%king%'` traf deshalb auch „Markings" und „Parking":
377 Zeilen, und die Vorauswahl bricht bei 400 ab. Kein einziger echter
König kam durch. Neue Spalte mit Leerzeichen zwischen den Wörtern.
- 🥷 **Bei mehreren Wörtern zählte nur das längste.** „schwarzer ninja"
suchte nach „black" – die 400 Zeilen waren voll, bevor der erste Ninja
kam. Jetzt muss jedes Wort vorkommen.
- 🎨 **Deutsche Farben umgingen die Farbprüfung.** „helm weiss" fand
Figuren, die gar nicht weiß sind, während „helmet white" sie richtig
aussortierte: `weiss` stand nicht in der Farbliste. Die Suche war nicht
besser, sondern lockerer.
### Geändert
- 🧩 **Allerweltswörter zählen in der Bildbeschreibung nur im Verbund.** Das
Sehmodell beschreibt jede Figur Teil für Teil, deshalb steht `torso` in
19.266 von 19.267 Beschreibungen und `yellow` in 13.209 – im Namen
dagegen nur 833 bzw. 1.155 Mal. Wer „gelb" suchte, bekam zwei Drittel des
Katalogs. Ein Wort über 30 % Häufigkeit zählt dort jetzt nur noch, wenn
die Anfrage im selben Abschnitt etwas Eigenes trifft: „gelber Kopf"
findet ihn, „gelb" allein nicht.
**Teil und Farbe zusammen bleiben scharf** – darum ging es: „Figur mit
blauem Hut, roten Beinen und grünem Torso" trifft genau eine Figur, und
zwar die richtige.
- 🇩🇪 **Die Bildbeschreibungen werden beim Update eingedeutscht.** Neu
beschriebene Figuren bekommen ihren deutschen Teil vom Sehmodell; die
vorhandenen zieht eine Wanderung nach – Wort für Wort aus demselben
Wörterbuch, ohne Modell und ohne Netz. 19.267 Zeilen in rund neun
Sekunden. Sie läuft bewusst **hier** und nicht zentral: Danach steht
„kopf" in praktisch jeder Beschreibung, und eine ältere App ohne die
Verbund-Regel fände damit den ganzen Katalog.
## 2.81.0 – September 2026
### Geändert
- 🏷 **Kein fremder Vorname mehr in der eigenen Installation.** Wer Brickfolio
aufsetzte und keinen Anzeigenamen eintrug, bekam einen fest eingebauten
Vornamen – im Logo, im Fenstertitel, auf dem Startbildschirm des Handys und
in den Kopfzeilen der Druckexporte. Das war der Name des Kindes, für das
diese App ursprünglich entstand, und er hatte in fremden Sammlungen nichts
zu suchen.
Ohne gesetzten Namen heißt die Instanz jetzt schlicht **„Dein Brickfolio"**
(englisch *Your Brickfolio*), und das Symbol bleibt namenlos – der
Symbol-Erzeuger zeichnet einfach keine Zeile mehr über das Gesicht. Wer
einen Namen einträgt, bekommt wie bisher „*Name*'s Brickfolio". Das
Eingabefeld zeigt statt eines Beispielnamens den Hinweis „ohne Namen".
Zusammengesetzt wird der Titel jetzt an **einer** Stelle (`_app_title()`)
statt an vier – vorher hing das `'s` an jedem Verwendungsort einzeln, und
aus „Dein" wäre dort „Dein's" geworden.
Dieselbe Bereinigung in der Beschreibung: Die vier Handbuch- und
README-Überschriften lauteten „*Name*'s Brickfolio" und heißen jetzt nur
noch **Brickfolio** – so wie das Projekt überall sonst auftritt.
## 2.80.3 – September 2026
### Geändert
- 📏 **Berichtigt, woran die verrutschten Rahmen lagen.** Die Erklärung in
2.80.1 und 2.80.2 war falsch: Nicht der Browser schickte zu große Bilder,
sondern **Brickognize rechnet selbst auf 1024 Pixel herunter** und
antwortet in diesem Maßstab. Belegt durch das Protokoll der Instanz:
`Upload 900x1200, Dienst 768x1024`. Die Lösung aus 2.80.1 stimmt
unverändert – sie nimmt die Maße aus der Antwort und nicht aus einer
Annahme. Berichtigt sind die Einträge, die Kommentare im Quelltext und die
Proben; dazu eine neue Probe mit genau diesen Zahlen.
Die Zeile im Container-Protokoll meldet jetzt nur noch den wirklich
auffälligen Fall – ein Bild, das ungekürzt ankommt. Umgerechnet wird bei
jedem Scan, das ist der Normalfall und keine Meldung wert.
## 2.80.2 – September 2026
### Geändert
- 🔎 **Das Verkleinern eines Fotos sagt jetzt, wenn es nicht greift.** Vor dem
Scannen rechnet der Browser jedes Foto auf 1200 Pixel herunter. An fünf
Stellen konnte er dabei stillschweigend das Original durchreichen. Das war
die **vermutete** Ursache der verrutschten Rahmen aus 2.80.1 – sie war es
nicht (siehe dort). Die fünf stummen Ausgänge bleiben trotzdem ein blinder
Fleck, und jeder schreibt jetzt seinen Grund in die Spur
(*Mehr → Wartung*).
Dazu eine Zeile im **Container-Protokoll**, wenn der Server einen Rahmen
umrechnen musste. Die Spur im Browser liegt auf dem Gerät; diese Zeile ist
von außen lesbar und kommt nur im Ausnahmefall.
## 2.80.1 – September 2026
### Behoben
- 🎯 **Die Rahmen um die erkannten Figuren saßen daneben.** Bei „Alle Figuren
erkennen" lagen sie zu klein und zu weit links oben – je weiter rechts die
Figur stand, desto deutlicher.
Der Erkennungsdienst rahmt sauber ein; das wurde eigens geprüft, indem der
zurückgegebene Rahmen in ein Foto gezeichnet wurde. Nur gilt er für das
Bild, auf dem **er** gearbeitet hat – und Brickognize rechnet selbst auf
höchstens 1024 Pixel herunter. Aus den 900×1200, die der Browser schickt,
werden dort 768×1024; der Browser zeichnete den Rahmen aber in den Maßen
seines eigenen Bildes, also um 1024/1200 = **0,853** zu klein und
entsprechend zu weit links oben.
**Nachtrag vom selben Tag:** In der ersten Fassung dieses Eintrags stand
als Ursache, der Browser habe ein zu großes Bild geschickt (1200/1400).
Das war falsch, belegt durch die Protokollzeile aus 2.80.2: `Upload
900x1200, Dienst 768x1024`. Die Probe, die zu dem Fehlschluss führte,
hatte zwei Bilder **unter** 1024 verglichen – dort verkleinert der Dienst
nichts. Die Lösung bleibt dieselbe, denn sie rechnet mit den Zahlen aus
der Antwort und nicht mit einer Annahme.
Der Server rechnet den Rahmen jetzt in die Maße des Bildes zurück, das er
bekommen hat – samt EXIF-Drehung. Beide Zahlen dafür liefert der Dienst
ohnehin mit (`image_width`, `image_height`), sie wurden bisher nur nicht
gelesen.
**Das betraf mehr als die Anzeige:** Aus denselben Rahmen schneidet die App
die Ausschnitte fürs eigene Foto am Artikel und fürs Weitersuchen. Die
kamen bisher vom falschen Fleck.
## 2.80.0 – September 2026
### Behoben
- 🏷 **Im Browser-Reiter stand auf jeder Instanz derselbe feste Name.** Das App-Symbol
trägt seit 2.2.0 den eigenen Anzeigenamen – das kleine Symbol im Reiter
aber nicht: `/favicon.ico` reichte eine feste Datei aus dem Repo durch.
Aufgefallen ist es erst, weil es auf der Instanz, auf der entwickelt
wird, richtig aussah. Nachgemessen am 20.09.2026 an einer fremden
Instanz: `/icon/192.png` lieferte dort ein Symbol mit **ihrem** Namen,
`/favicon.ico` dieselbe Datei wie das Repo, Prüfsumme gleich.
Jetzt kommt auch das Reiter-Symbol aus dem Erzeuger, als .ico mit den
drei Größen, die Browser abholen. Und die **mitgelieferten** Symbole
(`frontend/icons/`) sind namenlos: Sie sind der Rückfall, wenn Pillow
fehlt, und liegen öffentlich im Repo.
## 2.79.2 – September 2026
### Behoben
- 🧩 **Der Sprung zu einem Set blitzte nur auf.** Ein Klick auf das Set in
„Fehlende Set-Figuren" wechselt in die Sammlung und trägt die Setnummer
ins Suchfeld — das Set erschien kurz und wich dann wieder der
**vollständigen** Sammlung, obwohl die Nummer im Suchfeld stehenblieb.
Zwei Ursachen, beide behoben:
**Die Reihenfolge.** `showTab("collection")` stößt selbst einen
Ladevorgang an. Das Suchfeld wurde erst *danach* gesetzt, also lief ein
zweiter mit **leerer** Abfrage — und dessen Antwort kam zuletzt an. Jetzt
stehen die Felder vorher, `showTab` gibt seinen Ladevorgang zurück, und
es wird nur noch **einmal** geladen statt zweimal.
**Das Netz darunter.** `loadCollection` hatte keine Sperre gegen überholte
Antworten: Es gewann schlicht die, die zuletzt eintraf — auch die ältere.
Jede Abfrage trägt jetzt eine Laufnummer; wer überholt wurde, schreibt
nichts mehr. Das betrifft auch das schnelle Tippen im Suchfeld, wo
dasselbe passieren konnte.
## 2.79.1 – September 2026
### Behoben
- 📚 **„40878 Figuren" — der Katalog zählte Sets als Figuren.** BrickLinks
Figurenkatalog hat gut 19.000 Einträge; die Zahl war mehr als das
Doppelte. Sie stimmte trotzdem: Wer die Katalogdatei auch für **Sets**
einliest (der Text daneben rät ausdrücklich dazu), hat beides im Abzug —
auf einer Instanz 19.209 Figuren und 21.669 Sets. Nur die Beschriftung zählte
alles zusammen und nannte es „Figuren".
Jetzt steht dort, was drin ist: *„19.209 Figuren (19.209 beschrieben) und
21.669 Sets"*. Auch nach dem Einlesen: *„21.669 neu, 0 berichtigt ·
19.209 Figuren und 21.669 Sets im Abzug"*.
Dazu passend: **„beschrieben" und „ohne Namen" gelten nur für Figuren.**
Die Bildbeschreibung gibt es nur für sie, und der Namens-Nachtrag greift
ohnehin nur nach Zeilen mit Beschreibung — ein Set ohne Namen als „wird
nachgeschlagen" zu zählen wäre ein Versprechen gewesen, das niemand
einlöst.
## 2.79.0 – September 2026
### Behoben
- 📈 **Der Preis-Hintergrundjob kam bei größeren Sammlungen nie hinterher.**
Im Preis-Protokoll stand „Bei 328 Artikeln ist der Preisabruf älter als
7 Tage" — und die Zahl ging nicht weg. Das war kein Fehler, sondern
Arithmetik: feste **40 Einträge je Lauf**, zwei Läufe am Tag, also
**80 Preise täglich**. Bei 926 Artikeln bräuchte es 133.
Nachgemessen an der Altersverteilung: exakt 80 je Tagesstufe, und die
ältesten Einträge lagen bei 12,5 Tagen — genau der Kreislauf, den die
Rechnung vorhersagt (926 ÷ 80 ≈ 11,6 Tage). Damit war dauerhaft rund ein
Drittel überfällig, ohne dass irgendetwas hängen geblieben wäre.
**Der Stapel richtet sich jetzt nach der Sammlung**: so viel, dass eine
Runde in sieben Tagen durch ist, mindestens 40 und höchstens 400 je Lauf.
Bei 926 Artikeln sind das 83 je Lauf — eine Runde in 5,6 Tagen. Der
Deckel schützt das BrickLink-Kontingent: selbst ausgereizt sind es 1.600
Abrufe am Tag gegen erlaubte 5.000.
Das Handbuch versprach „nie älter als gut eine Woche" — das stimmte für
Sammlungen über 560 Artikel nicht und ist nachgezogen.
- 📈 **Die ältesten kommen zuerst dran.** Die Auswahl hatte kein
`ORDER BY`, also entschied die Zeilennummer. Ein Artikel, dessen Abruf
dauernd scheitert, behält seinen alten Zeitstempel und hätte sich so in
jedem Lauf wieder vorgedrängt, während die dahinter nie an die Reihe
gekommen wären. Im Betrieb ist das (noch) nicht passiert — alle
Rückstände hatten Preise —, aber die Reihenfolge war Zufall.
## 2.78.0 – September 2026
### Neu
- 📖 **Das ⓘ führt jetzt in den Artikel — auch dort, wo er anders heißt.**
„Bespin Guard" steht in der Jedipedia unter **Bespin-Sicherheitskräfte**;
das lässt sich aus dem Katalognamen nicht ableiten, nur nachschlagen. Für
die geläufigen Figuren liegt die Zuordnung jetzt bei — 190 Einträge, jeder
einzeln gegen die MediaWiki-Schnittstelle des Wikis geprüft. Im Betrieb
ruft Brickfolio dort weiterhin nichts ab.
**Was hinausgeht, sind Namen — nie BrickLinks Beschreibungen.** Die löst
die Begriffsbildung vorher heraus, und ein Test hält die Grenze: Jeder
Schlüssel muss schon sein eigenes Ergebnis sein, sonst steckt eine
Beschreibung darin.
- 📖 **Die Einheit hinter dem Komma bleibt stehen und wird verlinkt.** Bei
„Clone Trooper Commander, 187th Legion" ist die **187. Legion** der
interessantere Verweis, nicht der allgemeine Klonkommandant. Erkannt wird
eine Einheit an ihrer Form (Ordnungszahl oder Legion/Bataillon/Korps/…) —
eine Verbotsliste müsste jede Bemalung kennen, die BrickLink sich je
ausdenkt.
**Steht dort ein Name, geht er vor:** „Commander Fox, Coruscant Guard"
führt zu Fox, nicht zu seiner Garde.
- 📖 **Begriffsklärungsseiten werden aussortiert.** „Cody", „Fox", „Hammer",
„Hunter" — lauter Klonkrieger, und jeder dieser Titel ist im Wiki eine
Auswahlliste. Das Werkzeug erkennt sie an der Kategorie und nimmt
stattdessen den nächsten Kandidaten (`Commander Cody` → `CC-2224`). Ohne
das landete „Echo" sogar bei einem **imperialen Piloten** statt beim
Klon.
Nachgemessen an 563 Star-Wars-Figuren: **554 landen im Artikel** — vorher
waren es 151.
### Behoben
- 📖 **Eine offene Klammer als Suchbegriff.** „AT-DP Pilot (Imperial Combat
Driver - White Uniform)" wurde am Bindestrich *innerhalb* der Klammer
zerschnitten; übrig blieb „AT-DP Pilot (Imperial Combat Driver". Jetzt
fliegen die Klammern zuerst raus, dann wird getrennt.
## 2.77.2 – September 2026
### Behoben
- ⚠️ **Die Zuordnungstabelle aus 2.77.0 ist wieder raus — sie enthielt
BrickLink-Namen.** `frontend/jedipedia-titel.js` trug 123 Katalognamen als
Schlüssel („Imperial Stormtrooper", „Astromech Droid, R2-D2, Light Bluish
Gray Head") und lag damit in einem **öffentlichen** Repo.
Das verstößt gegen genau die Regel, die `katalogdienst/veroeffentlichen.py`
seit Langem festhält und begründet: Veröffentlicht werden Nummer und
eigene Bildbeschreibung, **nicht** der Name — der ist BrickLinks Inhalt,
und dessen Weitergabe an Dritte untersagen deren Nutzungsbedingungen. Die
Datei ist gelöscht, und das Werkzeug kann nichts mehr ausliefern; es misst
nur noch. Eine Zuordnung müsste an der **Nummer** hängen.
### Geändert
- 📖 **Dafür löst die Begriffsbildung jetzt mehr heraus.** Die Suche des
Wikis springt von allein in den Artikel, sobald der Begriff dort ein Titel
ist — es kam nur selten dazu, weil BrickLinks Namen Beiwerk mitschleppen:
- Eine **Kennung gewinnt, wo immer sie steht**. „Assassin Droid (IG-88)"
wurde zu „Assassin Droid"; jetzt zu `IG-88`. Ebenso hinter dem Komma:
„Astromech Droid, R2-D2, Light Bluish Gray Head" → `R2-D2`.
- **Hinter dem ersten Komma steht Beiwerk** — Einheit, Farbe, Bedruckung.
„Clone Scout Trooper, 41st Elite Corps" → „Clone Scout Trooper".
Nachgemessen an 563 Star-Wars-Figuren: **220 landen im Artikel** statt 151
— ohne dass eine Zeile Katalogtext mitgeliefert würde. Bei englischen
Gattungsnamen („Battle Droid" → „B1-Kampfdroide") bleibt es bei der
Trefferliste.
## 2.77.1 – September 2026
### Behoben
- 📖 **Die Beschreibung in der App stand noch auf »öffnet eine Suche«.** Mit
2.77.0 führt das ⓘ in den Artikel — nachgezogen hatte ich das aber nur in
README und Handbuch, nicht dort, wo es jemand liest: in der App selbst.
Betrifft die Karte *Mehr → 📖 Jedipedia-Verweis* und den Abschnitt unter
*Quellen & Rechtliches*. Beide sagen jetzt, was tatsächlich passiert —
einschließlich des Hinweises, dass die Zuordnung **einmalig** erfragt wurde
und im Betrieb nichts abgerufen wird.
## 2.77.0 – September 2026
### Behoben
- 📖 **Das ⓘ führt jetzt in den Artikel statt auf die Suchseite.** Gemeldet:
„Bei vielen kommt nur die Suchseite raus." Nachgemessen an 563
Star-Wars-Figuren: nur **151** landeten im Artikel, die übrigen 412 auf
einer Trefferliste.
Der Grund war die Sprache. Der Katalog ist englisch, die Jedipedia
deutsch — „Imperial Stormtrooper" steht dort unter „Sturmtruppen",
„Battle Droid" unter „B1-Kampfdroide". Das Wiki springt nur dann von
selbst in den Artikel, wenn der Suchbegriff der Titel ist.
Deshalb liegt jetzt eine feste Zuordnung bei (`frontend/jedipedia-titel.js`),
die `tools/jedipedia_titel.py` **einmalig** über die MediaWiki-Schnittstelle
des Wikis erfragt hat. Übernommen wurde nur, was es dort wirklich gibt.
Im Betrieb holt Brickfolio nach wie vor nichts von dort — es verlinkt nur.
Jetzt landen **398 der 563** Figuren im Artikel; wo nichts eingetragen ist,
öffnet sich unverändert die Suche.
- 📖 **Die Klammer trug den Namen und wurde weggeworfen.** „Assassin Droid
(IG-88)" wurde zum Suchbegriff „Assassin Droid" — Trefferliste, obwohl
„IG-88" ein Artikel ist. Steht in der Klammer eine Kennung wie `IG-88`,
`C1-10P` oder `U-3PO`, ist **sie** der Name; Beschreibungen wie
„(Padawan)" fliegen weiter raus.
## 2.76.0 – August 2026
### Geändert
- 🧩 **`in_sets` nennt jetzt auch den Zustand des Sets.** Bisher kamen
Nummer, Name und Anzahl – der Live-Scanner konnte damit nicht
unterscheiden, ob ein Set **versiegelt** oder längst geöffnet ist.
Der Unterschied ist beim Mitbieten entscheidend: In einem neuen Set
stecken die Figuren noch. Bei einem gebrauchten stünden sie längst
einzeln in der Sammlung – wer ein Set *mit* Figuren kauft, trägt die
Figuren einzeln ein.
Angehängt als **viertes** Feld (`nummer|name|anzahl|zustand`): Wer nur
drei liest, bekommt weiterhin genau das, was er bisher bekam.
## 2.75.1 – August 2026
### Behoben
- 📱 **Kompakte Ansicht plus Sortierung nach Thema war auf dem Handy
unbrauchbar.** Das Raster legte sich über die **Themenkarten** statt über
die Figuren: vier Spalten à 85 Pixel, in denen „Minifigure, Headgear"
und „Ohne Thema" samt Erklärtext zu Buchstabentürmen zerfielen.
Für die Rasteransicht gab es die Lösung längst
(`#collection-list.by-theme`), nur griff sie hier nicht: Sie hat dieselbe
Spezifität wie `#collection-list.kompakt-mode`, und bei Gleichstand
gewinnt die Regel, die weiter unten steht – meine neuere. Zwei Klassen
schlagen eine.
Jetzt trägt die Themenkarte das Layout, und das Raster sitzt eine Ebene
tiefer: auf 375 Pixeln drei Kacheln je Zeile, der Themenkopf über die
volle Breite.
## 2.75.0 – August 2026
### Behoben
- 💾 **Die tägliche Sicherung entstand erst mittags.** Sie hing an der
Preisschleife, und die schläft **zwölf Stunden**. Wann der Tagesstand
angelegt wurde, hing damit davon ab, wann der Container zuletzt neu
startete – irgendwo zwischen Mitternacht und Mittag. Der halbe Tag davor
war ungeschützt.
Am 30.08.2026 trat genau das ein: letzter Neustart 29.08. um 23:33,
Sicherung dort übersprungen (die des 29. lag schon), nächster Lauf wäre
**11:35** gewesen. Zurückgespielt wurde um **10:55** – vierzig Minuten zu
früh, und ein ganzer Tag Arbeit hing an der Sicherheitskopie, die das
Zurückspielen selbst anlegt.
Ein eigener Wächter sieht jetzt **viertelstündlich** nach. Der Aufruf ist
billig: Liegt der heutige Stand schon, kehrt er sofort zurück.
- 🗑️ **Jede Sicherheitskopie kostete einen Tagesstand.** Die Aufräumlogik
lief über ein einziges `brickfolio-*.db` – und alphabetisch steht
`brickfolio-manuell-…` **hinter** `brickfolio-2026-…`. Die Kopie galt
damit als neueste Datei und blieb immer liegen; gelöscht wurde der
älteste Tag. Lautlos. Aus 14 Tagen Historie waren 12 geworden.
Tagesstände und Sicherheitskopien werden jetzt getrennt gezählt, jeder
Topf behält seine 14. Fremde Dateien im Ordner werden nicht angefasst.
- 🧱 **Zurückspielen zieht die Migrationen nach.** Ein alter Stand bringt
den alten Datenbankaufbau mit. Nach dem Zurückspielen fehlte deshalb eine
tags zuvor hinzugekommene Tabelle, und die Themenauswahl im Katalog
antwortete mit **500** – bis der Container das nächste Mal startete.
## 2.74.2 – August 2026
### Geändert
- ⚖️ **Ein Abschnitt zur Haftung** – in der App unter *Mehr → Quellen &
Rechtliches*, im README und im Handbuch. Die MIT-Lizenz sagt das zwar
auch, aber auf Englisch und in einer Datei, die niemand öffnet.
Im Klartext: Brickfolio wird „wie besehen" bereitgestellt. Drei Dinge
stehen ausdrücklich dabei –
- **Preise sind Anhaltspunkte, keine Bewertung.** Nicht als Grundlage für
Versicherungssummen oder Angaben gegenüber Behörden.
- **Die Erkennung kann sich irren** – was Kamera und Suche vorschlagen,
ist ein Vorschlag.
- **Eure Daten liegen bei euch.** Ein Backup, das nie zurückgespielt
wurde, ist keines.
Die zwingende Haftung (Vorsatz, grobe Fahrlässigkeit, Personenschäden,
Produkthaftung) bleibt unberührt – ein Ausschluss davon wäre ohnehin
unwirksam.
## 2.74.1 – August 2026
### Geändert
- ⚖️ **Die Jedipedia steht jetzt bei den Quellen** – in der App unter
*Mehr → Quellen & Rechtliches*, im README und im Handbuch.
Festgehalten ist, was tatsächlich passiert: Der Verweis **verlinkt nur**.
Es werden keine Inhalte abgerufen, übernommen oder gespeichert, und
solange niemand das ⓘ antippt, geht nichts dorthin. Die Artikel stehen
unter der **GNU-FDL 1.3** und gehören ihren Autoren; das Wiki steht in
keiner Verbindung zu diesem Projekt.
## 2.74.0 – August 2026
### Geändert
- 📖 **Handbuch und README auf den Stand gebracht.** Der Tag hat viel
gebracht, und die Doku hinkte hinterher. Neu beschrieben:
- **Katalog durchblättern** samt Sprungbalken, Filtern und der Bremse
beim Aushaken (Handbuch 6.2)
- **Sets im Katalog** und warum es dafür den Kategoriebaum braucht –
Figuren tragen ihr Thema in der Nummer, Sets nicht
- **Katalog-Themen** mit Favoriten und Sichtbarkeit
- **Der Steckbrief in vier Abschnitten**, Beschriftung links, Thema oben
im Kopf – und der ✏️ nur dort, wo die App das Thema nicht ableiten kann
- **Jedipedia-Verweis**, ausgeschaltet voreingestellt
- **Bausteine einzeln abschalten** in der Absturzdiagnose, samt der
Begründung: Wenn alle Dumps nur diese Seite betreffen, hilft halbieren
statt raten
## 2.73.0 – August 2026
### Neu
- 🔬 **Bausteine einzeln abschalten – halbieren statt raten.** Unter
*Mehr → Absturzdiagnose* lassen sich vier Dinge abschalten, die diese
App tut und die meisten anderen Seiten nicht:
| Baustein | was aus ist |
|---|---|
| Sichtbarkeitsoptimierung | `content-visibility` auf den Sammlungskarten |
| Klebende Leisten | `position: sticky` bei Kopfleiste, Blocküberschriften, Sprungbalken |
| Milchglas | `backdrop-filter` im Design „Nova" |
| Offline-Helfer | der Service Worker |
**Warum:** Alle bisherigen Absturz-Dumps betreffen ausschließlich diese
Seite. Der Abbruch selbst steckt in Chromium – ein absichtlicher
`EXC_BREAKPOINT` im Renderer, in Edge 151 genauso wie in Chrome 152, bei
2 bis 9 MB Speicher. Aber irgendetwas hier löst ihn aus, und welches
Stück, sagt niemand: Der Aufrufstapel im Dump trägt keine Namen.
Fünf Vermutungen, fünf Fehlschläge. Deshalb der systematische Weg: eines
abschalten, ein paar Stunden laufen lassen. **Was aus war, steht in jedem
Fehlerbericht mit** (`OHNE: cv,blur`) – ohne diese Zuordnung wäre die
ganze Halbiererei wertlos.
Die Wahl liegt im `localStorage`, nicht im Profil: Sie muss einen Absturz
und das Neuladen danach überleben, ohne dass vorher ein Server antworten
muss. Sonst liefe die Sitzung, die es zu messen gilt, kurz mit
angeschaltetem Baustein an.
## 2.72.0 – August 2026
### Geändert
- 🏷️ **Das Thema steht jetzt oben im Steckbrief**, direkt unter Nummer und
Zustand – es gehört zur Figur, nicht zu dem, was man mit ihr macht. Aus
dem Abschnitt „Einordnung" ist es verschwunden.
- ✏️ **Kein Stift mehr, wo das Thema aus der Nummer folgt.** `sw1213` ist
Star Wars; da gibt es nichts zu entscheiden. An 910 Einträgen
nachgesehen hatte auch **nie jemand** etwas anderes gesetzt als das
Ableitbare.
Bei eigenen Figuren, Teilen und unbekannten Kürzeln – 159 der 910 –
weiß die App es dagegen nicht. Dort bleibt der Stift, und statt einer
leeren Zeile steht dort „Thema setzen" als Einladung.
Das Eingabefeld startet damit immer geschlossen. Vorher stand bei jedem
Eintrag ohne Thema ein offenes Feld im Weg.
## 2.71.1 – August 2026
### Behoben
- 🔇 **„Zu diesem Artikel gibt es kein Bild" bei jedem Schließen.** Die
Meldung war erst in 2.71.0 dazugekommen – und ging sofort daneben:
`closeGallery` leert die Bildquelle, und **eine geleerte Quelle löst
selbst ein `error`-Ereignis aus**. Der neue Behandler hielt das für ein
totes Bild.
Er prüft jetzt zuerst, ob überhaupt etwas geladen werden sollte, und die
Quelle wird entfernt statt auf leer gesetzt.
### Geändert
- 🔙 **`content-visibility: auto` steht wieder auf den Sammlungskarten.**
Der Versuch aus 2.67.0 ist gelaufen, das Ergebnis war negativ: Der
Bericht zu 2.70.0 führt **drei** weitere Abstürze, alle nach dem Ausbau.
Die Zeile spart dem Browser echte Arbeit – gemessen: statt 815
Hintergrundbildern beim Öffnen nur noch 16 – und der Fehler ist woanders.
Im Quelltext steht jetzt dabei, dass der Versuch gelaufen ist, damit ihn
niemand ein zweites Mal macht.
## 2.71.0 – August 2026
### Behoben
- 🧩 **Bei Teilen ging die Großansicht sofort wieder zu.** Antippen,
kurz aufblitzen, weg – bei Figuren und Sets funktionierte alles.
Der Server baute für Teile die Adresse `ItemImage/PN/0/<nr>.png`. Bei
Figuren und Sets stimmt die Null: Die haben keine Farbe. Ein Teil schon –
dort gehört die **Farbnummer** hin, und die kennt der Server an dieser
Stelle nicht. An sieben Teilen geprüft war die Adresse **jedes Mal** ein
404, und weil sie die einzige in der Galerie war, klappte die Ansicht
beim Ladefehler sofort wieder zu.
Teile bekommen jetzt `PL/<nr>.jpg` – farbunabhängig, und bei vier der
sieben vorhanden.
- 🔁 **Und einen Rückfall für den Rest.** Trägt auch das Katalogbild nicht,
nimmt die Galerie die Adresse, die an der Karte steht – die lag die ganze
Zeit daneben. Ist auch die tot, klappt sie zu und sagt warum, statt
wortlos zu verschwinden.
## 2.70.0 – August 2026
### Geändert
- 📐 **Beschriftung links, Inhalt rechts.** „Zustand", „Thema" und „Wert"
standen jedes für sich allein auf einer Zeile, mit der ganzen Breite
daneben frei. Sie stehen jetzt nebeneinander – das spart bei jedem
Steckbrief vier bis fünf Zeilen Höhe.
Nur die Notizen bleiben gestapelt: Ein Textfeld braucht die Breite.
Die Beschriftungsspalte ist so breit wie das längste Wort, nicht breiter.
Eine feste Breite säße bei „Anzahl" zu weit und bei „Bezahlt" zu eng.
- Eine Zeile ohne Inhalt verschwindet mitsamt Beschriftung: „Wert" steht
nur da, wenn es einen Marktpreis gibt. Über CSS statt über Code, weil
die Verdrahtung den Preis später nachträgt – so greift es von selbst.
- Aus dem Wertfeld ist das Wort „Wert" verschwunden; es steht jetzt als
Beschriftung daneben und stand sonst doppelt da.
## 2.69.0 – August 2026
### Geändert
- 🗂️ **Der Steckbrief ist in Abschnitte geteilt.** Er war über Monate
gewachsen und zuletzt eine flache Liste aus zehn Blöcken – Anzahl,
Zustand, Bezahlt, Tauschbörse, Thema, Notizen, BrickLink-Nummer,
Verweise, enthaltene Teile, Marktpreise – ohne erkennbaren Zusammenhang.
Vier Überschriften: **Mein Exemplar**, **Einordnung**, **Nachschlagen**,
**Marktpreise**. Die Reihenfolge innerhalb der Abschnitte ist
unverändert; Anzahl und Zustand stehen weiter zuerst, das braucht man
beim Erfassen als Erstes.
**Zugeklappt wird nichts.** Das spart zwar Scrollweg, kostet aber bei
jedem Öffnen einen Tipper – und die Preise sieht man beim Bewerten fast
immer an.
Ein Abschnitt, der leer bliebe, wird gar nicht gezeichnet: Ohne
BrickLink-Zugang gibt es keine Überschrift „Marktpreise" über einer
leeren Fläche. Die Felder darunter bleiben trotzdem im Dokument – sonst
schriebe die Verdrahtung ins Leere.
- Das **ⓘ** des Jedipedia-Verweises steht jetzt neben dem Namen statt
darunter.
## 2.68.0 – August 2026
### Neu
- 📖 **Jedipedia-Verweis bei Star-Wars-Figuren.** Ein kleines **ⓘ** neben
dem Namen schlägt die Figur im deutschen Star-Wars-Wiki nach.
Einzuschalten unter *Mehr → Jedipedia-Verweis*.
**Ausgeschaltet voreingestellt.** Es ist ein Weg nach draußen aus einer
App, die sonst vollständig im eigenen Netz läuft; solche gehören nicht
ungefragt hinein. Übertragen wird nichts, solange niemand das Zeichen
antippt.
**Gesucht wird, nicht direkt verlinkt.** Der Katalog ist englisch, die
Jedipedia deutsch: „Battle Droid" heißt dort „Kampfdroide", und
`/wiki/Battle_Droid` wäre eine tote Adresse. Die Suche landet auf einer
Trefferliste mit dem richtigen Artikel obenan.
Und nur bei Star Wars – das Wiki kennt nichts anderes. Bei einer
City-Figur wäre der Verweis eine leere Trefferliste. Die Variante fällt
weg: „Boba Fett - Classic Grays" sucht nach der Figur, nicht nach ihrer
Bemalung.
## 2.67.0 – August 2026
### Geändert
- 🧪 **`content-visibility: auto` ist ausgebaut – als Versuch.**
Von 40 Absturz-Dumps auf dem betroffenen Rechner sind **alle 40 auf
Brickfolio**; keine andere Seite. Der Abbruch selbst ist ein
Chromium-Fehler – ein absichtlicher `EXC_BREAKPOINT` im Renderer, in
Edge 151 genauso wie in Chrome 152, bei 2 bis 9 MB Speicherverbrauch.
Aber irgendetwas an dieser Seite löst ihn aus, und nur an dieser.
`content-visibility` war das Ungewöhnlichste, was die App tut – kaum
eine andere Seite benutzt es. Es saß auf den Sammlungskarten, also genau
dort, wo in den Berichten immer wieder der Schaden entstand, und es griff
ineinander mit `position: sticky`, dem Bildbeobachter und dem Bildladen
auf denselben Elementen.
Gebraucht wird es ohnehin kaum noch: Seine Aufgabe – nicht alles auf
einmal zeichnen – macht seit 2.54.1 der eigene Beobachter, nachweislich
(110 von 245 und 158 von 915 geladenen Bildern in den Berichten).
**Bleiben die Abstürze aus, war es das.** Kommen sie weiter, gehört die
Zeile zurück; ihr Fehlen kostet dann nur etwas Rechenzeit beim Scrollen
sehr langer Sammlungen.
## 2.66.0 – August 2026
### Neu
- 📦 **Sets im Katalog.** Der Dateiimport nimmt jetzt auch BrickLinks
`Sets.xml` – bisher warf er alles weg, was keine Minifigur war, und
meldete „Gebraucht wird der Download mit Item Type Minifigures".
Das war 2.46.1 richtig: Damals hatte eine `Parts.xml` 118.000 Steine als
Minifiguren in den Abzug gespült, und es gab keinen Ort, an den Sets
gehört hätten. Seit der Katalogliste gibt es einen. Teile und Zubehör
bleiben weiter draußen.
- 🗂️ **Themen für Sets über den Kategoriebaum.** Figuren tragen ihr Thema
in der Nummer – `sw1213` ist Star Wars. Sets nicht: `75192-1` sagt
nichts. Deren Thema steht allein in der BrickLink-Kategorie, und die
kommt als Nummer (129 verschiedene allein bei den Figuren).
Ein einziger Abruf der offiziellen API holt den Baum; danach steht er in
der Datenbank. Unterkategorien landen unter ihrem Dach: „Star Wars ▸
Episode I" gehört zu Star Wars, sonst stünden in der Auswahl hunderte
Zweige mit je einer Handvoll Sets. Der Knopf sitzt unter
*Mehr → Katalog*.
Ohne den Baum bleibt das Thema **leer** statt geraten.
### Behoben
- 🏷️ Eine neue Hilfsfunktion hieß `_katalog_bild` – so wie eine ganz andere,
die weiter unten schon stand. Python nimmt die spätere Definition, und
der Import legte daraufhin lautlos `None` in eine NOT-NULL-Spalte. Ein
Test wacht jetzt darüber, dass kein Name zweimal vergeben ist.
## 2.65.1 – August 2026
### Behoben
- 📦 **„Sets" im Katalog führte in einen leeren Raum.** Der veröffentlichte
Abzug enthält bisher **nur Minifiguren** – null Sets. Der Schalter ließ
sich trotzdem umlegen, und die Meldung dort sagte fälschlich, es sei gar
kein Katalog geladen.
Jetzt ist der Schalter ausgegraut, solange nichts dahintersteht, und die
Meldung nennt den wahren Grund. Drei Gründe für dieselbe leere Seite –
kein Katalog, alle Themen ausgeblendet, keine Sets im Abzug – führen an
ganz verschiedene Enden.
## 2.65.0 – August 2026
### Behoben
- ⏸️ **Ein Serverneustart wirft keine laufende Arbeit mehr weg.** Startet
die Instanz neu – nach einem Update etwa –, laden alle offenen Seiten
neu. Das ist richtig: Sonst liefe alter Programmcode gegen einen neuen
Server. Der Zeitpunkt war es nicht.
Am 29.08.2026 im LEGO-Museum: Beim Scannen lud sich die App mehrmals von
selbst neu. Foto, erkannte Figuren und gezogene Rahmen sind danach weg,
und die Arbeit fängt von vorn an – vor einer Vitrine besonders ärgerlich.
Das Neuladen wartet jetzt, solange etwas offen ist: eine laufende
Reihum-Suche, ein Foto mit Treffern, ein Steckbrief oder die Großansicht.
Eine Leiste sagt, dass eine neue Fassung bereitliegt; geladen wird, sobald
der Weg frei ist. Ein Update kann warten.
## 2.64.1 – August 2026
### Geändert
- 👆 **Der Hinweis unter der Großansicht verspricht kein Wischen mehr,
wenn es nichts zu blättern gibt.** Seit dem Aufräumen der Galerie ist
meist nur ein Bild da – „Wischen zum Blättern" versprach dann eine
Geste, die nichts tut. Mehrere Bilder gibt es in aller Regel erst, wenn
jemand ein eigenes Foto dazugehängt hat. Der Hinweis hängt jetzt an
derselben Bedingung wie die Pfeile.
## 2.64.0 – August 2026
### Behoben
- 🖼️ **Das überflüssige zweite Bild in der Galerie.** Beim Scannen speichert
die App die Adresse, die der Erkenner liefert – bei Brickognize ein
kleines Vorschaubild von einer ganz anderen Adresse. Die Galerie legte
BrickLinks Katalogbild daneben und zeigte damit „1/2" mit demselben
Motiv, das zweite Bild besser als das erste.
Gemessen an einer echten Sammlung: **379 von 910 Einträgen betroffen,
368 davon Vorschaubilder von Brickognize.** Zusammenfassen half nicht –
es sind wirklich zwei verschiedene Quellen.
Die Liste vom Server ist ohnehin vollständig: Sie prüft das Katalogbild
auf Existenz und hängt eigene Fotos selbst an. Das Startbild der Karte
kommt jetzt nur noch dazu, wenn diese Liste leer bleibt – bei eigenen
Figuren, oder wenn BrickLink kein Bild hat.
- 🧹 **Die Reihum-Zeichenfläche blieb liegen.** Wird beim Scannen
„Weitersuchen" angeboten, bleibt die abgesuchte Fläche absichtlich
stehen. Sie wanderte damit aber durch alle Ansichten und in den
Hintergrund mit. Jetzt wird sie beim Verlassen des Scan-Tabs freigegeben –
an derselben Grenze wie das Arbeitsbild, und nicht während eine Suche
läuft.
### Geändert
- 📏 **Der Fehlerbericht misst jetzt Fläche, nicht nur Anzahl.** „12 von 95
Bildern geladen" sagt nichts darüber, ob das zwölf Daumennägel sind oder
zwölf Plakate – entpackt kostet ein Bild Breite × Höhe × 4 Byte, und das
stand in keiner Zahl. Neu daneben: **MPx entpackt**, einschließlich der
Reihum-Zeichenfläche, die als Zeichenfläche in keiner der bisherigen
Zahlen auftauchte.
Anlass ist der Absturz vom 29.08.2026 um 17:31: Der Bericht meldete
7 MB JavaScript-Speicher und 12 von 95 geladenen Bildern – nach allem,
was gemessen wurde, harmlos. Genau deshalb fehlt hier eine Zahl.
## 2.63.0 – August 2026
### Neu
- ⭐ **Katalog-Themen auswählen und mit Sternen versehen.** Unter
*Mehr → 📚 Katalog-Themen* bekommt jedes Thema zwei Schalter: **★** hebt
es in der Auswahl ganz nach oben, **☑/☐** bestimmt, ob es dort überhaupt
erscheint.
Bei 199 Themen war die Auswahl im Katalog-Reiter sonst ein Fass ohne
Boden. Der bequemste Weg: ein paar Sterne setzen, dann **★ Nur
Favoriten** – das blendet alles andere aus.
Die Wahl gehört dem Benutzer, nicht der Instanz: Jeder kann eine ganz
andere haben. Und der Stern überlebt das Ausblenden – wer ein
Thema wieder einschaltet, findet seine Markierung, wo er sie gelassen
hat.
Ist alles ausgeblendet, sagt der Katalog-Reiter das auch. Vorher wäre er
aus demselben Grund leer gewesen wie ohne geladenen Katalog, und man
hätte am falschen Ende gesucht.
### Behoben
- 🖱️ **Schnelle Tipper gingen verloren.** Die ganze Themenwahl steht als
*eine* Zeile in den Benutzereinstellungen. Wer zügig fünf Themen
antippte, schickte fünf Anfragen, die sich überholten: Jede las denselben
alten Stand und schrieb ihr eigenes Thema zurück – vier Änderungen waren
danach weg. Gemessen kam von fünf Tippern einer an.
Lesen, Ändern und Schreiben laufen jetzt am Stück.
- Und ein zweiter Fall derselben Ungeduld: Nach jedem Umschalten wurde die
ganze Liste neu gezeichnet, wodurch die eben angetippte Zeile aus dem
Dokument fiel. Der nächste Tipper ging ins Leere. Jetzt wird nur die eine
Zeile umgestellt.
## 2.62.0 – August 2026
### Behoben
- 🗂️ **Die Themenauswahl gruppiert nach Thema, nicht nach Kürzel.**
Mit den vielen neuen Namen aus 2.61.0 tragen mehrere Kürzel denselben:
Belville läuft bei BrickLink unter vier (`belvbaby`, `belvfairy`,
`belvfemale`, `belvmale`), Scala unter dreien, Duplo unter vieren. Nach
Kürzeln gruppiert stand „Belville" viermal in der Auswahl, und jeder
Eintrag zeigte ein Viertel der 213 Figuren. Ein Fehler, den erst das
Benennen erzeugt hat.
Der Sprungbalken zeigt bei solchen Themen die Kürzel statt der Ziffern –
gekürzt um den gemeinsamen Anfang, weil „BELVFEMALE" auf einem Handy zu
breit ist und die ersten vier Buchstaben ohnehin bei allen gleich sind:
BABY, FAIRY, FEMALE, MALE.
### Neu
- 🥤 **Ein Kürzel kann zwei Themen tragen.** `cc4058` bis `cc4066` sind
Studios-Figuren (Kameramann, Schauspieler, Assistentin), `cc4443` bis
`cc4472` die Coca-Cola-Fußballer der WM-Serie 2002 – dieselben zwei
Buchstaben, weil BrickLink sie über die Artikelnummer der Packung führt
und nicht über das Thema.
Dafür gibt es jetzt Bereichsregeln neben der Kürzeltabelle. Eine eigene
Tabelle statt einer Ausnahme in der Zuordnung: So sieht man beim Lesen
sofort, dass es Bereiche gibt, und der nächste Fall ist eine Zeile.
- 🏷️ Drei weitere Kürzel benannt, alle am BrickLink-Katalog
bestätigt: `game` → Games, `hrf` → Studios (Frankenstein, Vampir,
Werwolf, Mumie) und `cc` → Studios beziehungsweise Coca-Cola.
## 2.61.0 – August 2026
### Behoben
- ↕️ **Der Sprungbalken sprang nur nach unten.** Wer bei Block 15 stand
und auf 08 tippte, blieb stehen.
Die Blocküberschriften kleben (`position: sticky`). Alle schon
durchlaufenen stapeln sich unsichtbar unter der Kopfleiste, und der
Browser meldet für jede von ihnen **diese** Position – über
`getBoundingClientRect` genauso wie über `offsetTop`. Gemessen lagen
Block 08 und Block 15 zwölf Pixel auseinander, obwohl 7.000 Zeilen
dazwischenstehen; der Sprung rechnete daraufhin „bin schon da".
Gemessen wird jetzt an der ersten Zeile hinter der Überschrift. Die
klebt nicht.
Dieselbe verfälschte Zahl hatte zuvor eine Prüfung bestanden: „Ziel bei
57 px" sah nach einem gelungenen Sprung aus und war der Wert, den der
Fehler erzeugt. Der Test prüft deshalb jetzt, **woran** gemessen wird.
- 🏷️ **Noch 100 Themenkürzel benannt** – darunter `fort` (Fortnite), das
beim ersten Durchgang durchfiel, weil nur die 45 größten Gruppen
angesehen worden waren. Jetzt sind alle 115 verbliebenen durchgegangen:
aus „ST" wurde Stranger Things, aus „BLU" Bluey, aus „SCD" Scooby-Doo,
aus „MOF" Monster Fighters. Von 212 Kürzeln im Index tragen 203 einen
Namen.
Nicht benannt bleibt, was die Katalognamen nicht hergeben – etwa `bdp`,
wo Löwenstein-Ritter, ein Hot-Dog-Verkäufer und ein Belagerungstechniker
nebeneinanderstehen.
## 2.60.0 – August 2026
### Behoben
- 🔓 **Die Sperre „Update wird installiert" blieb manchmal für immer
stehen** – nur ein Neuladen von Hand brachte die App zurück.
Die Wache erkennt einen Neustart daran, dass sich der Startzeitpunkt des
Servers ändert. Sie fragte ihn über einen Endpunkt ab, der eine Anmeldung
verlangt. Ging die Sitzung während des Updates verloren, schlug dieser
Aufruf fortan **immer** fehl: Die Seite erfuhr nie, dass der Server zurück
war. Nachgebaut am 29.08.2026 – Token weggenommen, Server getauscht, und
die Sperre stand auch nach Minuten noch.
Version und Startzeitpunkt liegen jetzt zusätzlich unter `/api/laufzeit`,
**ohne Anmeldung**. Geheim ist daran nichts: Die Version steht ohnehin in
jeder ausgelieferten Seite. Alles Weitere – Countdown, Helferzustand, wer
das Update angefordert hat – bleibt geschützt.
Dazu zwei Kleinigkeiten: Die Sperre zeigt nach 20 Sekunden mit, wie lange
sie schon wartet (ein Kasten, in dem sich nichts rührt, sieht nach zwei
Minuten aus wie abgestürzt), und der Knopf „Jetzt neu laden" erscheint
nach drei statt nach acht Minuten.
- 🏷️ **`mar` ist Super Mario, nicht Marvel.** `mar001` ff. sind Boo, Bowser
und Bowser Jr.; Marvel-Figuren laufen bei BrickLink unter `sh` (Super
Heroes). Der falsche Name fiel nie auf, weil die Figur unter dem falschen
Thema genauso aussieht wie überall sonst – erst die Themenauswahl der
neuen Katalogliste stellte die Namen nebeneinander.
Bei der Gelegenheit **44 weitere Kürzel benannt**: Der Index kennt 212,
benannt waren 57. Aus „SOC" wurde Fußball, aus „CRS" Cars, aus „DRM"
DREAMZzz. Aufgenommen wurde nur, was die Katalognamen selbst belegen; wo
sie es nicht taten (etwa `bdp`), bleibt das Kürzel stehen. Ein falscher
Name ist schlechter als gar keiner – er sieht aus, als wüsste man es.
- ↕️ **Der Sprungbalken schnitt den Sprung ab.** Der angesprungene Block
stand ganz am Ende des Geladenen, und weiter als bis zum Dokumentende
kann kein Browser scrollen: Man landete eine halbe Seite zu früh (Ziel
414 px statt 57 px unter der Kopfleiste). Jetzt wird erst genug
darunter nachgeschoben, dann gesprungen – und mit Abstand zur
Kopfleiste, die sonst den Blockkopf verdeckte.
### Neu
- 🔢 **Der Sprungbalken trägt sein Thema im Kopf.** „SW" über „00, 01, 02 …"
liest sich als `sw00xx`; ohne den Kopf waren es nur Zahlen, und danach
wurde prompt gefragt. Der gerade sichtbare Block ist markiert und zieht
beim Scrollen mit – vorher blieb markiert, was man zuletzt angetippt
hatte, und das stimmte nach drei Wischern nicht mehr.
- ⬆️ **Zurück zum Anfang.** Ein runder Pfeil unten rechts, sobald man zwei
Bildschirmhöhen weit unten ist – in jeder langen Liste, nicht nur im
Katalog. In Popups und während der Update-Sperre bleibt er weg.
## 2.59.0 – August 2026
### Neu
- 📚 **Den Katalog durchblättern.** Vierter Reiter unter *Listen*: alle
Figuren eines Themas in Nummernfolge, mit dem eigenen Besitzstand daneben.
Bisher konnte die App nur „wo ist X?" beantworten; die andere Frage –
*was gibt es überhaupt, und was davon fehlt mir?* – ging nur über die
Suche, und die zeigt nur, wonach man gefragt hat.
Sortiert wird nach **Nummer, nicht alphabetisch**. So stehen Varianten
beieinander (sw0001a bis sw0001d) und das Jahr wächst von oben nach unten.
Am rechten Rand liegt ein Sprungbalken mit den Hunderterblöcken – bei
1.663 Star-Wars-Figuren der Unterschied zwischen Suchen und Finden.
**✔** legt die Figur in die Sammlung, **♥** auf die Wunschliste, ein Tipp
auf den Namen öffnet einen Steckbrief. Vier Filter grenzen ein: *Alle*,
*Fehlt mir*, *Hab ich*, *Gemerkt*.
**Ausgehakt wird nur, was nichts wert ist.** Hängt an der Figur eine
Stückzahl über eins oder eine Notiz, sagt die App das und rührt den
Eintrag nicht an. Ein Fehltipper auf einem daumengroßen Knopf darf keine
Kaufpreise wegräumen; Löschen geht in der Sammlung.
Die Liste hält **alle** Zeilen eines Themas im Dokument, lädt aber nur die
Bilder in Sichtweite: bei 1.663 Zeilen sind das rund 26. Umgekehrt zur
Sammlung, wo die Adresse im HTML steht und ein Beobachter hinterher
aufräumt – hier lädt der Beobachter, statt freizugeben. Bei 80 Zeilen je
Nachschub-Schritt wären es sonst 80 Bilder auf einen Schlag, von denen 60
sofort wieder wegkämen. Entpackte Bilder liegen außerhalb des
JavaScript-Speichers und haben in der Sammlung wiederholt den Tab
umgebracht.
### Geändert
- Das Popup einer Katalogzeile nimmt **denselben Daumennagel** wie die Zeile
darüber. Bei 180 px Anzeige sieht man keinen Unterschied, aber der Browser
hat das Bild schon und lädt kein zweites.
## 2.39.0 – August 2026
### Neu
- 🔄 **Der Katalogabzug zieht Änderungen von BrickLink nach.** Er entsteht,
indem Nummern der Reihe nach abgeklappert werden – sw0001, sw0002, … –, und
danach steht der Zeiger hinter der höchsten gefundenen Nummer. Neue Figuren
werden so gefunden, eine **Umbenennung nie**: Eine bekannte Nummer wurde
kein zweites Mal abgefragt.
Naheliegend wäre, den Abzug reihum neu abzufragen. Das wären 9.741 Abrufe,
gut zweieinhalb Stunden, und das BrickLink-Kontingent teilt sich der Lauf
mit den Preisen. Der Change Log leistet dasselbe für eine Handvoll
HTML-Seiten und **ohne Kontingent** – im August 2026 waren es 12 umbenannte
Minifiguren im ganzen Monat.
Der Leser dafür war schon da, zeigte aber in die andere Richtung: Er wurde
nur befragt, wenn ein Artikel aus der *Sammlung* verschwunden war. Jetzt
liest er zusätzlich Namensänderungen (`viewAction=N`) und schreibt Name,
Suchtext und Nummer im Katalogindex fort. Läuft alle zwölf Stunden mit.
Die Sammlung bleibt bewusst unangetastet: Für Figuren, die jemand besitzt,
gibt es weiterhin die Benachrichtigung mit „Nummer übernehmen" – dort
bestätigt ein Mensch die Änderung, statt dass sie still geschieht.
**Gelöschte Figuren sind kein Fall.** Die Log-Seite kennt zwar „Item Marked
for Deletion", aber von Juni bis August 2026 stand dort kein einziger
Eintrag. BrickLink löscht nicht, es legt zusammen oder nummeriert um –
beides steht im Log und wird übernommen.
## 2.38.5 – August 2026
### Behoben
- 🔁 **Eine einzige Figur hielt 9.740 fertige auf.** Der Bilderlauf blieb bei
9.740 von 9.741 stehen. Die letzte offene war `cty0131` – dort verfiel das
Modell im Aufdruck-Feld in „TATATATATA…", die Längengrenze schnitt die
Zeichenkette ab, es begann im nächsten Feld von vorn, und `num_predict`
kappte schließlich mitten im JSON. Unlesbar.
Weil ein Fehlschlag bewusst nichts wegschreibt, stand dieselbe Figur beim
nächsten Griff wieder vorn – zwölf Anläufe, dann beendete die
Ausfallschwelle den ganzen Lauf.
Zwei Dinge, die gleich aussahen, werden jetzt getrennt: „gar nicht
geantwortet" ist ein Ausfall des Dienstes und hakt weiterhin nichts ab –
sonst gälte der halbe Katalog als angesehen, ohne dass je jemand
hingesehen hat. „Geantwortet, aber unlesbar" ist figurenspezifisch: Nach
drei Anläufen wird die Figur ohne Ergebnis abgehakt, und der Lauf kommt
ans Ende.
### Geändert
- ⚡ **Wiederholungsbremse für die Bildanalyse.** Ollama fährt ohne
(`repeat_penalty` 1.0), und bei `temperature: 0` gibt es aus einer
Schleife dann keinen Ausweg. Mit 1.1 antwortet dieselbe Figur in 3,5 s
statt 12,6 mit gültigem JSON.
Der Nebeneffekt ist größer als die Behebung: An sechs Vergleichsfiguren
blieben Art und Farben gleich, die Laufzeit **halbierte sich** (8–9,7 s
auf 2,4–4,3 s). Das Modell polstert nicht mehr aus.
## 2.38.4 – August 2026
### Behoben
- 🔢 **„Alle Bilder angesehen", obwohl 8.328 offen waren.** Die Statusanzeige
meldete null offene Figuren, während erst 1.413 von 9.741 eine Beschreibung
hatten.
`offen` stand im Laufzustand des Bilderlaufs – einem Wörterbuch im
Arbeitsspeicher – und wurde nur *während* eines laufenden Durchgangs
gefüllt. Nach jedem Neustart des Containers stand dort wieder 0, und an
diesem Tag wurde dreimal ausgerollt.
Eine Null, die „fertig" bedeutet, ist die unangenehmste Sorte Fehler: Sie
sieht aus wie ein Erfolg, und niemand sucht nach ihr. Die Zahl beschreibt
die Daten, nicht den Lauf – sie wird jetzt bei jeder Abfrage frisch
gezählt.
## 2.38.3 – August 2026
### Behoben
- 🥇 **Der goldene Droide stand auf Platz 6.** „goldener Droide" ergibt vier
übersetzte Begriffe – `Gold Droid`, `C-3PO`, `Droid`, `Gold` –, und die
Suche arbeitete sie nacheinander ab. Der erste traf fünf Astromechs mit
zufälligen Goldanteilen (ein goldener Helmstreifen bei R5-D4, ein goldener
Torso beim ASP Droid), und C-3PO kam erst danach.
Die Sortierung nach Wortzahl bleibt richtig – ohne sie liefe `Minifigure`
vor `Knight`, und in einer echten Sammlung stand daraufhin Greedo unter den
Rittern (2.28.1). Sie sagt aber nur, welcher Begriff **anfängt**, nicht,
dass er alle Plätze bekommt: Wortreicher heißt eingegrenzter, nicht
treffender.
Die Treffer werden jetzt reihum genommen – je Runde höchstens zwei pro
Begriff, dann ist der nächste dran. Kein Begriff verhungert mehr hinter
einem anderen, die Reihenfolge bleibt erhalten, und die UND-Logik innerhalb
eines Begriffs ist unangetastet. Gilt für Sammlung und Katalog.
## 2.38.2 – August 2026
### Behoben
- 🔍 **„Ritter" fand Luke Skywalker.** Die Katalogsuche lieferte auf „Ritter"
drei Figuren, die keine sind: Luke Skywalker (Tatooine), einen Imperial
Royal Guard und den siebenjährigen Boba Fett. Alle drei trugen
`art='knight'` – die vom Bildmodell geratene Art der Figur, die
gleichberechtigt neben dem Namen im Suchtext stand.
Das ist derselbe Fehler wie „Greedo unter den Rittern" in 2.28.1, nur
durch eine andere Tür: Dort war es die Sortierung, hier eine Vermutung mit
dem Gewicht einer Tatsache. Ein einziges Wort für die ganze Figur, und die
Kategorien sind breit genug („Knight", „Alien", „Soldier"), um ständig mit
deutschen Suchbegriffen zu kollidieren.
Naheliegend wäre, dem Bildmodell Name und Thema mitzugeben, damit es
besser rät. Gemessen an denselben drei Figuren verschwand „Knight"
daraufhin zwar, wurde aber durch „Pilot" bzw. „Soldier" ersetzt – zwei von
drei blieben falsch, und nebenbei kippte Boba Fetts Haarfarbe von
„schwarz" (richtig) auf „dunkelblau".
Deshalb steht im Suchtext jetzt nur noch, was entweder Katalogwahrheit ist
(der Name) oder beobachtet (Farben und Teilbeschreibung). Geraten wird
dort nicht mehr. `art` bleibt in der Datenbank – für die Anzeige taugt es,
als Suchbegriff nicht.
## 2.38.1 – August 2026
### Behoben
- 🔁 **Der Bilderlauf blieb an einer einzelnen Figur hängen – und gab dann
ganz auf.** Bei `sw0326` brach die Analyse jedes Mal nach exakt 120 s ab.
Nach fünf solchen Figuren beendete sich der komplette Lauf; 9.000 Figuren
blieben unbearbeitet liegen.
Die naheliegende Erklärung – zu wenig Speicher auf dem Mac mini – war
falsch, und die exakte Wiederholung von „2m0s" hätte das verraten müssen:
Eine Ladeverzögerung streut, eine harte Zeitgrenze auf einer nie endenden
Antwort nicht. Das Modell lud in 3,8 s, verarbeitete das Bild in 2,8 s und
schrieb dann 15.190 Token am Stück – 436 Sekunden lang eine Endlosschleife
**innerhalb einer einzigen Zeichenkette**:
"...and a dark blue stripe on the upper part of the legs, and a dark
blue stripe on the lower part of the legs, and a dark blue stripe ..."
Die Teileliste hielt ihre sechs Einträge ein – Arrays begrenzte das Schema
also. Die Länge einer Zeichenkette begrenzte es nicht, und bei
`temperature: 0` mit `repeat_penalty` 1.0 gibt es aus so einer Schleife
keinen Ausweg. Die Grammatik muss sie verhindern.
Jetzt hat jede Zeichenkette im Schema eine Höchstlänge. Dieselbe Figur:
**4,1 s statt 436**, mit brauchbarem Ergebnis. Ein Ausreißer wird dabei
mitten im Wort abgeschnitten – gewollt: Ein angeschnittenes Merkmal ist
Suchtext, eine hängende Anfrage kostet den ganzen Lauf. Dazu kommt eine
Notbremse (`num_predict`), die großzügig über einer vollständigen Antwort
liegt; ein Test rechnet das gegen die Längen im Schema nach.
### Geändert
- ⏱️ **Der Bilderlauf hält mehr aus.** Er gab nach fünf Fehlschlägen in Folge
auf – passend für einen Lauf über Minuten, zu wenig für den ersten
vollständigen über Stunden. Ein Moment, in dem Home Assistant sich das
Textmodell in den Speicher holt, genügte. Jetzt sind es zwölf, und
entscheidend: mit 20 s Pause dazwischen statt 0,3 s. Vorher brannten fünf
Versuche in anderthalb Sekunden durch, während Ollama noch lud. Ein echter
Ausfall wird weiterhin erkannt – er dauert nun vier Minuten.
## 2.36.0 – August 2026
### Behoben
- 🔢 **Der Katalog-Abzug fand halbe Themen gar nicht.** Er fragte fest nach
vier Ziffern (`cas0001`) – die Burgfigur heißt aber `cas001`. Damit gingen
`cas`, `pi`, `hp`, `jw`, `sp`, `ww`, `lor` und `iaj` **komplett leer** aus,
und das Tückische: Der Lauf meldete nach fünfundzwanzig Fehlgriffen brav
„fertig". Von außen sah es aus, als gäbe es diese Themen nicht.
Die Breite wird jetzt zu Beginn jedes Themas mit ein paar Abrufen
ermittelt. Ein `429` beendet dabei auch die Erkennung – sie als „gibt es
nicht" zu lesen hieße, bei erschöpftem Kontingent munter weiterzufragen.
### Neu
- 📚 **Die Themenliste ist jetzt vollständiger.** Statt sieben geratener
Präfixe stehen vierzehn gemessene darin: `sw`, `cty`, `njo`, `sh`, `frnd`,
`gen`, `iaj`, `cas`, `pi`, `hp`, `jw`, `sp`, `ww`, `lor`.
Ermittelt über die Bestandteile bekannter Sets – eine Liste der Präfixe
gibt BrickLink nicht heraus, und die Katalogseite darf man nicht
auslesen. Dabei kam auch heraus: Präfix ist **nicht** Kategorie. `cty`
deckt „Town" und „Train" ab.
Vollständig ist auch das nicht; weitere trägt man einfach dazu.
## 2.35.2 – August 2026
### Behoben
- 🔘 **„Cannot set properties of null (setting 'disabled')".** Aus dem
Betrieb gemeldet, aus dem Abbrechen-Knopf der Update-Leiste: Der Handler
schaltet den Knopf ab, wartet auf die Antwort und schaltet ihn wieder
ein – nur ist `ev.currentTarget` dann **null**. Der Browser räumt es auf,
sobald der Handler das erste Mal zurückkehrt, und das ist beim ersten
`await`.
Der Knopf wird jetzt vor dem `await` festgehalten. Dieselbe Stelle gab es
ein zweites Mal beim anteiligen Verteilen eines Gesamtpreises auf eine
Einkaufsliste – dort ausgerechnet im Fehlerzweig, wo der Knopf hängen
blieb und die Fehlermeldung verschluckt wurde.
Ein Test sucht das Muster im ganzen Frontend, damit es nicht wieder
hineinwächst.
## 2.35.1 – August 2026
### Behoben
- 🌍 **Die Merkmale aus dem Bild waren deutsch – und trafen deshalb nie.**
2.35.0 legte „rot" und „droide" ab. Gesucht wird aber mit den Begriffen
aus der Übersetzung, und die sind **englisch** („Red Protocol Droid").
Die beiden konnten sich nicht begegnen.
Selbst die rohe deutsche Frage half nicht: „roter Protokolldroide" trifft
„rot" nicht, weil die Beugung dazwischensteht. Deutsche Wortformen sauber
aufeinander abzubilden wäre ein eigenes Projekt.
Jetzt fragt die App auf Englisch und legt englisch ab – der Index ist
einsprachig, und die Übersetzung greift wie überall sonst. Nebenbei
antwortet `qwen3-vl` auf Englisch besser: beim Wookiee „Wookiee" statt
nur „Alien".
Damit greift auch die Genauigkeit wie erwartet: „roter Protokolldroide"
findet den roten und **nicht** den grauen, weil alle Wörter des Begriffs
vorkommen müssen.
## 2.35.0 – August 2026
### Neu
- 🎨 **Auch die Art der Figur kommt jetzt aus dem Bild**, nicht nur die
Farbe. „Soldat", „Droide", „Alien" – vieles davon steht in keinem Namen:
`R-3PO Protocol Droid` nennt keine Farbe, `Wicket (Ewok)` keine Art. Erst
mit beidem findet „roter Droide", was gemeint ist.
**Das ist eine Rücknahme.** 2.34.0 fragte bewusst nur nach Farben, weil
`minicpm-v` die Art in zwei von drei Proben verfehlte und Darth Vader für
einen Droiden hielt. Diese Messung stammte aus einer Zeit, in der es das
beste verfügbare Modell war. Mit `qwen3-vl` sieht es anders aus: an zehn
echten Figuren aus dem Abzug **zehn Treffer** – Stormtrooper → Soldat,
Wookiee → Alien, R2-D2 → Droide, Luke im Fluganzug → Pilot, Yoda → Alien,
Leia → Mensch.
Die Einschränkung hing also am Modell, nicht an der Aufgabe. Wer ein
schwächeres einstellt, bekommt entsprechend schwächere Antworten – die
landen dann als Rauschen im Suchtext. Das ist der Preis der freien Wahl
und steht so im Handbuch.
Art und Farbe stehen in getrennten Spalten, damit sich eines verwerfen
lässt, ohne das andere zu verlieren.
## 2.34.1 – August 2026
### Behoben
- 🧠 **Denkmodelle antworten woanders hin.** `qwen3-vl` legt seine Antwort
in `thinking` ab; `content` bleibt leer, und `think: false` ändert daran
nichts. Für die App sah das aus, als liefere das Modell gar nichts –
ausgerechnet das beste Bildmodell im Haus wirkte kaputt, obwohl die
richtige Antwort dastand, nur im falschen Feld.
Ist `content` leer, wird jetzt `thinking` gelesen. Wo beides steht, zählt
weiter `content`: Das Denkfeld ist der Notnagel, nicht die Quelle.
Gemessen am 21.08.2026 gegen dieselben drei Figuren – `qwen3-vl` erkennt
R-3PO als Droiden, den AT-AT-Fahrer als Soldaten und Darth Vader
**namentlich**, bei richtigen Farben in allen drei Fällen. `gemma3:12b`
liegt knapp dahinter, `qwen2.5vl:7b` und `minicpm-v` deutlicher.
## 2.34.0 – August 2026
### Neu
- 🎨 **Farben aus den Katalogbildern.** Zweiter Durchgang nach dem Abzug:
Die lokale KI sieht sich die Bilder an und schreibt die Farben dazu. Viele
BrickLink-Namen nennen keine – „R-3PO Protocol Droid" sagt nirgends „rot".
Danach findet „roter Protokolldroide" beides: die Art aus dem Namen, die
Farbe aus dem Bild.
**Nur Farben, mit Absicht.** Nach der Art der Figur gefragt, lag
`minicpm-v` in keiner von drei Proben richtig, `gemma3:12b` in zwei –
und die Art steht ohnehin schon im Namen. Sie hier noch einmal raten zu
lassen brächte nur Fehler hinein.
Auch ein leeres Ergebnis wird festgehalten, sonst versuchte der nächste
Lauf dieselbe Figur wieder und käme nie ans Ende.
- 🖼 **Das Modell fürs Bilderansehen ist getrennt einstellbar.** Übersetzen
und Bilder ansehen sind verschiedene Aufgaben, und die besten Modelle
dafür sind verschiedene.
In beiden Listen stehen nur noch **sinnvolle** Modelle: Code-Modelle
fallen raus. Für Bilder stehen die bildfähigen oben und tragen ein 👁.
**Sortiert, nicht gefiltert** – `gemma3:12b` meldet Ollama gegenüber gar
keine Bildfähigkeit und ist trotzdem das beste im Haus. Wer hart nach dem
Merkmal filtert, versteckt den Sieger.
### Behoben
- 📚 **Der Abzug speicherte keine Bildadresse.** Treffer aus dem eigenen
Abzug wären ohne Bild geblieben, obwohl BrickLink sie in derselben
Antwort mitliefert. Bestehende Zeilen werden beim Start nachgetragen –
ohne einen einzigen zusätzlichen Abruf, denn die Adresse folgt der Nummer
(und der Bildserver unterscheidet nicht zwischen Groß- und
Kleinschreibung). Fehlt sie in der Antwort, wird sie ebenso gebildet.
## 2.33.1 – August 2026
### Behoben
- 📚 **Die Karte des Katalog-Abzugs sprach noch von Star Wars.** Sie hieß
„Katalog-Abzug (Star Wars)" und versprach „rund 25 Minuten" – beides war
seit 2.33.0 falsch: Sie kann alle Themen, und die 25 Minuten stammten aus
einer Schätzung mit 0,5 s je Abruf.
Gemessen sind es **0,38 Abrufe je Sekunde** – BrickLink antwortet unter
Dauerlast langsamer als bei Einzelabfragen. Das heißt rund **eine Stunde
je 1.500 Nummern**, für alle sieben Themen zusammen etwa fünf. Handbuch
und Oberfläche nennen jetzt diese Zahl.
## 2.33.0 – August 2026
### Neu
- 📚 **Der Katalog-Abzug kann mehrere Themen.** Bisher stand `sw` fest im
Knopf. Jetzt trägt man sie mit Komma ein – `sw, cty, njo` – und sie laufen
**nacheinander** ab, mit Fortschritt und Warteschlange in der Anzeige.
Nacheinander, nicht nebeneinander: Alle Läufe teilen sich denselben
BrickLink-Zugang. Zwei gleichzeitig hieße doppelter Takt – die Drosselung
wäre ausgehebelt, für die es hier gute Gründe gibt.
Bricht ein Lauf mit einem Kontingentfehler ab (`429`), bleiben auch die
folgenden Themen stehen. Der Zugang ist derselbe; weiterzumachen würde das
Problem nur verlängern.
Als Präfix sind nur Buchstaben zugelassen – es wandert in eine Adresse,
und `../` hätte dort nichts zu suchen.
Gemessene Größenordnungen: `cty` über 2.000 Nummern, `njo` und `sh` je
1.000–2.000, `cas`, `hp` und `col` je unter 500. Beim gemessenen Takt von
0,38 Abrufen je Sekunde sind das für alle zusammen rund fünf Stunden –
abbrechbar und fortsetzbar, also gut über mehrere Abende zu verteilen.
## 2.32.0 – August 2026
### Neu
- 📚 **Ein eigener Abzug des BrickLink-Katalogs (Star Wars).** Damit findet
die Suche endlich, was man nur beschreiben kann: „Protokolldroide" führt
zu `R-3PO Protocol Droid`. Über den gewöhnlichen Katalog ging das nicht –
Rebrickable nennt dieselbe Figur schlicht `R-3PO`, ohne ein einziges Wort
zum Suchen. Kein Modell muss dafür etwas wissen; gesucht wird in eigenem
Text.
Der Abzug läuft die Nummern der Reihe nach ab (`sw0002`, `sw0003`, …).
Eine Auflistung einer Kategorie bietet BrickLink nicht an – geprüft: dort
gibt es nur das Nachschlagen einer einzelnen Nummer. Gemessen liegen die
Nummern dicht: Von `sw0002` bis etwa `sw1500` fehlt praktisch keine.
**Gedrosselt auf einen Abruf je Sekunde**, rund 25 Minuten. Das ist keine
Höflichkeit gegenüber BrickLink, sondern Selbstschutz: Es ist derselbe
Zugang, über den die Preise laufen. Ein Durchlauf mit Vollgas könnte das
Tageskontingent aufbrauchen – und dann stünde der Scanner ohne Preise da.
Jederzeit anhaltbar, der Fortschritt bleibt: Zwanzig Minuten Arbeit dürfen
nicht verfallen, nur weil jemand gestoppt hat. Lücken in der Nummerierung
beenden den Lauf nicht (25 am Stück gelten als Ende), ein anderer Fehler
als „gibt es nicht" dagegen sofort – `429` heißt Kontingent erschöpft, und
stur weiterzulaufen machte das schlimmer.
Findet der eigene Abzug etwas, wird Rebrickable gar nicht mehr gefragt.
### Behoben
- Der Vorfilter der Abzugssuche benutzte den rohen Namen, der Vergleich
danach die satzzeichenfreie Form – „c3 po" fand `C-3PO` deshalb nicht,
weil `LIKE '%c3%'` am Bindestrich scheitert. Beide benutzen jetzt dieselbe
Elle.
## 2.31.1 – August 2026
### Geändert
- 📖 **Die gelernten Begriffe haben ein eigenes Fenster.** In den
Einstellungen stand die vollständige Liste – bei ein paar Zeilen ging das,
aber sie wächst mit jedem Suchlauf, und ein geplanter Durchlauf über die
BrickLink-Nummern brächte Tausende auf einen Schlag. Die Einstellungen
wären damit unbrauchbar geworden.
Dort steht jetzt nur die Bilanz („38 Begriffe gelernt, davon 12 eigene").
**Ansehen und pflegen** öffnet die Liste mit Suchfeld, seitenweise zu 25.
Gesucht wird in beiden Richtungen: „ritter" über den deutschen Begriff,
„Knight" über das, was dabei herauskommt – wer eine Zeile korrigieren
will, weiß mal das eine und mal das andere.
Die Bilanz gilt dabei immer für alles, nie für die gefilterte Sicht: Sonst
sagte „12 eigene" plötzlich etwas anderes, nur weil jemand etwas ins
Suchfeld getippt hat.
Die Liste trägt jetzt dieselbe Laufnummer gegen überholte Antworten wie
die Katalogsuche. Wer sofort nach dem Öffnen tippt, löst eine zweite
Abfrage aus, während der Erstaufbau noch läuft – käme der später zurück,
überschriebe er das gefilterte Ergebnis.
## 2.31.0 – August 2026
### Neu
- 📖 **Die Suche lernt – und du kannst ihr etwas beibringen.** Die Zuordnung
„deutscher Begriff → englische Katalogbegriffe" lag bisher nur im
Arbeitsspeicher: nach jedem Neustart weg, nur vom Modell beschrieben, für
niemanden einsehbar. Wer „roter c3po" tippte, bekam für immer
C-3PO-Varianten – obwohl die gesuchte Figur „R-3PO Protocol Droid" heißt.
Unter **Mehr → 🤖 Lokale KI** steht die Liste jetzt offen da. Jede
erfolgreiche Übersetzung wandert automatisch hinein, eigene Zeilen trägst
du selbst ein:
Gesucht wird nach: roter c3po
Finden soll er: R-3PO
Drei Entscheidungen stecken darin:
- **Das Gelernte hängt an der App, nicht am Modell.** Ein Wechsel des
Modells oder des Rechners nimmt den Wissensstand mit; ein
nachtrainiertes Modell täte das nicht. Deshalb gelten eigene Zeilen auch
dann, wenn gar keine KI eingerichtet ist.
- **Die KI überschreibt eine eigene Zeile nicht.** Sonst wäre das
Beigebrachte beim nächsten Suchlauf wieder weg.
- **Fehlschläge werden nicht gelernt.** Ein leeres Ergebnis ist kein
Wissen; dauerhaft gespeichert stellte es den Begriff für immer tot.
Nebenbei wird die Suche deutlich schneller: Ein bekannter Begriff kostet
**4 Millisekunden statt 1,6 Sekunden**, weil das Modell gar nicht erst
gefragt wird.
### Geändert
- Ein Wechsel der KI-Adresse leert weiterhin den Zwischenspeicher, fragt das
Modell aber nicht erneut nach bereits Gelerntem – das steht ja in der
Liste. Taugt eine Zeile nichts, löscht man sie sichtbar, statt sie stumm
neu raten zu lassen.
## 2.30.1 – August 2026
### Behoben
- 🔇 **Die Katalogsuche endete stumm.** Wer beim manuellen Erfassen einen
Begriff eintippte, der nichts fand, bekam **gar keine Meldung** – nicht
einmal „Nichts gefunden". Man wusste nicht, ob noch gesucht wird, ob die
KI dran ist oder ob etwas kaputt ist.
Die Ursache stand schon länger im Code: `renderSuggestions` setzt bei
leerer Liste selbst „Nichts gefunden …", und eine Zeile später löschte ein
pauschales `hint.hidden = true` die Meldung wieder – ohne Ansehen des
Ergebnisses. Jetzt wird der Hinweis nur weggenommen, wenn es Treffer gibt.
Zwei weitere stumme Ausgänge kamen mit 2.29.0 dazu: Fand die KI nichts
oder fiel sie aus, blendete der Zweig den Hinweis ebenfalls aus. Beide
hinterlassen jetzt wieder die „Nichts gefunden"-Meldung.
Und ohne eingerichtete Katalogsuche steht endlich da, warum nichts
passiert, statt dass man tippt und ins Leere schaut.
Geprüft am laufenden Programm, alle vier Wege: kein Katalog, KI ohne
Treffer, KI ausgefallen, KI erfolgreich.
## 2.30.0 – August 2026
### Neu
- 📋 **Das KI-Modell wird ausgesucht, nicht abgetippt.** Der Name musste
exakt so eingetragen werden, wie Ollama ihn führt – `qwen2.5:14b`, nicht
`qwen2.5-14b` und nicht `qwen 2.5`. Ein Tippfehler sah dabei aus wie ein
kaputter Dienst: Die Verbindung stand, nur das Modell gab es nicht. Auf
dem Server im Haushalt liegen 14 Stück, darunter `qwen2.5:14b` **und**
`qwen2.5:14b-instruct` – die Verwechslung ist keine Theorie.
Steht die Adresse, holt die App jetzt die Liste der installierten Modelle
und stellt sie zur Wahl. **Modelle laden** holt sie erneut, etwa nach
einem `ollama pull`.
**Kein `datalist`.** Der wäre der kürzere Weg gewesen, aber iOS zeigt ihn
bis heute nicht an – und dort wird die App am meisten benutzt. Also eine
echte Auswahlliste.
**Das Textfeld bleibt.** Schweigt der Dienst oder ist die Adresse noch
nicht gespeichert, übernimmt es wie bisher; die Auswahl ist eine
Bequemlichkeit, kein Zugangsweg. Auch abfragen lässt sich eine noch nicht
gespeicherte Adresse – sonst müsste man erst eine ungeprüfte Einstellung
sichern, um zu sehen, was dort zur Wahl steht.
Ein bereits gespeichertes Modell bleibt wählbar, auch wenn es nicht mehr
auf dem Server liegt – sonst überschriebe ein Speichern still eine noch
gültige Einstellung.
## 2.29.0 – August 2026
### Neu
- 🤖 **Die KI-Suche gilt jetzt auch für den Katalog.** 2.28.0 hat die
Übersetzung an die Sammlungssuche gehängt. Ausprobiert wird sie aber
zuerst dort, wo man beim Erfassen tippt: im Feld **Name** unter
„✏️ Manuell erfassen". Das sucht im Katalog, und dort gab es die
Übersetzung nicht – „Roter c3po" blieb leer, und von außen sah das aus,
als funktioniere die KI nicht.
Dabei ist der Katalog der Ort, an dem sie am meisten hilft: In der eigenen
Sammlung kann man notfalls blättern, im Katalog sucht man etwas
Unbekanntes. Ohne Treffer hat man gar nichts.
Findet der Katalog nichts, übersetzt die App und fragt noch einmal nach –
wie in der Sammlung mit dem genauesten Begriff zuerst, sortiert nach
Wortzahl und ausdrücklich nicht nach Länge (daran hing 2.28.1). Über den
Treffern steht, wonach zusätzlich gesucht wurde.
**Höchstens zwei Versuche.** In der Sammlung kostet ein Begriff mehr fast
nichts, die Einträge liegen im Speicher. Hier ist jeder Versuch eine
eigene Anfrage an Rebrickable – mehr Wartezeit beim Tippen und mehr Last
auf einem fremden Kontingent. Zwei decken den Anlassfall ab („roter c3 po"
→ `C-3PO`, dann `C-3PO red`), ohne aus einer Suche fünf zu machen.
Unverändert gilt: Das Modell liefert **Suchbegriffe, niemals Ergebnisse**.
Jede Zeile kommt weiter von Rebrickable, ein erfundener Begriff findet
dort nichts. Antwortet der Katalog beim Zusatzversuch nicht, bleibt es bei
der leeren Liste – ein Fehlschlag der Zugabe ist kein Fehler der Suche.
## 2.28.1 – August 2026
### Behoben
- 🎭 **Greedo stand unter den Rittern.** Beim ersten Einsatz an einer echten
Sammlung (888 Figuren) zeigte die neue KI-Suche für „Ritter" neun Treffer –
darunter Greedo und Obi-Wan. Für „Zauberer" kam ein kampfbeschädigter
Anakin Skywalker. Zwei Ursachen, beide in der Testsammlung unsichtbar, weil
dort schlicht nichts so hieß:
**Die Länge war das falsche Maß für Genauigkeit.** Das Modell liefert für
„Ritter" die Begriffe `Knight, Minifigure, Hero, Character`. Sortiert wurde
nach Wortzahl *und Länge* – damit lief `Minifigure` (10 Zeichen) vor
`Knight` (6) und griff sich als Erstes alles, was „Minifigure" im Namen
trägt. Innerhalb gleicher Wortzahl bleibt jetzt die Reihenfolge des Modells
stehen; es nennt den Eigennamen zuerst.
**„Mage" steckt in „Damaged".** Damit „c3 po" den Artikel „C-3PO" findet,
wirft der Vergleich Satzzeichen weg – und verlor dabei die Wortgrenze. Ein
Begriff muss jetzt dort stehen, wo auch ein Wort anfängt. Bindestrichnamen
bleiben trotzdem auffindbar.
## 2.28.0 – August 2026
### Neu
- 🤖 **„Ritter" fand nichts, obwohl die Figuren im Regal lagen.** Die
Oberfläche ist deutsch, die Namen in der Sammlung kommen von BrickLink und
sind **englisch**. Die Suche war ein reines `LIKE '%…%'` auf Name und
Nummer – wer „Ritter" eintippte, bekam eine leere Liste, obwohl die Figur
als „Castle Knight" in der eigenen Datenbank steht. Das war kein Randfall,
sondern die naheliegendste Suche eines deutschen Nutzers. Dasselbe galt für
„Kopf" (Head), „Schwert" (Sword) und „Piraten" (Pirate).
Findet die Suche nichts, fragt die App jetzt eine **optionale** lokale KI
nach englischen Begriffen und sucht damit erneut. Über den Treffern steht,
wonach zusätzlich gesucht wurde – gemeldet werden nur Begriffe, die
wirklich etwas gefunden haben.
**Die KI liefert Suchbegriffe, niemals Ergebnisse.** Jede angezeigte Zeile
kommt weiter aus der eigenen Datenbank; ein erfundener Begriff findet
schlicht nichts. Deshalb genügt hier ein kleines Modell auf dem eigenen
Rechner, und deshalb kann die Funktion nichts erfinden, was es nicht gibt.
Einzurichten unter **Einstellungen → Lokale KI für die Suche** mit der
Adresse eines [Ollama](https://ollama.com) und einem Modellnamen
(Vorgabe `qwen2.5:14b`), wahlweise über `OLLAMA_URL` und `OLLAMA_MODEL` aus
der `docker-compose.yml`. **Ohne Adresse ist alles wie vorher** – nicht
jeder betreibt eine lokale KI. Antwortet der Dienst nicht innerhalb von
acht Sekunden, bleibt es beim gewohnten Hinweis „Nichts gefunden".
Die Adresse wird wie ein API-Schlüssel aus Fehlerberichten entfernt: Sie
verrät den Aufbau des Heimnetzes und kann Zugangsdaten enthalten, und ein
Fehlerbericht kann als öffentliches Issue enden.
**Satzzeichen zählen nicht mit.** BrickLink schreibt die bekanntesten
Figuren mit Bindestrich – `C-3PO`, `R2-D2` –, getippt wird „c3 po" oder
„r2d2". Der Vergleich lässt deshalb alles außer Buchstaben und Ziffern weg.
Aus mehreren Wörtern müssen **alle** vorkommen, sonst zöge ein erfundener
Begriff wie „Knight Hunter" jeden Ritter herein.
**Der genaueste Begriff zuerst.** „roter c3 po" ergibt `C-3PO (red)` und
`C-3PO`. In der Reihenfolge des Modells sammelte der breite Begriff alle
C-3POs ein, und die Farbvariante kam auf null neue Treffer – die Eingrenzung
verpuffte. Jetzt steht der rote oben, die übrigen darunter als Rückfall.
Gleiche Frage, gleiche Antwort: Ein Zwischenspeicher verhindert, dass beim
Tippen alle 300 ms ein Modellaufruf losläuft. **Ein Fehlschlag verfällt nach
einer Minute** – die erste Fassung merkte ihn sich dauerhaft, sodass ein
einziger Aussetzer (etwa während Ollama das Modell lud) genau diesen
Suchbegriff bis zum Neustart tot bleiben ließ. Damit das seltener vorkommt,
bittet die App Ollama, das Modell 30 Minuten geladen zu lassen.
## 2.27.0 – August 2026
### Behoben
- 💤 **Die Absturzerkennung zählte das Betriebssystem mit.** Wirft iOS eine
App im Hintergrund aus dem Speicher, läuft `pagehide` nicht – für die
Erkennung sah das aus wie ein Abbruch. Das war nicht bloß unsauber, es hat
zwei Wochen Suche in die falsche Richtung geschickt.
Von 23 Abbrüchen im Archiv lagen **15** nach einer Pause von einer bis
achtunddreißig Stunden. Aus einem davon – 15.351 Elemente am 15.08., danach
8,7 Stunden Lücke – entstand die These, die Sammlung sei zu groß. Sie war
es nicht: Am 19.08. hat ein iPhone die Sammlung mit 664 Bildern
durchgescrollt und lief weiter, ein Mac mit 886 Bildern ebenso. Von den
acht verbleibenden echten Abbrüchen kamen sieben in Sitzungen vor, die nie
über 2.000 Elemente hinauskamen.
Die App merkt sich jetzt beim Wechsel in den Hintergrund einen Vermerk und
löscht ihn beim Zurückkommen. Fehlt der Abschied und liegt der Vermerk noch
da, heißt es „im Hintergrund weggeräumt" und zählt in einer eigenen Zeile –
mitsamt der Liegezeit. Die Fälle verschwinden also nicht, sie stehen nur
nicht mehr in derselben Spalte wie die echten Abstürze.
**Ohne Zeitvergleich**, anders als beim Abschiedszettel: Auf dem
Schreibtisch misst ein verborgener Tab gedrosselt weiter, sein letzter
Messwert ist dann jünger als der Vermerk. Auch die Auswertung „wie lange
lief eine Sitzung vor dem Abbruch" lässt diese Fälle jetzt aus – 38 Stunden
im Hintergrund verzerren dort jede Aussage.
## 2.26.3 – August 2026
### Behoben
- 🔍 **Ein Hub-Ausfall hinterließ keine Spur.** Am 13.08.2026 um 10:03 meldete
eine Instanz einen 502 bei `POST /api/hub/trades/sync`. Im Fehlerbericht
stand davon nur „Fehler 502" und der Anfang einer Cloudflare-Fehlerseite.
Die App hatte ihre Erklärung durchaus dabei – „Hub: …" oder „Hub nicht
erreichbar" –, aber der Rumpf ihrer Antwort wurde zwischen Instanz und
Browser durch jene Fehlerseite ersetzt. Der Hub wiederum antwortet nach
außen grundsätzlich nur mit „interner Fehler", damit kein Innenleben nach
draußen geht, und seine eigenen Protokolle wurden nicht aufbewahrt.
Beide Seiten kannten den Grund, keine behielt ihn. Nicht einmal die Frage,
ob der Worker überhaupt zu Wort gekommen war oder etwas davor geantwortet
hatte, ließ sich nachträglich klären – und genau daran hängt, wo man
weitersucht.
Die Instanz schreibt eine Störung des Hubs jetzt selbst ins Protokoll:
Status, Grund und – wenn keine JSON-Antwort kam – den Anfang dessen, was
stattdessen kam. Bei einer Zeitüberschreitung steht dort die Art
(`ConnectTimeout` heißt „nie erreicht", `ReadTimeout` heißt „angenommen und
dann nichts mehr") samt Zeitgrenze. Abgelehnte Anfragen bleiben still: Ein
401 bei falschem Token ist eine Antwort, kein Ausfall. Der Instanz-Token
steht nie in der Zeile.
Im Hub ist zusätzlich die Aufbewahrung der Worker-Protokolle eingeschaltet
(`[observability]`). Ohne sie sah `console.error` nur, wer zufällig gerade
`wrangler tail` laufen ließ.
## 2.26.2 – August 2026
### Behoben
- 🔐 **CSP-Meldungen schleppten ein Access-JWT mit.** Aus einer Instanz kam
zweimal „Vom Browser blockiert: img-src →
flat-leaf-5175.cloudflareaccess.com". Kein Defekt: Die Instanz steht hinter
Cloudflare Access, und ist dessen Sitzung abgelaufen, antwortet Access auf
jede Anfrage – hier das Symbol der Web-App – mit einer Umleitung auf seine
Anmeldeseite. Die liegt auf einem anderen Host, und den erlaubt `img-src`
nicht.
In der Meldung stand bisher die vollständige Adresse samt einem JWT von
rund 1,5 kB. Das ist kein Zugangsschlüssel (ein `meta`-Token mit
`auth_status: NONE`, fünf Minuten gültig), es gehört aber weder ins
Fehlerprotokoll noch in einen Bericht an den Hub. Gespeichert wird jetzt
nur noch Herkunft und Pfad, ein `?…` zeigt an, dass gekürzt wurde.
Außerdem steht bei dieser einen Umleitung dabei, was sie bedeutet:
„(Access-Anmeldung abgelaufen)". Ohne den Hinweis sucht man den Fehler in
der App, obwohl niemand etwas zu reparieren hat.
## 2.26.1 – August 2026
### Behoben
- 🔍 **Die Fremdsuche meldete die eigene Zieh-Anzeige.** In den Berichten einer Instanz
vom 10.08.2026 stand in **jeder** Zeile `FREMD: <div.ptr>` – und das war
die App selbst: die Anzeige für „nach unten ziehen = neu laden", die es
nur beim Start vom Startbildschirm gibt.
Der Grund ist eine Reihenfolge. Beim Laden merkt sich die App, was unter
`<body>` steht; alles, was später dazukommt, gilt als fremd. Die
Zieh-Anzeige entsteht danach und bleibt stehen.
Der Fehler ist nicht die falsche Zeile, sondern was sie verdeckt: Das Feld
soll die seit Wochen offene Frage beantworten, welcher fremde Code im
Renderer sitzt, wenn der Tab stirbt. Solange es in jeder Zeile dasselbe
meldet, liefert es null Information – und sieht dabei aus wie eine
Bestätigung.
Betroffen war nicht nur `div.ptr`: Dialoge, der Kopier-Notausgang und die
Download-Verweise hängen ebenfalls nachträglich an `<body>` und hätten
während einer Messung genauso im Bericht gestanden. Die bisherige Ausnahme
galt nur für das Artikel-Popup und hätte mit jedem neuen Overlay wachsen
müssen. Stattdessen kennzeichnet die App jetzt am Element selbst, was von
ihr stammt – ein Test hält fest, dass keine Stelle das vergisst.
## 2.26.0 – August 2026
### Neu
- 🐞 **Fehlerbericht an den Hub senden.** Der Speicher-Verlauf liegt im
Browser und nirgends sonst – für die Absturzsuche fehlte damit genau das
Stück, das die Frage entscheidet: Stürzt es nur bei **einem** ab (dann
liegt es an dessen Gerät) oder bei **allen** (dann an der App)?
Der Knopf erscheint **nur nach einem erkannten Absturz**. Vor dem Senden
bekommt man wortwörtlich zu sehen, was rausgeht – derselbe Text wie bei
„Verlauf kopieren", aus derselben Funktion. Darin stehen Zeitpunkte,
Speicher, Elemente, Bilder, Version, Design, Ansicht, Gerät und die Namen
fremder Erweiterungen im Fenster; **keine** Artikel, Namen oder Preise.
Nach dem Senden wird der Verlauf auf dem Gerät geleert, damit derselbe
Absturz nicht dreimal ankommt.
**Eigener Token, nicht der des Tausch-Netzwerks.** Das ist keine
Ordnungsliebe: Von vier Instanzen im Haushalt sind zwei Mitglied im
Netzwerk. Hinge der Kanal am Mitgliedskonto, bliebe die Hälfte stumm – und
zwar ausgerechnet die, deren Berichte am meisten erklären würden.
Umgekehrt gibt niemand mit einem Bericht etwas über sein Tauschen preis,
und der Kanal lässt sich einzeln zurückziehen.
**Ohne hinterlegten Token** bietet derselbe Knopf den Bericht zum
Kopieren an, statt stumm zu bleiben.
### Hub (1.5.0)
- Neue Tabellen `report_tokens` und `crash_reports`, der Endpunkt
`POST /v1/crash` **vor** der Mitglieder-Anmeldung, und in der
Admin-Konsole eine Übersicht, die mehrere Berichte nebeneinanderlegt –
samt Auszählung, auf welchen Ansichten sich Abstürze häufen.
## 2.25.0 – August 2026
### Neu
- 🔎 **Der Speicher-Verlauf notiert die geöffnete Ansicht** an jedem
Messwert (`▸ scan`), und die Zusammenfassung sagt, wo die App bei einem
Absturz zuletzt stand: „↳ zuletzt offen war dabei: scan (2×)". Gezählt
wird die Ansicht des **letzten Messwerts davor** – der Starteintrag nennt
die nach dem Neustart und damit die falsche.
Anlass sind zwei bestätigte Abstürze (08. und 09.08.), die beide auf der
Scan-Ansicht passierten, bei identischem Zustand: 7 MB, 1007 Elemente,
6 Bilder. Ob das ein Muster ist oder Zufall, war nicht zu beantworten –
die Ansicht stand nur in der **Spur**, und die behält zwanzig Einträge und
ist nach einem Neustart weg. Jetzt zeigt der dritte und vierte Absturz es
von selbst.
## 2.24.0 – August 2026
### Neu
- 📉 **Größte Wertverluste** in der Statistik, als Gegenstück zu den besten
Wertsteigerungen: die fünf Stücke, bei denen der Kaufpreis am weitesten
über dem heutigen Wert liegt. Ein Tipp auf eine Zeile öffnet den
Steckbrief.
### Geändert
- 📈 **Verluste stehen nicht mehr unter „Beste Wertsteigerungen".** Dort
landeten sie bisher nur dann, wenn es **weniger als fünf Gewinner** gab –
ausgerechnet in einer gewachsenen Sammlung sah man sie also nie, und wenn
doch, dann unter einer Überschrift, die das Gegenteil versprach. Die
Steigerungen zeigen jetzt nur noch Gewinne, die Verluste stehen daneben
## 2.23.0 – August 2026
Vier Funde aus dem vollständigen Funktionstest, die lange liegen geblieben
sind. Keiner davon hat je jemanden umgebracht – gemeinsam ist ihnen, dass
sie **still** danebengehen.
### Behoben
- 👤 **„ " war ein gültiger Benutzername.** Die Längenprüfung zählte die
rohe Eingabe, abgeschnitten wurde erst danach – zwei Leerzeichen kamen
damit durch und landeten als **leerer** Name in der Datenbank. Anmelden
konnte sich damit niemand mehr, und in der Benutzerverwaltung stand eine
namenlose Zeile. Auch Steuerzeichen sind jetzt draußen: Ein Name mit
Zeilenumbruch zerlegt jede Liste, in der er auftaucht. Anlegen, Umbenennen
und Einrichten prüfen ab sofort **gleich** – vorher hatte jede Stelle ihre
eigene, halbe Fassung
- 🖼️ **Gelöschte Artikel ließen ihre Fotos liegen** – die Einträge *und* die
Dateien. Sichtbar war das nirgends, erreichbar auch nicht: Ohne Artikel
gibt es keine Galerie, in der sie auftauchen könnten. Nur der Platz auf
der Platte wuchs. Aufgeräumt wird jetzt, sobald der Artikel **überall**
weg ist – Sammlung, Wunschliste, Einkaufslisten. Eine Aufnahme, die an
mehreren Artikeln hängt, bleibt liegen, solange einer sie noch braucht
- 🔗 **Die Galerie zeigte Bilder, die es nicht gibt.** Findet die
BrickLink-API kein Bild, baut die App eine Adresse aus Typ und Nummer
zusammen – das ist eine Vermutung. Stimmte sie nicht, stand ein leerer
Rahmen zum Durchblättern in der Galerie. Jetzt wird nachgefragt, aber die
Beweislast liegt beim Weglassen: Nur ein klares „gibt es nicht" (404)
wirft die Adresse raus. Zeitüberschreitung oder gar kein Netz heißen
*unbekannt* – dann bleibt die Vermutung stehen, denn eine leere Galerie
wäre schlimmer als ein Bild, das vielleicht lädt
### Geändert
- 💼 **Wer die Instanz einrichtet, ist jetzt auch Sammlerprofi.** Vorher
bekam das erste Konto nur Admin-Rechte und sah damit weder Kaufpreise noch
Einkaufslisten oder Verkaufsliste – freischalten musste man sich in der
Benutzerverwaltung selbst. Ein Einrichtungsassistent, nach dem man sich
erst selbst freischaltet, ist keiner. Alle weiteren Benutzer starten
unverändert als Standard-Konto
## 2.22.0 – August 2026
### Behoben
- 🧮 **Der Speicher-Verlauf erfand Abstürze.** Ein zweiter Tab wurde als
„OHNE ABSCHIED" eingetragen – also als Absturz. Der Abschiedszettel liegt
im localStorage, und der gehört **allen** Tabs derselben Adresse
gemeinsam: Ein frisch geöffneter Tab fand darin keinen frischen Abschied,
während der erste munter weiterlief, und trug sich selbst als Absturz ein.
Im Verlauf vom 06.08. um 23:31:40 stand genau das, und drei Sekunden
später maßen **zwei** Reihen im Abstand von 30 Sekunden weiter. Der alte
Notbehelf (ein Aufruf mehr als 90 Sekunden nach dem letzten Messwert zählt
nicht) griff dort nicht – es waren 27 Sekunden.
Das ist der schlimmste Fehler, den eine Messung haben kann: Sie erfand die
Ereignisse, die sie erklären sollte. Jeder Tab hat jetzt eine eigene
Kennung und meldet ein Lebenszeichen; beim Start wird nachgesehen, ob ein
*anderer* gerade läuft. Dann steht dort **„weiterer Tab"** statt eines
Absturzes. Echte Abstürze werden unverändert erkannt.
### Neu
- 🪟 **Der Verlauf sagt, wenn mehrere Tabs offen sind** („2 Tabs offen").
Alle schreiben in dieselbe Liste, ihre Messwerte wechseln sich also ab –
ohne diese Angabe sah das nach wilden Sprüngen bei Speicher und Elementen
aus. Genau danach hatten wir gesucht.
### Geändert
- 🔍 Der **allererste Eintrag** eines Verlaufs wird nicht mehr bewertet. Er
hat keinen Vorgänger, über dessen Ende sich etwas sagen ließe – stand aber
trotzdem als „OHNE ABSCHIED" da. Die Zählung überspringt ihn längst, die
Anzeige tat es nicht
## 2.21.3 – August 2026
### Behoben
- 🐳 **`sudo bash update.sh` scheiterte auf Synology – nach getaner Arbeit.**
`sudo` bringt einen eigenen, kurzen Suchpfad mit, und dort fehlt
`/usr/local/bin`, wo auf der Synology `docker` liegt. Das Skript lief
deshalb bis zum letzten Schritt durch, legte den Datenbank-Schnappschuss
an, **tauschte den Quellstand auf der Platte aus** – und brach erst dann
mit `docker: command not found` ab. Zurück blieb der schlechteste
Zustand: auf der Platte der neue Stand, im Betrieb der alte Container,
und eine Ausgabe, die bis zur vorletzten Zeile nach Erfolg aussah. Das
Skript ergänzt den Suchpfad jetzt selbst und prüft **vor** dem ersten
Schreiben, ob es `docker` überhaupt gibt – fehlt es, bleibt die Instanz
unangetastet. Über den Aufgabenplaner fiel das nie auf, weil der einen
längeren Suchpfad mitbringt; betroffen war nur der Weg von Hand, den die
App selbst anzeigt
## 2.21.2 – August 2026
### Behoben
- 🪟 **Der Steckbrief ging hinter der Karte auf, aus der er kam.** Die
Figurenliste eines Sets steht im Detail-Fenster einer Sammlungs-Karte
(Ebene 70) – der Steckbrief lag auf der Grundebene der Popups (60) und
damit dahinter. Man sah nur, dass irgendwo etwas aufging. Er liegt jetzt
auf 80: über der Karte, unter der Großansicht, damit ein Tipp auf sein
Bild die Galerie weiterhin davor öffnet
- ⌨️ **Escape schloss beides auf einmal.** Die Detail-Karte bringt einen
eigenen Escape-Empfänger mit. Jetzt schließt jeder Druck nur das oberste
Fenster
- 🔤 **Die Schrift im Steckbrief passte nicht zum Rest.** Die Artikelnummer
stand mit 16 px in voller Textfarbe da statt mit 12,5 px gedämpft wie
überall sonst – fast so laut wie der Name darüber. Grund: `.sub` hat keine
Grundregel, sondern wird immer im Zusammenhang gesetzt, und der Steckbrief
stand außerhalb. Auch die Abschnitte („Marktpreis", „Steckt in diesen
Sets") hatten eigene Größen; sie benutzen jetzt dieselben Klassen wie der
Detailblock einer Karte. Der Name selbst hatte die Browser-Vorgabe für
Überschriften (18,7 px) – bei „Snowtrooper – Male, Printed Legs, White
Hands" eine Wand, jetzt 16 px
## 2.21.1 – August 2026
### Behoben
- 👓 **Das Update-Banner war in Galaxie und Nova nicht zu lesen.** Seine
Fläche ist die Akzentfarbe – in Galaxie ein helles Gelb, in Nova ein
helles Blau –, die Schrift blieb aber die helle des dunklen Designs.
Gemessen waren das **1,22 : 1** (Galaxie) und **1,66 : 1** (Nova); lesbar
wären 4,5 : 1. Ausgerechnet die Meldung, die auffallen soll, war damit
unsichtbar. Jetzt steht dunkle Schrift darauf: 13,2 : 1 und 8,8 : 1
- 🔗 **„Release-Notes ansehen" nahm die Browser-Vorgabe für Verweise.** Auf
der hellen Fläche kaum zu sehen, und einmal besucht vollends weg – im
Bildschirmfoto ein dunkles Rot auf Hellblau. Der Verweis erbt jetzt die
Schriftfarbe des Banners und bleibt über die Unterstreichung als Verweis
erkennbar
## 2.21.0 – August 2026
### Neu
- 👤 **Figuren-Steckbrief: ein Tipp auf die Zeile, und alles steht da.**
Überall, wo eine Figur bisher nur als Zeile auftauchte – unter einem Set in
eurer Sammlung, in der Teileliste, bei den fehlenden Set-Figuren, auf den
Einkaufslisten, auf der Wunschliste, in der Statistik und bei den Doppelten
–, öffnet ein Tipp jetzt den **Steckbrief**: Bild, Nummer, Jahr,
Marktpreise, ob ihr sie habt (Sammlung / Einkaufsliste / Wunschliste), in
welchen eurer Sets sie steckt, dazu + Sammlung, ☆ Merken und BrickLink.
Schließt beim Tippen daneben, mit ✕ oder Escape. Das Bild behält seine
Aufgabe: ein Tipp darauf öffnet weiterhin die Bildergalerie – jetzt auch
aus dem Steckbrief heraus, und Escape schließt erst das Bild, dann den
Steckbrief
### Geändert
- 🛒 **„Auf einer Einkaufsliste" ist jetzt blau statt gelb.** Bisher sah die
Marke genauso aus wie „auf der Wunschliste" – dabei bedeuten die beiden das
Gegenteil voneinander: im Korb gegen fehlt euch. Gleiche Farbe hieß damit
gar nichts. Grün heißt *habt ihr*, blau *ist unterwegs*, gelb *wollt ihr*
### Behoben
- 📷 **„Nur Foto dazu" stand auch da, wenn es den Artikel gar nicht gab.**
Der Knopf hängt ein Foto an einen vorhandenen Artikel – ohne Artikel gibt
es nichts, woran es hängen könnte. Er erscheint jetzt nur noch, wenn das
Stück in eurer Sammlung oder auf einer Einkaufsliste steht. Die
Wunschliste zählt bewusst nicht: Was man sich wünscht, hat man gerade nicht
## 2.20.1 – August 2026
### Behoben
- 🌍 **„30 Artikel haben noch Preise aus einem anderen Gebiet" – obwohl nie
ein Gebiet umgestellt wurde.** Der Zähler füllte sich selbst nach. Kaufte
man einen Wunsch („✔ Gekauft!") oder verbuchte einen angekommenen Posten
von einer Einkaufsliste, wanderten Preis, Zeitstempel und Rohdaten mit in
die Sammlung – **Gebiet und Währung aber nicht**. Der Artikel galt damit
sofort als „fremdes Gebiet", obwohl sein Preis aus genau dem eingestellten
stammte. Nachrechnen half bis zum nächsten Kauf und kostete dabei zwei
BrickLink-Abrufe je Artikel für nichts. Beide Wege reichen Gebiet und
Währung jetzt mit durch; ein Preis, der wirklich aus den USA stammt, wird
weiterhin gemeldet
## 2.20.0 – August 2026
### Neu
- 🛒 **Die Wunschliste sagt jetzt, was schon unterwegs ist.** Steht ein Wunsch
bereits auf einer offenen Einkaufsliste, trägt seine Karte einen blauen
Vermerk „🛒 auf Einkaufsliste: Flohmarkt". Bei mehreren Listen stehen alle
da, mit der zusammengezählten Stückzahl. Abgehakte Posten und archivierte
Listen zählen nicht mit – abgehakt heißt gekauft, archiviert heißt vorbei.
Zusammen mit dem grünen „✔ in eurer Sammlung" beantwortet die Wunschliste
damit auf einen Blick die Frage, die man vor dem Kauf hat: *haben wir das
schon, oder holt es gerade jemand anders?*
## 2.19.2 – August 2026
### Behoben
- 🐞 **„Ein Fehler wurde aufgezeichnet" – und der Bericht war leer.** Wer den
Fehlerbericht leerte, ließ den Zettel dazu stehen. Er zeigte danach auf
einen Fehler, den es nicht mehr gab. Das Leeren räumt die Zettel jetzt mit
weg
- 🔕 **Ein verwaister Zettel machte die App stumm.** Gemeldet wird nur, wenn
kein Zettel offen ist – damit ein Problem nicht zehn Karten übereinander
stapelt. Zeigte der offene aber ins Leere, kam **nie wieder** eine
Meldung. Jetzt blockiert nur noch ein Zettel, dessen Fehler wirklich
existiert; verwaiste werden dabei abgeräumt
> Gefunden auf einer laufenden Instanz: drei Benachrichtigungen vom Typ
> `error`, null Zeilen im Fehlerbericht. Der jüngste Zettel war offen – und
> hätte jede weitere Fehlermeldung verschluckt.
## 2.19.1 – August 2026
### Behoben
- 🔎 **Die Suche nach fremdem Code lief zum falschen Zeitpunkt.** Sie stand
nur in der Startzeile – und die entsteht beim **Laden** der Seite, also
bevor eine Erweiterung ihre Sachen einhängt. Das leere Ergebnis war
deshalb kein Ergebnis, sondern ein Messfehler. Jetzt wird bei jeder
Messung nachgesehen; geschrieben wird nur, wenn etwas da ist
## 2.19.0 – August 2026
### Neu
- 🔎 **Der Bericht nennt jetzt, wer sonst noch in der Seite sitzt.** Bisher
stand dort „Script error." – der Satz, auf den der Browser jeden Fehler
aus **fremden Skripten** zusammenkürzt. Er sagt, *dass* fremder Code lief,
nicht *welcher*. Jetzt stehen die Erweiterungs-Adressen und die
nachträglich eingehängten Elemente daneben, im Fehlereintrag **und** in
jeder Startzeile des Speicher-Verlaufs
> **Warum das jetzt zählt.** Vier ausgewertete Abstürze, vier verschiedene
> Situationen: Listen offen mit 5094 Elementen, zweimal Leerlauf im
> Hintergrund, zuletzt die **leere Scan-Ansicht mit 970 Elementen und 4
> Bildern**. Derselbe Tab hat vorher 14.585 Elemente mit 822 Bildern
> getragen. Kein Maß der App erklärt das – aber fremder Code läuft im
> **selben Renderer-Prozess**, und stürzt der ab, nimmt er die Seite mit,
> ganz gleich wie klein sie ist.
>
> Gemeldet wird nur, nie geblockt: Es ist euer Browser, und eine
> Passwort-Ausfüllhilfe hat dort gute Gründe zu sein.
## 2.18.0 – August 2026
Gefunden beim vollständigen Durchlauf einer frisch aufgesetzten Instanz –
von der Installation bis zur Wiederherstellung.
### Behoben
- 💾 **Das Kaufbuch fehlte in der Sicherung.** `purchases` stand nicht in
`BACKUP_TABLES`. Nach einer Wiederherstellung war es leer, während der
aufsummierte Kaufpreis an der Zeile stehen blieb: Man sah, **dass** etwas
bezahlt wurde, aber nicht mehr wann, wo und wie oft
- 🖼 **Artikel ohne Bildadresse bekamen nie eins.** „🖼 Bilder jetzt holen"
spiegelte nur schon bekannte Adressen auf die Instanz – wer per CSV
importiert, legt aber Zeilen ganz ohne an. Der Lauf meldete „nichts zu
tun", während jede Karte den Platzhalter zeigte. Jetzt schlägt er die
fehlende Adresse erst im Katalog nach
- 💶 **„Preislose erneut abrufen" übersprang die nie versuchten.** In der
Bedingung stand `price_updated_at IS NOT NULL` – gedacht als „schon
versucht, nichts gefunden". Damit blieben ausgerechnet die Artikel außen
vor, die noch nie an der Reihe waren
- 🗂 **CSV: `item_type` galt nicht als Typspalte.** `item_id` zählte als
Nummer, das Gegenstück aber nicht – ein Set landete still als Minifigur,
und Preise, Themen und Filter stimmten danach nie wieder
- 🐞 **Gleichartige Fehler wurden nicht zusammengefasst.** Die Kennung nahm
den **Detailtext** und ließ den **Ort** weg – genau verkehrt herum. Bei
„Script error." steht im Detail die Spur der letzten Schritte, die jedes
Mal anders aussieht: Jedes Auftreten erzeugte einen neuen Eintrag
> **Warum das lange nicht auffiel.** Der übliche Weg führt über Scannen und
> Suchen, und dort kommt schon eine Bildadresse mit, wird schon ein Preis
> geholt, steht schon ein Typ fest. Hineingelaufen ist nur, wer importiert
> oder wiederhergestellt hat.
## 2.17.0 – August 2026
### Behoben
- 🧹 **Die Listen-Ansicht blieb für immer im Dokument stehen.** Ein Blick in
die Einkaufslisten legte bei 310 Artikeln rund **4600 Elemente und 310
Bilder** ab – und die blieben dort, auch wenn längst Sammlung, Statistik
oder Einstellungen offen waren. Für die Sammlung wird seit 2.9 beim
Verlassen geräumt; für die Listen fehlte es
- 📦 **Eine eingeklappte Liste baute ihre Zeilen trotzdem auf.** Sie standen
nur auf `display: none` – unsichtbar, aber vollständig im Dokument. Jetzt
entstehen sie erst beim Aufklappen und verschwinden beim Zuklappen
> Gemessen an 310 Listenposten:
>
> | | vorher | nachher |
> |---|---|---|
> | Listen-Tab, eingeklappt | 4631 Elemente · 310 Bilder | **973 · 4** |
> | nach dem Weiterklicken | 4631 Elemente · 310 Bilder | **973 · 4** |
>
> Aufgeklappt sind es weiterhin rund 5900 Elemente – das ist die Liste, die
> man gerade ansieht.
## 2.16.0 – August 2026
### Behoben
- 🖼 **Neun Stellen holten weiterhin Bilder in voller Größe.** 2.11.0 hat den
Daumennagel eingeführt, aber nur die Sammlungskarten umgestellt. Listen,
Statistik, Doppelte, fehlende Set-Figuren, die Set-Figuren-Dialoge und die
Hub-Angebote luden weiter 400 px – und die zugehörige Prüfung sah es nicht,
weil sie `class="card-img"` **wörtlich** verlangte und diese Stellen
`class="card-img fig-img"` heißen
> **Aus einem eingeschickten Verlauf.** Der Tab stand drei Stunden ruhig bei
> 1784 Elementen und 32 Bildern. Dann ging die Listen-Ansicht auf: **5094
> Elemente, 336 Bilder** – 90 Sekunden später war der Renderer tot, bei 7 MB
> JS-Speicher.
>
> | | vorher | nachher |
> |---|---|---|
> | 336 Bilder, entpackt | 215 MB | 34 MB |
>
> Entpackte Bilder liegen **außerhalb** des JS-Speichers. Deshalb blieb die
> Kurve flach, während der Tab starb – und deshalb war die Ursache so lange
> nicht zu sehen.
- 🧪 **Die Prüfung dazu prüft jetzt den Anfang der Klassenliste.** Sonst
rutscht dieselbe Sorte Stelle beim nächsten Mal wieder durch
## 2.15.0 – August 2026
Gefunden beim Durchtesten an einer laufenden Instanz.
### Behoben
- ⬆️ **Auch nach einer eigenen Änderung sprang die Liste nach oben.**
2.12.0 hat das fürs automatische Auffrischen erledigt – löschen, Nummer
richtigstellen, Thema setzen, Benachrichtigung übernehmen und die
Sammelaktionen unter „Mehr" luden aber weiter schlicht neu. Elf Stellen,
jetzt alle über denselben Weg
- 🪟 **Ein Thema zu setzen räumte das Popup weg.** Bei Sortierung nach Thema
wechselt der Eintrag die Gruppe, die Liste muss also neu – aber nicht in
dem Moment, in dem man gerade „Setzen" gedrückt hat. Jetzt wartet es, bis
das Popup zu ist
- ✍️ **Der Text beim Bildabruf sprach von Preisen.** „BrickLink führt zu
dieser Nummer keine verkauften Artikel" klang, als wäre nur gerade nichts
verkauft worden – beim Bild fehlt aber der **Eintrag**, nicht der Verkauf
> **Sortierung, Suche und Filter landen weiter am Anfang.** Dort steht
> danach etwas anderes in der Liste; die alte Stelle zu halten wäre kein
> Dienst, sondern ein neuer Fehler.
## 2.14.0 – August 2026
### Geändert
- 🏷 **Das Themenfeld steht nur noch da, wenn keins gefunden wurde.** Als es
kam (1.90.0), standen Teile reihenweise unter „Ohne Thema" – BrickLink
sortiert sie nach **Form** („Brick, Modified"), nicht nach Thema. Seit das
Thema über die Zweitnummer gefunden wird, ist der Normalfall erledigt, und
Eingabefeld samt Knopf standen für etwas da, das längst richtig ausgefüllt
war. Jetzt steht bei einem gefundenen Thema nur noch das Thema
> Ganz weg ist es nicht: Der Stift daneben holt das Feld zurück. Falsch
> zugeordnet wird auch mal etwas, und ohne einen Weg dahin bliebe es falsch.
> Wer das Thema leert, bekommt das Feld wieder offen – dann steht der
> Eintrag ja wirklich ohne.
## 2.13.0 – August 2026
### Behoben
- 🖼 **Das ↻ neben dem Bild holte bei bedruckten Teilen nichts.** Dieselbe
Verwechslung wie beim Preis: Die Rebrickable-Nummer ging unverändert an
BrickLink. Jetzt nimmt auch der Bildabruf die BrickLink-Nummer, wenn die
eigene nichts ergibt
- 🚦 **Ein 404 wurde als „BrickLink nicht erreichbar" gemeldet.**
`requests.HTTPError` ist eine Unterklasse von `RequestException` – stand
kein eigener Zweig davor, fiel „kennt die Nummer nicht" in den Ast für
Ausfälle. Betroffen waren der Bildabruf und die Teileliste einer Figur
- 📋 **Fehlgeschlagene Aufrufe standen in keinem Bericht.** Aufgezeichnet
wurde nur, was niemand auffing. Fast jeder Knopf fängt seinen Fehler aber
ab und schreibt ihn in eine Kurzmeldung – auf dem Bildschirm stand „Fehler
502", und der Bericht meldete „keine Fehler"
> Jetzt landet jede Antwort ab Status 500 im Protokoll, mit Weg und dem
> **Anfang der Antwort**. Genau daran hängt die Frage, die zählt: Kommt der
> Fehler aus der App, steht dort ihr JSON mit `detail`; kommt er von etwas
> davor – Zwischenserver, Tunnel, Zugangsschutz –, steht dort dessen
> HTML-Seite. Ohne diesen Unterschied sucht man an der falschen Stelle.
>
> Ein 404 („kennt BrickLink nicht") und ein 400 („Eingabe nicht gültig")
> bleiben draußen: gewöhnlicher Betrieb, der das Protokoll nur zumüllt.
## 2.12.0 – August 2026
### Behoben
- 💶 **Bedruckte Teile bekamen keine Preise.** Rebrickable nennt den
Gungan-Schild `2586pr0028`, BrickLink nennt ihn `2586ps1`; beim
Karbonitblock stehen `87561pr0001` und `87561pb01` nebeneinander. Fürs
Thema wurde diese Übersetzung längst gemacht, beim Preis nicht – dort ging
die Rebrickable-Nummer unverändert an BrickLink und kam als „kennt die
Nummer nicht" zurück. Jetzt wird bei einem Teil die BrickLink-Nummer
nachgeschlagen und der Preis noch einmal darunter geholt
> Gefragt wird erst, wenn die eigene Nummer nichts ergeben hat, und die
> Antwort bleibt gespeichert – auch eine leere, sonst ginge dieselbe
> vergebliche Frage bei jedem Aufklappen erneut nach draußen. Stammt der
> Preis von der Zweitnummer, steht sie im Popup dabei: Sonst sucht man ihn
> auf BrickLink unter der eigenen Nummer vergebens.
- ✍️ **Der Hinweis dazu stimmte nicht.** Er schob es pauschal auf eine
Rebrickable-Figurennummer und riet zu „BrickLink-Nr. setzen" – ein Feld,
das die Oberfläche bei einem Teil gar nicht anbietet. Bei einem Teil steht
dort jetzt, was wirklich los ist
- ⬆️ **Die Liste sprang beim Auffrischen an den Anfang.** Sie baut sich
blockweise auf, und ein Neuaufbau fängt wieder bei den ersten 60 Karten an
– die Seite wird kurz sehr kurz, und der Browser setzt das Fenster nach
oben. Wer bei Nummer 300 stand, sah danach den Anfang. Jetzt werden Platz
und Kartenzahl gemerkt und danach wieder eingenommen
> Ausgelöst wurde das nicht nur, wenn jemand etwas anlegt: auch beim bloßen
> Zurückkommen aus einem anderen Fenster und nach jedem Preisabruf, der
> einen Kaufpreis nachträgt – dessen Summe steckt im Fingerabdruck, an dem
> die App Änderungen erkennt.
- 🪟 **Ein offenes Popup wurde vom Auffrischen weggeräumt.** Wer darin gerade
etwas eintrug, verlor es mitten im Satz. Jetzt wartet das Auffrischen, bis
das Popup zu ist, und holt es dann nach
## 2.11.0 – August 2026
### Behoben
- 🖼 **Karten holten Bilder in sechsfacher Größe.** Katalogbilder liegen mit
400 px auf der Instanz, angezeigt werden sie in den Karten mit **72**. Der
Browser entpackt aber immer die volle Größe – 0,6 MB je Bild, und zwar
**außerhalb** des JS-Speichers, wo keine Messung hinschaut. Jetzt gibt es
eine Daumennagel-Fassung mit 160 px; die Großansicht bekommt weiter das
volle Bild
> **Warum das kein Schönheitsfehler ist.** In einem eingeschickten Verlauf
> standen **839 Bilder** in einer Ansicht, bei 8 MB JS-Speicher. Entpackt
> sind das rund **500 MB**, die in keiner Kurve auftauchen – und wenige
> Sekunden später brach der Tab ab. Mit 160 px bleiben davon 85 MB.
>
> | Ansicht | vorher | nachher |
> |---|---|---|
> | 130 Bilder | 79 MB | 13 MB |
> | 839 Bilder | 512 MB | 85 MB |
>
> Erzeugt wird die kleine Fassung einmal und liegt dann neben dem Original.
> Freie Größen bedient der Server nicht – sonst könnte man ihn mit 500
> Anfragen 500 Dateien schreiben lassen.
## 2.10.1 – August 2026
### Behoben
- 🔁 **Jeder Ansichtswechsel lud die Ansicht ein zweites Mal.** Der neue
Änderungs-Fühler verglich mit `letzterStand && letzterStand[name]` – das
ergibt **`null`**, wenn noch nichts gemerkt ist, und `null !== undefined`
ist wahr. Damit galt der erste Blick nach jedem Wechsel als Änderung, und
die gerade frisch geladene Ansicht lud sofort erneut. Bei einer Sammlung
mit hundert Bildern ist das kein Schönheitsfehler
> Im eingeschickten Verlauf war es gut zu sehen: `10:45:35 Ansicht: lists`,
> zwei Sekunden später „lade neu"; `10:45:48 Ansicht: collection`, fünf
> Sekunden später wieder. Jetzt: drei Wechsel, kein einziger Ladevorgang –
> und eine echte Änderung von außen kommt weiterhin an.
## 2.10.0 – August 2026
### Neu
- 📡 **Die Ansicht hält sich von selbst aktuell – ohne Fensterwechsel.**
2.9.0 frischte beim Zurückkommen auf; wer die App aber **neben** einem
anderen Fenster liegen hat, will gar nicht erst wechseln müssen. Jetzt
fragt Brickfolio alle fünf Sekunden nach einem **Fingerabdruck** der Daten
– eine Handvoll Zahlen, kein Datenbestand – und lädt die offene Ansicht
nur dann neu, wenn er sich geändert hat
> **Gemessen:** Einkaufsliste offen und aufgeklappt, von außen eine vierte
> Figur dazugelegt, den Browser **nicht angefasst** – acht Sekunden später
> stand sie da. Die Liste blieb dabei offen, und es wurde genau **einmal**
> geladen.
>
> Der Fingerabdruck zählt nicht nur Zeilen: Menge, Haken und Preis gehen
> mit ein, sonst fiele das Ändern einer bestehenden Zeile nicht auf. Ein Tab
> im Hintergrund fragt gar nicht, und der Scannen-Tab wird nie aufgefrischt.
## 2.9.0 – August 2026
### Neu
- 🔄 **Die Ansicht frischt sich auf, wenn ihr zum Tab zurückkommt.** Bisher
wurde beim Zurückkehren nur das Tausch-Netzwerk abgefragt – Sammlung,
Listen und Statistik blieben auf dem Stand von vorhin. Das fällt auf,
sobald **mehr als ein Weg** in die Daten führt: ein Familienmitglied am
Handy, ein zweiter Tab, oder ein Werkzeug an der Schnittstelle. Man sah
dann eine Liste, die es so nicht mehr gab
> **Zwei Einschränkungen mit Absicht:** Der **Scannen-Tab** bleibt
> unberührt – dort steht womöglich ein Foto samt Treffern, und das darf ein
> Fensterwechsel nicht wegräumen. Und wer nur kurz hin- und herklickt, löst
> nichts aus; erst ab vier Sekunden Abwesenheit wird geladen.
>
> Gemessen: Liste mit 1 Artikel offen, von außen ein zweiter dazu, Fenster
> gewechselt – danach **2 Artikel, Einkauf 13,00 €**. Und bei 0,3 Sekunden
> Wegklicken: kein einziger Ladevorgang.
## 2.8.4 – August 2026
### Behoben
- 🖼 **Zwei Bilder im README wurden gar nicht angezeigt.** Die
Alternativtexte enthielten typografische Anführungszeichen („…"), womit
GitHub die `<img>`-Auszeichnung nicht mehr las – statt der Bilder stand
dort der nackte Quelltext. Die Alternativtexte sind jetzt schlicht
### Geändert
- 📸 **Kein fremdes Bildmaterial mehr in den Abzügen.** Die neuen
Bildschirmabzüge zeigten Katalogbilder von BrickLink. Die vorhandenen
Abzüge kommen seit jeher ohne aus – sie zeigen den Platzhalter der App.
Neu erzeugt, jetzt genauso; die Fotos in der Galerie sind selbst erzeugte
Beispielbilder
## 2.8.3 – August 2026
### Neu
- 🐢 **Der Speicher-Verlauf sagt jetzt, ob der schonende Bildmodus lief.**
Jede Messzeile trägt bei eingeschaltetem Modus ein `🐢 schonend`. Ohne
diese Angabe ließe sich hinterher nicht sagen, welcher der beiden Wege in
einer Sitzung aktiv war – und der Vergleich, wofür der Modus gebaut wurde,
wäre wertlos
## 2.8.2 – August 2026
### Behoben
- 🔢 **„1 Bilder, 24 KB".** In der Sicherungskarte stand die Mehrzahl auch bei
einem einzigen Bild. Beim Erstellen der neuen README-Bilder aufgefallen –
wer Abzüge macht, liest die Oberfläche eben zum ersten Mal wieder genau
### Dokumentation
- 📸 **Neue Bildschirmabzüge im README**: Scan-Treffer mit dem Kästchen fürs
eigene Foto und dem Knopf „Nur Foto dazu", die Galerie mit Katalogbild und
eigenem Foto nebeneinander, sowie die Sicherung mit „Eigene Bilder
mitsichern". Der alte Scan-Abzug zeigte den Stand von Mitte Juli
- 📖 Die Funktionsliste nennt die eigenen Fotos und die Bilder in der Sicherung
## 2.8.1 – August 2026
### Aufgeräumt
- 🧹 **Totes Feld `letzteBoxen`** entfernt – wurde nie gelesen und stand
verwirrend neben `scanBoxen`, das dasselbe hält und tatsächlich benutzt wird
- 🧹 **Vier CSS-Regeln** für den Anzahl-Block, den es seit 2.1.0 nicht mehr
gibt
- 🏷 **Klasse `eigenbild-wahl` → `wahl-kasten`.** Sie gilt längst für drei
Kästchen – Scan-Foto, Sicherung, schonender Modus – und der alte Name
behauptete etwas anderes
### Dokumentation
- 📖 **„Browser aktualisieren" allein reicht nicht.** Das Handbuch legte das
nahe; tatsächlich war nach dem Edge-Update die alte Bucket-ID verschwunden
und sofort eine **neue** da – gleiche Art Fehler, andere Stelle. Steht
jetzt so drin, samt einer Reihenfolge, was zu tun bleibt
## 2.8.0 – August 2026
### Neu
- 🐢 **Schonender Bildmodus** (*Mehr → Fehlerbericht*, standardmäßig aus).
Diese App entpackt Fotos, malt sie auf Zeichenflächen, liest Bildpunkte
aus und kodiert wieder – Arbeit, die der Browser gern auf die
**Grafikeinheit** schiebt und die kaum eine andere Seite ihm gibt. Der
Modus geht denselben Weg zu Fuß, im Hauptspeicher: Entpacken über ein
gewöhnliches Bildelement statt `createImageBitmap`, Zeichenflächen mit
`willReadFrequently`. Etwas langsamer, sonst gleich
> **Wofür das gut ist:** Bricht der Tab beim Scannen ab, während die
> Speicherkurve flach bleibt, lässt sich damit prüfen, ob es an diesem Weg
> liegt. Gemessen liefern beide Modi dasselbe Ergebnis (3000×2000 → Vorschau
> 1200×800, gleicher Treffer, gleiche Dauer).
>
> Ehrlicherweise: Ein Absturz **ohne jeden Scan** zeigt, dass es nicht nur
> daran liegen kann. Der Modus ist ein Werkzeug zum Eingrenzen, kein Heilmittel.
### Behoben
- ⏳ **`img.decode()` blieb an einem losen Bild hängen.** Beim Bauen des
schonenden Modus aufgefallen: Ein Bild, das nicht im Dokument hängt, gibt
das Versprechen unter Umständen nie zurück – der ganze Scan blieb stehen.
`onload` genügt für das Weiterzeichnen
## 2.7.1 – August 2026
### Behoben
- 🧹 **Das entpackte Foto blieb nach „Foto dazu" liegen.** Um den Ausschnitt
zu schneiden, entpackt die App das Original in Arbeitsgröße – bis zu
2400 px, gemessen **16 MB**. Alle anderen Wege gaben es danach wieder frei,
der neue Foto-Weg aus 2.5.0 als einziger nicht: Es lag bis zum nächsten
Foto herum. Jetzt geht es acht Sekunden nach dem letzten Gebrauch weg, und
beim Verlassen des Scan-Tabs sofort
> **Warum das in keiner Kurve zu sehen war:** Eine entpackte Bitmap liegt
> **außerhalb** des JS-Speichers. Der Verlauf unter *Mehr → Fehlerbericht*
> zeigte weiter flache 6 MB – im Browser lagen die 16 MB trotzdem. Genau
> solche unsichtbaren Brocken sind es, die einen Tab umbringen, während die
> Kurve nichts anzeigt.
>
> Ein Test wacht darüber, dass **jede** Stelle, die einen Ausschnitt
> schneidet, das Arbeitsbild auch wieder loslässt.
## 2.7.0 – August 2026
### Neu
- 📷 **„Nur Foto dazu" auf der Trefferkarte.** Steht die Figur längst in der
Sammlung und man will bloß ein Bild davon hinterlegen, genügt jetzt ein
Tipp. Der Knopf hängt das Foto an den Artikel und rührt sonst nichts an –
keine zweite Zeile, keine erhöhte Menge, kein Listeneintrag
> Er wirkt **unabhängig vom Kästchen** oben: Das gilt fürs Anlegen, hier ist
> das Foto der ganze Zweck. Bei mehreren erkannten Figuren nimmt auch dieser
> Weg den Ausschnitt, in dem die jeweilige gefunden wurde.
## 2.6.1 – August 2026
### Behoben
- 🪟 **„Mein Foto entfernen?" ging hinter der Großansicht auf.** Die Rückfrage
lag auf Ebene 80, die Großansicht auf 100 – man sah die Frage nur
abgedunkelt durchschimmern und die Aktion schien zu hängen. Rückfragen
liegen jetzt über allem außer dem Toast
> Ein Test hält die Reihenfolge fest: Rückfrage über Großansicht, Toast über
> allem. Sonst rutscht das beim nächsten Umbau wieder durcheinander.
## 2.6.0 – August 2026
### Geändert
- 📷 **Das eigene Foto kommt jetzt *neben* das Katalogbild, nicht an seine
Stelle.** In 2.5.0 hat es das Katalogbild ersetzt – das war nicht gemeint.
Gedacht ist es wie die Bilder, die Käufer bei BrickLink beisteuern: Das
Katalogbild bleibt das erste, was man sieht, das eigene Foto kommt daneben
### Neu
- 🖼 **Galerie mit den eigenen Fotos.** Tippt auf das Bild eines Artikels und
blättert: Erst das Katalogbild, dann eure Fotos. Bei einem eigenen steht
oben **„mein Foto"**, und unten erscheint **🗑 Mein Foto entfernen**
- 💾 **Eigene Bilder gehen in die Sicherung mit.** Sie sind Dateien, keine
Datenbankzeilen – bisher trug die Sicherung nur den Verweis, und nach einem
Umzug zeigten die Artikel ins Leere. Jetzt steht in der Sicherungs-Karte
ein Kästchen mit Anzahl und Größe; die Bilder wandern als Teil derselben
JSON-Datei mit und werden beim Einspielen unter ihren alten Namen wieder
angelegt. Gilt auch für die Sicherung beim allerersten Start
> **Die Fotos hängen am Artikel, nicht an der Sammlungszeile.** Wer dieselbe
> Figur zweimal hat – einmal neu, einmal gebraucht –, sieht bei beiden
> dieselben Fotos. Es ist ja dieselbe Figur.
>
> Ab etwa 150 MB Bildern verweigert die App das Mitsichern und sagt es auch;
> dann gehört `data/uploads/` ins normale Backup.
## 2.5.0 – August 2026
### Neu
- 📷 **Das eigene Scan-Foto als Bild des Artikels.** Über den Treffern steht
ein Kästchen: **„Mein Foto statt des Katalogbilds"**. Ist es angehakt,
bekommt alles, was aus diesem Scan angelegt wird – Sammlung, Wunschliste
**und** Einkaufsliste – das eigene Bild
- 🧩 **Bei mehreren Figuren jeweils der eigene Ausschnitt.** Nicht einmal das
ganze Regalfoto für alle, sondern genau der Rahmen, in dem die Figur
gefunden wurde – gleich, ob er aus der Reihum-Suche stammt, von einem
gemerkten Rahmen oder von einem selbst gezogenen
> **Standardmäßig aus**, denn ein Katalogbild ist meist das sauberere; die
> Entscheidung merkt sich die App auf dem Gerät. Hochgeladen wird erst beim
> Anlegen – wer nur schaut oder abbricht, lädt nichts hoch.
### Dokumentation
- ⚠️ **Was die Sicherung nicht enthält.** Eigene Bilder sind Dateien in
`data/uploads/`, keine Datenbankeinträge. Die JSON-Sicherung trägt den
**Verweis** darauf, nicht die Datei. Beim Umzug gehört `data/uploads/`
also mit kopiert – das galt immer schon für eigene Figuren, stand aber
nirgends. Jetzt steht es in beiden Handbüchern
## 2.4.4 – August 2026
### Behoben
- 📋 **Kopieren scheiterte trotz Rückfallweg.** Die Reihenfolge war falsch
herum. `navigator.clipboard.writeText` liefert ein Versprechen – wer darauf
wartet, gibt die **Benutzergeste** des Klicks aus der Hand, und genau die
verlangt der Rückfallweg `execCommand`. Schlug die moderne Schnittstelle
fehl, kam der Rückfall zu spät: Er half nur, wenn er gar nicht nötig war.
Jetzt läuft erst der **synchrone** Weg, das Versprechen danach
### Neu
- 🆘 **Und wenn beides nichts wird, ist der Text trotzdem da.** Statt einer
Absage legt die App ihn in einem Fenster **fertig markiert** hin –
Strg/Cmd+C genügt
- 🔍 **Die Absage nennt jetzt den Grund.** In Klammern hinter der Meldung, und
zusätzlich im Verlauf unter *Speicher-Verlauf*. „Geht nicht" allein war als
Auskunft wertlos
## 2.4.3 – August 2026
### Geändert
- 🧩 **„Script error." sieht nicht mehr nach einem Defekt aus.** Der Eintrag
stand ohne Datei und Zeile zwischen echten Fehlern. Er kommt aber gar nicht
aus der App: Fehler aus **fremden Skripten** kürzt der Browser aus
Sicherheitsgründen auf genau diesen Satz zusammen – in Frage kommen
Erweiterungen, Inhaltsblocker und was der Browser selbst einspritzt. Solche
Einträge sind jetzt als **🧩 Kein Fehler der App** beschriftet, auch die
schon gespeicherten
- 🔎 **Und sie tragen jetzt etwas bei.** Wo der Browser Datei und Zeile
verschweigt, hängt die App die **letzten Schritte vor dem Fehler** an. Damit
lässt sich wenigstens sehen, wobei es passiert
> Die Aussage steht auf einem prüfbaren Fundament: Die Seite lädt zwei eigene
> Skripte und bindet keine Rahmen ein. Ein Test wacht darüber – käme je ein
> fremdes Skript dazu, wäre die Beschriftung eine Lüge und der Test rot.
## 2.4.2 – August 2026
### Behoben
- 🙈 **Benutzernamen auf dem Anmeldebogen.** Nach dem Einspielen einer
Sicherung (2.4.0) stand dort „Jetzt anmelden als: anna, bruno" – gedacht
als Hilfe, tatsächlich aber eine Liste aller Admin-Namen auf einer Seite,
an der noch niemand angemeldet ist. Der Hinweis nennt jetzt keine Namen
mehr, und auch das Namensfeld bleibt leer
> Der Endpunkt gibt die Namen gar nicht erst heraus – nicht nur die Anzeige
> ist weg, sondern die Quelle. Wer die Sicherung eingespielt hat, kennt seine
> Zugangsdaten ohnehin.
## 2.4.1 – August 2026
### Neu
- 🔢 **Version steht auf dem Startbildschirm.** Klein und grau unter der
Anmeldekarte („Brickfolio 2.4.1"). Wer mehrere Instanzen betreibt, sieht
jetzt ohne Anmeldung, welche er gerade vor sich hat – und wer einen Fehler
meldet, muss die Version nicht erst suchen
> Verraten wird damit nichts Neues: Die Version stand auf dieser Seite
> ohnehin schon, nur unsichtbar – an den Versionsmarken der Dateien
> (`style.css?v=…`), die jeder Seitenquelltext zeigt.
## 2.4.0 – August 2026
### Neu
- 📥 **Sicherung gleich beim ersten Start einspielen.** Wer umzieht, hatte
bisher einen unnötigen Umweg: erst ein Admin-Konto anlegen, das die
Sicherung gleich darauf wieder überschreibt. Jetzt steht im Willkommens-
Bogen unter dem Anlegen-Knopf **„📥 Sicherung einspielen"** – der ganze
alte Stand kommt herüber, samt Konten. Danach meldet man sich mit den
**bisherigen Zugangsdaten** an
> **Ohne Anmeldung – ist das in Ordnung?** Ja, denn es geht nur, solange die
> Instanz **leer** ist. Wer sie in diesem Zustand erreicht, könnte ohnehin
> das erste Admin-Konto anlegen und wäre damit Herr über alles; der Weg gibt
> also nichts preis, was nicht schon offenstünde. Sobald ein Benutzer
> existiert, antwortet er nur noch mit einer Absage.
## 2.3.1 – August 2026
### Behoben
- 👥 **Fehler 500 beim Entfernen eines Benutzers.** Freigeräumt wurde nur die
Sammlung. Auf den Benutzer zeigen aber noch vier weitere Stellen – Wünsche,
angelegte Listen, abgehakte Listeneinträge und die Push-Anmeldung –, und die
Datenbank ließ das Löschen deshalb nicht zu. Wer also irgendetwas davon
hinterlassen hatte, war nicht zu entfernen
> **Was jetzt mit seinen Sachen passiert:** Sammlung, Wünsche, Listen und
> Haken bleiben – sie gehören der Instanz, nicht der Person; nur der Name
> dahinter verschwindet. Mit gelöscht wird allein die Push-Anmeldung, damit
> sein Gerät keine Meldungen dieser Instanz mehr bekommt.
## 2.3.0 – August 2026
### Behoben
- 📋 **„Kopieren nicht möglich" im Heimnetz.** Die Knöpfe zum Kopieren –
Fehlerbericht, Wiederherstellungscode, Cloudflare-Befehl, Diagnose – gingen
nur über `https://` oder `localhost`. Ruft man die App über die IP-Adresse
im Heimnetz auf, ist das kein *sicherer Kontext*, und der Browser rückt die
Zwischenablage nicht heraus. Jetzt gibt es einen Rückfallweg über ein
unsichtbares Textfeld, der auch dort kopiert
> Der Rückfallweg braucht einen echten Klick – das ist der Grund, warum er
> nicht überall greifen kann, sondern nur an den Kopier-Knöpfen selbst.
> Geprüft mit ausgeblendeter Zwischenablage: echter Klick, echter Text.
### Geändert
- 🔤 **Gleicher Name überall.** Fenstertitel und der Name der installierten
App schrieben `Annas Brickfolio`, die Überschrift in der App dagegen
`Anna's Brickfolio`. Jetzt steht überall dasselbe
## 2.2.0 – August 2026
### Behoben
- 📱 **Derselbe feste Name auf jedem Handy.** Legte man die App auf den
Startbildschirm, stand dort der fest eingebaute Name – auch auf einer
Instanz, die längst anders heißt. Manifest, Fenstertitel und der Name für
iOS kommen jetzt aus dem **Anzeigenamen** unter *Mehr → Anzeigename*
- 🖼 **Und der feste Name stand im Symbol.** Das App-Symbol wird jetzt erzeugt: die
bekannte Zeichnung, darüber der Anzeigename der Instanz. Die Schriftgröße
richtet sich nach der Länge, damit auch längere Namen hineinpassen
> Gebraucht wird dafür keine mitgelieferte Schriftdatei – Pillow bringt eine
> skalierbare Standardschrift mit, die auch im schlanken Docker-Abbild
> vorhanden ist. Erzeugt wird je Name und Größe einmal, danach kommt das
> Symbol aus dem Zwischenspeicher.
## 2.1.1 – August 2026
### Behoben
- 🧭 **„Reihum-Suche fertig (–)" statt der Zahl.** Endete die Suche endgültig,
war der Suchstand beim Schreiben der Protokollzeile schon freigegeben – im
Verlauf stand dann ein Strich statt der Zahl der gefundenen Figuren. Jetzt
steht dort, was wirklich gefunden wurde
> **Was der Verlauf vom 2.8. sonst zeigt:** Die Wiederherstellung aus 2.0.0
> hat gegriffen – nach dem Absturz um 00:16:19 setzte die App bei „Listen"
> wieder auf, also genau dort, wo die Sitzung aufgehört hatte. Und das
> Weitersuchen aus 2.1.0 lief: 10 Figuren, dann eine elfte.
## 2.1.0 – August 2026
### Neu
- 🔎 **Weitersuchen statt Wand.** Die Reihum-Suche hört nach 10 Figuren auf –
das ist keine technische Grenze, sondern Rücksicht auf einen kostenlos
bereitgestellten Dienst. Sind noch Figuren da, erscheint jetzt
**🔎 Weitersuchen**: Die App macht dort weiter, wo sie aufgehört hat, und
die neuen Funde kommen zu den bisherigen dazu
- 🧠 **Der Suchstand bleibt liegen**, solange weitergesucht werden kann – und
wird freigegeben, sobald die Suche zu Ende ist oder ein neues Foto kommt.
So kostet das Weitersuchen keine zweite Runde durch das ganze Bild
> **Gemessen an einem Bild mit 14 Figuren:** erster Durchgang 10, dann
> „Weitersuchen" → insgesamt 13 (die vierzehnte Anfrage ging an den
> Einzelscan beim Fotografieren). Rahmen und Karten stimmen nach beiden
> Durchgängen überein, der Knopf verschwindet, sobald nichts mehr kommt.
## 2.0.0 – August 2026
### Neu
- 💾 **Ein Abbruch kostet nichts mehr.** Verhindern lässt sich der
Edge-Absturz nicht (siehe 1.99.0) – aber die App kommt jetzt zurück: Sie
merkt sich die **offene Ansicht** und die **angefangene Eingabe** im
Formular „Manuell erfassen". Nach einem Abbruch steht beides wieder da
- 🎯 **Nur nach einem Abbruch.** Bei einem normalen Start öffnet die App wie
immer den Scan-Tab – niemand will nach dem Öffnen in den Einstellungen
landen, nur weil er dort zuletzt etwas nachgesehen hat. Unterschieden wird
am Abschiedszettel, der beim gewollten Ende geschrieben wird und beim
Abwürgen eben nicht
> **Was nicht gerettet wird:** ein ausgewähltes Foto. Das ließe sich nur mit
> erheblichem Aufwand ablegen, und der Schaden ist gering – neu fotografieren
> dauert Sekunden. Ein halb ausgefülltes Formular mit Preis und Notiz ist das,
> was wirklich wehtut.
## 1.99.0 – August 2026
### Neu
- 🔎 **Der Absturz ist gefunden – und er liegt nicht in der App.** Die
Absturzliste von Edge zeigt 17 Abstürze über vier Tage, **alle unter
derselben Bucket-ID** und an derselben Stelle im Programm: `P6 = renderer`
(der Tab selbst), `P3 = Microsoft_Edge_Framework` (Edges eigener Code),
`P7 = 0x6` (auf macOS SIGABRT). Drei davon treffen sekundengenau die
„OHNE ABSCHIED"-Einträge unseres Speicher-Verlaufs – die übrigen vierzehn
hat die App nie gesehen, weil sie gar nicht offen war
- 💡 **Der Weg dorthin steht jetzt in der App.** Beim Speicher-Verlauf hängt
ein Hinweis: Bleibt die Kurve flach und der Tab stirbt trotzdem, steht der
echte Grund in `edge://crashes` – und gleiche Bucket-ID heißt gleicher
Fehler des Browsers
> **Was das für die Diagnose bedeutet.** Sieben Versionen lang habe ich in der
> App gesucht: Hintergrundbilder, Glasflächen im Nova-Design, entpackte Fotos,
> die Sammlungsansicht. Jede These war messbar falsch, weil der Tab immer bei
> 6 bis 8 Megabyte starb – zuletzt im **Vordergrund**, auf einem Mac mit
> 16 GB. Die Zahlen haben die App früh entlastet; was fehlte, war der Blick in
> die Absturzliste des Browsers. Der steht jetzt dort, wo man ihn sucht.
## 1.98.0 – August 2026
### Behoben
- 🧭 **Die Reihum-Suche stand nicht in der Spur.** Sie kam in 1.97.0 dazu,
schrieb aber nichts mit – und ausgerechnet in die 46 Sekunden davor fiel ein
Absturz. Jetzt steht jede Runde einzeln drin: Start, jede gefundene Figur
mit Nummer und Sicherheit, Ende
- 🧹 **Halber Speicherbedarf beim Suchen.** Bitmap und Zeichenfläche hielten
dieselbe Bildfläche doppelt, bis die Schleife fertig war. Die Bitmap wird
jetzt sofort nach dem ersten Zeichnen freigegeben; die Zeichenfläche wird
auch bei einem Fehler zuverlässig geleert
- 🔁 **Abbruch bei doppeltem Fund.** Liefert der Dienst zweimal denselben
Bereich, hört die Suche auf, statt bis zum Anschlag weiterzufragen
> **Gemessen:** fünf vollständige Durchläufe hintereinander, JS-Speicher
> 2,4 → 2,9 MB. Ein halbes Megabyte auf fünf Läufe ist kein Leck, das einen
> Tab umbringt – der Verdacht gegen den neuen Ablauf ist damit **nicht**
> bestätigt, aber auch nicht widerlegt. Dafür sagt es beim nächsten Mal die
> Spur.
## 1.97.0 – August 2026
### Neu
- 🔎 **Die App sucht die Figuren nicht mehr selbst – der Erkennungsdienst
sucht.** Jede Antwort von Brickognize bringt einen Rahmen mit; er sagt also
immer mit, *wo* er hingeschaut hat. „Alle Figuren erkennen" nutzt das jetzt
reihum: erkennen, den gefundenen Bereich in **Hintergrundfarbe** ausblenden,
erneut fragen – bis nichts mehr kommt
- 🎯 **Kommt mit Anordnungen zurecht, an denen alles bisherige scheiterte:**
Figuren, die sich **berühren**, **mehrere Reihen**, kreuz und quer Liegendes.
Gemessen an vier Klonkriegern dicht nebeneinander: **4 von 4 Figuren, 72–91 %
sicher, in 1,2 Sekunden** – das alte Verfahren fand an derselben Aufnahme
**gar nichts**
- 🧹 **206 Zeilen weniger.** Spaltenanalyse, Kantenberechnung, Talsuche, der
Regler für die Streifenzahl und die Reihen-Warnung aus 1.93.0 sind
ersatzlos entfallen – es gibt nichts mehr einzustellen und nichts mehr zu
warnen
> **Warum es vorher nicht ging.** Das alte Verfahren maß die Struktur je
> Bildspalte und schnitt in den Lücken. Bei Figuren, die sich berühren, gibt es
> keine Lücke – deshalb kam bei einem Testfoto in **keinem** Streifen etwas an.
> Der Dienst kann dagegen lokalisieren; das war die ganze Zeit da und wurde nur
> einmal statt mehrfach genutzt.
> **Gemessen, nicht vermutet.** Die Maskenfarbe entscheidet: Mit einer fest
> gewählten Farbe blieben nach drei Figuren harte Rechteckkanten stehen, die
> der Dienst für ein Objekt hielt – die vierte fand er nicht mehr. Mit der aus
> den Bildecken gemittelten Hintergrundfarbe: alle vier.
## 1.96.0 – August 2026
### Neu
- 🛡 **Bremse vor dem Erkennungsdienst.** Brickognize stellt seine Erkennung
kostenlos bereit; jeder Ausschnitt ist eine eigene Anfrage. Der Server lässt
jetzt **40 Erkennungen je Minute** für die ganze Instanz durch und weist
darüber hinaus mit einer verständlichen Meldung ab. Die Grenze sitzt
bewusst im Server – sie gilt damit für alle Benutzer und auch dann, wenn
jemand an der Oberfläche vorbei anfragt
- 🔢 **Auch von Hand gemerkte Rahmen sind gedeckelt.** Die automatische
Trennung hörte seit jeher bei 10 auf, die gemerkten Rahmen waren
unbegrenzt. Jetzt gilt dieselbe Zahl für beide Wege
> **Geprüft und wieder verworfen:** Brickognize hat einen eigenen Endpunkt für
> Minifiguren (`/predict/figs/`). Zweimal gegen `/predict/` gemessen – einmal
> mit einem sauberen Figurenbild, einmal mit einem Ausschnitt samt
> Tischplatte und angeschnittenen Nachbarfiguren: **beide Male dasselbe
> Ergebnis, 89 % bzw. 90 %.** Kein Gewinn, dafür der Nachteil, dass man dann
> kein Set mehr einrahmen könnte. Bleibt also bei `/predict/`.
## 1.95.0 – August 2026
### Behoben
- 🟩 **Fünf Rahmen, unter denen „nichts erkannt" stand.** Die nummerierten
Rahmen blieben stehen, egal was die Abfrage ergab – das Bild behauptete
fünf gefundene Figuren, während darunter „Keine Übereinstimmung gefunden"
zu lesen war. Jetzt bleiben **nur die Streifen stehen, in denen wirklich
etwas erkannt wurde**; ergab keiner etwas, verschwinden alle und es steht
dran, dass sich dieses Bild so nicht zerlegen lässt
- 🏷 **„Geteilt in: 5 Streifen" statt „Gefunden: 5 Figuren".** Vor der
Abfrage weiß die App nur, wo sie geschnitten hat – nicht, was dort steht.
Die Beschriftung sagt das jetzt
> **Warum die Warnung aus 1.93.0 hier nicht kam:** Sie misst die Figur, die
> der Erkennungsdienst beim ersten Scan gefunden hat, an der Bildhöhe. Findet
> er **gar nichts**, gibt es nichts zu messen. Für diesen Fall greift jetzt
> das Ergebnis selbst: Keine Treffer, keine Rahmen.
## 1.94.0 – August 2026
### Behoben
- 🔢 **Die geklärte BrickLink-Nummer galt nur halb.** Seit 1.92.0 fragt die
App bei Rebrickable nach der BrickLink-Entsprechung (`2586pr0028` →
`2586ps1`) – benutzt hat sie sie aber nur für die Zweitnummer. Die
**Kategorie** wurde weiter mit der Nummer abgefragt, die BrickLink gar nicht
kennt, und lief deshalb ins Leere. Jetzt wird die Nummer **einmal** geklärt
und für beide Wege verwendet
- 🗂️ **Damit greift auch der Katalogpfad.** Teile ohne Zweitnummer bekommen
ihre Kategorie als Thema: Aus *Catalog: Parts: Minifigure, Shield* wird
**„Minifigure, Shield"** statt „Ohne Thema"
- ⚡ Die Kategorie-ID kommt jetzt mit dem Katalogeintrag mit – eine Abfrage
weniger je Teil
> **Was das für die beiden Teile heißt.** Der Karbonitblock hat eine
> Zweitnummer (`sw0978`) und landet unter **Star Wars**. Der Gungan-Schild
> steht bei BrickLink ohne Zweitnummer, dort bleibt nur der Pfad: **Minifigure,
> Shield**. Das ist eine Form und kein Thema – wem das nicht passt, setzt auf
> der Karte von Hand „Star Wars".
## 1.93.0 – August 2026
### Behoben
- 🚫 **Vier Rahmen, die nichts bedeuteten.** Bei einem Regalfoto mit mehreren
Reihen schnitt „🔎 Alle Figuren erkennen" das Bild in senkrechte Streifen –
in jedem standen dann fünf Figuren übereinander. Angezeigt wurden vier
nummerierte Rahmen, als wären es vier Figuren. Das ist schlimmer als kein
Ergebnis
- ❓ **Jetzt fragt die App vorher.** Füllt die Figur, die der Erkennungsdienst
beim ersten Scan gefunden hat, **weniger als ein Drittel der Bildhöhe**,
steckt mehr als eine Reihe im Bild. Dann kommt ein Hinweis samt dem Weg
über gemerkte Rahmen – „Trotzdem versuchen" bleibt möglich
> **Woher die App das weiß, ohne zu raten:** Der Erkennungsdienst liefert
> beim ersten Scan seinen eigenen Rahmen mit („hier geschaut"). Wie groß der
> im Verhältnis zum Bild ist, ist eine gemessene Zahl – keine Schätzung. Bei
> einem einreihigen Foto füllt die Figur 60 bis 90 % der Höhe, beim Regalfoto
> 15 %.
## 1.92.0 – August 2026
### Neu
- 🗂️ **Teile bekommen ihr Thema doch – über die Zweitnummer.** BrickLink
führt Teile nach Form („Minifigure, Utensil, Decorated"), aber bedruckte
Teile tragen im Katalog die Nummer der Figur, zu der sie gehören: Beim
Karbonitblock mit Han Solo steht **`sw0978`** daneben – und `sw…` heißt
Star Wars. „🔄 Themen nachladen" liest das jetzt aus
- 🔁 **Zwei Kataloge, zwei Nummern.** Rebrickable nennt dasselbe Teil
`87561pr0001`, BrickLink `87561pb01`. Führt die eigene Nummer zu nichts,
wird die Entsprechung bei Rebrickable erfragt und der Abruf wiederholt
- ✅ Ein echtes Thema hat Vorrang vor der Formkategorie
> **Korrektur zu 1.90.0.** Dort stand, für Teile ließe sich grundsätzlich
> nichts abrufen. Das stimmte nicht: Die *Kategorie* eines Teils sagt nichts
> über das Thema – die *Zweitnummer* sehr wohl. Der Hinweis bei „Ohne Thema"
> ist entsprechend richtiggestellt.
## 1.91.0 – August 2026
### Behoben
- 🔍 **Ausschnitte kamen aus der Vorschau statt aus dem Foto.** Zugeschnitten
wurde bisher aus der auf 1200 Pixel verkleinerten Fassung – bei vielen
Figuren im Bild blieb einer einzelnen damit kaum mehr als ein Daumennagel,
und genau der ging zur Erkennung. Jetzt wird aus einer **Arbeitskopie mit
2400 Pixeln** geschnitten: gemessen an einem 12-MP-Foto **238×334 statt
120×168 Pixel – die vierfache Fläche**
- 💬 **Ein Hinweis statt Rätselraten.** Bleibt ein einzelner Treffer unter
60 %, steht jetzt darüber, woran es liegt: Die Erkennung sucht **ein**
Objekt je Anfrage – bei vielen Figuren im Bild hilft ein Rahmen oder ein
Foto aus der Nähe
> **Warum nicht direkt aus dem Original geschnitten wird.** Gemessen: Ein
> Ausschnitt per Quellrechteck aus der 12-MP-Datei kostet rund 50 ms – **je
> Ausschnitt**, weil dabei jedes Mal das ganze Bild entpackt wird. Bei vierzig
> Figuren wären das vierzig volle Entpackvorgänge; daran ist der Tab schon
> gestorben. Einmal auf 2400 entpacken kostet dieselben ~300 ms **insgesamt**
> und hält rund 17 MB, deren Lebensdauer bekannt ist.
## 1.90.0 – August 2026
### Neu
- 🗂️ **Thema von Hand setzen.** Auf jeder Karte steht jetzt ein Feld
**Thema** – mit Vorschlagsliste aus den Themen, die in der Sammlung schon
vorkommen, damit nicht „Star wars" neben „Star Wars" entsteht. Leeren setzt
den Eintrag zurück auf „Ohne Thema"
- 🔒 Ein von Hand gesetztes Thema **bleibt stehen**: Die Automatik rührt ein
vorhandenes nie an
> **Warum das nötig ist.** Für **Teile** kann die Automatik grundsätzlich
> nichts liefern: BrickLink führt sie nach **Form** („Brick, Modified"), nicht
> nach Thema – da ist nichts abzurufen, was hier stehen könnte. Bei Minifiguren
> steckt das Thema in der Nummer (`sw…`), bei Sets in der Kategorie; bei Teilen
> gibt es diesen Weg nicht. „🔄 Themen nachladen" hilft dort also nie, und
> genau das steht jetzt auch bei der Gruppe „Ohne Thema".
## 1.89.0 – August 2026
### Neu
- 📱 **Welches Gerät?** Der Verlauf hält beim Sitzungsbeginn fest, worauf die
App läuft: System, Browser, **als App oder im Browser**, Arbeitsspeicher des
Geräts und Bildschirmgröße. Nach vier Abstürzen stand das in den Daten
bisher nirgends
- ⏱ **„Abgestürzt nach … Minuten Laufzeit."** Die Zusammenfassung rechnet aus,
wie lange eine Sitzung lief, bevor sie abbrach. Zweimal dieselbe Dauer wäre
ein Muster und kein Zufall
- 🔄 **Der Update-Vorgang steht jetzt in der Spur**: nach Update gesucht,
Update angefordert, Update-Sperre sichtbar, Server nicht erreichbar, Server
wieder da, Server neu gestartet
> **Warum genau das.** Die beiden Abstürze vom 1.8. um 16:41 und 16:51 fielen
> beide in den Update-Vorgang – und die Sitzungen liefen **8:27** bzw. **9:14**
> Minuten, bevor der Tab starb. Der zweite lag außerdem **nicht** in der
> Scan-Ansicht, womit meine Vermutung von vorhin („beide beim Fotografieren")
> widerlegt ist. Beide Male: 7 MB von 4096 MB Grenze.
## 1.88.0 – August 2026
### Neu
- 🧭 **Eine Spur neben dem Speicher-Verlauf.** Zwischen zwei Messwerten
liegen 30 Sekunden – ein Absturz wartet darauf nicht. Deshalb wird jetzt
**sofort** festgehalten, was passiert: Foto aufgenommen (mit
**Megapixeln und Dateigröße**), verkleinert auf …, Erkennung läuft/fertig,
Ansicht gewechselt, **in den Hintergrund / wieder da**
- 📋 Die Spur steht unter der Kurve und geht beim Kopieren mit
> **Warum das nötig war.** Der Verlauf vom 1.8. zeigt zwei Stunden zwischen
> 5 und 9 MB, ohne jedes Wachstum – und trotzdem starb der Tab um 16:41 bei
> **7 MB und 981 Elementen**. Damit ist der JavaScript-Speicher als Ursache
> erledigt. Beide bisher auswertbaren Abstürze fielen in dieselbe Lage: die
> Scan-Ansicht bei rund 980 Elementen. Was dort groß ist, steht außerhalb
> jeder Messung – das Foto selbst und die Kamera-App daneben. Ob die Seite in
> dem Moment im Hintergrund war, sagt ab jetzt die Spur.
## 1.87.0 – August 2026
### Behoben
- 🗂️ **„LEGO Ideas (CUUSOO)" statt „LEGO Ideas (CUUSOO)".** BrickLink
liefert Kategorienamen HTML-maskiert; bei Artikelnamen wurde das längst
umgewandelt, bei den Themen nicht. Da die Oberfläche beim Anzeigen ein
zweites Mal maskiert, stand die Maskierung selbst auf dem Bildschirm.
Betrifft alle Themen mit Klammern oder Sonderzeichen im Namen
- 🔧 **Bestehende Einträge werden beim Start geradegezogen** – auch die schon
gespeicherte Kategorieliste, ohne neuen Abruf. Nichts nachzuladen, das
Update genügt
## 1.86.0 – August 2026
### Neu
- 📤 **Gegenstück zum Übernehmen: austragen.** Fragt jemand nach einem
deiner Artikel und du nimmst an, geht das Stück ja weg. Dafür steht im
Gespräch jetzt **📤 Aus der Sammlung austragen** – in Rot, damit es nicht
mit dem grünen Übernehmen zu verwechseln ist
- ❓ **Neu oder gebraucht? Wird gefragt, nicht geraten.** Steht dieselbe
Nummer zweimal in der Sammlung, fragt das Fenster **„Welches Stück?"**.
Ohne Antwort passiert nichts – ein geratener Zustand wäre ein verlorenes
Exemplar
- ⏳ **„noch nicht ausgetragen"** an angenommenen eingehenden Vorgängen,
passend zum „noch nicht verbucht" der anderen Richtung
Ausgetragen wird ausschließlich nach Bestätigung im App-Fenster: Artikel,
Gegenüber und der Bestand stehen darin, dazu die Anzahl. Bleibt nichts übrig,
verschwindet die Zeile samt Kaufbuch – wie beim Austragen über die Karte.
## 1.85.0 – August 2026
### Behoben
- 🤝 **„Annehmen" tat sichtbar nichts.** Der Vorgang wurde zwar auf
*angenommen* gesetzt, aber bei einem schon angenommenen Tausch änderte sich
nichts auf dem Bildschirm – und vor allem: Der Artikel selbst blieb außen
vor und musste von Hand nachgetragen werden. Jetzt bestätigt eine Meldung
die Zusage, und es geht direkt das Fenster **Tausch übernehmen** auf
### Neu
- 📥 **Angenommene Tausche verbuchen.** Wohin (Sammlung oder eine
Einkaufsliste), Anzahl, Zustand, bezahlter Preis – der Eintrag entsteht wie
ein normaler: gleiche Nummer erhöht die Anzahl, der Preis landet im
Kaufbuch, in den Notizen steht „Tausch mit …". Der Knopf steht im Gespräch
unter dem Verlauf, solange der Tausch angenommen ist und der Artikel zu mir
kommt
- ⏳ **„noch nicht verbucht"** an angenommenen Vorgängen in der Liste – bis
der Artikel wirklich eingetragen ist. Gebucht wird nur auf Knopfdruck:
Zwischen Zusage und Karton in der Hand liegen beim Tauschen gern ein paar
Tage, und der Preis steht oft erst dann fest
- 🏷 **Art, Bild und Zustand reisen mit der Anfrage mit.** Gespeichert waren
bisher nur Nummer und Name; damit ließ sich ein Tausch nicht sauber
übernehmen. Ältere Vorgänge raten die Art aus der Nummer (reine Ziffern =
Set)
## 1.84.0 – Juli 2026
### Behoben
- 📷 **Ein Handyfoto wurde vollständig entpackt, bevor es verkleinert
wurde.** Bei 12 Megapixeln sind das **46 MB in einem Stück**, bei einem
50-MP-Handy rund 200 MB – außerhalb des JS-Speichers, wo keine Messung
etwas sieht. Jetzt wird schon **beim Entpacken** verkleinert: gemessen
**46 MB → 4 MB, 91 % weniger**
- 🔁 **Jeder Ausschnitt entpackte das Foto neu.** Bei fünf Figuren fünfmal
gut 20 MB, zeitweise nebeneinander. Jetzt wird einmal entpackt und für
alle Ausschnitte wiederverwendet – gemessen **1 statt 5**
> **Warum das jetzt kommt.** Der Absturz vom 31.7. um 21:58 trug „OHNE
> ABSCHIED", geschah im **klassischen** Design – die Glasflächen aus 1.77.0
> waren es also nicht – und zwar bei **980 Elementen und 6 Bildern**, während
> fotografiert wurde. Die Seite war winzig, der JS-Speicher bei 6 MB. Was in
> diesem Moment groß ist, ist das entpackte Foto.
## 1.83.0 – Juli 2026
### Neu
- 🖐 **Mehrere Rahmen sammeln.** Die automatische Trennung sucht senkrechte
Lücken – sie ist für Figuren gemacht, die **nebeneinander** stehen. Liegen
sie kreuz und quer oder versetzt hintereinander, gibt es keine Lücke, an
der sich schneiden ließe. Deshalb jetzt: Rahmen ziehen, **➕ Rahmen
merken**, für jede weitere Figur wiederholen, **🔎 Alle erkennen**. Das
funktioniert bei jeder Anordnung, weil die Grenzen von Hand kommen
### Behoben
- 🟩 **Zwei grüne Rahmen mit zwei Bedeutungen.** Der Rahmen des
Erkennungsdienstes stand neben den nummerierten und sah aus wie eine
weitere Figur. Er trägt jetzt die Beschriftung **„hier geschaut"** und
verschwindet, sobald nummerierte Rahmen da sind
> **Was ich versucht und wieder verworfen habe.** Eine Trennung in Flächen
> statt Streifen, damit auch kreuz und quer liegende Figuren automatisch
> gefunden werden. In vier Anläufen kippte das Ergebnis jedes Mal: mal fehlten
> Figuren, mal wurde ein Lichtreflex mitgezählt. Jede Stellschraube half
> einem Fall und schadete einem anderen. Statt weiter an Schwellwerten zu
> drehen, bleibt die Automatik bei dem, was sie nachweislich kann – Figuren
> nebeneinander – und für alles andere gibt es den Weg von Hand, der immer
> stimmt.
## 1.82.0 – Juli 2026
### Neu
- ➕ **Die BrickLink-Endung kommt beim Erfassen von selbst dazu.** Wer bei
einem Set `21306` eintippt – die Zahl von der Packung –, bekommt `21306-1`
und landet damit sofort in derselben Zeile wie ein gescanntes Exemplar.
Vorbeugen statt hinterher zusammenführen. Gilt auch für Wunschliste und
CSV-Import
- 🏷 **Der Katalogname hat Vorrang.** Sind die BrickLink-Schlüssel hinterlegt,
wird beim Ergänzen der Nummer gleich der offizielle Name übernommen –
„Yellow Submarine" statt „gelbes U-Boot vom Flohmarkt". Ohne Schlüssel
bleibt der eingetippte stehen, und eine Erfassung scheitert nie daran,
dass der Katalog gerade nicht antwortet
- Beim Zusammenführen zweier Zeilen gilt derselbe Grundsatz: Es bleibt die
BrickLink-Zeile **samt ihres Namens**
> **Angefasst wird nur, was eindeutig ist:** eine reine Zahl bei einem
> **Set**. Figurennummern, Teilenummern, eigene Nummern und alles mit
> vorhandener Endung bleiben unverändert.
## 1.81.0 – Juli 2026
### Neu
- 🔗 **Dieselbe Nummer, zweimal erfasst.** Auf der Packung steht `21306`,
BrickLink führt dasselbe Set als `21306-1`. Wer eines von Hand einträgt und
das andere scannt, hatte zwei Zeilen für ein Set – und die Sammlung zählte
es doppelt. Die App erkennt solche Paare jetzt und fragt auf der Scan-Seite
nach, mit **zwei** Antworten statt einer:
- **Ein Exemplar** – derselbe Kasten, zweimal erfasst. Eine Zeile bleibt,
das Kaufbuch der aufgegebenen fällt weg (sonst stünde der Betrag doppelt
drin)
- **Zwei Exemplare** – ihr besitzt wirklich zwei. Stückzahlen werden
addiert, beide Käufe bleiben im Kaufbuch
- Bleiben darf die Zeile mit der **BrickLink-Nummer** – sie hat Preise,
Set-Inhalte und passt zum Katalog
> **Wo die App sich heraushält:** Bei zwei echten Varianten wie `21306-1` und
> `21306-2` kommt kein Hinweis. Das sind zwei verschiedene Ausgaben, und
> welche gemeint ist, weiß nur der Mensch davor. Aus demselben Grund führt
> die App auch nichts von allein zusammen.
## 1.80.0 – Juli 2026
### Behoben
- 📷 **Figurentrennung, die auch in der Vitrine funktioniert.** Der erste
Anlauf (1.79.0) verglich jeden Bildpunkt mit einer aus dem Bildrand
geschätzten Hintergrundfarbe. Auf weißem Papier geht das – in einer
Vitrine nicht: Das Glas spiegelt, der Regalboden ist hell, die Rückwand
blaugrau und die Figuren sind genau so blaugrau. Es gibt keine Farbe, von
der sie sich abheben
- Jetzt zählt **Struktur statt Farbe**: Wo eine Figur steht, wechseln
Helligkeiten dicht an dicht – Helm, Arme, Gürtel; die Lücke daneben ist
ruhig. Geschnitten wird in den Tälern dieser Kantendichte, und zwar dort,
wo sie **ausgeprägt** sind: Gemessen lagen echte Lücken bei einer
Ausprägung von 58, Rauschen bei 17 bis 22
- 🔢 **Die Zahl lässt sich nachbessern.** Unter dem Bild steht, wie viele
Figuren gefunden wurden, mit **−** und **+**. Wer die Zahl ändert, bekommt
das Bild gleichmäßig geteilt und alles erneut abgefragt – das hilft bei
Figuren, die sich berühren, wo es keine Lücke zum Schneiden gibt
- ✂️ **Der Ausschnitt geht über die volle Bildhöhe.** Vorher endete er dort,
wo die Kantendichte nachließ – und das ist bei einer Figur der Helm:
rund, ruhig, kaum Kanten. Gemessen fehlte er im Ausschnitt
## 1.79.0 – Juli 2026
### Neu
- 🔎 **Alle Figuren auf einem Bild erkennen.** Der Dienst kann nur **ein**
Objekt je Anfrage – also trennt die App die Figuren jetzt selbst: Sie
schätzt aus dem Bildrand die Hintergrundfarbe, sucht die abweichenden
Flecken, fasst Kopf, Körper und Beine einer Figur zusammen und schickt
jeden Bereich einzeln zur Erkennung. Die Figuren werden nummeriert
eingerahmt, darunter steht für jede eine eigene Karte
- Ein Foto von vier Figuren statt vier Fotos
> **Bedingung:** einfarbiger Hintergrund und etwas Abstand zwischen den
> Figuren – dieselben Bedingungen, die der Erkennung ohnehin guttun. Findet
> die Trennung nur eine Figur, sagt die App das; dann hilft der Rahmen von
> Hand aus 1.78.0.
## 1.78.0 – Juli 2026
### Neu
- 🔍 **Mehrere Figuren auf einem Bild.** Die Erkennung sucht **ein** Objekt je
Anfrage – so ist der Dienst gebaut, seine Antwort enthält genau einen
Rahmen. Bisher hieß das: Bei fünf Figuren auf dem Tisch riet sie über eine
davon, und niemand sah, über welche.
- Jetzt umrahmt die Vorschau die erkannte Figur **grün**, und für die
übrigen zieht man einfach einen **eigenen Rahmen** und tippt auf
**🔍 Diesen Ausschnitt erkennen**. Zugeschnitten wird im Browser, zum
Server geht nur der Ausschnitt – bei fünf Figuren fünf Rahmen statt fünf
Fotos
## 1.77.0 – Juli 2026
### Neu
- 🪟 **Eigene Fenster statt Browser-Abfragen.** Sechs Stellen benutzten das
graue `prompt()` des Browsers – eigene Schrift, eigene Farben, und für
zwei Angaben zwei Fenster hintereinander. Jetzt fragt ein Fenster im Stil
der App alles auf einmal: weiterer Kauf, neue Liste, mehr Einladungen,
Passwort setzen. Mit Enter bestätigen, mit Esc abbrechen
### Verbessert
- 🧊 **Nova: weniger Glasflächen.** „Glas" heißt, dass der Browser den
Hintergrund in Echtzeit weichzeichnet – jede solche Fläche kostet ihn eine
eigene Zeichenfläche im Grafikspeicher, und **den sieht keine Messung**.
Auf den Einstellungen lagen so **19 davon gleichzeitig**, und die Karte im
Popup zeichnete weich, was die Überlagerung darunter schon weichgezeichnet
hatte. Mehrfach vorkommende Flächen tragen jetzt eine durchscheinende
Farbe – kaum zu sehen, aber statt rund zwanzig Zeichenflächen sind es drei
- 🔍 **Das Design steht jetzt im Speicher-Verlauf.** Nur so lässt sich
überhaupt feststellen, ob Abstürze an Nova hängen
> **Warum das jetzt kommt.** Der Absturz vom 31.7. um 20:36 trug „OHNE
> ABSCHIED" – ein echter also – und passierte bei **2.005 Elementen und 64
> Bildern**. Die Seite war winzig. Damit ist klar, dass die Bilder nicht die
> Ursache waren; die Kosten liegen woanders, und Echtzeit-Weichzeichner sind
> der nächste Ort, an dem sie außerhalb jeder Messung anfallen.
## 1.76.1 – Juli 2026
### Verbessert
- 🧹 **Die Kaufpreis-Ecke der Karte aufgeräumt.** „Bezahlt" stand zweimal
untereinander – einmal als Feld, einmal am Anfang der Gewinnzeile. Jetzt
steht der Betrag einmal, das **+ für einen weiteren Kauf** sitzt am Ende
derselben Zeile statt als eigener Knopf in der Fläche, und die Gewinnzeile
beginnt mit dem Wert. Ohne Marktpreis fällt sie ganz weg, statt nur den
Betrag von oben zu wiederholen
## 1.76.0 – Juli 2026
### Neu
- 🧾 **Kaufbuch: mehrere Käufe zum selben Artikel.** Dasselbe Set einmal bei
LEGO für 39,99 € und einmal im Markt für 34,99 € – in der Sammlung war das
**eine** Zeile mit Stückzahl 2, und danach ließ sich nicht mehr sagen,
welcher Kauf welcher war. Jetzt steht unter der Gewinnzeile die
Aufstellung: Stückzahl, Preis, Quelle, Datum. **+ Weiterer Kauf** trägt
einen Posten ein (die Stückzahl wächst mit), **✕** nimmt ihn zurück
- Gilt für **Sets und Figuren** gleichermaßen – der Kauf hängt am Eintrag,
nicht am Typ
- Der bisherige Bestand wird **übernommen**: Was heute als Kaufpreis
dasteht, wird beim ersten Start ein Posten im Buch
> **Was sich nicht ändert.** Oben steht weiterhin die Summe, und mit ihr
> rechnen Statistik, Gewinn und die Einkaufslisten. Damit Summe und
> Aufstellung nicht auseinanderlaufen können, gehen alle sechs Stellen, die
> bisher einen Kaufpreis geschrieben haben – Anlegen, Zusammenführen,
> CSV-Import, Zustandswechsel, Bearbeiten, Verbuchen aus der Liste – jetzt
> durch denselben Weg.
## 1.75.0 – Juli 2026
### Neu
- 💬 **Ungelesene Nachrichten sieht man sofort.** Bisher stand der Zähler nur
am Unter-Reiter im Tausch-Bereich – wer woanders war oder die App gerade
erst geöffnet hatte, merkte von einer neuen Nachricht nichts. Jetzt sitzt
ein Zeichen mit der Zahl **oben in der Kopfzeile**, von jedem Tab aus
sichtbar. Ein Tipp führt direkt zu *Tausch → Meine Vorgänge*
- Ist nichts offen, ist auch **kein Zeichen** da – die Kopfzeile bleibt so
ruhig wie vorher
- Beim Öffnen der App wird **einmal beim Hub nachgefragt**, statt nur den
zuletzt bekannten Stand zu zeigen. Sonst stünde die Zahl bis zum nächsten
Takt auf dem Wert von gestern
## 1.74.1 – Juli 2026
### Behoben
- 💬 **„Anfrage senden" ging gar nicht.** Der Wegweiser für
`POST /api/hub/trades` stand seit dem 29. Juli über der falschen Funktion:
Beim Einbau der Schlüsselprüfung landete eine interne Hilfsfunktion
zwischen dem Wegweiser und dem Vorgang, der dort hingehört. Seitdem
beantwortete diese Hilfsfunktion die Anfrage – und verlangte eine Angabe,
die die App gar nicht schickt. Ein Test prüft jetzt, dass **keine** Route
auf eine Hilfsfunktion zeigt
- 🇩🇪 **Halb deutsch, halb englisch.** Die Eingabeprüfung im Server schreibt
englisch („Field required"), und das stand ungefiltert mitten im deutschen
Satz. Jetzt wird daraus ein ganzer Satz in der eingestellten Sprache:
„Eingabe nicht gültig: Da fehlt eine Angabe" bzw. „Invalid input:
Something is missing here"
## 1.74.0 – Juli 2026
### Verbessert
- 🧱 **Die Sammlung kommt blockweise.** Bisher entstanden beim Öffnen alle
Karten auf einen Schlag – bei 815 Einträgen **14.697 Elemente und 837
Bilder** in einem Rutsch. Jetzt sind es die ersten 60; der Rest kommt beim
Scrollen nach. Gemessen mit denselben 815 Einträgen: **1.952 Elemente,
64 Bilder, 28 Bilder vom Server** beim Öffnen
- 👁 **Was weit außerhalb des Fensters liegt, wird nicht mehr gezeichnet.**
Selbst wenn man sich durch die ganze Sammlung scrollt und am Ende alle
815 Karten im Dokument stehen, hat der Browser nur **82 Bilder** geholt
und 60 entpackt – der Rest wird übersprungen und darf wieder weg
- 🗂 **Zugeklappte Themen kosten nichts mehr.** Nach Thema gruppiert wurden
bisher auch die zugeklappten Gruppen mit allen Karten aufgebaut. Jetzt
füllt sich eine Gruppe erst, wenn man sie sieht: **163 statt 815 Karten**
beim Öffnen
> **Warum das der Punkt war.** Der JS-Speicher blieb bei allen Abstürzen
> flach – entpackte Bilder liegen außerhalb und tauchen dort nicht auf.
> 837 Bilder auf einmal sind entpackt ein halbes Gigabyte, und das war die
> letzte Stelle, an der die App das noch tat.
## 1.73.1 – Juli 2026
### Behoben
- 🪧 **Der Abschiedszettel lag am falschen Ort und wurde falsch gelesen.**
Zwei Fehler, beide beim ersten Einsatz aufgefallen: Er lag im
`sessionStorage`, und der verschwindet ausgerechnet dann, wenn die App
geschlossen wird – also im häufigsten *sauberen* Fall. Und verglichen
wurde mit der Uhr (10 Sekunden), nicht mit dem letzten Messwert. Wer die
App zumachte und später wieder aufmachte, wäre als Absturz gezählt worden.
Jetzt liegt der Zettel im `localStorage` und gilt, wenn er **nach** dem
letzten Messwert geschrieben wurde – egal wie lange das her ist
- ⏱ **Die 90-Sekunden-Frist ist weg.** Sie war der Notbehelf, solange es den
Zettel nicht gab. Ein Absturz um 21:08, bemerkt beim Wiederöffnen um 21:16,
fiel damit durchs Raster – der Eintrag trug „OHNE ABSCHIED", die
Zusammenfassung meldete trotzdem nichts
- 🔐 **Antwort ohne JSON wird nicht mehr verschluckt.** Sitzt zwischen App und
Instanz ein Zugangsschutz (Cloudflare Access) oder ein Zwischenserver, kommt
dessen Anmeldeseite zurück – als HTML, mit Status 200. Daraus wurde
stillschweigend ein leeres Objekt, die Oberfläche baute darauf weiter und
fiel erst viel später über ein fehlendes Element. Jetzt sagt sie sofort,
was los ist
## 1.73.0 – Juli 2026
### Verbessert
- 🪧 **Der Abschiedszettel.** Bisher blieb ein Rest Rätselraten: Ein Neuladen
von Hand sah im Verlauf genauso aus wie ein Absturz. Jetzt hinterlässt die
Seite beim Verlassen eine Notiz – das passiert bei jedem gewollten Ende
(neu laden, weiterklicken, schließen) und ausgerechnet **nicht**, wenn der
Browser sie abwürgt. Fehlt die Notiz, war es wirklich ein Absturz.
Der Verlauf sagt das jetzt im Klartext: „ohne sich zu verabschieden – das
ist ein echter Absturz" gegen „von Hand neu geladen – kein Absturz"
- 🗂 **Ein zweiter Tab zählt nicht mehr als Absturz.** Wer die App noch einmal
öffnet, während die erste Sitzung läuft, hat weder Notiz noch Vorgeschichte
– das sah aus wie ein Abbruch und war keiner
## 1.72.0 – Juli 2026
Aus einem Belastungstest: 132 Endpunkte, bis zu 5.041 Einträge, alle Tabs.
Angemeldet, Rechte, Einschleusung, XSS, Pfad-Ausbruch – alles dicht. Was
nicht gehalten hat, steht hier.
### Behoben
- 🇬🇧 **Der Export war deutsch, auch auf Englisch.** Druckausgabe und CSV
hatten ihre Überschriften fest im Code: „Nummer, Name, Jahr, Anz., Zustand".
Jetzt laufen Titel, Spalten, Dateinamen und Zahlenformat über die
Übersetzung – und die Geldspalten tragen die **eingestellte Währung** statt
eines festen „(EUR)"
- 💥 **CSV-Import stürzte ab statt zu meckern.** Ein einzelnes
Anführungszeichen ohne Gegenstück macht aus dem Rest der Datei ein Feld; ab
128 KB gab Python auf und der Server antwortete mit einem nackten
„Internal Server Error". Jetzt kommt der Satz, der weiterhilft
- 🔀 **Zwei Leute, derselbe Artikel, im selben Moment.** Beide Anfragen sahen
„gibt es noch nicht", eine legte an, die andere lief in die eindeutige
Bedingung – Serverfehler, und ihr Stück war weg. Jetzt wird daraus
nachträglich das Zusammenführen
- 🧾 **„… in 3 von 12 Setsvon 12 Sets"** – in der Druckausgabe der fehlenden
Set-Figuren stand die Zahl doppelt
- 🔎 **Suche ohne Treffer zeigte eine leere Fläche.** Kein Hinweis, kein
Ladezeichen – man wusste nicht, ob nichts passt oder noch geladen wird.
Jetzt steht „Nichts gefunden" da, mit einem Knopf, der die Filter räumt
- 🔌 **„Failed to fetch".** Ist die Instanz nicht erreichbar (NAS schläft,
VPN weg, Update läuft), stand diese englische Browser-Meldung als ganzer
Inhalt in der Statistik. Jetzt: „Keine Verbindung zur Instanz. Läuft der
Server, und ist das Gerät im richtigen Netz?"
### Verbessert
- 🧹 **Die Sammlung gibt den Platz frei, wenn man sie verlässt.** Bisher
blieben alle Karten im Dokument stehen, auch in der Statistik – gemessen
bei 400 Einträgen: **5.731 → 988 Elemente**, bei 815 sind es rund 13.800
weniger. Die Daten bleiben im Speicher, beim Zurückkommen ist die Liste
sofort wieder da
- 🔒 **`item_type` wird geprüft** – bisher landete „raumschiff" klaglos in
der Datenbank und tauchte danach in Adressen und Auswertungen wieder auf.
Und **Bildadressen** nehmen nur noch die eigene Instanz oder http(s);
`javascript:` und `data:` sind raus (ausgeführt wurde davon nie etwas, die
CSP hat es abgefangen – in der Datenbank hatte es trotzdem nichts verloren)
## 1.71.0 – Juli 2026
### Neu
- ↓ **Nach unten ziehen lädt neu.** Vom Startbildschirm gestartet fehlt die
Adressleiste – und damit der Knopf zum Neuladen; auf iOS gibt es dort auch
keine Geste dafür. Jetzt kommt ein Stein von oben mit dem Finger herunter,
färbt sich grün, sobald es reicht, und beim Loslassen lädt die Seite neu.
Nur in der App: Im Browser bringt die Adressleiste das schon mit, zwei
Anzeigen übereinander wären keine Verbesserung
> Der Zug greift nur ganz oben und nur, wenn kein Popup offen ist – und er
> fängt weder das Scrollen noch das Wischen zur Seite ab. Das Neuladen trägt
> sich als **„Nach unten gezogen"** in den Speicher-Verlauf ein, damit es
> dort nicht als Absturz erscheint.
## 1.70.1 – Juli 2026
### Verbessert
- 🔍 **Der Verlauf sagt jetzt, *warum* eine Sitzung neu begann.** Bisher galt
jeder Start kurz nach dem letzten Messwert als Absturz – auch dann, wenn die
App sich selbst neu geladen hatte. Genau das passiert nach jedem
Server-Neustart, damit niemand mit veraltetem Code weiterarbeitet. Im
Verlauf vom 30.7. steht der Beweis: Der „Absturz" um 09:19:44 war das Update
auf 1.70.0, eine halbe Minute später lief die neue Version. Jetzt trägt
jedes gewollte Neuladen seinen Grund, und die Zusammenfassung zählt getrennt:
„ohne erkennbaren Grund", „vom Browser weggeräumt", „App selbst neu geladen"
- 🖥 **Die Startzeit des Servers steht in jedem Messwert.** Springt sie, ist der
Container neu gestartet – das ist im Verlauf jetzt direkt zu sehen, statt es
aus einem Neustart der Seite erraten zu müssen
- 🧹 **Der Browser verrät, wenn er den Tab weggeräumt hat** (`wasDiscarded`).
Das tut er bei Speichermangel – es ist der einzige Hinweis auf Speicher, den
er einer Seite gibt, und damit der erste belastbare statt eines vermuteten
## 1.70.0 – Juli 2026
### Behoben
- 💥 **Der abstürzende Tab.** Der Speicher-Verlauf aus 1.69.0 hat die Stelle
gezeigt: 6 MB JS-Speicher, flach über elf Minuten, 14.680 Elemente,
815 Bilder – und dann weg. Die Kurve blieb flach, also lag es woanders.
Es lag am **weichen Hintergrundbild der Sammlungskarten**: Jede Karte trug
ein zweites Bild, und für CSS-Hintergründe gibt es kein `loading="lazy"`.
Mit 815 Einträgen nachgestellt – identisch bis auf 100 Elemente genau –
holte das Öffnen der Sammlung **815 Bilder auf einmal**, ohne eine Zeile zu
scrollen. Entpackt ist das ein halbes Gigabyte, und das steht nirgends im
JS-Speicher. Jetzt bekommt eine Karte ihr Hintergrundbild erst, wenn sie in
die Nähe des Fensters kommt, und gibt es wieder her, wenn sie weit weg ist:
gemessen **54 statt 815** Bilder beim Öffnen, und beim Weiterscrollen
wandert ein Fenster von rund 40 Karten mit
### Verbessert
- 🔒 **Auch die Hintergrundbilder laufen jetzt über die eigene Instanz.**
Sie hingen als einzige noch am Original bei BrickLink – damit verriet jede
angezeigte Karte, was hier steht, und geladen wurde die unverkleinerte
Fassung. Jetzt gilt für sie derselbe Weg wie für die Kartenbilder
## 1.69.0 – Juli 2026
### Neu
- 🩺 **Speicher-Verlauf im Fehlerbericht.** Ein abgestürzter Tab hinterlässt
normalerweise nichts – keine Konsole, kein Protokoll. Deshalb misst die App
jetzt alle 30 Sekunden JS-Speicher, Zahl der Elemente und Zahl der Bilder
und legt das **im Browser** ab, wo es einen Abbruch übersteht. Nach dem
nächsten Start steht da, was in den zwei Stunden davor passiert ist, samt
Kurve
- ⚠️ **Abstürze werden erkannt und gezählt.** Folgt der Beginn einer Sitzung
unmittelbar auf einen Messwert, ohne dass jemand neu geladen hat, war es
ein Abbruch. Senkrechte Linien in der Kurve zeigen, wo
- 📋 Der Verlauf lässt sich als Text kopieren; er bleibt auf dem Gerät
> **Was die Zahl aussagt – und was nicht.** Gemessen wird der
> JavaScript-Speicher. Entpackte Bilder und der Seitenaufbau stecken da nicht
> drin. Wächst die Kurve, liegt es an der App. Bleibt sie flach, während der
> Tab trotzdem stirbt, liegt es sehr wahrscheinlich woanders. Auch das ist
> ein Ergebnis.
## 1.68.5 – Juli 2026
### Verbessert
- 🖼 **Bilder werden vor Anzeige und Versand verkleinert.** Ein
Bildschirmfoto in 4K belegt entpackt **32 MB** im Browser – obwohl die
Vorschau es auf 300 Pixel Höhe zeigt und der Server es ohnehin auf 1200
Pixel bringt, bevor er es zur Erkennung weiterreicht. Jetzt passiert das
gleich im Browser: aus 32 MB werden 3 MB, und statt 10 MB gehen 250 KB
durch die Leitung. Für die Erkennung ändert sich nichts – der Server hat
auch vorher nur die verkleinerte Fassung gesehen
- 🧹 **Der Zwischenspeicher der Übersetzung mistet aus.** Er hält Verweise auf
Elemente, um beim Sprachwechsel zurücksetzen zu können. Neu gezeichnete
Listen ließen die alten darin zurück – bei tausend Karten summiert sich
das. Betraf nur die englische Fassung
## 1.68.4 – Juli 2026
### Behoben
- 🧠 **Jedes hineingezogene Bild blieb für immer im Speicher.** Die
Scan-Vorschau erzeugt für das gewählte Foto eine Objekt-Adresse – und die
hält die Datei bis zum Neuladen der Seite fest, auch wenn längst ein
anderes Bild angezeigt wird. Drei andere Stellen in der App geben ihre
Adressen ordentlich frei, ausgerechnet diese nicht. Wer nacheinander
Bildschirmfotos in die Erkennung zieht, sammelte sie also alle an: ein
2560×1440-Foto belegt entpackt rund **14 MB**. Nach ein paar Dutzend
beendet der Browser den Tab – bei Edge mit „Auf dieser Seite gibt es ein
Problem". Jetzt wird die vorherige Vorschau freigegeben, sobald die
nächste kommt
- 🧪 Ein Test zählt `createObjectURL` gegen `revokeObjectURL` in `app.js` –
wer künftig eine Adresse erzeugt, ohne sie freizugeben, fällt auf
## 1.68.3 – Juli 2026
### Behoben
- 📷 **Das eigene Foto war in der Vorschau nie zu sehen.** Sie zeigt das
gerade aufgenommene oder hereingezogene Bild als `blob:` aus dem
Arbeitsspeicher, noch bevor es hochgeladen ist – und genau dieses Schema
fehlte in den Sicherheits-Regeln. Der Browser blockierte also ausgerechnet
das Bild, das man selbst ausgewählt hatte, und es blieb beim Platzhalter.
Aufgefallen ist es, weil der Fehlerbericht seit 1.60.2 blockierte Inhalte
meldet: „Vom Browser blockiert: img-src → blob"
### Vorbeugend
- 🧪 **Ein Test leitet aus dem Quelltext ab, welche Schemata die Oberfläche
benutzt**, und prüft, ob die Regeln dazu passen – statt eine feste Liste
abzuhaken. Das ist der vierte Fall dieser Art (Katalogbilder, Bild-Ersatz,
Design-Setzen, jetzt die Vorschau); eine Liste, die jemand pflegen muss,
hätte ihn wieder nicht gefunden
## 1.68.2 – Juli 2026
### Behoben
- 🎨 **Der Scan-Knopf war in Nova die Warnfarbe.** Er nutzt `--red` – im
hellen Design das LEGO-Rot, und dort sieht er auch genau richtig aus. In
Nova ist Rot aber die Farbe für Löschen und Verlust. Der wichtigste Knopf
der App stand damit als große pinke Fläche da und las sich wie eine
Fehlermeldung. Jetzt in der Akzentfarbe des Designs, mit dunkler Schrift
wie auf allen anderen hellen Flächen dort, einem leichten Verlauf und
passenden Noppen. Klassisch und Galaxie bleiben unverändert rot
## 1.68.1 – Juli 2026
### Verbessert
- 🏷 **Der Hub sagt jetzt, welcher Stand läuft.** Bisher hatte der Worker
keine Versionsnummer – nach einem Deploy war nirgends abzulesen, ob der
neue Code tatsächlich oben ist. Die Zahl in der Admin-Konsole ist deren
**eigene** und steht nur zufällig neben „Hub-Admin", was leicht zu
verwechseln ist. `/v1/health` und `/v1/me` nennen den Hub-Stand jetzt
ausdrücklich (`version` bzw. `hub_version`), beginnend bei **1.4.0**
## 1.68.0 – Juli 2026
Zweiter Teil der Durchsicht: der Hub und der Weg dorthin. Ein struktureller
Fund, zwei kleinere.
### Sicherheit
- 🔐 **Der Hub verteilt die Verschlüsselungs-Schlüssel – und konnte damit
dazwischengehen.** Die Nachrichten sind Ende-zu-Ende verschlüsselt, aber
verschlüsselt wird mit dem Schlüssel, den der Hub liefert. Wer ihn
kontrolliert, hätte statt des echten einen eigenen ausliefern und
mitlesen können, ohne dass es auffällt. Keine Hintertür im Programm, aber
die Stelle, an der man dem Hub vertrauen musste. Dagegen jetzt:
- **Die Instanz merkt sich jeden Schlüssel beim ersten Mal.** Taucht später
ein anderer auf, wird **nichts verschickt**, sondern abgebrochen. Ein
Wechsel kann harmlos sein – unterscheiden lässt es sich nur durch
Nachfragen; danach bestätigt ein Admin den neuen Schlüssel
- **Sicherheitsnummer zum Vergleichen** im Gespräch: zwei kurze Zahlenreihen,
einmal am Telefon vorgelesen. Stimmen sie, ist niemand dazwischen
- 🎟 **Ein Einladungscode konnte doppelt eingelöst werden.** Prüfen und
Einlösen waren zwei Schritte – zwei gleichzeitige Anmeldungen mit demselben
Code kamen beide durch. Jetzt ein einziger Schritt, und wer verliert, wird
gar nicht erst angelegt
- 🤐 **Der Hub verriet bei einem internen Fehler dessen Wortlaut.** Solche
Texte können Tabellennamen oder Abfragen enthalten. Sie stehen jetzt nur
noch im Worker-Protokoll, das der Hub-Admin sieht
### Geprüft und in Ordnung
- **Zugriff auf fremde Vorgänge**: Jeder Nachrichten- und Löschzugriff prüft,
ob man überhaupt beteiligt ist
- **Token** sind 192 Bit Zufall und liegen nur als SHA-256 im Hub
- **SQL im Worker** läuft durchgehend über gebundene Parameter
- **Keine Rechte-Erhöhung**: Der Endpunkt zum Ändern des eigenen Profils fasst
nur den Anzeigenamen an – „Admin" lässt sich nicht mitschicken
- **Was der Hub überhaupt sieht**: veröffentlichte Angebote (Nummer, Name,
Zustand, Menge, Vorschaubild) und Vorgangsdaten. Sammlung, Preise, Notizen
und Einkaufslisten bleiben zu Hause
### Offen
- **Keine Ratenbremse im Hub.** Für ein Netzwerk unter Bekannten mit
Einladungspflicht vertretbar; wächst es, gehört das nachgezogen
## 1.67.0 – Juli 2026
Ergebnis einer systematischen Durchsicht: alle 129 Endpunkte und ihre Rechte,
SQL, Dateipfade, XSS (mit vergifteten Daten in jedem Feld), der Update-Weg,
die Sitzungslogik. Zwei echte Lücken, beide behoben.
### Sicherheit
- 🔐 **Ein Passwortwechsel beendet jetzt alle bisherigen Sitzungen.** Bisher
blieb ein einmal ausgestelltes Token **90 Tage** gültig – auch nach einem
Passwortwechsel. Wer sein Passwort änderte, weil ein Gerät abhandengekommen
war, sperrte es damit *nicht* aus. Jetzt zählt jeder Wechsel einen Stand
hoch, den jedes Token mitführt; das eigene Gerät bekommt eine frische
Sitzung und bleibt drin. Dasselbe beim Zurücksetzen durch einen Admin und
beim Abnehmen des zweiten Faktors – gerade dort ist es der Sinn der Sache
- 🤐 **Fehlermeldungen kannten nur die Hälfte der Geheimnisse.** Entfernt
wurden bisher nur die API-Schlüssel und der GitHub-Token. **Hub-Zugang,
privater Hub-Schlüssel und Push-Schlüssel wären stehen geblieben** – und
eine Fehlermeldung kann per Knopfdruck ein **öffentliches** GitHub-Issue
werden. Jetzt gibt es eine Liste, und ein Test schlägt an, sobald eine neue
Einstellung dazukommt, die niemand eingeordnet hat
- 🧪 12 neue Tests dafür, unter anderem: alte Token ohne Zählerstand bleiben
gültig (niemand wird durch das Update ausgeloggt)
### Geprüft und in Ordnung
- **Rechte** kommen bei jeder Anfrage frisch aus der Datenbank – Entzug und
Löschen wirken sofort, nicht erst mit Ablauf der Sitzung
- **SQL**: Werte laufen ausnahmslos über Platzhalter; wo Tabellennamen
eingesetzt werden, stammen sie aus festen Listen im Code
- **Dateipfade**: Uploads über eine strenge Namensprüfung, Sicherungen gegen
eine Positivliste, Katalogbilder über einen Hash – kein Weg nach oben
- **XSS**: mit Schadcode in Artikelnamen, Notizen, Listennamen, Benutzernamen,
Fehlermeldungen und Hinweisen durchgespielt und in allen Ansichten
nachgemessen – nichts wurde ausgeführt, nichts als Markup eingeschleust
- **Der Update-Helfer** liest aus der Markierungsdatei nur eine Zahl und führt
ein festes Skript aus. Selbst wer die Datei schreiben könnte, bekäme keinen
eigenen Befehl ausgeführt
- **Keine CORS-Freigabe**, Sitzung im Header statt im Cookie – damit ist die
klassische Cross-Site-Anfrage kein Thema
## 1.66.2 – Juli 2026
### Behoben
- 🎨 **Die Themenkarten hatten in Galaxy und Nova einen dicken hellen Rahmen.**
Sie fehlten in der Liste der Flächen, die in den dunklen Designs anders
aussehen – und griffen deshalb auf die 2px-Kante des hellen Designs zurück,
die dort aus der Textfarbe gebildet wird und damit fast weiß ist. Jetzt
gleichen sie den Kacheln darüber
- 📕 **Die zugeklappte Karte „Fehlerbericht" zeigte die Benachrichtigung
trotzdem.** Der Kasten trug `display:block` als Inline-Stil, und der schlägt
jede Regel aus dem Stylesheet – auch die fürs Zuklappen. Als Klasse verliert
er diesen Wettstreit und verschwindet mit
## 1.66.1 – Juli 2026
### Behoben
- 🏷 **Neue Sets und Teile bekommen ihr Thema jetzt von selbst** ([#13]).
Bisher blieb es leer, bis jemand *Themen nachladen* drückte – wer das nicht
wusste, sammelte nach und nach Einträge unter „Ohne Thema". Der Abruf läuft
im Hintergrund, hält also das Erfassen nicht auf. Bei Sets zusätzlich noch
einmal, sobald die Set-Inhalte da sind: Erst dann kann der Rückfall über
die Figuren greifen. Ein von Hand gesetztes Thema wird nie überschrieben
- 🖼 **Ein Aussetzer beim CDN wird einmal nachgefasst** ([#12]). Ein einzelner
Netzhänger ließ das Vorschaubild sonst als Platzhalter stehen, bis jemand
die Seite neu lud
- 🔕 **Ein Bild, das nicht lädt, ist kein Fehler mehr.** Als die Bilder noch
direkt vom CDN kamen, war die Meldung berechtigt. Seit sie über die eigene
Instanz laufen, heißt ein Fehlschlag nur: Das CDN hat gerade nicht
geantwortet. Gemeldet wurde es trotzdem – bis hin zu einem GitHub-Issue und
einer Meldung aufs Handy, für ein einziges hakeliges Vorschaubild. Vom
Browser **blockierte** Inhalte werden weiterhin gemeldet
[#12]: https://github.com/Melle79/brickfolio/issues/12
[#13]: https://github.com/Melle79/brickfolio/issues/13
## 1.66.0 – Juli 2026
### Neu
- 🔔 **Benachrichtigung aufs Gerät bei neuen Fehlern.** Web-Push **von der
eigenen Instanz** – einzuschalten je Gerät unter *Mehr → Wartung →
Fehlerbericht*. Damit erfährt man von einem Fehler auch, wenn Brickfolio
gerade zu ist
- 🧪 **Probemeldung senden**, damit sich eine klemmende Zustellung nicht erst
beim echten Fehler zeigt
### Bewusst so gebaut
- 🔑 **Die Schlüssel entstehen auf eurem Server** und bleiben dort; der
private Teil verlässt ihn nie. Ein Test wacht darüber, dass er in keiner
Antwort auftaucht
- 🤐 **Die Meldung sagt nur, *dass* etwas war** – kein Fehlertext, keine
Nummer, nichts aus der Sammlung. Zustellen muss der Push-Dienst des
Browser-Herstellers, anders geht Web-Push nicht; der Inhalt ist dabei
verschlüsselt, aber was gar nicht drinsteht, kann auch nicht auffallen
- 🚫 **Der Tausch-Hub ist nicht beteiligt.** Fehler sind Sache dieser
Instanz. Sie an einen Dienst zu schicken, den jemand anderes betreibt,
wäre genau die Telemetrie, die es hier nicht geben soll
- 🧹 Abonnements, die ins Leere zeigen (App neu installiert), räumt der
Server beim nächsten Versand selbst weg – ein Aussetzer beim Push-Dienst
trägt dagegen **kein** Gerät aus
### Voraussetzungen
- **https** (Cloudflare-Tunnel oder eigenes Zertifikat) – über `http` im
Heimnetz erlauben Browser keine Benachrichtigungen
- Auf dem iPhone die **auf dem Startbildschirm installierte** App
- Neue Abhängigkeit `pywebpush`; fehlt sie, bleibt die Karte einfach aus
## 1.65.0 – Juli 2026
### Neu
- 🔔 **Ein neuer Fehler hinterlässt einen Zettel auf der Startseite.** Bisher
füllte sich das Protokoll still – man musste von sich aus nachsehen. Jetzt
steht dort, dass etwas aufgezeichnet wurde, mitsamt der Meldung und einem
Knopf **Fehlerbericht öffnen**, der direkt zur passenden Karte springt und
sie aufklappt
- 🙈 **Höchstens ein Zettel gleichzeitig.** Ein Problem löst oft mehrere
verschiedene Fehler aus; zehn Karten übereinander helfen niemandem. Ist der
eine weggeklickt, meldet sich der nächste **neue** Fehler wieder –
derselbe zum zweiten Mal nicht
- 👑 **Nur Admins sehen ihn.** Der Fehlerbericht liegt in einer Admin-Karte,
ein Zettel dorthin wäre für alle anderen eine Sackgasse
## 1.64.2 – Juli 2026
### Verbessert
- 🔑 **Liegt ein Token, verschwindet das Eingabefeld.** Es stand sonst leer da
und lud dazu ein, aus Versehen zu überschreiben. Stattdessen stehen dort
jetzt drei Knöpfe: **Token prüfen**, **Ersetzen** (holt das Feld zurück,
ohne den alten zu löschen) und **Token entfernen**
- ⚠️ Das Entfernen fragt nach – GitHub zeigt einen Token **kein zweites Mal**,
wer ihn hier löscht, braucht sonst einen neuen
## 1.64.1 – Juli 2026
### Verbessert
- 🔑 **Beim GitHub-Token sieht man jetzt, ob einer liegt.** Bisher war das nur
daran zu erkennen, dass der Melden-Knopf an einem Fehler auftauchte – und
der taucht erst auf, wenn es überhaupt einen Fehler gibt. Jetzt steht über
dem Feld „Gespeichert: …9999" oder „Kein Token hinterlegt"
- ✅ **Neuer Knopf „Token prüfen".** Er fragt GitHub, ob der Token gültig ist
und das Repository sehen darf, und sagt beim Scheitern, *woran* es liegt:
abgelaufen, oder gültig aber Repository nicht freigegeben. Ob er auch
schreiben darf, prüft GitHub erst beim Schreiben – das sagt die Antwort
ausdrücklich, statt eine Sicherheit vorzugeben, die sie nicht hat
## 1.64.0 – Juli 2026
### Verbessert
- ⚙️ **Der Mehr-Tab ist sortiert.** 17 Karten lagen in einer flachen Liste,
und die Sortierung der Sammlung saß mitten zwischen Admin-Sachen. Jetzt
stehen sie in vier Gruppen, geordnet danach, **wen es angeht**:
🙋 Für dich · 🏠 Diese Instanz · 🌐 Nach außen · 🛠 Wartung. Quellen &
Rechtliches bleibt ohne Gruppe ganz unten
- 🙈 **Leere Gruppen verschwinden mitsamt ihrer Überschrift.** Ein normaler
Benutzer sieht damit nur „Für dich" und die Quellen – statt dreier
Zwischenzeilen ohne Inhalt darunter
## 1.63.2 – Juli 2026
### Behoben
- 🔎 **Ein klemmendes Katalogbild meldete die falsche Adresse.** Seit die
Bilder über die eigene Instanz laufen, stand im Fehlerbericht deren Name –
als wäre der eigene Server kaputt. Gemeldet wird jetzt der Host dahinter,
also der, der wirklich nicht antwortet
## 1.63.1 – Juli 2026
### Behoben
- 🏷 **Der Rückfall über die Figuren lief nur mit BrickLink-Schlüsseln.** Er
stand innerhalb der Schl