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 <noreply@anthropic.com>
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration {
|
||||
/**
|
||||
* TrackingController::watch() artık izleme (session + bölüm) başına tek
|
||||
* satır tutup güncelliyor; bu index olmadan her ping tabloyu tarardı.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasIndex('analytics_watch_events', 'analytics_watch_events_session_id_episode_id_index')) {
|
||||
Schema::table('analytics_watch_events', function (Blueprint $table) {
|
||||
$table->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');
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user