- Editor zeigt „Bearbeitet: <Name>“, solange eine gespeicherte Karte gebunden ist,
und bietet „Neue Karte“ (setzt zurück, bricht Laden ab, entfernt ?karte=;
fragt bei ungespeicherten Änderungen per eigenem Dialog „Verwerfen?“)
- EditorState.savedConfig als Vergleichsbasis für ungespeicherte Änderungen
- bindEditorToAuth: Abmelden leert den Editor, Kontowechsel A -> B entkoppelt die
Karte (Entwurf bleibt), Anmelden ohne Vorgänger und abgelaufene Sitzung behalten
den Entwurf; auth.onLogout unterscheidet eigenes Abmelden von bemerktem Ablauf
- Speichern nimmt den Schnappschuss pro Klick (auch für die Wiederholung nach 401)
- save: row_not_found beim Update legt eine neue Karte an (inkl. Aufräumen)
- Karten-Seite: Editor-Abgleich auch nach dem Verlassen der Seite, Löschen-Dialog
wird beim Verlassen geschlossen, keine doppelten Vorschau-URLs
- confirm-dialog als gemeinsames Modul (Löschen, Verwerfen)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- account/cards.ts: Kartendienst (neu/bestehend speichern mit Aufräumen halber
Uploads, Umbenennen, Löschen, Laden) über ein schmales CardsApi-Interface,
Appwrite-Anschluss mit 22.4.1-Objektparametern, fetchFile über
client.prepareRequest (Projekt-Header + Cookie, kein getFileView)
- account/with-login.ts: bei 401 Nutzer neu prüfen, einmal anmelden, wiederholen
- editor/save.ts: Speichern-Ablauf (ein Lauf zur Zeit, 401 -> Login -> einmal
wiederholen, deutsche Fehlermeldung)
- Editor: Speichern mit Schnappschuss und 480-px-Vorschau, Karte öffnen über
?karte=<id>, Bildwechsel während des Speicherns gesperrt
- pages/cards-page.ts: /karten mit Kacheln, Öffnen, Herunterladen, Umbenennen,
Löschen (eigener Dialog), Abmelde- und Leer-Ansicht
- Tests für Dienst, withLogin, Speichern-Ablauf, Karten-Seite und Editor-Anbindung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- login(): bei user_session_already_exists aktuelle Sitzung beenden und genau
einmal neu versuchen; Meldung für den Restfall in errorMessage
- requireLogin(): schlägt showModal fehl, wird aufgeräumt und der Fehler geworfen,
damit spätere Aufrufe nicht an einem toten Promise hängen
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- appwrite 22.4.1 (exakt gepinnt); Client mit Endpoint aus VITE_APPWRITE_ENDPOINT
bzw. location.origin + /v1, Projekt aus VITE_APPWRITE_PROJECT_ID bzw. aircard
- auth.ts: getCurrentUser (401 -> null, ungültige Antwort -> Fehler), login, register,
logout, Passwort-Link anfordern/abschließen, onAuthChange, validatePassword
- errors.ts: deutsche Meldungen nach type, dann code (Tabelle aus dem Plan)
- Login-Dialog (Anmelden/Registrieren/Passwort vergessen) als gemeinsames <dialog>,
Konto-Menü im Seitenkopf, Seite /passwort-neu
- Tests: errors, auth, Dialog, Passwort-neu-Seite
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
web/scripts/appwrite-setup.mjs legt Datenbank aircard, Tabelle cards
(4 Spalten) und Bucket card-images idempotent per fetch an, wartet auf
Spalten-Status available und meldet Abweichungen, ohne sie zu ändern
(--check: nichts anlegen, Exit 1 bei Fehlendem/Abweichendem).
docs/appwrite-console.md ist die Klickliste für Projekt, Plattformen,
Auth, Dienste und API-Key. Tests laufen mit node --test gegen einen
Fake-Appwrite; Vitest nimmt nur src/**/*.test.ts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Store, Upload-Prüfung/Dekodierung und Download-Dateiname mit Tests; drei Spalten
(Vorlagen mit Live-Miniatur, Vorschau mit Ziehen/Zoom, Optionen), einspaltig unter 900 px.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
renderCard zeichnet in 1536 x 969 in fester Reihenfolge (Grund, Bild mit
begrenztem Ausschnitt, Chip, Kontaktlos, Nummer, PLATINUM, Logo, Netzwerk),
drawCard skaliert auf beliebige Canvas ohne Alpha, loadCardAssets wartet
auf Schrift und Logos, exportCard liefert PNG/WebP als Blob.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
loadMarkImage: Cache je (id, tone), eingefärbter Blob mit eigener Größe,
Freigabe der Blob-URL bei load und error, erneuter Versuch nach Fehler.
Neuer Test: jedes url(#...) zeigt auf eine id derselben SVG-Datei.
amex-outline: Rahmen nach außen verschoben, berührt "A" und "S" nicht mehr.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
18 Netzwerk-Logos, AirCards-Symbol/-Text und Apple als bereinigte SVGs
(Wikimedia Commons, gemeinfrei; abgeleitete Varianten selbst gebaut),
Register marks.ts mit Einfärben (currentColor) und Bild-Lader sowie
festfarbiges Favicon.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Vite + TypeScript ohne UI-Framework in web/, exakte Versionen, History-Router
(matchRoute, navigate, startRouter mit Cleanup, a[data-link], popstate),
Grundlayout mit Kopfzeile, Fußzeile und Platzhalterseiten.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>