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:
2026-07-15 14:59:00 +03:00
co-authored by Claude Opus 4.8
parent 87e0d7dcf5
commit 2ef6916891
2 changed files with 49 additions and 12 deletions
@@ -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');
});
}
};