docs: anleitung, changelog 0.3.0 und roadmap zu phase 3
Vier neue Kapitel in der Anleitung (mehrere Sammler, Preise, Erinnerungen, Dubletten) mit vier automatisch erzeugten Bildern, Changelog 0.3.0 samt der bewusst weggelassenen BrickLink-Anbindung, Roadmap abgehakt und um einen offenen Ausblick ergaenzt, Devlog mit Zeiten und Stolpersteinen. Dazu zwei Korrekturen aus dem Testlauf: Der Zeitplan fuer Erinnerungen liess sich nicht aus Next' instrumentation.ts starten - die Datei wird auch fuer die Edge-Runtime uebersetzt, und das native SQLite-Modul bricht dort den Build. Er startet jetzt aus dem Healthcheck heraus, den der Container ohnehin alle 30 Sekunden aufruft, und zusaetzlich aus dem App-Layout; der Aufruf ist idempotent. Der Screenshot-Lauf waehlte ploetzlich die falschen Kacheln aus: Der neue Sammler-Umschalter benutzt ebenfalls aria-pressed. Die Auswahlkacheln tragen jetzt ein eigenes data-set-card. Ausserdem raeumen die Testskripte einen Container weg, den ein abgebrochener Lauf zurueckgelassen hat - sonst blockiert er den Port. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@@ -27,7 +27,11 @@ Kinderzimmer, nicht für den Schreibtisch.
|
||||
13. [Noch ein Konto für die Familie](#13-einladungen)
|
||||
14. [Daten sichern, umziehen, auswerten](#14-daten)
|
||||
15. [Auf den Startbildschirm legen](#15-startbildschirm)
|
||||
16. [Antworten auf die zwei wichtigen Fragen](#16-die-zwei-fragen)
|
||||
16. [Zwei Kinder, ein Katalog](#16-mehrere-sammler)
|
||||
17. [Was ein Set heute wert ist](#17-preise)
|
||||
18. [Erinnerung vor dem Termin](#18-erinnerungen)
|
||||
19. [Schutz vor doppelten Einträgen](#19-dubletten)
|
||||
20. [Antworten auf die zwei wichtigen Fragen](#20-die-zwei-fragen)
|
||||
|
||||
---
|
||||
|
||||
@@ -419,7 +423,115 @@ den Zwischenspeicher, damit auf einem geteilten Gerät nichts lesbar bleibt.
|
||||
|
||||
---
|
||||
|
||||
## 16. Die zwei Fragen
|
||||
## 16. Mehrere Sammler
|
||||
|
||||

|
||||
|
||||
Kommt ein zweites Kind dazu, wird aus „hat er das schon?" die Frage „hat
|
||||
**er** das schon?". Genau dafür gibt es Sammler.
|
||||
|
||||
Der **Katalog bleibt gemeinsam**: Ein Set existiert einmal, unabhängig davon,
|
||||
wer es besitzt. **Sammlung und Wunschlisten** gehören dagegen je einem
|
||||
Sammler. Ein Set, das nur die Schwester hat, fällt für den Bruder wieder unter
|
||||
„fehlt noch" – und darf auf seine Wunschliste.
|
||||
|
||||
> **Solange es nur einen Sammler gibt, siehst du davon nichts.** Kein
|
||||
> Umschalter, keine Abfrage, keine Farben. Die App bleibt genauso einfach wie
|
||||
> vorher. Erst der zweite Sammler schaltet all das frei – und dann willst du
|
||||
> es auch.
|
||||
|
||||
Anlegen unter **Verwaltung → Sammler**. Jeder bekommt einen Namen und eine
|
||||
Farbe zur Unterscheidung.
|
||||
|
||||

|
||||
|
||||
Danach steht in Katalog und Sammlung oben ein Umschalter. „Alle zusammen"
|
||||
zeigt den Haushalt als Ganzes, ein Name zeigt genau dessen Sicht – inklusive
|
||||
der Frage, was **diesem** Kind noch fehlt.
|
||||
|
||||
Beim Hinzufügen zur Sammlung fragt die App jetzt, wer das Set bekommt. Und
|
||||
beim Anlegen einer Wunschliste, für wen sie ist: Das bestimmt, wessen Sammlung
|
||||
als „hat er schon" zählt und wann ein Wunsch automatisch als erfüllt gilt.
|
||||
|
||||
> Die Umstellung einer bestehenden Instanz macht nichts kaputt: Beim Update
|
||||
> entsteht ein Sammler namens „Sammlung", dem alles Vorhandene gehört.
|
||||
> Umbenennen unter **Verwaltung → Sammler**, fertig.
|
||||
|
||||
---
|
||||
|
||||
## 17. Preise
|
||||
|
||||

|
||||
|
||||
Auf jeder Set-Seite gibt es **„Preis notieren"**: Betrag, Zustand (neu oder
|
||||
gebraucht), wann und wo gesehen. Daraus wird eine Reihe – und damit eine
|
||||
Antwort auf die eigentlich interessante Frage: Was hat das Set seit dem Kauf
|
||||
gemacht?
|
||||
|
||||
- **Ursprünglich** ist die UVP des Sets, sonst der älteste notierte Preis.
|
||||
- **Aktuell** ist der neueste notierte Preis.
|
||||
- **Entwicklung** ist die Differenz in Prozent.
|
||||
|
||||
In der Sammlung wird die Kachel „Wert nach UVP" automatisch zu **„Aktueller
|
||||
Wert"**, sobald irgendwo ein Preis notiert ist.
|
||||
|
||||
> Es wird **kein** Preisdienst abgefragt. Was hier steht, hast du selbst
|
||||
> eingetragen – das ist ehrlicher als eine Zahl, deren Herkunft niemand kennt,
|
||||
> und es geht nichts nach draußen.
|
||||
|
||||
---
|
||||
|
||||
## 18. Erinnerungen
|
||||
|
||||

|
||||
|
||||
Wenn ein Wunschlisten-Termin näher rückt und **noch Wünsche offen sind**,
|
||||
schickt Bricktrack dir eine E-Mail – standardmäßig 14 Tage vorher, höchstens
|
||||
einmal pro Woche je Liste. Ist alles reserviert, bleibt es still: eine
|
||||
Erinnerung ohne Handlungsbedarf ist nur Lärm.
|
||||
|
||||
Dafür braucht es einen SMTP-Zugang in der `.env`:
|
||||
|
||||
```bash
|
||||
SMTP_HOST=mail.example.de
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=bricktrack@example.de
|
||||
SMTP_PASSWORD=…
|
||||
SMTP_FROM=Bricktrack <bricktrack@example.de>
|
||||
|
||||
# Optional, Standard ist 14:
|
||||
REMINDER_DAYS_BEFORE=14
|
||||
```
|
||||
|
||||
Unter **Verwaltung → Erinnerungen** kannst du die Verbindung prüfen, dir eine
|
||||
Testnachricht schicken und die Prüfung sofort auslösen, statt auf die nächste
|
||||
Stunde zu warten. Dort steht auch, welche Listen einen Termin haben und wie
|
||||
viel dort noch offen ist.
|
||||
|
||||
Ohne SMTP-Zugang ist die Funktion vollständig aus – alles andere funktioniert
|
||||
unverändert.
|
||||
|
||||
---
|
||||
|
||||
## 19. Dubletten
|
||||
|
||||
Beim Anlegen eines neuen Sets schaut Bricktrack nach, ob es das schon gibt:
|
||||
|
||||
- **gleiche Setnummer beim gleichen Hersteller** – dann ist es dasselbe Set,
|
||||
- **sehr ähnlicher Name** – meist ein Tippfehler oder eine andere Schreibweise,
|
||||
- **gleiche Nummer bei einem anderen Hersteller** – meist der falsche
|
||||
Hersteller im Formular.
|
||||
|
||||
Passt etwas, erscheint ein Hinweis mit Link zu den Verdächtigen. Von dort
|
||||
kommst du direkt zum vorhandenen Eintrag – oder legst mit „Trotzdem anlegen"
|
||||
weiter an, wenn es wirklich ein anderes Set ist.
|
||||
|
||||
Die Erkennung ist bewusst zurückhaltend eingestellt: Tippfehler schlagen an,
|
||||
zwei echte Sets desselben Themas nicht.
|
||||
|
||||
---
|
||||
|
||||
## 20. Die zwei Fragen
|
||||
|
||||
Dafür ist die ganze App gebaut:
|
||||
|
||||
@@ -428,7 +540,8 @@ Dafür ist die ganze App gebaut:
|
||||
|
||||
**„Welche Sets hat er noch nicht?"**
|
||||
→ Katalog, Filter „Fehlt noch". Von dort in zwei Handgriffen auf eine
|
||||
Wunschliste und per Link zu Oma.
|
||||
Wunschliste und per Link zu Oma. Bei mehreren Kindern beantwortet der
|
||||
Umschalter oben die Frage für jedes einzeln.
|
||||
|
||||
Im Laden vor dem Regal: Scanner öffnen, Strichcode einlesen. Steht ein grüner
|
||||
Haken dran, habt ihr es schon.
|
||||
|
||||
@@ -45,6 +45,20 @@ Commit-Spalte verweist auf den Stand am Ende des Schritts.
|
||||
|
||||
**Summe Phase 2: 0:55**
|
||||
|
||||
## Phase 3 – Nice to have (v0.3.0)
|
||||
|
||||
### 07.09.2026
|
||||
|
||||
| Von | Bis | Dauer | Schritt | Ergebnis | Commit |
|
||||
|---|---|---|---|---|---|
|
||||
| 08:35 | 09:00 | 0:25 | Mehrere Sammler | Neue Tabelle, Migration mit Nachziehen der Bestandsdaten, Besitzlogik um eine Dimension erweitert, Umschalter in Katalog und Sammlung, Zuordnung in Sammlungseintrag und Wunschliste | `c23b754` |
|
||||
| 09:00 | 09:13 | 0:13 | Dublettenprüfung | Ähnlichkeitsvergleich mit konservativer Schwelle, Warndialog mit Links, E2E-Test | `87131b8` |
|
||||
| 09:13 | 09:17 | 0:04 | Preisbeobachtung | Preisreihe je Set, Wertentwicklung gegen die UVP, Kachel „Aktueller Wert" | `91fb66b` |
|
||||
| 09:17 | 09:22 | 0:05 | Erinnerungen | SMTP optional, stündliche Prüfung, Sperrfrist je Liste, Verwaltungsseite mit Testfunktionen | `0d08df0` |
|
||||
| 09:22 | 09:50 | 0:28 | Verifikation und Dokumentation | Docker-Build, Smoke-Test, Screenshots, Changelog 0.3.0, Anleitung | folgt |
|
||||
|
||||
**Summe Phase 3: 1:15**
|
||||
|
||||
---
|
||||
|
||||
## Notizen und Entscheidungen
|
||||
@@ -120,6 +134,21 @@ Commit-Spalte verweist auf den Stand am Ende des Schritts.
|
||||
Konfliktregeln für jede Tabelle und wäre im Ergebnis nicht vorhersagbar.
|
||||
Der Import ersetzt deshalb – dafür mit getipptem `ERSETZEN` als Bremse.
|
||||
|
||||
### Phase 3
|
||||
|
||||
- **Migration mit Bestandsdaten**: Die generierte SQL-Datei wurde von Hand um
|
||||
drei Anweisungen ergänzt, die einen Sammler anlegen und alles Vorhandene
|
||||
zuordnen. Ohne das wären nach dem Update alle Sammlungseinträge ohne
|
||||
Besitzer gewesen.
|
||||
- **Instrumentation und native Module**: Der Zeitplan für Erinnerungen liess
|
||||
sich nicht aus Next' `instrumentation.ts` starten – die Datei wird auch für
|
||||
die Edge-Runtime übersetzt, und das native SQLite-Modul bricht dort den
|
||||
Build. Der Zeitplan startet jetzt aus dem Healthcheck heraus, den der
|
||||
Container ohnehin alle 30 Sekunden aufruft.
|
||||
- **BrickLink bewusst weggelassen**: OAuth1 mit einer pro Nutzer registrierten
|
||||
Anwendung ist viel Apparat für eine Zahl, die man in zehn Sekunden eintippt.
|
||||
Im Plan war der Punkt als optional vermerkt.
|
||||
|
||||
### Beim Testen gefunden und behoben
|
||||
|
||||
- Eine spontan aus dem Katalog angelegte Wunschliste war **nicht teilbar**:
|
||||
@@ -130,3 +159,8 @@ Commit-Spalte verweist auf den Stand am Ende des Schritts.
|
||||
`required` des Eingabefeldes.
|
||||
- In der Mehrfachauswahl verdeckte die Aktionsleiste die letzte Kachelreihe;
|
||||
das Raster bekommt im Auswahlmodus zusätzliches Polster nach unten.
|
||||
- Die Sperrfrist der Erinnerungen rechnete mit umgedrehtem Vorzeichen und
|
||||
hätte jede Erinnerung dauerhaft unterdrückt. Der Test dafür war zuerst da.
|
||||
- Der Screenshot-Lauf wählte plötzlich die falschen Kacheln aus: Der neue
|
||||
Sammler-Umschalter benutzt ebenfalls `aria-pressed`. Die Auswahlkacheln
|
||||
tragen jetzt ein eigenes `data-set-card`.
|
||||
|
||||
@@ -46,12 +46,25 @@ Laeuft vollstaendig im Docker-Stack.
|
||||
Sammlung zusaetzlich als CSV
|
||||
- [x] PWA: Manifest, Service Worker, Katalog offline lesbar
|
||||
|
||||
## Phase 3 - Nice to have (Ziel: v0.3.0)
|
||||
## Phase 3 - Nice to have (v0.3.0, abgeschlossen am 07.09.2026)
|
||||
|
||||
- [ ] Mehrere Sammler mit eigener Sammlung und eigenen Wunschlisten,
|
||||
- [x] Mehrere Sammler mit eigener Sammlung und eigenen Wunschlisten,
|
||||
gemeinsamer Katalog
|
||||
- [ ] Preisbeobachtung und Wertentwicklung (manuell gepflegt,
|
||||
optional BrickLink-Preisfuehrer)
|
||||
- [ ] E-Mail-Erinnerung (SMTP), wenn ein Wunschlisten-Termin naeher
|
||||
- [x] Preisbeobachtung und Wertentwicklung (manuell gepflegt).
|
||||
Der BrickLink-Preisfuehrer war als optional vermerkt und wurde
|
||||
bewusst weggelassen: er verlangt OAuth1 mit einer pro Nutzer
|
||||
registrierten Anwendung - viel Apparat fuer eine Zahl, die sich in
|
||||
zehn Sekunden eintippen laesst. Die Datenstruktur ist offen dafuer.
|
||||
- [x] E-Mail-Erinnerung (SMTP), wenn ein Wunschlisten-Termin naeher
|
||||
rueckt und Eintraege unreserviert sind
|
||||
- [ ] Dublettenpruefung beim Anlegen von Sets
|
||||
- [x] Dublettenpruefung beim Anlegen von Sets
|
||||
|
||||
## Danach
|
||||
|
||||
Phase 1 bis 3 sind umgesetzt. Was noch offen ist, steht hier - ohne Termin
|
||||
und ohne Anspruch auf Vollstaendigkeit:
|
||||
|
||||
- [ ] BrickLink-Preisfuehrer anbinden, falls der Aufwand sich doch lohnt
|
||||
- [ ] Mehrere Fotos je Sammlungseintrag (bisher nur je Set)
|
||||
- [ ] Anleitungen im PDF-Viewer durchsuchen
|
||||
- [ ] Statistik ueber die Zeit: was kam wann dazu
|
||||
|
||||
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 288 KiB After Width: | Height: | Size: 294 KiB |
|
Before Width: | Height: | Size: 201 KiB After Width: | Height: | Size: 204 KiB |
|
Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 211 KiB |
|
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 224 KiB |
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 293 KiB After Width: | Height: | Size: 326 KiB |
|
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 301 KiB After Width: | Height: | Size: 343 KiB |
|
Before Width: | Height: | Size: 294 KiB After Width: | Height: | Size: 328 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 238 KiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 185 KiB |