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',
|
'percent' => 'nullable|integer|min:0|max:100',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
WatchEvent::create([
|
// Oynatıcı 30 saniyede bir ping atar ve her ping o ana kadarki KÜMÜLATİF
|
||||||
'user_id' => auth()->id(),
|
// 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(),
|
'session_id' => session()->getId(),
|
||||||
'anime_id' => $data['anime_id'],
|
|
||||||
'episode_id' => $data['episode_id'] ?? null,
|
'episode_id' => $data['episode_id'] ?? null,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'user_id' => auth()->id(),
|
||||||
|
'anime_id' => $data['anime_id'],
|
||||||
'season_number' => $data['season_number'],
|
'season_number' => $data['season_number'],
|
||||||
'episode_number' => $data['episode_number'],
|
'episode_number' => $data['episode_number'],
|
||||||
'seconds_watched' => $data['seconds'],
|
'seconds_watched' => $data['seconds'],
|
||||||
'total_seconds' => $data['total'] ?? 0,
|
'total_seconds' => $data['total'] ?? 0,
|
||||||
'percent_complete'=> $data['percent'] ?? 0,
|
'percent_complete'=> $data['percent'] ?? 0,
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
|
|
||||||
// Oturum izleme süresini güncelle
|
// Oturum izleme süresini güncelle
|
||||||
try {
|
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