optimizations
This commit is contained in:
96
app/Services/FollowAnalyticsService.php
Normal file
96
app/Services/FollowAnalyticsService.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
final class FollowAnalyticsService
|
||||
{
|
||||
public function recordFollow(int $actorId, int $targetId): void
|
||||
{
|
||||
if (! Schema::hasTable('user_follow_analytics')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->increment($actorId, 'follows_made');
|
||||
$this->increment($targetId, 'followers_gained');
|
||||
}
|
||||
|
||||
public function recordUnfollow(int $actorId, int $targetId): void
|
||||
{
|
||||
if (! Schema::hasTable('user_follow_analytics')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->increment($actorId, 'unfollows_made');
|
||||
$this->increment($targetId, 'followers_lost');
|
||||
}
|
||||
|
||||
public function summaryForUser(int $userId, int $currentFollowersCount = 0): array
|
||||
{
|
||||
if (! Schema::hasTable('user_follow_analytics')) {
|
||||
return $this->emptySummary();
|
||||
}
|
||||
|
||||
$today = now()->toDateString();
|
||||
$weekStart = now()->subDays(6)->toDateString();
|
||||
|
||||
$todayRow = DB::table('user_follow_analytics')
|
||||
->where('user_id', $userId)
|
||||
->whereDate('date', $today)
|
||||
->first();
|
||||
|
||||
$weekly = DB::table('user_follow_analytics')
|
||||
->where('user_id', $userId)
|
||||
->whereBetween('date', [$weekStart, $today])
|
||||
->selectRaw('COALESCE(SUM(followers_gained), 0) as gained, COALESCE(SUM(followers_lost), 0) as lost')
|
||||
->first();
|
||||
|
||||
$dailyGained = (int) ($todayRow->followers_gained ?? 0);
|
||||
$dailyLost = (int) ($todayRow->followers_lost ?? 0);
|
||||
$weeklyGained = (int) ($weekly->gained ?? 0);
|
||||
$weeklyLost = (int) ($weekly->lost ?? 0);
|
||||
$weeklyNet = $weeklyGained - $weeklyLost;
|
||||
$baseline = max(1, $currentFollowersCount - $weeklyNet);
|
||||
|
||||
return [
|
||||
'daily' => [
|
||||
'gained' => $dailyGained,
|
||||
'lost' => $dailyLost,
|
||||
'net' => $dailyGained - $dailyLost,
|
||||
],
|
||||
'weekly' => [
|
||||
'gained' => $weeklyGained,
|
||||
'lost' => $weeklyLost,
|
||||
'net' => $weeklyNet,
|
||||
'growth_rate' => round(($weeklyNet / $baseline) * 100, 1),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
private function increment(int $userId, string $column): void
|
||||
{
|
||||
DB::table('user_follow_analytics')->updateOrInsert(
|
||||
[
|
||||
'user_id' => $userId,
|
||||
'date' => now()->toDateString(),
|
||||
],
|
||||
[
|
||||
$column => DB::raw("COALESCE({$column}, 0) + 1"),
|
||||
'updated_at' => now(),
|
||||
'created_at' => now(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function emptySummary(): array
|
||||
{
|
||||
return [
|
||||
'daily' => ['gained' => 0, 'lost' => 0, 'net' => 0],
|
||||
'weekly' => ['gained' => 0, 'lost' => 0, 'net' => 0, 'growth_rate' => 0.0],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user