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:
parent
df6f6584c3
commit
b8fa71462a
3 changed files with 29 additions and 13 deletions
|
|
@ -275,10 +275,10 @@ export function IssueDetail({ issueId, onDelete }: IssueDetailProps) {
|
|||
if (!issue) return;
|
||||
try {
|
||||
if (currentlySubscribed) {
|
||||
await api.unsubscribeFromIssue(id, userId);
|
||||
await api.unsubscribeFromIssue(id, userId, userType);
|
||||
setSubscribers((prev) => prev.filter((s) => !(s.user_id === userId && s.user_type === userType)));
|
||||
} else {
|
||||
await api.subscribeToIssue(id, userId);
|
||||
await api.subscribeToIssue(id, userId, userType);
|
||||
setSubscribers((prev) => [
|
||||
...prev,
|
||||
{ issue_id: id, user_type: userType, user_id: userId, reason: "manual" as const, created_at: new Date().toISOString() },
|
||||
|
|
|
|||
|
|
@ -206,17 +206,23 @@ export class ApiClient {
|
|||
return this.fetch(`/api/issues/${issueId}/subscribers`);
|
||||
}
|
||||
|
||||
async subscribeToIssue(issueId: string, userId?: string): Promise<void> {
|
||||
async subscribeToIssue(issueId: string, userId?: string, userType?: string): Promise<void> {
|
||||
const body: Record<string, string> = {};
|
||||
if (userId) body.user_id = userId;
|
||||
if (userType) body.user_type = userType;
|
||||
await this.fetch(`/api/issues/${issueId}/subscribe`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(userId ? { user_id: userId } : {}),
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
}
|
||||
|
||||
async unsubscribeFromIssue(issueId: string, userId?: string): Promise<void> {
|
||||
async unsubscribeFromIssue(issueId: string, userId?: string, userType?: string): Promise<void> {
|
||||
const body: Record<string, string> = {};
|
||||
if (userId) body.user_id = userId;
|
||||
if (userType) body.user_type = userType;
|
||||
await this.fetch(`/api/issues/${issueId}/unsubscribe`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(userId ? { user_id: userId } : {}),
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue