fix: enhance publish record deletion logic and add soft delete functionality
Backend CI / Backend (push) Successful in 14m47s
Backend CI / Backend (push) Successful in 14m47s
This commit is contained in:
@@ -425,16 +425,17 @@ func (s *MediaService) DeletePublishRecord(ctx context.Context, recordID int64)
|
||||
|
||||
var publishBatchID int64
|
||||
var articleID int64
|
||||
var cancelErrorJSON []byte
|
||||
cancelErrorJSON, err = marshalOptionalJSON(map[string]any{
|
||||
var publishStatus string
|
||||
cancelErrorJSONBytes, err := marshalOptionalJSON(map[string]any{
|
||||
"reason": "publish_record_deleted",
|
||||
"source": "tenant_web",
|
||||
})
|
||||
if err != nil {
|
||||
return nil, response.ErrInternal(50044, "publish_record_delete_payload_failed", "failed to delete publish record")
|
||||
}
|
||||
cancelErrorJSON := string(cancelErrorJSONBytes)
|
||||
err = tx.QueryRow(ctx, `
|
||||
SELECT pr.publish_batch_id, pr.article_id
|
||||
SELECT pr.publish_batch_id, pr.article_id, pr.status
|
||||
FROM publish_records pr
|
||||
JOIN articles a
|
||||
ON a.id = pr.article_id
|
||||
@@ -447,7 +448,7 @@ func (s *MediaService) DeletePublishRecord(ctx context.Context, recordID int64)
|
||||
AND pb.initiator_user_id = $3
|
||||
AND pr.deleted_at IS NULL
|
||||
FOR UPDATE OF pr
|
||||
`, recordID, actor.TenantID, actor.UserID).Scan(&publishBatchID, &articleID)
|
||||
`, recordID, actor.TenantID, actor.UserID).Scan(&publishBatchID, &articleID, &publishStatus)
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, response.ErrNotFound(40435, "publish_record_not_found", "publish record not found")
|
||||
@@ -468,20 +469,22 @@ func (s *MediaService) DeletePublishRecord(ctx context.Context, recordID int64)
|
||||
return nil, response.ErrNotFound(40435, "publish_record_not_found", "publish record not found")
|
||||
}
|
||||
|
||||
if _, err := tx.Exec(ctx, `
|
||||
UPDATE desktop_tasks
|
||||
SET status = 'aborted',
|
||||
error = $3,
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
updated_at = NOW()
|
||||
WHERE tenant_id = $1
|
||||
AND kind = 'publish'
|
||||
AND status = 'queued'
|
||||
AND payload->>'publish_record_id' = $2
|
||||
`, actor.TenantID, recordID, cancelErrorJSON); err != nil {
|
||||
return nil, response.ErrInternal(50044, "publish_record_delete_cancel_task_failed", "failed to cancel queued publish task before deleting record")
|
||||
if publishRecordMayHaveQueuedTask(publishStatus) {
|
||||
if _, err := tx.Exec(ctx, `
|
||||
UPDATE desktop_tasks
|
||||
SET status = 'aborted',
|
||||
error = $3::jsonb,
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
updated_at = NOW()
|
||||
WHERE tenant_id = $1
|
||||
AND kind = 'publish'
|
||||
AND status = 'queued'
|
||||
AND payload->>'publish_record_id' = $2::text
|
||||
`, actor.TenantID, recordID, cancelErrorJSON); err != nil {
|
||||
return nil, response.ErrInternal(50044, "publish_record_delete_cancel_task_failed", "failed to cancel queued publish task before deleting record")
|
||||
}
|
||||
}
|
||||
|
||||
batchStatus, err := recalculatePublishBatchStatus(ctx, tx, publishBatchID)
|
||||
@@ -532,6 +535,15 @@ func publishPlatformRequiresCover(platformID string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func publishRecordMayHaveQueuedTask(status string) bool {
|
||||
switch strings.TrimSpace(status) {
|
||||
case "queued", "publishing", "pending", "running":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func pointerStringValue(value *string) string {
|
||||
if value == nil {
|
||||
return ""
|
||||
|
||||
@@ -115,7 +115,7 @@ func cancelQueuedPublishTasksForUnavailableArticle(ctx context.Context, tx pgx.T
|
||||
if tx == nil || tenantID <= 0 || articleID <= 0 {
|
||||
return nil
|
||||
}
|
||||
errorJSON, err := marshalOptionalJSON(map[string]any{
|
||||
errorJSONBytes, err := marshalOptionalJSON(map[string]any{
|
||||
"code": "article_unavailable",
|
||||
"message": "article is unavailable before publishing",
|
||||
"source": "article_unavailable_cleanup",
|
||||
@@ -123,6 +123,7 @@ func cancelQueuedPublishTasksForUnavailableArticle(ctx context.Context, tx pgx.T
|
||||
if err != nil {
|
||||
return response.ErrInternal(50120, "publish_task_cancel_payload_failed", "failed to encode publish task cancellation payload")
|
||||
}
|
||||
errorJSON := string(errorJSONBytes)
|
||||
|
||||
if _, err := tx.Exec(ctx, `
|
||||
WITH affected_records AS (
|
||||
@@ -154,7 +155,7 @@ func cancelQueuedPublishTasksForUnavailableArticle(ctx context.Context, tx pgx.T
|
||||
updated_tasks AS (
|
||||
UPDATE desktop_tasks dt
|
||||
SET status = 'aborted',
|
||||
error = $3,
|
||||
error = $3::jsonb,
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
@@ -280,7 +281,7 @@ func cancelQueuedPublishTasksForDesktopAccountUnbind(
|
||||
if tx == nil || tenantID <= 0 || workspaceID <= 0 || accountID == uuid.Nil {
|
||||
return 0, nil
|
||||
}
|
||||
errorJSON, err := marshalOptionalJSON(map[string]any{
|
||||
errorJSONBytes, err := marshalOptionalJSON(map[string]any{
|
||||
"code": "desktop_account_unbound",
|
||||
"message": "desktop account was unbound before publishing",
|
||||
"source": "desktop_account_unbind",
|
||||
@@ -288,6 +289,7 @@ func cancelQueuedPublishTasksForDesktopAccountUnbind(
|
||||
if err != nil {
|
||||
return 0, response.ErrInternal(50120, "publish_task_cancel_payload_failed", "failed to encode publish task cancellation payload")
|
||||
}
|
||||
errorJSON := string(errorJSONBytes)
|
||||
|
||||
rows, err := tx.Query(ctx, `
|
||||
SELECT DISTINCT pr.id, pr.publish_batch_id, pr.article_id
|
||||
@@ -354,7 +356,7 @@ func cancelQueuedPublishTasksForDesktopAccountUnbind(
|
||||
tag, err := tx.Exec(ctx, `
|
||||
UPDATE desktop_tasks dt
|
||||
SET status = 'aborted',
|
||||
error = $4,
|
||||
error = $4::jsonb,
|
||||
active_attempt_id = NULL,
|
||||
lease_token_hash = NULL,
|
||||
lease_expires_at = NULL,
|
||||
|
||||
@@ -1,9 +1,2 @@
|
||||
DROP INDEX CONCURRENTLY IF EXISTS idx_publish_records_visible_status;
|
||||
|
||||
DROP INDEX CONCURRENTLY IF EXISTS idx_publish_records_article_account_active;
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_publish_records_article_account_active
|
||||
ON publish_records (tenant_id, article_id, platform_account_id, updated_at DESC, id DESC)
|
||||
WHERE status IN ('queued', 'publishing', 'success');
|
||||
|
||||
ALTER TABLE publish_records
|
||||
DROP COLUMN IF EXISTS deleted_at;
|
||||
|
||||
@@ -1,12 +1,2 @@
|
||||
ALTER TABLE publish_records
|
||||
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ;
|
||||
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_publish_records_visible_status
|
||||
ON publish_records (tenant_id, status, created_at DESC, id DESC)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
DROP INDEX CONCURRENTLY IF EXISTS idx_publish_records_article_account_active;
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_publish_records_article_account_active
|
||||
ON publish_records (tenant_id, article_id, platform_account_id, updated_at DESC, id DESC)
|
||||
WHERE status IN ('queued', 'publishing', 'success')
|
||||
AND deleted_at IS NULL;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX CONCURRENTLY IF EXISTS idx_publish_records_visible_status;
|
||||
@@ -0,0 +1,3 @@
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_publish_records_visible_status
|
||||
ON publish_records (tenant_id, status, created_at DESC, id DESC)
|
||||
WHERE deleted_at IS NULL;
|
||||
@@ -0,0 +1,3 @@
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_publish_records_article_account_active
|
||||
ON publish_records (tenant_id, article_id, platform_account_id, updated_at DESC, id DESC)
|
||||
WHERE status IN ('queued', 'publishing', 'success');
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX CONCURRENTLY IF EXISTS idx_publish_records_article_account_active;
|
||||
@@ -0,0 +1 @@
|
||||
DROP INDEX CONCURRENTLY IF EXISTS idx_publish_records_article_account_active;
|
||||
@@ -0,0 +1,4 @@
|
||||
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_publish_records_article_account_active
|
||||
ON publish_records (tenant_id, article_id, platform_account_id, updated_at DESC, id DESC)
|
||||
WHERE status IN ('queued', 'publishing', 'success')
|
||||
AND deleted_at IS NULL;
|
||||
Reference in New Issue
Block a user