Files
AirCardIOS/docs/superpowers/specs/2026-10-05-aircard-benutzernamen-design.md
T
2026-10-05 06:23:08 +00:00

7.4 KiB
Raw Blame History

AirCard-IOS – Benutzernamen – Design

Stand: 2026-10-05 · Status: Entwurf im Chat von Kenso freigegeben („ja passt, mach weiter“), Spec + Plan + Umsetzung ohne weitere Rückfrage · baut auf 2026-10-04-aircard-logos-sprache-design.md auf (live, main 13b46da)

1. Ziel und Rahmen

Jedes Konto bekommt einen eindeutigen Benutzernamen. Logos und Community-Karten zeigen „von @name“ statt „Anonym“, damit man Leute wiedererkennt.

Punkt Entscheidung (Kenso)
Eindeutig Ja, jeder Name nur einmal; Groß-/Kleinschreibung zählt beim Vergleich nicht.
Pflicht Ja, auch für bestehende Konten. Registrieren nur mit Name; alte Konten werden nach dem Anmelden einmal gefragt; Hochladen und Veröffentlichen gehen erst mit Name.
Anzeige Immer der Benutzername; das Feld „Anzeigename“ fällt weg; gilt auch für vorhandene Einträge des Kontos.
Ändern Ja, im Konto-Menü; danach überall der neue Name, der alte wird frei.

2. Regeln für den Namen

  • Muster: ^[A-Za-z0-9][A-Za-z0-9._-]{2,19}$. Das sind 3–20 Zeichen, das erste ein Buchstabe oder eine Zahl, danach Buchstaben, Zahlen, ., _, -.
  • Schlüssel für die Eindeutigkeit: der Name in Kleinbuchstaben (usernameKey). Gespeichert und angezeigt wird der Name, wie er eingegeben wurde.
  • Gesperrte Schlüssel: admin, administrator, root, system, support, moderator, mod, aircard, aircardios, aircard-ios, aircard.ios, aircard_ios, webklar, anonym, anonymous, null, undefined, team, staff, official, offiziell, hilfe, help, kontakt, contact, info.
  • Anzeige mit @ davor: „von @name“ bzw. „by @name“.

3. Daten (Appwrite, Datenbank aircard, Setup-Skript erweitert)

Tabelle profiles (rowSecurity an, keine Tabellenrechte für Clients):

Spalte Typ Inhalt
username string 20, Pflicht Name wie eingegeben
usernameKey string 20, Pflicht Name klein geschrieben
  • Zeilen-ID = Nutzer-ID (eine Zeile pro Konto).
  • Index username_key: unique auf usernameKey. Damit kann auch bei Gleichzeitigkeit kein Name doppelt vergeben werden.
  • Zeilenrecht genau ['read("any")'], öffentlich lesbar. Schreiben nur über die API.

4. API-Dienst aircard-api

Eigenes Modul deploy/api/profiles.js, eingebunden wie logos.js. Der Betrieb kopiert künftig sechs Dateien: appwrite.js, common.js, app.js, logos.js, profiles.js, server.js.

POST /api/profil {username}, Nutzer-JWT:

  • 401 ohne Anmeldung.
  • 400 usernameInvalid bei falschem Muster.
  • 400 usernameReserved bei gesperrtem Schlüssel.
  • 409 usernameTaken, wenn ein anderes Konto den Schlüssel hat. Das wird vorab per Abfrage geprüft; bei einem Rennen meldet Appwrite 409 auf dem Unique-Index, das wird ebenfalls zu usernameTaken.
  • Sonst: Hat das Konto schon eine Zeile, wird sie aktualisiert (der alte Name ist damit frei); sonst wird sie mit ID = Nutzer-ID und read("any") angelegt. Antwort 200 {username}.
  • Groß-/Kleinschreibung des eigenen Namens ändern („kenso“ → „Kenso“) ist erlaubt.
  • Sperre je Konto (profile:<userId>).

Pflicht serverseitig: POST /api/logos/hochladen und POST /api/veroeffentlichen antworten 403 usernameRequired, wenn das Konto keine Zeile in profiles hat. Die Prüfung läuft nach der Anmeldung und vor allen anderen Prüfungen. Bestehende Logos und Karten bleiben unberührt.

Neue MSG-Texte:

  • usernameInvalid: „Der Benutzername muss 3–20 Zeichen lang sein, mit einem Buchstaben oder einer Zahl beginnen und darf nur Buchstaben, Zahlen, Punkt, Unterstrich und Bindestrich enthalten.“
  • usernameReserved: „Dieser Benutzername ist nicht erlaubt.“
  • usernameTaken: „Dieser Benutzername ist schon vergeben.“
  • usernameRequired: „Bitte wähle zuerst einen Benutzernamen.“

