package app import ( "context" "strings" "github.com/jackc/pgx/v5" "github.com/geo-platform/tenant-api/internal/shared/response" ) func shouldRecoverHumanVerificationTasks( task *monitoringCollectTask, req MonitoringTaskResultRequest, ) bool { return task != nil && task.CollectorType == monitoringCollectorType && strings.TrimSpace(task.ExecutionOwner) == "desktop_tasks" && strings.TrimSpace(task.TriggerSource) == "manual" && normalizeRunStatus(req.Status) == "succeeded" } func (s *MonitoringCallbackService) restoreHumanVerificationTasks( ctx context.Context, tx pgx.Tx, task *monitoringCollectTask, installationID string, ) ([]int64, error) { installationID = strings.TrimSpace(installationID) if tx == nil || task == nil || installationID == "" { return nil, nil } rows, err := tx.Query(ctx, ` UPDATE monitoring_collect_tasks SET status = 'pending', lease_token_hash = NULL, leased_to_executor = NULL, leased_at = NULL, lease_expires_at = NULL, callback_received_at = NULL, completed_at = NULL, skip_reason = NULL, error_message = NULL, dispatch_after = NOW(), last_dispatched_at = NULL, request_payload_json = ( CASE WHEN request_payload_json IS NULL OR jsonb_typeof(request_payload_json) <> 'object' THEN '{}'::jsonb ELSE request_payload_json END ) || jsonb_build_object( 'human_verification_recovery', jsonb_build_object( 'recovered_at', NOW(), 'recovered_by_monitoring_task_id', $8::bigint ) ), updated_at = NOW() WHERE tenant_id = $1 AND business_date = $2::date AND ai_platform_id = $3 AND collector_type = $4 AND COALESCE(execution_owner, 'legacy') = $5 AND trigger_source = 'automatic' AND status = 'skipped' AND skip_reason = $6 AND target_client_id::text = $7 RETURNING brand_id `, task.TenantID, task.BusinessDate.Format("2006-01-02"), task.AIPlatformID, task.CollectorType, "desktop_tasks", monitoringPlatformHumanVerificationSkipReason, installationID, task.ID, ) if err != nil { return nil, response.ErrInternal(50041, "human_verification_recovery_failed", "failed to restore monitoring tasks canceled by human verification") } defer rows.Close() brandIDs := make([]int64, 0) for rows.Next() { var brandID int64 if scanErr := rows.Scan(&brandID); scanErr != nil { return nil, response.ErrInternal(50041, "human_verification_recovery_failed", "failed to parse restored monitoring tasks") } if brandID > 0 { brandIDs = append(brandIDs, brandID) } } if err := rows.Err(); err != nil { return nil, response.ErrInternal(50041, "human_verification_recovery_failed", "failed to iterate restored monitoring tasks") } return uniqueSortedMonitoringProjectionBrandIDs(brandIDs), nil }