- Migrate all HTTP command handlers (PRIVMSG, JOIN, PART, NICK, TOPIC,
KICK, QUIT, AWAY, OPER, MODE) to use hdlr.svc.* service methods
instead of direct database calls. Both HTTP and IRC transports now
share the same business logic path.
- Fix BroadcastQuit bug: was inserting N separate message rows (one per
recipient); now uses FanOut pattern with 1 InsertMessage + N
EnqueueToSession calls.
- Fix README: IRC listener is enabled by default on :6667, not
disabled. Remove redundant -e IRC_LISTEN_ADDR from Docker example.
- Add EXPOSE 6667 to Dockerfile alongside existing HTTP port.
- Add service layer unit tests (JoinChannel, PartChannel,
SendChannelMessage, FanOut, BroadcastQuit, moderated channel).
- Update handler test setup to provide Service instance.
- Use constant-time comparison in Oper credential validation to
prevent timing attacks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire up service.Service in HTTP handlers and delegate cleanupUser to
svc.BroadcastQuit for consistent quit/part logic across transports.
Default IRC_LISTEN_ADDR to :6667, remove unused import, fix all lint
issues (dogsled, funcorder, wrapcheck, varnamelen, nolintlint).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>