#Gallery
#Features
| Feature |
Description |
| Directory navigation |
Two-level hierarchy: Year > Date + Event name |
| Thumbnail grid |
Paginated (60 images per page) with full-screen view |
| S3 Storage |
RustFS (Apache 2.0) instead of MinIO (AGPL) |
| Passkey Authentication |
WebAuthn/FIDO2 via one-time password registration |
| Image Upload |
Multi-file, MIME validation (JPEG, PNG, WebP), automatic thumbnails with EXIF rotation |
| Delete |
Individual images and entire galleries (incl. S3 cleanup) |
| Battle submission |
Send photos from the gallery directly to FotoBattle |
| Darkroom UI |
Dark design with amber accents, WCAG 2.1 AA, responsive |
#Routing
| Method |
Path |
Description |
GET |
/ |
Home page (annual directories) |
GET |
/browse/{id} |
Directory with subfolders + image grid |
GET |
/image/{id} |
Image proxy from S3 (with ETag caching) |
GET/POST |
/register |
Passkey registration via OTP |
POST |
/register/challenge |
WebAuthn registration challenge |
POST |
/register/complete |
Complete WebAuthn registration |
GET/POST |
/login |
Passkey login |
POST |
/login/challenge |
WebAuthn login challenge |
POST |
/login/complete |
Complete WebAuthn login |
POST |
/logout |
Log out (CSRF-protected) |
GET/POST |
/gallery/create |
Create Event Gallery (Auth) |
GET/POST |
/upload |
Image Upload (Auth) |
POST |
/image/{id}/delete |
Delete Image (Auth, CSRF) |
POST |
/gallery/{id}/delete |
Delete Gallery (Auth, CSRF) |
POST |
/battle/withdraw/{image_id} |
Battle Withdrawal (HMAC Token) |
#Services
| Service |
Description |
GalleryService |
Directory/image CRUD, breadcrumbs, event gallery creation |
PasskeyService |
WebAuthn registration and authentication, OTP management |
UploadService |
Multi-file upload, MIME validation, thumbnail workflow |
ThumbnailGenerator |
GD-based resizing (max 400×300px) with EXIF rotation |
BucketScanner |
Catalog S3 bucket in database |
S3ClientFactory |
AWS SDK S3Client for RustFS endpoint |
DatabaseFactory |
PDO connection from environment variables |
#CLI Tools
docker compose exec php php bin/scan.php
docker compose exec php php bin/thumbs.php
#Database (Gallery Tables)
| Table |
Description |
dirs |
Directory hierarchy with parent_id self-reference, unique on dirname + bucket |
images |
Image files with S3 metadata (name, size, hash), FK on dir_id |
thumbs |
Thumbnail paths, FK on image_id (1:1) |
passkeys |
WebAuthn credentials (credential_id, public_key, counter, transports JSON) |
otp_status |
Single-row table: OTP used yes/no |