FotoBattle

Kompetitive Foto-Battle-Plattform: Fotografen reichen Fotos ein, Voter wählen in 1v1-Duellen ihren Favoriten, ein Elo-Rating-System berechnet objektive Rankings.

Architektur

Hybrider Ansatz: Event Sourcing für die kompetitiven Kerndomänen, CRUD für den Rest.

┌─────────────────────────────────────────────┐
│           FotoBattle Domains                │
├──────────────────┬──────────────────────────┤
│   CRUD           │   Event Sourced (ES)     │
├──────────────────┼──────────────────────────┤
│ User Management  │ Battle Domain            │
│ Photo Management │ Rating Domain            │
│ Social Features  │ Infrastructure           │
│ Read-Side        │  (Event Store)           │
└──────────────────┴──────────────────────────┘

Rollen

Rolle Beschreibung
Besucher Galerie, Leaderboard und Top-Fotos ansehen
Voter Registrierung mit E-Mail/Passwort. Abstimmen, kommentieren, liken, folgen
Photographer Muss von Admin freigeschaltet werden. Fotos hochladen und an Battles einreichen
Admin Fotografen freischalten, Battles verwalten, Moderation, Statistiken

Features

MVP (P0)

ID Feature Beschreibung
FOTO-1 User Registration & Login E-Mail/Passwort, bcrypt, Rate Limiting (5 Versuche → 15 Min Sperre)
FOTO-2 Photographer Approval & Roles Bewerbung, Admin-Freischaltung, Rollenwechsel
FOTO-3 Photo Upload & Management Upload in Battles, Status-Verwaltung (pending → active → withdrawn)
FOTO-4 Event Store & Aggregate Infrastructure MySQL-basiertes Event Sourcing mit Optimistic Locking
FOTO-5 1v1 Photo Battle & Voting Paarweises Matchmaking (min. 10 Fotos), Duplikat-Schutz (24h)
FOTO-6 Elo Rating Engine K-Faktor: 40 (neu) / 20 (etabliert), Floor 100, Start 1500
FOTO-7 Ranking & Leaderboard Foto- und Fotografen-Rankings aus rating_history

Social (P1)

ID Feature Beschreibung
FOTO-8 Comments Kommentare auf Fotos
FOTO-9 Likes Favoriten-Toggle (unique pro User+Entry)
FOTO-10 Follow System Fotografen folgen
FOTO-11 User Profiles & Galleries Profil mit Avatar, Bio, Foto-Galerie

Advanced (P2)

ID Feature Beschreibung
FOTO-12 Categories & Tags Battle- und Entry-Kategorisierung
FOTO-13 Battle History & Statistiken Voting-Volumen, Top-Voter, Battle-Statistiken
FOTO-14 Benachrichtigungen In-App-Notifications

Elo-Rating

Erwartete Punktzahl:  E_A = 1 / (1 + 10^((R_B - R_A) / 400))
Neues Rating:         R'_A = R_A + K × (S - E_A)

K-Faktor:  40 (< 30 Battles)  /  20 (≥ 30 Battles)
Floor:     100 (Ratings fallen nie unter 100)
Startwert: 1500

Event Store

Eigene Implementierung (kein externer EventStore):

  • append(AggregateRoot) — Event in event_store Tabelle schreiben
  • getEvents(aggregateId) — Alle Events für ein Aggregat laden
  • Optimistic Locking über aggregate_id + event_version (Unique)
  • ConcurrencyException bei Versionskonflikten
  • Projektionen: elo_rating auf battle_entries (Cache), rating_history (Leaderboard)

Routing

Öffentlich

Methode Pfad Beschreibung
GET / Startseite (abstimmbare Battles)
GET/POST /register Registrierung
GET/POST /login Login
POST /logout Abmelden
GET /leaderboard Foto-Rankings
GET /leaderboard/photographers Fotografen-Rankings
GET /vote/{id} Battle-Arena (1v1)
POST /api/vote Abstimmung (AJAX)
GET /entry/{id} Foto-Detailseite
POST /api/favorite/{id} Like-Toggle

Authentifiziert

Methode Pfad Beschreibung
GET/POST /apply Fotografen-Bewerbung
GET /my-entries Eigene Fotos
GET /profile/{username} User-Profil
GET /following Following-Liste
POST /api/follow/{id} Follow-Toggle

Admin

Methode Pfad Beschreibung
GET/POST /admin/battles Battles erstellen und verwalten (draft → open → voting → closed)
GET/POST /admin/photographers Bewerbungen freischalten
GET/POST /admin/users Benutzerverwaltung
GET /admin/statistics Statistiken und Ratings

Gallery-Integration (HMAC-geschützt)

Methode Pfad Beschreibung
POST /api/gallery-submit Foto aus Gallery an Battle senden
POST /api/gallery-withdraw Foto aus Battle zurückziehen

Datenbank (FotoBattle-Tabellen)

User & Auth

Tabelle Beschreibung
users Username, E-Mail, Passwort-Hash, Rolle (voter/photographer/admin), Avatar, Bio
photographer_applications Bewerbungen mit Status (pending/approved/rejected)
login_attempts Rate Limiting per IP-Hash

Battles & Voting

Tabelle Beschreibung
battles Titel, Status (draft/open/voting/closed), Zeitfenster
battle_entries Fotos in Battles, FK auf images.id (Gallery), Elo-Rating-Cache
battle_votes Abstimmungen (left/right/winner Entry, User, IP-Hash)

Rating & Events

Tabelle Beschreibung
rating_history Elo-Verlauf pro Entry (alt → neu, K-Faktor, Gegner)
event_store Event Sourcing (aggregate_id, type, data JSON, version)

Social

Tabelle Beschreibung
comments Kommentare auf Entries
favorites Likes (unique pro User+Entry)
follows Follow-Beziehungen (unique pro Paar)
notifications In-App-Benachrichtigungen

Metadaten

Tabelle Beschreibung
categories + entry_categories Kategorien (M:N)
tags + entry_tags Tags (M:N)

Tests

19 PHPUnit-Testdateien:

  • Event Store & Aggregate (2 Tests)
  • Elo-Berechnung & Rating-Service (2 Tests)
  • Auth, Battle, Vote, Entry Services (4 Tests)
  • Social Services: Comment, Favorite, Follow, Profile, Notification (5 Tests)
  • Leaderboard, Category, Role, Statistics, Tag, RateLimiter (6 Tests)