Backend fuer oeffentliche Community-Fremdprofile (Stufe 2 der Roadmap).
handle.ts:
- handleToSlug: KochHeld#A23B -> KochHeld-A23B (URL-tauglich, '#' geht
nicht im Pfad).
- parseHandleSlug: zerlegt am LETZTEN Bindestrich (Username darf Bindestriche
enthalten), validiert Username + Discriminator gegen das Alphabet.
users.publicProfileByHandle (protectedProcedure):
- DATENSCHUTZ: liefert nur bei profileVisible=true, sonst NOT_FOUND (privates
und nicht existierendes Profil sind von aussen ununterscheidbar).
- Strikte Feld-Whitelist: handle, username, discriminator, bio, image.
NIEMALS Art.-9-Daten (Gewicht/Kalorien/Ziele), keine Kontakt-/Auth-Felder.
- Aggregat-Punkte gesamt + 30 Tage aus activity_logs.points, plus
anonymisierte Aktivitaets-Streak (distinkte aktive Tage der letzten 7).
Tests (node:test): 9 Slug-Tests + 6 Endpoint-Tests (sichtbar, Leak-Schutz,
NOT_FOUND bei privat/unbekannt/ungueltigem Slug, Auth-Pflicht).
Verifiziert: 75 API-Tests gruen, Typecheck 3/3.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Battle.net-Style Handle Username#XXXX als Basis fuer kommende
Community-Features (Stufe 2 der Roadmap). Diese Stufe: Schema, Migration,
Generator und API. Die UI im Profil-Tab folgt in einem eigenen Commit.
Schema (packages/db/src/schema/auth.ts):
- Neue Spalten an der user-Tabelle: username, discriminator, bio (alle
nullable), profileVisible (notNull, default false = Privacy-by-Default).
- uniqueIndex auf (username, discriminator); NULLs distinct, greift also
nur bei vollstaendigen Handles. Index user_username_idx auf username
fuer die Handle-Erstvergabe-Query.
- Migration 0019_community_profile, per drizzle-kit generate erzeugt,
driftfrei (zweiter generate: keine Aenderung), drizzle-kit check ok.
Noch nicht gegen die DB angewendet.
Generator (packages/api/src/lib/handle.ts):
- Discriminator aus verwechslungsarmem Alphabet, Kollisions-Retry.
- formatHandle, validateUsername. 17 node:test-Unit-Tests.
API (packages/api/src/trpc/routers/users.ts):
- myProfile um die Felder + abgeleitetes handle erweitert (Feld-Whitelist).
- setMyHandle: Discriminator stabil bei Erst-Vergabe, Kollisionspruefung
inkl. DB-unique-violation-Fallback (PG 23505).
- updateMyCommunityProfile: bio + Sichtbarkeit, strikt userId-gescoped.
Verifiziert: Typecheck gruen (db/api/admin), 62 API-Tests gruen,
drizzle-kit check ok. Datenmodell-Architekt abgenommen (Index-Auflage
erfuellt).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>