Adds POST /:id/voting/start and POST /:id/voting/end endpoints that
broadcast poll lifecycle events and persist poll state to the sessions
table. The poll.leading WebSocket message is now handled server-side
(rebroadcast + DB persist) with self-healing for polls started before
the persistence columns existed.
Co-authored-by: Cursor <cursoragent@cursor.com>
- findAdminByKey returns role from admins.json (defaults to 'admin')
- JWT includes config-defined role instead of hardcoded 'admin'
- PresenceBar split into "who's here?" (page admins) and "connected"
(bot/utility services with icon+color badges)
- Bot/utility roles appear in presence on all pages when connected
- usePresence hook uses refs to avoid WS reconnect on navigation
- WS auth log prints admin name instead of generic 'admin'
- WS connection log reads X-Forwarded-For for real client IP
- AuthContext stores adminRole from login response
- Uncomment admins.json Docker volume mount, add SELinux :z flags
Made-with: Cursor