json( $queue->listPayload($request->user(), $request->only(['batch_id', 'status', 'sort'])) ); } public function store(Request $request, UploadQueueService $queue): JsonResponse { $validated = $request->validate([ 'name' => ['nullable', 'string', 'max:160'], 'files' => ['required', 'array', 'min:1', 'max:50'], 'files.*.name' => ['required', 'string', 'max:255'], 'defaults' => ['nullable', 'array'], 'defaults.category_id' => ['nullable', 'integer', 'exists:categories,id'], 'defaults.tags' => ['nullable', 'array', 'max:' . (int) config('tags.max_user_tags', 30)], 'defaults.tags.*' => ['string', 'max:64'], 'defaults.visibility' => ['nullable', 'string', 'in:public,unlisted,private'], 'defaults.is_mature' => ['nullable', 'boolean'], 'defaults.group' => ['nullable', 'string', 'max:90'], ]); $batch = $queue->createBatch( $request->user(), (array) $validated['files'], (array) ($validated['defaults'] ?? []), Arr::get($validated, 'name') ); return response()->json([ 'batch' => [ 'id' => (int) $batch->id, 'name' => $batch->name, ], 'items' => $batch->items->map(fn ($item): array => [ 'id' => (int) $item->id, 'artwork_id' => (int) $item->artwork_id, 'original_filename' => (string) $item->original_filename, ])->values()->all(), 'queue' => $queue->listPayload($request->user(), ['batch_id' => (int) $batch->id]), ], 201); } public function markFailed(Request $request, int $id, UploadQueueService $queue): JsonResponse { $validated = $request->validate([ 'error_code' => ['nullable', 'string', 'max:64'], 'error_message' => ['nullable', 'string', 'max:4000'], ]); $queue->markItemFailedForUser( $request->user(), $id, (string) ($validated['error_code'] ?? 'upload_failed'), (string) ($validated['error_message'] ?? 'Upload failed before processing completed.') ); return response()->json(['ok' => true]); } public function bulk(Request $request, UploadQueueService $queue): JsonResponse { $validated = $request->validate([ 'action' => ['required', 'string', 'in:publish,delete,apply_category,apply_tags,set_visibility,generate_ai'], 'item_ids' => ['required', 'array', 'min:1', 'max:200'], 'item_ids.*' => ['integer'], 'params' => ['nullable', 'array'], 'params.category_id' => ['nullable', 'integer', 'exists:categories,id'], 'params.tags' => ['nullable', 'array', 'max:' . (int) config('tags.max_user_tags', 30)], 'params.tags.*' => ['string', 'max:64'], 'params.visibility' => ['nullable', 'string', 'in:public,unlisted,private'], 'confirm' => ['required_if:action,delete', 'string'], ]); if (($validated['action'] ?? '') === 'delete' && ($validated['confirm'] ?? '') !== 'DELETE') { return response()->json([ 'errors' => ['You must type DELETE to confirm draft deletion.'], 'success' => 0, 'failed' => count((array) ($validated['item_ids'] ?? [])), ], 422); } $result = $queue->bulkAction( $request->user(), (string) $validated['action'], (array) $validated['item_ids'], (array) ($validated['params'] ?? []) ); return response()->json($result, $result['success'] > 0 ? 200 : 422); } public function retry(Request $request, int $id, UploadQueueService $queue): JsonResponse { $queue->retryProcessingForUser($request->user(), $id); return response()->json(['ok' => true]); } }