Spaces:
Running
Running
File size: 2,372 Bytes
45dc401 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | <?php
declare(strict_types=1);
namespace App\Domain\Analytics;
use App\Infrastructure\Database\BaseRepository;
use App\Infrastructure\Ids\UuidGenerator;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
final class AnalyticsVisitorRepository extends BaseRepository
{
public function __construct(private readonly UuidGenerator $ids) {}
protected function table(): string
{
return 'analytics_visitors';
}
protected function hasDeletedAtColumn(): bool
{
return false;
}
public function findByToken(string $token): ?\stdClass
{
return DB::table($this->table())->where('visitor_token', $token)->first();
}
public function findById(string $id): ?\stdClass
{
return DB::table($this->table())->where('id', $id)->first();
}
/**
* Find-or-create a visitor by token, updating last_seen_at on every call.
* Returns the visitor id.
*/
public function upsert(string $token, ?string $memberId): string
{
$now = Carbon::now()->toDateTimeString();
$existing = $this->findByToken($token);
if ($existing) {
$patch = ['last_seen_at' => $now, 'updated_at' => $now];
if ($memberId !== null && $existing->member_id === null) {
$patch['member_id'] = $memberId;
}
DB::table($this->table())->where('id', $existing->id)->update($patch);
return $existing->id;
}
$id = $this->ids->generate();
DB::table($this->table())->insert([
'id' => $id,
'visitor_token' => $token,
'member_id' => $memberId,
'first_seen_at' => $now,
'last_seen_at' => $now,
'created_at' => $now,
'updated_at' => $now,
]);
return $id;
}
/**
* Link an anonymous visitor to a known member after login.
* Only writes when member_id is not already set to prevent duplicate stitches.
*/
public function stitch(string $visitorId, string $memberId): void
{
DB::table($this->table())
->where('id', $visitorId)
->whereNull('member_id')
->update([
'member_id' => $memberId,
'updated_at' => Carbon::now()->toDateTimeString(),
]);
}
}
|