Controllers:
- ApiAuthController: POST /api/auth/login with JWT generation (HS256, 24h TTL)
- Validates email + password against DB
- Returns JWT token with userId, email, roles, iat, exp
- Static verifyJwt() for use by live/sandbox controllers
- Only ROLE_ORGANIZER can authenticate
- ApiLiveController: empty shell at /api/live (routes to implement)
- ApiSandboxController: empty shell at /api/sandbox (routes to implement)
Auth is shared: one /api/auth/login for both environments using real credentials.
Sandbox fixtures (data/sandbox/fixtures.json):
- 2 events (Brocante + Convention Cosplay)
- 4 categories across events
- 6 billets with varied types (billet, reservation_brocante)
- 6 billet details with descriptions, images, categories, events
- 4 scan results (2 accepted, 2 refused with different reasons)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>