From 2ef69168910bf370ff413f95fba159f4edb40bbe Mon Sep 17 00:00:00 2001 From: ayrisdev Date: Wed, 15 Jul 2026 14:59:00 +0300 Subject: [PATCH] Fix inflated watch metrics: one row per viewing instead of per 30s ping The player pings /track/watch every 30s with the CUMULATIVE position, and each ping inserted a new row (~18 rows per viewing, 254k/day). SUM(seconds_watched) therefore summed cumulative snapshots: a single 58-minute viewing reported as 4238 minutes (~73x), skewing TrendingController's watch-minute ranking and the admin "total_sec"/"plays" figures. Upsert per (session_id, episode_id) so SUM is the real watch time and COUNT is the real play count. Adds the supporting index. Co-Authored-By: Claude Opus 4.8 --- .../Frontend/TrackingController.php | 34 ++++++++++++------- ..._session_episode_index_to_watch_events.php | 27 +++++++++++++++ 2 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 database/migrations/2026_07_15_000001_add_session_episode_index_to_watch_events.php diff --git a/app/Http/Controllers/Frontend/TrackingController.php b/app/Http/Controllers/Frontend/TrackingController.php index 711c29f..39906b1 100644 --- a/app/Http/Controllers/Frontend/TrackingController.php +++ b/app/Http/Controllers/Frontend/TrackingController.php @@ -74,18 +74,28 @@ class TrackingController extends Controller 'percent' => 'nullable|integer|min:0|max:100', ]); - WatchEvent::create([ - 'user_id' => auth()->id(), - 'session_id' => session()->getId(), - 'anime_id' => $data['anime_id'], - 'episode_id' => $data['episode_id'] ?? null, - 'season_number' => $data['season_number'], - 'episode_number' => $data['episode_number'], - 'seconds_watched' => $data['seconds'], - 'total_seconds' => $data['total'] ?? 0, - 'percent_complete'=> $data['percent'] ?? 0, - 'created_at' => now(), - ]); + // Oynatıcı 30 saniyede bir ping atar ve her ping o ana kadarki KÜMÜLATİF + // konumu gönderir. Ping başına yeni satır atmak hem tabloyu şişiriyor + // (izleme başına ~18 satır) hem de SUM(seconds_watched) ile hesaplanan + // izleme süresini katbekat şişiriyordu. İzleme (session + bölüm) başına + // tek satır tutup güncelliyoruz: SUM artık gerçek süreyi, COUNT gerçek + // oynatma sayısını veriyor. + WatchEvent::updateOrCreate( + [ + 'session_id' => session()->getId(), + 'episode_id' => $data['episode_id'] ?? null, + ], + [ + 'user_id' => auth()->id(), + 'anime_id' => $data['anime_id'], + 'season_number' => $data['season_number'], + 'episode_number' => $data['episode_number'], + 'seconds_watched' => $data['seconds'], + 'total_seconds' => $data['total'] ?? 0, + 'percent_complete'=> $data['percent'] ?? 0, + 'created_at' => now(), + ] + ); // Oturum izleme süresini güncelle try { diff --git a/database/migrations/2026_07_15_000001_add_session_episode_index_to_watch_events.php b/database/migrations/2026_07_15_000001_add_session_episode_index_to_watch_events.php new file mode 100644 index 0000000..f961a78 --- /dev/null +++ b/database/migrations/2026_07_15_000001_add_session_episode_index_to_watch_events.php @@ -0,0 +1,27 @@ +index(['session_id', 'episode_id']); + }); + } + } + + public function down(): void + { + Schema::table('analytics_watch_events', function (Blueprint $table) { + $table->dropIndex('analytics_watch_events_session_id_episode_id_index'); + }); + } +};