fix(publish): scope desktop publish task list and retry by creator user

Now that desktop clients can be re-registered with a new id under the
same user, listing/searching publish tasks by client.id missed the user's
older history and the retry path forbade jobs created from a previous
client. Switch the list/count queries to join desktop_publish_jobs and
filter by created_by_user_id, and enforce the same ownership when
retrying via desktop task. Qualify column names with the t. alias so the
join doesn't break the existing ORDER BY clauses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-27 20:06:47 +08:00
parent 543fe0635f
commit aa8cc6aff4
2 changed files with 76 additions and 36 deletions
@@ -480,7 +480,7 @@ func (s *DesktopTaskService) ListPublishTasks(ctx context.Context, client *repos
title,
0,
0,
`CASE WHEN status = 'in_progress' THEN 0 ELSE 1 END ASC, created_at ASC, desktop_id DESC`,
`CASE WHEN t.status = 'in_progress' THEN 0 ELSE 1 END ASC, t.created_at ASC, t.desktop_id DESC`,
)
if err != nil {
return nil, err
@@ -517,7 +517,7 @@ func (s *DesktopTaskService) ListPublishTasks(ctx context.Context, client *repos
title,
remaining,
historyOffset,
`updated_at DESC, desktop_id DESC`,
`t.updated_at DESC, t.desktop_id DESC`,
)
if listErr != nil {
return nil, listErr
@@ -546,32 +546,38 @@ func (s *DesktopTaskService) listPublishTasksByStatuses(
) ([]DesktopTaskView, error) {
query := `
SELECT
desktop_id,
job_id,
tenant_id,
workspace_id,
target_account_id,
target_client_id,
platform_id,
kind,
payload,
status,
dedup_key,
active_attempt_id,
lease_expires_at,
attempts,
result,
error,
created_at,
updated_at
FROM desktop_tasks
WHERE workspace_id = $1
AND target_client_id = $2
AND kind = 'publish'
AND status = ANY($3)
AND ($4 = '' OR COALESCE(payload->>'title', '') ILIKE '%' || $4 || '%')
t.desktop_id,
t.job_id,
t.tenant_id,
t.workspace_id,
t.target_account_id,
t.target_client_id,
t.platform_id,
t.kind,
t.payload,
t.status,
t.dedup_key,
t.active_attempt_id,
t.lease_expires_at,
t.attempts,
t.result,
t.error,
t.created_at,
t.updated_at
FROM desktop_tasks AS t
JOIN desktop_publish_jobs AS j
ON j.desktop_id = t.job_id
AND j.workspace_id = t.workspace_id
WHERE t.workspace_id = $1
AND j.created_by_user_id = $2
AND t.kind = 'publish'
AND t.status = ANY($3)
AND (
$4 = ''
OR COALESCE(t.payload->>'title', j.title, '') ILIKE '%' || $4 || '%'
)
`
args := []any{client.WorkspaceID, client.ID, statuses, title}
args := []any{client.WorkspaceID, client.UserID, statuses, title}
if strings.TrimSpace(orderBy) != "" {
query += "\nORDER BY " + orderBy
@@ -599,13 +605,19 @@ func (s *DesktopTaskService) countPublishTasksByStatuses(
var count int
err := s.pool.QueryRow(ctx, `
SELECT COUNT(1)
FROM desktop_tasks
WHERE workspace_id = $1
AND target_client_id = $2
AND kind = 'publish'
AND status = ANY($3)
AND ($4 = '' OR COALESCE(payload->>'title', '') ILIKE '%' || $4 || '%')
`, client.WorkspaceID, client.ID, statuses, title).Scan(&count)
FROM desktop_tasks AS t
JOIN desktop_publish_jobs AS j
ON j.desktop_id = t.job_id
AND j.workspace_id = t.workspace_id
WHERE t.workspace_id = $1
AND j.created_by_user_id = $2
AND t.kind = 'publish'
AND t.status = ANY($3)
AND (
$4 = ''
OR COALESCE(t.payload->>'title', j.title, '') ILIKE '%' || $4 || '%'
)
`, client.WorkspaceID, client.UserID, statuses, title).Scan(&count)
if err != nil {
return 0, response.ErrInternal(50109, "desktop_publish_tasks_query_failed", "failed to list desktop publish tasks")
}