fix(subscribers): pass user_type to subscribe/unsubscribe API for correct agent handling

Root cause: backend hardcoded UserType="member" in subscribe/unsubscribe handlers,
so unsubscribing an agent actually tried to delete a member record (no-op), and
the WS event broadcast wrong user_type causing other subscribers' UI to break.

- Backend: accept optional user_type in subscribe/unsubscribe request body
- Frontend: pass userType through API client to backend
- Fixes: clicking agent checkbox no longer affects member subscriptions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Naiyuan Qing 2026-03-28 20:56:37 +08:00
parent df6f6584c3
commit b8fa71462a
3 changed files with 29 additions and 13 deletions

View file

@ -59,10 +59,12 @@ func (h *Handler) SubscribeToIssue(w http.ResponseWriter, r *http.Request) {
return
}
// Default to current user; allow specifying another user
// Default to current user as member; allow specifying another user/agent
targetUserID := requestUserID(r)
targetUserType := "member"
var req struct {
UserID *string `json:"user_id"`
UserID *string `json:"user_id"`
UserType *string `json:"user_type"`
}
if r.Body != nil {
json.NewDecoder(r.Body).Decode(&req)
@ -70,10 +72,13 @@ func (h *Handler) SubscribeToIssue(w http.ResponseWriter, r *http.Request) {
if req.UserID != nil && *req.UserID != "" {
targetUserID = *req.UserID
}
if req.UserType != nil && *req.UserType != "" {
targetUserType = *req.UserType
}
err := h.Queries.AddIssueSubscriber(r.Context(), db.AddIssueSubscriberParams{
IssueID: issue.ID,
UserType: "member",
UserType: targetUserType,
UserID: parseUUID(targetUserID),
Reason: "manual",
})
@ -86,7 +91,7 @@ func (h *Handler) SubscribeToIssue(w http.ResponseWriter, r *http.Request) {
callerID := requestUserID(r)
h.publish(protocol.EventSubscriberAdded, workspaceID, "member", callerID, map[string]any{
"issue_id": issueID,
"user_type": "member",
"user_type": targetUserType,
"user_id": targetUserID,
"reason": "manual",
})
@ -104,8 +109,10 @@ func (h *Handler) UnsubscribeFromIssue(w http.ResponseWriter, r *http.Request) {
}
targetUserID := requestUserID(r)
targetUserType := "member"
var req struct {
UserID *string `json:"user_id"`
UserID *string `json:"user_id"`
UserType *string `json:"user_type"`
}
if r.Body != nil {
json.NewDecoder(r.Body).Decode(&req)
@ -113,10 +120,13 @@ func (h *Handler) UnsubscribeFromIssue(w http.ResponseWriter, r *http.Request) {
if req.UserID != nil && *req.UserID != "" {
targetUserID = *req.UserID
}
if req.UserType != nil && *req.UserType != "" {
targetUserType = *req.UserType
}
err := h.Queries.RemoveIssueSubscriber(r.Context(), db.RemoveIssueSubscriberParams{
IssueID: issue.ID,
UserType: "member",
UserType: targetUserType,
UserID: parseUUID(targetUserID),
})
if err != nil {
@ -128,7 +138,7 @@ func (h *Handler) UnsubscribeFromIssue(w http.ResponseWriter, r *http.Request) {
callerID := requestUserID(r)
h.publish(protocol.EventSubscriberRemoved, workspaceID, "member", callerID, map[string]any{
"issue_id": issueID,
"user_type": "member",
"user_type": targetUserType,
"user_id": targetUserID,
})