Change HandleWebSocket to use r.URL.Path as the room identifier instead
of r.URL.Query().Get("room"). This enables clean URL-based room routing
(e.g., ws://host/room-a) without query strings.
Update test helpers (dialTestHub, dialWSWithRoom) to connect via path
segments and fix direct broadcast channel tests to use path-style room
names (with leading slash).
All existing tests pass — clients connecting to / get the default room.
🤖 Assisted by the code-assist SOP
Add tests verifying that the broadcast case in Hub.Run() correctly
sends messages only to clients in the same room as the sender:
- TestIntegration_RoomIsolation_MessagesOnlyGoToSameRoom: verifies
messages from room-a are received by room-a clients and NOT by
room-b clients
- TestIntegration_RoomIsolation_MultipleRoomsIndependent: verifies
two rooms operate independently with no message leakage
- TestIntegration_BroadcastToEmptyRoom: verifies graceful handling
when broadcasting to a non-existent room (no panic, hub remains
functional)
- TestBroadcastRoomIsolation: unit-level room isolation test using
the broadcast channel directly
Also adds dialWSWithRoom helper for room-aware WebSocket connections
in integration tests.
🤖 Assisted by the code-assist SOP
Add a 'logging' section to config.yaml supporting:
- output: stderr (default), stdout, or a file path
- level: debug, info, warn, error (default: info)
Implementation:
- New internal/logging package with Setup() for output destination
and Logger struct with level-aware Debug/Info/Warn/Error methods
- Config struct extended with Logging section (output + level fields)
- Hub refactored to accept *logging.Logger via constructor injection
- main.go initializes logging early after config load
The leveled logger suppresses messages below the configured threshold
while maintaining the stdlib log format. File output uses append mode
with 0644 permissions for safe log rotation.
🤖 Assisted by the code-assist SOP
- Fix metrics: change MessagesTotal, ConnectionsTotal, DisconnectionsTotal
from Gauge to Counter with proper _total naming convention
- Fix broadcast write-error handling: failed clients now get properly
removed with accurate metrics updates
- Add graceful shutdown: SIGINT/SIGTERM handling with 10s timeout,
CloseGoingAway frame sent to clients before disconnect
- Add integration tests: 11 tests using real WebSocket connections
covering connect, broadcast, disconnect, concurrency, and shutdown
- Fix example client port: changed from 8000 to 8443 to match config
- Rewrite README.md to reflect current features and usage
- Add AGENTS.md and .agents/summary/ documentation for AI assistants