- press_release_events (type view/share, channel, ohne Personenbezug):
Model/Enums/Factory, Cascade-Delete an der PM
- Detailaufruf loggt View-Event zusaetzlich zum Legacy-hits-Zaehler
(bleibt bewusst einfacher Page-Request-Zaehler, User-Vorgabe 10.07.)
- POST press-release/{slug}/share (throttle 30/min, nur archiv-sichtbare
PMs des Portals) loggt Teilen-Klicks je Kanal (LinkedIn/X/E-Mail/Copy)
- Kundenpanel-PM-Seite: neue Kachel Geteilt mit Kanal-Aufschluesselung
- lang: web.detail.views (de/en)
- Tests: Web/PressReleaseTrackingTest (7)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
47 lines
1.1 KiB
PHP
47 lines
1.1 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Enums\PressReleaseEventType;
|
|
use App\Enums\PressReleaseShareChannel;
|
|
use Database\Factories\PressReleaseEventFactory;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
/**
|
|
* Einzelnes getracktes Ereignis an einer Pressemitteilung (Aufruf/Share).
|
|
* Reines Append-Log ohne Personenbezug; `channel` ist nur bei Shares gesetzt.
|
|
*/
|
|
class PressReleaseEvent extends Model
|
|
{
|
|
/** @use HasFactory<PressReleaseEventFactory> */
|
|
use HasFactory;
|
|
|
|
public const ?string UPDATED_AT = null;
|
|
|
|
protected $fillable = [
|
|
'press_release_id',
|
|
'type',
|
|
'channel',
|
|
];
|
|
|
|
/**
|
|
* @return array<string, string>
|
|
*/
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'type' => PressReleaseEventType::class,
|
|
'channel' => PressReleaseShareChannel::class,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return BelongsTo<PressRelease, $this>
|
|
*/
|
|
public function pressRelease(): BelongsTo
|
|
{
|
|
return $this->belongsTo(PressRelease::class);
|
|
}
|
|
}
|