feat: ship creator journey v2 and profile updates

This commit is contained in:
2026-04-12 21:42:07 +02:00
parent a2457f4e49
commit d5cff21ea2
335 changed files with 20147 additions and 1545 deletions

View File

@@ -16,14 +16,10 @@ use Illuminate\Http\Request;
*
* Fire-and-forget view tracker.
*
* Deduplication strategy (layered):
* 1. Session key (`art_viewed.{id}`) prevents double-counts within the
* same browser session (survives page reloads).
* 2. Route throttle (5 per 10 minutes per IP+artwork) catches bots that
* don't send session cookies.
*
* The frontend should additionally guard with sessionStorage so it only
* calls this endpoint once per page load.
* Every page visit should count as a new view.
* Lightweight abuse protection is handled at the route layer via throttling,
* while the stat increment itself is applied immediately so Studio analytics
* reflect new visits without waiting for the scheduler to flush Redis deltas.
*/
final class ArtworkViewController extends Controller
{
@@ -43,18 +39,11 @@ final class ArtworkViewController extends Controller
return response()->json(['error' => 'Not found'], 404);
}
$sessionKey = 'art_viewed.' . $id;
// Already counted this session — return early without touching the DB.
if ($request->hasSession() && $request->session()->has($sessionKey)) {
return response()->json(['ok' => true, 'counted' => false]);
}
// Write persistent event log (auth user_id or null for guests).
$this->stats->logViewEvent((int) $artwork->id, $request->user()?->id);
// Defer to Redis when available, fall back to direct DB increment.
$this->stats->incrementViews((int) $artwork->id, 1, defer: true);
// Apply the increment immediately so counters stay fresh in Studio.
$this->stats->incrementViews((int) $artwork->id, 1, defer: false);
$viewerId = $request->user()?->id;
if ($artwork->user_id !== null && (int) $artwork->user_id !== (int) ($viewerId ?? 0)) {
@@ -66,11 +55,6 @@ final class ArtworkViewController extends Controller
);
}
// Mark this session so the artwork is not counted again.
if ($request->hasSession()) {
$request->session()->put($sessionKey, true);
}
return response()->json(['ok' => true, 'counted' => true]);
}
}