feat: unique display names + inline recover on join (v0.13.1)

Backend: migration 007 adds a case-insensitive unique index on user names
per event. join endpoint returns 409 conflict when the name is taken.
find_by_event_and_name uses LOWER() for case-insensitive recovery.

Frontend: join page handles 409 with a name-taken view — amber warning,
name-choice tips, inline PIN recovery form, and "Anderen Namen wählen"
button. Test guide updated with Steps 8 and 9.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-04-03 18:37:51 +02:00
parent de0e395a9e
commit 0351e967c0
6 changed files with 170 additions and 24 deletions

View File

@@ -40,3 +40,18 @@ Please test each step in order and report any errors (console errors, wrong text
23. Open a new **private/incognito** window at **http://localhost:5173/recover**
24. Enter the same name (`Max`) and the PIN you copied
25. ✅ Expected: You're redirected to the feed with the same account
### Step 8 — Upload rate-limit auto-retry
26. Upload more than 20 photos in one hour to trigger the rate limit
27. ✅ Expected: When the limit is hit, remaining items stay **Wartend** (not error)
28. ✅ Expected: An amber banner appears in the queue: "Upload-Limit erreicht. Wird in Xs automatisch fortgesetzt."
29. ✅ Expected: The countdown ticks down and uploads resume automatically when it reaches 0
### Step 9 — Name uniqueness (case-insensitive)
30. In a private/incognito window go to **http://localhost:5173/join**
31. Enter `max` or `MAX` — the same name already taken in Step 1 (different case)
32. ✅ Expected: Instead of creating a new account, an amber warning appears: „Max ist bereits vergeben." with name tips
33. ✅ Expected: A PIN input and **Anmelden** button appear, plus an **Anderen Namen wählen** button
34. Enter your PIN from Step 1 and click **Anmelden**
35. ✅ Expected: You're signed in to the existing `Max` account and redirected to the feed
36. Alternatively, click **Anderen Namen wählen** — ✅ Expected: the name input reappears with `max` pre-filled so you can edit it