mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-09 01:46:46 +08:00
position ranks an issue inside its own (workspace, status) column, but a status change carried the old column's value over unchanged. The value that put an issue on top of Todo is roughly zero, and lands it below every hand-dragged issue in Done — so agent-completed work sank into the middle of a long Done column and read as "the task disappeared". Re-rank to the top of the destination column on both status-write paths, reusing the MIN(position) - 1 policy new issues already get. An explicit position still wins, so cross-column drag-and-drop keeps the slot it dropped on, and a same-status write leaves position alone. The re-rank reads MIN(position) for the destination (workspace, status), which idx_issue_status could only serve with a heap fetch per issue in the column — paid on every completion against the column that grows without bound. Add (workspace_id, status, position) to make it an index-only min. Closes #7410 Co-authored-by: J <[email protected]> Co-authored-by: multica-agent <[email protected]>
31 lines
955 B
Go
31 lines
955 B
Go
package issueposition
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
type queryRower interface {
|
|
QueryRow(ctx context.Context, sql string, args ...any) pgx.Row
|
|
}
|
|
|
|
// NextTopPosition returns a position that sorts before every existing issue in
|
|
// the workspace/status column when manual sorting orders by position ASC.
|
|
//
|
|
// UpdateIssue and UpdateIssueStatus in queries/issue.sql inline the same
|
|
// MIN(position) - 1 policy to re-rank an issue whose status moves it to a
|
|
// different column. Change them together.
|
|
func NextTopPosition(ctx context.Context, q queryRower, workspaceID pgtype.UUID, status string) (float64, error) {
|
|
var minPos float64
|
|
if err := q.QueryRow(ctx,
|
|
`SELECT COALESCE(MIN(position), 0) FROM issue WHERE workspace_id = $1 AND status = $2`,
|
|
workspaceID, status,
|
|
).Scan(&minPos); err != nil {
|
|
return 0, fmt.Errorf("query min issue position: %w", err)
|
|
}
|
|
return minPos - 1, nil
|
|
}
|