validate([ 'event_id' => ['nullable', 'uuid'], 'event_type' => ['required', 'string', 'in:view,click,favorite,download'], 'artwork_id' => ['required', 'integer', 'exists:artworks,id'], 'occurred_at' => ['nullable', 'date'], 'algo_version' => ['nullable', 'string', 'max:64'], 'meta' => ['nullable', 'array'], ]); $eventId = (string) ($payload['event_id'] ?? (string) Str::uuid()); $algoVersion = (string) ($payload['algo_version'] ?? config('discovery.algo_version', 'clip-cosine-v1')); $occurredAt = isset($payload['occurred_at']) ? (string) $payload['occurred_at'] : now()->toIso8601String(); IngestUserDiscoveryEventJob::dispatch( eventId: $eventId, userId: (int) $request->user()->id, artworkId: (int) $payload['artwork_id'], eventType: (string) $payload['event_type'], algoVersion: $algoVersion, occurredAt: $occurredAt, meta: (array) ($payload['meta'] ?? []) )->onQueue((string) config('discovery.queue', 'default')); return response()->json([ 'queued' => true, 'event_id' => $eventId, 'algo_version' => $algoVersion, ], Response::HTTP_ACCEPTED); } }