5. Oberfläche

  • Registrieren (Login-Dialog, Reiter „Registrieren“): neues Pflichtfeld „Benutzername“ vor der E-Mail, autocomplete="username", Hinweis „3–20 Zeichen: Buchstaben, Zahlen, . _ -“.
    • Vor dem Anlegen des Kontos werden Muster, Sperrliste und Verfügbarkeit geprüft (Abfrage auf profiles). Ein Fehler steht am Feld.
    • Danach: Konto anlegen → anmelden → POST /api/profil.
    • Scheitert dieser letzte Schritt (Rennen, Netz), ist man trotzdem angemeldet, und der Dialog „Benutzername wählen“ erscheint.
  • Dialog „Benutzername wählen“ mit Feld, „Speichern“ und „Später“ bzw. „Abbrechen“:
    • Nach dem Anmelden oder beim Seitenstart mit Sitzung, wenn das Konto keinen Namen hat. Einmal pro Sitzung (Merker in sessionStorage aircard.usernamePrompted, Zugriffe in try/catch), mit „Später“.
    • Vor dem Hochladen eines Logos und vor dem Veröffentlichen, wenn kein Name da ist. Hier gibt es „Abbrechen“ statt „Später“; ohne Namen geht es nicht weiter.
    • Antwortet der Server mit usernameRequired, erscheint der Dialog ebenfalls.
  • Konto-Menü: Statt der E-Mail steht „@name“ oben (die E-Mail darunter klein). Neuer Eintrag „Benutzername ändern“, der den Dialog vorbelegt öffnet. Ohne Namen heißt der Eintrag „Benutzername wählen“.
  • Anzeige „von @name“: Logo-Kacheln, Logo-Infozeile, Detailseite einer Community-Karte.
    • Der Name wird über ownerId in profiles nachgeschlagen, gesammelt je Seite (equal('$id', ids)) und zwischengespeichert.
    • Ohne Profil: der früher gespeicherte displayName (ohne @), sonst „Anonym“.
    • Nach einer eigenen Namensänderung aktualisieren Kacheln, Infozeile und Detailseite die eigenen Einträge sofort.
  • Weg fällt das Feld „Anzeigename“ in den Dialogen „Logo hochladen“ und „Veröffentlichen“ samt account/display-name.ts und dem localStorage-Schlüssel aircard.displayName. Der Client schickt displayName: ''; die API nimmt das Feld weiter an (Altbestand).

Alle Texte gibt es auf Deutsch und Englisch.

6. Fehlerbehandlung

Fall Meldung
Muster falsch / gesperrt / vergeben die drei MSG-Texte aus § 4, am Feld
Server meldet usernameRequired Dialog „Benutzername wählen“
Netz/API weg beim Speichern „Der Dienst ist gerade nicht erreichbar.“, Dialog bleibt offen
Profil lässt sich nicht lesen (Anzeige) Fallback displayName bzw. „Anonym“, kein Fehlertext

7. Tests

  • node:test:
    • /api/profil: anlegen, ändern, Groß/klein am eigenen Namen, vergeben 409, gesperrt 400, Muster 400, ohne JWT 401.
    • Rennen mit zwei Konten: genau eines bekommt den Namen.
    • Zeilenrechte genau read("any").
    • Hochladen und Veröffentlichen ohne Profil → 403 usernameRequired.
    • Setup-Skript deckt profiles mit Unique-Index ab.
  • Vitest:
    • Prüfung des Namens (Muster, Sperrliste, Schlüssel).
    • Registrieren mit Vorabprüfung und Fehlern am Feld.
    • Dialog: Später, Abbrechen, Speichern, Fehler.
    • Einmal-pro-Sitzung-Abfrage.
    • Konto-Menü mit „@name“ und Ändern.
    • Anzeige „von @name“ mit Fallbacks; sofortige Aktualisierung nach Umbenennen.
    • Dialoge ohne „Anzeigename“.
    • Hochladen und Veröffentlichen fragen vorher nach dem Namen.
    • Gleichlauf der API-Codes, i18n-Abdeckung.
  • Live: Gast sieht „von …“-Zeilen. Kenso registriert bzw. wird gefragt, ändert den Namen und sieht ihn an seinem Logo.

8. Nicht im Umfang

Profilseiten, Suche nach Benutzernamen, Moderation von Namen, Konto löschen, Avatar-Bilder, Benutzername als Anmeldename (angemeldet wird weiter per E-Mail).