feat(desktop): drop parked review flow, add publish management

SaaS 侧人工审核后才创建 publish job,desktop 不再做二次审核:移除
manual/waiting_user/parked/from_parked 状态机与 LeaseFromParked 查询,
desktop client 只执行发布并新增"发布管理"页(待发布队列 / 历史 / 再次
发送)。同时抽离 @geo/publisher-platforms 共享适配器包、新增 Redis-based
desktop_presence 与 publish_record_support,刷新 admin-web 发布弹窗与
媒体库;plan A / spec 文档同步口径。
This commit is contained in:
2026-04-20 09:52:48 +08:00
parent b16e9f0bd1
commit a617d39a4a
93 changed files with 5519 additions and 3594 deletions
@@ -18,12 +18,11 @@ SET status = 'aborted',
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $2
AND target_client_id = $3
AND status IN ('queued', 'waiting_user')
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
AND status = 'queued'
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type CancelDesktopTaskByClientParams struct {
@@ -52,7 +51,6 @@ func (q *Queries) CancelDesktopTaskByClient(ctx context.Context, arg CancelDeskt
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -68,12 +66,11 @@ SET status = 'aborted',
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $2
AND lease_token_hash = $3
AND status = 'in_progress'
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type CancelDesktopTaskByLeaseParams struct {
@@ -102,7 +99,6 @@ func (q *Queries) CancelDesktopTaskByLease(ctx context.Context, arg CancelDeskto
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -119,12 +115,11 @@ SET status = $1,
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $4
AND lease_token_hash = $5
AND status = 'in_progress'
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type CompleteDesktopTaskParams struct {
@@ -161,7 +156,6 @@ func (q *Queries) CompleteDesktopTask(ctx context.Context, arg CompleteDesktopTa
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -240,8 +234,7 @@ INSERT INTO desktop_tasks (
kind,
payload,
status,
dedup_key,
parked_reason
dedup_key
)
VALUES (
$1,
@@ -254,10 +247,9 @@ VALUES (
$8,
$9,
$10,
$11,
$12
$11
)
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type CreateDesktopTaskParams struct {
@@ -272,7 +264,6 @@ type CreateDesktopTaskParams struct {
Payload []byte `json:"payload"`
Status string `json:"status"`
DedupKey pgtype.Text `json:"dedup_key"`
ParkedReason pgtype.Text `json:"parked_reason"`
}
func (q *Queries) CreateDesktopTask(ctx context.Context, arg CreateDesktopTaskParams) (DesktopTask, error) {
@@ -288,7 +279,6 @@ func (q *Queries) CreateDesktopTask(ctx context.Context, arg CreateDesktopTaskPa
arg.Payload,
arg.Status,
arg.DedupKey,
arg.ParkedReason,
)
var i DesktopTask
err := row.Scan(
@@ -308,7 +298,6 @@ func (q *Queries) CreateDesktopTask(ctx context.Context, arg CreateDesktopTaskPa
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -370,7 +359,7 @@ SET lease_expires_at = now() + interval '10 minutes',
WHERE desktop_id = $1
AND lease_token_hash = $2
AND status = 'in_progress'
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type ExtendDesktopTaskLeaseParams struct {
@@ -398,7 +387,6 @@ func (q *Queries) ExtendDesktopTaskLease(ctx context.Context, arg ExtendDesktopT
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -434,7 +422,7 @@ func (q *Queries) FinishDesktopTaskAttempt(ctx context.Context, arg FinishDeskto
}
const getDesktopTaskByDesktopID = `-- name: GetDesktopTaskByDesktopID :one
SELECT id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
SELECT id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
FROM desktop_tasks
WHERE desktop_id = $1
AND workspace_id = $2
@@ -466,7 +454,6 @@ func (q *Queries) GetDesktopTaskByDesktopID(ctx context.Context, arg GetDesktopT
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -495,11 +482,10 @@ SET active_attempt_id = $1,
lease_expires_at = now() + interval '10 minutes',
status = 'in_progress',
attempts = t.attempts + 1,
parked_reason = NULL,
updated_at = now()
FROM candidate
WHERE t.desktop_id = candidate.desktop_id
RETURNING t.id, 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_token_hash, t.lease_expires_at, t.attempts, t.parked_reason, t.result, t.error, t.created_at, t.updated_at
RETURNING t.id, 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_token_hash, t.lease_expires_at, t.attempts, t.result, t.error, t.created_at, t.updated_at
`
type LeaseNextQueuedDesktopTaskParams struct {
@@ -534,64 +520,6 @@ func (q *Queries) LeaseNextQueuedDesktopTask(ctx context.Context, arg LeaseNextQ
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const leaseParkedDesktopTask = `-- name: LeaseParkedDesktopTask :one
UPDATE desktop_tasks
SET active_attempt_id = $1,
lease_token_hash = $2,
lease_expires_at = now() + interval '10 minutes',
status = 'in_progress',
attempts = attempts + 1,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $3
AND target_client_id = $4
AND status = 'waiting_user'
AND active_attempt_id IS NULL
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type LeaseParkedDesktopTaskParams struct {
AttemptID pgtype.UUID `json:"attempt_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
DesktopID pgtype.UUID `json:"desktop_id"`
ClientID pgtype.UUID `json:"client_id"`
}
func (q *Queries) LeaseParkedDesktopTask(ctx context.Context, arg LeaseParkedDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, leaseParkedDesktopTask,
arg.AttemptID,
arg.LeaseTokenHash,
arg.DesktopID,
arg.ClientID,
)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -607,12 +535,11 @@ SET active_attempt_id = $1,
lease_expires_at = now() + interval '10 minutes',
status = 'in_progress',
attempts = attempts + 1,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $3
AND target_client_id = $4
AND status = 'queued'
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type LeaseQueuedDesktopTaskByDesktopIDParams struct {
@@ -647,7 +574,6 @@ func (q *Queries) LeaseQueuedDesktopTaskByDesktopID(ctx context.Context, arg Lea
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -663,11 +589,10 @@ SET status = 'unknown',
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE target_client_id = $2
AND workspace_id = $3
AND status IN ('waiting_user', 'in_progress')
AND status = 'in_progress'
`
type MarkDesktopTasksUnknownByClientParams struct {
@@ -684,55 +609,6 @@ func (q *Queries) MarkDesktopTasksUnknownByClient(ctx context.Context, arg MarkD
return result.RowsAffected(), nil
}
const parkDesktopTask = `-- name: ParkDesktopTask :one
UPDATE desktop_tasks
SET status = 'waiting_user',
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = $1,
updated_at = now()
WHERE desktop_id = $2
AND lease_token_hash = $3
AND status = 'in_progress'
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
`
type ParkDesktopTaskParams struct {
ParkedReason pgtype.Text `json:"parked_reason"`
DesktopID pgtype.UUID `json:"desktop_id"`
LeaseTokenHash []byte `json:"lease_token_hash"`
}
func (q *Queries) ParkDesktopTask(ctx context.Context, arg ParkDesktopTaskParams) (DesktopTask, error) {
row := q.db.QueryRow(ctx, parkDesktopTask, arg.ParkedReason, arg.DesktopID, arg.LeaseTokenHash)
var i DesktopTask
err := row.Scan(
&i.ID,
&i.DesktopID,
&i.JobID,
&i.TenantID,
&i.WorkspaceID,
&i.TargetAccountID,
&i.TargetClientID,
&i.PlatformID,
&i.Kind,
&i.Payload,
&i.Status,
&i.DedupKey,
&i.ActiveAttemptID,
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const reconcileDesktopTask = `-- name: ReconcileDesktopTask :one
UPDATE desktop_tasks
SET status = CASE
@@ -747,13 +623,12 @@ SET status = CASE
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
attempts = attempts + CASE WHEN $1::text = 'retry' THEN 1 ELSE 0 END,
updated_at = now()
WHERE desktop_id = $4
AND workspace_id = $5
AND status = 'unknown'
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type ReconcileDesktopTaskParams struct {
@@ -790,7 +665,6 @@ func (q *Queries) ReconcileDesktopTask(ctx context.Context, arg ReconcileDesktop
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,
@@ -806,12 +680,11 @@ SET status = 'aborted',
active_attempt_id = NULL,
lease_token_hash = NULL,
lease_expires_at = NULL,
parked_reason = NULL,
updated_at = now()
WHERE desktop_id = $2
AND workspace_id = $3
AND status IN ('queued', 'waiting_user')
RETURNING id, 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_token_hash, lease_expires_at, attempts, parked_reason, result, error, created_at, updated_at
AND status = 'queued'
RETURNING id, 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_token_hash, lease_expires_at, attempts, result, error, created_at, updated_at
`
type TenantCancelDesktopTaskParams struct {
@@ -840,7 +713,6 @@ func (q *Queries) TenantCancelDesktopTask(ctx context.Context, arg TenantCancelD
&i.LeaseTokenHash,
&i.LeaseExpiresAt,
&i.Attempts,
&i.ParkedReason,
&i.Result,
&i.Error,
&i.CreatedAt,