From 8c6502de2f8ec2bd8382cd6945c327d7be400e14 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Wed, 28 Jan 2026 05:34:41 +0000
Subject: [PATCH] =Queue cleanup - seems to be working enough to get legacy before and after going!

---
 inc/rest/routes/QueueRoutes.php |  132 ++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 116 insertions(+), 16 deletions(-)

diff --git a/inc/rest/routes/QueueRoutes.php b/inc/rest/routes/QueueRoutes.php
index db567e3..400717b 100644
--- a/inc/rest/routes/QueueRoutes.php
+++ b/inc/rest/routes/QueueRoutes.php
@@ -79,6 +79,40 @@
 				]
 			]
 		]);
+
+		register_rest_route($this->namespace, '/queue/errors', [
+			'methods'   => 'GET',
+			'callback'  => [$this, 'getOperationErrors'],
+			'permission_callback' => [$this, 'checkPermission'],
+		]);
+
+		register_rest_route($this->namespace, '/queue/poll', [
+			'methods'   => 'GET',
+			'callback'  => [$this, 'pollQueue'],
+			'permission_callback' => [$this, 'checkPermission'],
+			'args' => [
+				'since' => [
+					'type' => 'string',
+					'description' => 'ISO timestamp - only return operations updated after this'
+				],
+				'ids' => [
+					'type' => 'string',
+					'description' => 'Comma-separated IDs to check'
+				]
+			]
+		]);
+
+		register_rest_route($this->namespace, '/queue/(?P<id>[a-zA-Z0-9_-]+)', [
+			'methods'   => 'GET',
+			'callback'  => [$this, 'getOperation'],
+			'permission_callback' => [$this, 'checkPermission'],
+			'args' => [
+				'id' => [
+					'required' => true,
+					'type' => 'string',
+				]
+			]
+		]);
 	}
 
     /**
@@ -175,7 +209,7 @@
 	/**
 	 * Format Operation object for API response
 	 */
-	protected function formatOperationFromObject(\JVBase\managers\queue\Operation $op): array
+	protected function formatOperationFromObject(\JVBase\managers\queue\Operation $op, bool $full = false): array
 	{
 		$formatted = [
 			'id' => $op->id,
@@ -183,30 +217,30 @@
 			'status' => $this->mapStateToStatus($op->state, $op->outcome),
 			'progress_count' => $op->processedItems,
 			'count' => $op->totalItems,
-			'retries' => $op->retries,
-			'data' => $op->requestData,
-			'result' => $op->result ?? [],
+			'title' => $this->getOperationTitle($op->type, $op->requestData),
+			'created_at' => $this->formatTimestamp($op->scheduledAt),
+			'updated_at' => $this->formatTimestamp($op->completedAt ?? $op->startedAt ?? $op->scheduledAt),
 		];
 
-		$formatted['created_at'] = $this->formatTimestamp($op->scheduledAt);
-		$formatted['updated_at'] = $this->formatTimestamp($op->completedAt ?? $op->startedAt ?? $op->scheduledAt);
-
-		if ($op->state === 'completed' && $op->completedAt) {
-			$formatted['completed_at'] = $this->formatTimestamp($op->completedAt);
+		if ($op->processedItems > 0 && $op->totalItems > 0) {
+			$formatted['progress_percentage'] = round(($op->processedItems / $op->totalItems) * 100);
 		}
 
 		if ($op->errorMessage) {
 			$formatted['error_message'] = $op->errorMessage;
 		}
 
-		if ($formatted['count'] > 0) {
-			$formatted['progress_percentage'] = round(
-				($formatted['progress_count'] / $formatted['count']) * 100
-			);
-		}
+		// Only include heavy data when requested
+		if ($full) {
+			$formatted['data'] = $op->requestData;
+			$formatted['result'] = $op->result ?? [];
+			$formatted['retries'] = $op->retries;
+			$formatted['user_dismissed'] = $op->userDismissed;
 
-		$formatted['title'] = $this->getOperationTitle($op->type, $op->requestData);
-		$formatted['user_dismissed'] = $op->userDismissed;
+			if ($op->state === 'completed' && $op->completedAt) {
+				$formatted['completed_at'] = $this->formatTimestamp($op->completedAt);
+			}
+		}
 
 		return $formatted;
 	}
@@ -402,4 +436,70 @@
 			'cleanup_reason' => null
 		];
 	}
+
+
+	public function pollQueue(WP_REST_Request $request): WP_REST_Response
+	{
+		$user_id = $request->get_param('user');
+		$since = $request->get_param('since');
+		$ids = $request->get_param('ids');
+
+		$filters = [
+			'not_dismissed' => true,
+			'limit' => 50,
+		];
+
+		if (!empty($ids)) {
+			$filters['ids'] = array_map('trim', explode(',', $ids));
+		}
+
+		$operations = JVB()->queue()->getUserOperations($user_id, $filters);
+
+		// Filter by timestamp if provided
+		if ($since) {
+			$sinceTime = strtotime($since);
+			$operations = array_filter($operations, function($op) use ($sinceTime) {
+				$updatedAt = strtotime($op->completedAt ?? $op->startedAt ?? $op->scheduledAt);
+				return $updatedAt > $sinceTime;
+			});
+		}
+
+		// Return minimal data
+		$items = array_map(function($op) {
+			return [
+				'id' => $op->id,
+				'status' => $this->mapStateToStatus($op->state, $op->outcome),
+				'progress_count' => $op->processedItems,
+				'count' => $op->totalItems,
+				'updated_at' => $this->formatTimestamp($op->completedAt ?? $op->startedAt ?? $op->scheduledAt),
+				'error_message' => $op->errorMessage,
+			];
+		}, $operations);
+
+		return new WP_REST_Response([
+			'items' => array_values($items),
+			'server_time' => date('c'),
+			'has_active' => count(array_filter($items, fn($i) => in_array($i['status'], ['pending', 'processing']))) > 0,
+		]);
+	}
+
+	public function getOperation(WP_REST_Request $request): WP_REST_Response
+	{
+		$id = $request->get_param('id');
+		$user_id = $request->get_param('user');
+
+		$op = JVB()->queue()->get($id);
+
+		if (!$op || $op->userId !== $user_id) {
+			return new WP_REST_Response([
+				'success' => false,
+				'message' => 'Operation not found'
+			], 404);
+		}
+
+		return new WP_REST_Response([
+			'success' => true,
+			'operation' => $this->formatOperationFromObject($op, true) // Full data
+		]);
+	}
 }

--
Gitblit v1.10.0