Warenwirtschaft: Review-Fix — Indizes + schlanke API-Bestellungen-Seite

Indizes auf shopping_orders.shipped/shipped_at/created_at (Board-Filter,
Tages-Kacheln) und products.wp_number (SKU-Auflösung). Die
API-Bestellungen-Seite lud das komplette JSON-payload für alle 500 Zeilen
und serialisierte es in Inline-Attribute; jetzt persistierte
positions_count, Liste ohne payload, Inhalt on-demand über show-Endpoint.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-20 13:02:47 +00:00
parent f4256bfc89
commit 50243a07b4
8 changed files with 172 additions and 20 deletions

View file

@ -20,13 +20,17 @@ class ApiOrderLogController extends Controller
{
$limit = $request->query('all') ? null : self::INDEX_LIMIT;
// Ohne payload (Review 20.07.2026): der Inhalt wird erst im Modal per show()
// nachgeladen, statt für alle Zeilen mehrere MB JSON in die Seite zu rendern.
$logs = ApiOrderLog::query()
->with(['shoppingOrder', 'shoppingUser'])
->with(['shoppingUser:id,billing_firstname,billing_lastname'])
->select(['id', 'shopping_order_id', 'shopping_user_id', 'wp_order_number', 'positions_count', 'has_errors', 'error_summary', 'created_at'])
->orderByDesc('id')
->when($limit !== null, fn ($query) => $query->limit($limit))
->get();
$errorCount = ApiOrderLog::query()->where('has_errors', true)->count();
$logTotal = ApiOrderLog::query()->count();
// SKU-Konsistenz (Plan §4): doppelte WP-Nummern brechen die Zuordnung,
// aktive Produkte ohne WP-Nummer können nie per API zugeordnet werden.
@ -57,9 +61,24 @@ class ApiOrderLogController extends Controller
return view('admin.inventory.api-orders.index', [
'logs' => $logs,
'listLimit' => $limit,
'listTotal' => $logTotal,
'errorCount' => $errorCount,
'duplicateSkuProducts' => $duplicateSkuProducts,
'missingSkuProducts' => $missingSkuProducts,
]);
}
/**
* Inhalt einer Übertragung on-demand fürs Modal (Review 20.07.2026): liefert die
* Positionen bzw. den Roh-Body als JSON, damit die Liste ohne payload auskommt.
*/
public function show(ApiOrderLog $apiOrderLog)
{
return response()->json([
'lines' => $apiOrderLog->payload['lines'] ?? [],
'raw' => isset($apiOrderLog->payload['raw'])
? json_encode($apiOrderLog->payload['raw'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
: null,
]);
}
}

View file

@ -19,6 +19,7 @@ class ApiOrderLog extends Model
'shopping_user_id',
'wp_order_number',
'endpoint',
'positions_count',
'payload',
'has_errors',
'error_summary',
@ -51,6 +52,7 @@ class ApiOrderLog extends Model
'shopping_user_id' => $shoppingUser?->id,
'wp_order_number' => is_numeric($wpOrderNumber) ? (int) $wpOrderNumber : null,
'endpoint' => 'order',
'positions_count' => 0,
'payload' => ['raw' => is_string($rawOrder) ? $rawOrder : json_decode(json_encode($rawOrder), true)],
'has_errors' => true,
'error_summary' => $summary,
@ -95,6 +97,7 @@ class ApiOrderLog extends Model
'shopping_user_id' => $shoppingUser->id,
'wp_order_number' => is_numeric($wpOrderNumber) ? (int) $wpOrderNumber : null,
'endpoint' => 'order',
'positions_count' => count($payloadLines),
'payload' => ['lines' => $payloadLines],
'has_errors' => $failedCount > 0,
'error_summary' => $failedCount > 0