feat(api): add WebSocket endpoint with hub/client architecture#10
Merged
feat(api): add WebSocket endpoint with hub/client architecture#10
Conversation
Add new scm-engineer agent for Git/GitHub SCM operations. Update orchestrator workflow to include scm-engineer step before code-reviewer. Extend orchestrator with GitHub issue management instructions and additional tools (terminal, agent, todo). Minor additions to code-reviewer, devops-engineer, frontend-developer, go-api-developer, and qa-engineer agent definitions.
Add a /ws WebSocket endpoint for real-time bidirectional communication. A Hub manages all active client connections and broadcasts messages. WebSocketHandler is a separate struct (not Handler) injected with *Hub. - internal/websocket: Hub + Client types with goroutine-safe broadcast, register/unregister, and graceful shutdown via hub.Shutdown() - handlers/websocket.go: upgrades HTTP to WebSocket with origin validation from CORS_ALLOWED_ORIGINS config - routes.go: /ws route registered outside rate limiter (connections are long-lived); hub injected via SetupRoutes signature - main.go: hub created and started before router setup; hub.Shutdown() called during graceful shutdown - docs regenerated to include /ws endpoint
There was a problem hiding this comment.
Pull request overview
Adds a top-level /ws WebSocket endpoint to the Go (Gin) backend using a hub/client architecture, wiring it into routing and graceful shutdown, and regenerates Swagger docs accordingly. Also updates the repo’s “agent” markdown configurations to include model/tool metadata and adds a new SCM Engineer agent.
Changes:
- Register
GET /wsin route setup (outside the rate limiter) and inject a*websocket.HubthroughSetupRoutes. - Start/stop the WebSocket hub from
api/main.goand add handler + unit tests for WebSocket upgrades/origin checks. - Regenerate Swagger artifacts and update
.github/agents/*configurations (new SCM Engineer agent + tooling/model fields).
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/internal/api/routes/routes.go | Extends SetupRoutes to accept a hub and registers GET /ws outside rate limiting. |
| backend/internal/api/routes/routes_test.go | Updates route setup test to construct/run/shutdown a hub and pass it into SetupRoutes. |
| backend/internal/api/handlers/websocket.go | Adds WebSocketHandler to upgrade connections and validate Origin against allowed origins. |
| backend/internal/api/handlers/websocket_test.go | Adds unit/integration-style tests for origin validation and basic hub/client interaction via /ws. |
| backend/api/main.go | Creates/starts hub before route setup and shuts hub down during graceful shutdown. |
| backend/docs/swagger.yaml | Adds /ws endpoint and updates version description text. |
| backend/docs/swagger.json | Adds /ws endpoint and top-level produces/schemes; updates version description text. |
| backend/docs/docs.go | Updates generated template/spec fields (produces, schemes) and adds /ws path. |
| .github/agents/scm-engineer.md | Adds new SCM Engineer agent definition and workflow guidance. |
| .github/agents/orchestrator.md | Updates orchestrator workflow to include SCM engineer step and issue-management instructions. |
| .github/agents/qa-engineer.md | Adds model metadata to agent definition. |
| .github/agents/go-api-developer.md | Adds model metadata and expands tools list formatting. |
| .github/agents/frontend-developer.md | Adds model metadata and includes problems tool. |
| .github/agents/devops-engineer.md | Adds model metadata and includes problems tool. |
| .github/agents/code-reviewer.md | Adds model metadata and expands tools list formatting. |
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+39
to
+52
| upgrader := gorilla.Upgrader{ | ||
| ReadBufferSize: 1024, | ||
| WriteBufferSize: 1024, | ||
| CheckOrigin: h.checkOrigin, | ||
| } | ||
|
|
||
| conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) | ||
| if err != nil { | ||
| slog.Error("WebSocket upgrade failed", "error", err) | ||
| return | ||
| } | ||
|
|
||
| if _, err := websocket.NewClient(h.hub, conn); err != nil { | ||
| slog.Error("WebSocket client creation failed", "error", err) |
Comment on lines
+278
to
+287
| // The upgrade itself succeeds (HTTP → WS), but NewClient fails | ||
| // because the hub is closed. The server closes the connection. | ||
| conn, _, err := gorilla.DefaultDialer.Dial(wsURL, nil) | ||
| if err != nil { | ||
| // Connection refused or failed — acceptable when hub is closed | ||
| return | ||
| } | ||
| defer conn.Close() | ||
|
|
||
| // If dial succeeded, the connection should be immediately closed by server |
Cover all six functions in client.go with direct unit tests: - NewClient: success path (client registered, pumps started) and hub-already- shut-down path (ErrHubClosed returned, conn closed by NewClient) - writeMessage: successful text frame delivery to peer; NextWriter error on closed conn - writePing: successful ping frame (peer PingHandler fires); write error on closed conn - handleSend: ok=false sends close frame + returns errChanClosed; ok=true single message; ok=true with queued drain (3 messages in order); closed conn returns write error - readPump: normal close frame (CloseNormalClosure) triggers unregister; unexpected TCP drop triggers unregister; CloseProtocolError triggers the slog.Warn path (IsUnexpectedCloseError=true) then unregister - writePump: single message forwarded to peer; multiple messages in order; closed send channel sends WS close frame and exits cleanly Remaining uncovered statements are gorilla/websocket library-internal paths (SetWriteDeadline returns nil lazily s(SetWriteDeadline returns nil lazily s(SetWriteDeadline retunt(SetWriteDeadline returns nil lazily s(SetWriteDeadline returns nil lazily s��(SetWriteDeadline returns nil lazily s(SetWriteDeadline retage: 45.5% → 85.7%
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
/wsWebSocket endpoint for real-time bidirectional communication between the server and connected clients.Changes
Backend – WebSocket feature
internal/websocket— Hub + Client types with goroutine-safe broadcast, register/unregister, and gracefulhub.Shutdown()for clean teardownhandlers/websocket.go—WebSocketHandlerstruct (separate fromHandler) that upgrades HTTP connections to WebSocket; validates origin againstCORS_ALLOWED_ORIGINShandlers/websocket_test.go— unit tests for the WebSocket handlerroutes.go—/wsroute registered outside the rate limiter (connections are long-lived); hub injected via updatedSetupRoutessignaturemain.go— hub created and started before router setup;hub.Shutdown()called during graceful shutdowndocs/— Swagger docs regenerated to include the/ws-docs/— Swagger docs regenerated to include the * — new SCM Engineer agent for Git/GitHub SCM operations.github/agents/orchestrator.md— workflow updated to include scm-engineer step; added GitHub issue management instructions