PM-Tracking: Ereignis-Log fuer Aufrufe + Shares (press_release_events)
- 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>
This commit is contained in:
parent
80a37f8fcd
commit
644f860223
14 changed files with 392 additions and 0 deletions
|
|
@ -183,6 +183,14 @@ class PressRelease extends Model
|
|||
return $this->hasMany(PressReleaseStatusLog::class)->orderByDesc('created_at');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ereignis-Log (Aufrufe/Shares) — Aufruf-Gesamtzähler bleibt `hits`.
|
||||
*/
|
||||
public function events(): HasMany
|
||||
{
|
||||
return $this->hasMany(PressReleaseEvent::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Versionierter Audit-Trail der KI-Deklarationen (Art. 50 KI-VO) —
|
||||
* jeder Submit erzeugt einen neuen, unveränderlichen Eintrag.
|
||||
|
|
|
|||
47
app/Models/PressReleaseEvent.php
Normal file
47
app/Models/PressReleaseEvent.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue