Skip to content

Commit c6dba20

Browse files
julianknutsenclaude
andcommitted
fix: show Multiple (pending) when competing submissions exist
Both browse and detail views now count main claimer + upstream PRs as candidates. When total candidates > 1, claimed_by shows "Multiple (pending)" instead of just the main claimer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a9a61a3 commit c6dba20

3 files changed

Lines changed: 37 additions & 19 deletions

File tree

internal/api/types.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,24 @@ func toDetailResponse(d *sdk.DetailResult, mode string) *DetailResponse {
292292
})
293293
}
294294

295+
itemJSON := toWantedItemJSON(d.Item)
296+
// If there are competing upstream submissions, overlay claimed_by to
297+
// reflect the full set of candidates (main claimer + upstream PRs).
298+
if itemJSON != nil && len(upstreamPRs) > 0 {
299+
mainClaimer := itemJSON.ClaimedBy
300+
totalCandidates := len(upstreamPRs)
301+
if mainClaimer != "" {
302+
totalCandidates++
303+
}
304+
if totalCandidates > 1 {
305+
itemJSON.ClaimedBy = "Multiple (pending)"
306+
} else if upstreamPRs[0].ClaimedBy != "" {
307+
itemJSON.ClaimedBy = upstreamPRs[0].ClaimedBy + " (pending)"
308+
}
309+
}
310+
295311
return &DetailResponse{
296-
Item: toWantedItemJSON(d.Item),
312+
Item: itemJSON,
297313
Completion: toCompletionJSON(d.Completion),
298314
Stamp: toStampJSON(d.Stamp),
299315
Branch: d.Branch,

internal/sdk/reads.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,23 @@ func (c *Client) Browse(filter commons.BrowseFilter) (*BrowseResult, error) {
8080
best = p
8181
}
8282
}
83-
// Only overlay if upstream state is further than current.
83+
// Only overlay status if upstream state is further than current.
8484
if stateRank[best.Status] > stateRank[items[i].Status] {
8585
items[i].Status = best.Status
86-
if len(pending) > 1 {
87-
items[i].ClaimedBy = "Multiple (pending)"
88-
} else if best.ClaimedBy != "" {
89-
items[i].ClaimedBy = best.ClaimedBy + " (pending)"
90-
}
91-
} else if items[i].ClaimedBy == "" && best.RigHandle != "" {
92-
// Status not further, but no claimed_by yet — show rig handle.
93-
if len(pending) > 1 {
94-
items[i].ClaimedBy = "Multiple (pending)"
95-
} else {
96-
items[i].ClaimedBy = best.RigHandle + " (pending)"
97-
}
86+
}
87+
// Overlay claimed_by to reflect the full set of candidates
88+
// (main claimer + upstream PRs).
89+
totalCandidates := len(pending)
90+
if items[i].ClaimedBy != "" {
91+
totalCandidates++
92+
}
93+
switch {
94+
case totalCandidates > 1:
95+
items[i].ClaimedBy = "Multiple (pending)"
96+
case best.ClaimedBy != "":
97+
items[i].ClaimedBy = best.ClaimedBy + " (pending)"
98+
case best.RigHandle != "":
99+
items[i].ClaimedBy = best.RigHandle + " (pending)"
98100
}
99101
}
100102

internal/sdk/sdk_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -855,10 +855,10 @@ func TestBrowse_PendingFurthestState(t *testing.T) {
855855
t.Error("w-1 not found in results")
856856
}
857857

858-
func TestBrowse_PendingClaimedBy_PreservesExisting(t *testing.T) {
858+
func TestBrowse_PendingClaimedBy_MultipleWithExisting(t *testing.T) {
859859
db := newFakeDB()
860860
// In PR mode, branch overlays set ClaimedBy before upstream merge.
861-
// Verify upstream doesn't overwrite branch-overlay ClaimedBy.
861+
// When there's also an upstream PR, both are candidates → "Multiple (pending)".
862862
db.seedItem(fakeItem{ID: "w-1", Title: "Fix bug", Status: "open", Priority: 1, PostedBy: "alice", EffortLevel: "medium"})
863863
db.branches["wl/bob/w-1"] = true
864864
db.branchItems["wl/bob/w-1"] = map[string]*fakeItem{
@@ -883,9 +883,9 @@ func TestBrowse_PendingClaimedBy_PreservesExisting(t *testing.T) {
883883

884884
for _, item := range result.Items {
885885
if item.ID == "w-1" {
886-
// Branch overlay set ClaimedBy="bob"; upstream with same rank should NOT overwrite.
887-
if item.ClaimedBy != "bob" {
888-
t.Errorf("w-1: expected ClaimedBy='bob' (from branch overlay), got %q", item.ClaimedBy)
886+
// bob (branch overlay) + charlie (upstream) = 2 candidates.
887+
if item.ClaimedBy != "Multiple (pending)" {
888+
t.Errorf("w-1: expected ClaimedBy='Multiple (pending)', got %q", item.ClaimedBy)
889889
}
890890
return
891891
}

0 commit comments

Comments
 (0)