ClaudeandClaude Opus 5.5 af05e5f1f1 fix(api): Logo löschen blendet das Logo zuerst aus, dann folgen Datei, Herzen, Meldungen und die Zeile
deleteLogo löschte zuerst die Datei und zuletzt die Zeile. Brach es dazwischen ab, blieb eine öffentliche Zeile mit gelöschter Datei stehen: unter
dieser Datei-ID kann jedes Konto im Bucket eine neue Datei anlegen, und alle gespeicherten Karten mit diesem Logo zeigten bis zur Wiederholung deren Bild.

- logos.js: Vor dem Löschen der Datei wird das Logo ausgeblendet wie bei der Admin-Sichtbarkeit (hideLogo: Datei, dann Zeile auf genau die ausgeblendeten
  Rechte mit hidden: true; die Rechte der Zeile bleiben die des Hochladers, auch wenn ein Admin löscht). Ein schon ausgeblendetes Logo überspringt das.
  Danach wie bisher Datei, Herzen, Meldungen, die Zeile zuletzt. Wer nicht löschen darf (403), ändert nichts. Das Zurückziehen von Karten bleibt unverändert.
- Tests: Reihenfolge (Datei und Zeile ausblenden, Datei, Herzen, Meldungen, Zeile); Abbruch nach dem Löschen der Datei bei „Herzen lesen“, „Meldungen lesen“
  und „Zeile löschen“ (Hochlader und Admin): die Zeile bleibt mit genau den ausgeblendeten Rechten, kein Gast liest sie, die Wiederholung vollendet das
  Löschen ohne erneutes Ausblenden; scheitert schon das Ausblenden, ist nichts gelöscht; Fremde und schon ausgeblendete Logos lösen kein Ausblenden aus.
- README und Spec: Reihenfolge beim Löschen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 05:19:57 +00:00

AirCard-IOS

Inoffizielles Hobbyprojekt, mit dem man eigene Kartenmotive für Apple Wallet unter https://aircard-ios.org gestalten kann. Bild hochladen, Vorlage und Community-Logo wählen, als PNG herunterladen – oder mit Konto speichern und in der Community-Galerie veröffentlichen. Keine Verbindung zu Apple, Visa, Mastercard, UnionPay, American Express, JCB oder Discover; Logos und Motive stammen von Nutzern, alle Marken gehören ihren Inhabern.

Funktionen

  • Editor (/gestalten): Bild hochladen, Vorlage, Ausschnitt, Details (Hell/Dunkel) und das Logo oben links (AirCard-IOS) wählen, als PNG herunterladen oder mit Konto speichern („Meine Karten“, /karten).
  • Community-Logos unten rechts auf der Karte: Angemeldete laden Logos hoch (PNG, JPG, WebP oder SVG; der Browser schneidet sie zu, verkleinert sie auf höchstens 720 × 250 px und lädt ein PNG hoch), alle können sie wählen. Eingebaute Marken-Logos gibt es nicht. Je Konto und Logo gibt es ein Herz (nur angemeldet); die Herzen bestimmen die Sortierung „Beliebt“. Logos lassen sich melden (ab 3 Meldern aus verschiedenen Netzen werden sie ausgeblendet) und vom Hochlader löschen; Admins (Label admin) sehen zusätzlich „Gemeldet“ und „Ausgeblendet“.
  • Community-Galerie (Startseite / und /community/<id>): Karten veröffentlichen, ansehen, melden und zurückziehen.
  • Deutsch und Englisch: Die Sprache folgt der Browsersprache; der Sprachknopf in der Kopfzeile schaltet ohne Neuladen um und merkt sich die Wahl. Daneben steht ein GitHub-Link zum Original-Projekt AirCard-iOS.

Aufbau

web/ – Vite + TypeScript ohne Framework. Frontend-Module in src/:

  • card/ – Geometrie, Zuschnitt, Canvas-Rendering (keine DOM-Abhängigkeiten, einzeln testbar)
  • editor/ – UI (Vorlagen, Vorschau, Download, Speichern)
  • logos/ – Community-Logos: Lesen aus Appwrite, Auswahl mit Herzen und Infozeile (Melden, Löschen, Admin), Hochladen mit Aufbereitung im Browser (Zuschnitt, Verkleinern, PNG)
  • community/ – Galerie: Lesen, Veröffentlichen, Melden, Aufrufe des API-Dienstes
  • account/ – Appwrite-Client, Auth, Kartenverwaltung
  • i18n/ – Deutsch und Englisch: t('Deutscher Text') und msg('…'), Wörterbuch Deutsch → Englisch in en.ts (ein Test verlangt für jeden Text einen Eintrag)
  • pages/ – Routen (/, /gestalten, /karten, /community/<id>, /passwort-neu via History-API)
  • shell/ – Kopfzeile (GitHub-Link, Sprachknopf, Hell/Dunkel), Fußzeile, Spenden-Banner

deploy/ – Webhook-Router (Port 8087), Build-Skript (deploy.sh), nginx-Config, Traefik-Route für Appwrite.

docs/ – Spec, Plan, Appwrite-Konfiguration.

Lokal entwickeln

cd web
npm ci
npm run dev          # Entwicklungsserver http://localhost:5173

Login und Speichern brauchen die Appwrite-API. Ohne Einstellung gilt als Endpoint ${location.origin}/v1 (der Entwicklungsserver hat keinen Proxy dafür, es würde also der Vite-Server selbst gefragt). Für die lokale Entwicklung deshalb in web/.env.local (steht über .env* in .gitignore) den Endpoint setzen:

VITE_APPWRITE_ENDPOINT=https://appwrite.webklar.com/v1

Die Projekt-ID ist als Standard im Code hinterlegt (6ac2130a00289343d6d5, VITE_APPWRITE_PROJECT_ID überschreibt sie). Damit Appwrite den lokalen Host akzeptiert, muss die Web-Plattform localhost in der Appwrite-Console eingetragen sein (Projekt → Overview → Integrations → Platforms). Der Produktions-Build bekommt VITE_APPWRITE_ENDPOINT=https://aircard-ios.org/v1 aus der Container-Umgebung (deploy/compose-snippet.yml).

Tests

Im Frontend (web/):

cd web
npx vitest run               # Unit-Tests (alle Module unter src/)
npx tsc --noEmit             # TypeScript-Prüfung, auch der Tests
npm run build                # Produktions-Build; die Prüfung davor nutzt tsconfig.build.json (ohne Tests)

Im Repo-Wurzelverzeichnis:

node --test deploy/webhook-server.test.js        # Webhook-Server (deploy.sh wird dort durch einen Stub ersetzt)
node --test deploy/deploy.test.js                # deploy.sh (echtes Skript, lokaler git-Remote, npm-Stub)
node --test "deploy/api/*.test.js"               # API-Dienst (Glob in Anführungszeichen)
node --test web/scripts/appwrite-setup.test.mjs  # Appwrite-Schema-Skript

Deploy

Automatisch: Push auf main → Gitea-Webhook → Container webklar-aircard-build führt npm ci und npm run build (Typprüfung ohne Tests, dann vite build) aus → Ergebnis nach out/ → nginx webklar-aircard liefert.

Reihenfolge, wenn eine Änderung auch Schema und API braucht (wie die Community-Logos): erst das Schema anlegen, dann die API-Dateien ersetzen und neu starten, zuletzt main pushen. Die Schritte stehen in deploy/README.md, Abschnitt „Reihenfolge bei Änderungen an Schema, API und Seite“.

Manuell:

docker exec webklar-aircard-build sh /deploy.sh

Starten nur mit:

docker compose up -d aircard-build aircard aircard-api

aircard-api ist der kleine API-Dienst der Community-Galerie und der Community-Logos (deploy/api/, Route aircard-ios.org/api, siehe deploy/api/README.md).

Die Appwrite-API wird über /home/webklar/apps/traefik/dynamic/aircard.yml geroutet (Vorlage: deploy/traefik/aircard.yml): Requests auf aircard-ios.org/v1 mit Header X-Appwrite-Project: 6ac2130a00289343d6d5 gehen an den Appwrite-Container. Ohne diesen Header antwortet der nginx der Seite mit 404.

Appwrite

Projekt „AirCard“ auf appwrite.webklar.com:

  • Projekt-ID (öffentlich, von Appwrite generiert): 6ac2130a00289343d6d5. Sie steht in deploy/traefik/aircard.yml, in /home/webklar/apps/.env (AIRCARD_APPWRITE_PROJECT_ID) und als Standard in web/src/account/appwrite.ts.
  • Datenbank: aircard; Tabellen: cards (private Karten), gallery und reports (Community-Galerie, Meldungen), logos, logo_likes und logo_reports (Community-Logos, Herzen, Meldungen); Buckets: card-images, gallery-images und logo-images (das Skript unten legt sie an und prüft sie)
  • Console-Einstellungen laut docs/appwrite-console.md (Soll-Stand, nicht maschinell geprüft; --check prüft nur das Schema): Auth mit E-Mail + Passwort, Sitzungsdauer 30 Tage, max. 5 Sitzungen pro Nutzer, Nutzerlimit 2000, Web-Plattformen aircard-ios.org und localhost. Schritte 3 und 4 dort (Auth-Härtung, Dienste abschalten) sind optional und am Live-Projekt unbestätigt.

Schema prüfen:

node --env-file=/home/webklar/apps/.env web/scripts/appwrite-setup.mjs --check

Schema erstmalig anlegen:

node --env-file=/home/webklar/apps/.env web/scripts/appwrite-setup.mjs

Umgebungsvariablen (in /home/webklar/apps/.env):

  • AIRCARD_APPWRITE_PROJECT_ID – Projekt-ID (idempotent im Skript lesbar)
  • AIRCARD_APPWRITE_API_KEY – API-Key aircard-provision (nur für Setup)

Hinweis

Inoffizielles Hobbyprojekt. Alle Marken gehören ihren Inhabern.

S
Description
No description provided
Readme
1.9 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 74.9%
JavaScript 21.8%
CSS 2.8%
Shell 0.4%
HTML 0.1%