admin: Aktivitäts-Verlauf unter Reports ▸ Verlauf

Chronologisches Protokoll der Systemereignisse als neue Admin-Seite
(/admin/reports/activity) mit Filter nach Ereignistyp, Zeitraum und
Suche. Erfasst ab jetzt fortlaufend:

- Registrierungen inkl. Weg (Formular, Google, Magic-Link)
- Anmeldungen inkl. Weg (Passwort, Google, Magic-Link, Impersonation)
- PM-Statuswechsel mit Ergebnis/Begründung (zentral im Status-Log-Hook;
  KI-/Scheduler-Wechsel erscheinen als „System")
- Zahlungseingänge (Rechnungsspiegelung) und Credit-Aufladungen
- Formular-Eingänge: Kontakt, Rechtsanfrage, Widerruf, Kündigung,
  Newsletter-Anmeldung (Observer auf den Modellen)

Schreiben ist Best-Effort über den ActivityLog-Service — ein
fehlgeschlagener Verlaufseintrag bricht nie den fachlichen Ablauf.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-15 16:00:58 +00:00
parent a574898ca9
commit 3a11963990
19 changed files with 720 additions and 4 deletions

View file

@ -2,10 +2,12 @@
namespace App\Services\Billing;
use App\Enums\ActivityType;
use App\Enums\CreditTransactionType;
use App\Enums\SinglePurchaseStatus;
use App\Models\CreditTopup;
use App\Models\User;
use App\Services\ActivityLog;
use App\Services\Billing\Concerns\LocksModelForUpdate;
/**
@ -17,7 +19,10 @@ class CreditTopupService
{
use LocksModelForUpdate;
public function __construct(private readonly CreditWalletService $wallet) {}
public function __construct(
private readonly CreditWalletService $wallet,
private readonly ActivityLog $activityLog,
) {}
/**
* Verfügbare Credit-Pakete aus der Config.
@ -94,6 +99,20 @@ class CreditTopupService
$locked,
);
$this->activityLog->record(
ActivityType::CreditTopup,
sprintf(
'Wallet-Aufladung: %d Credits (Paket %s) — %s (%s).',
$locked->credits,
$locked->pack_key,
$locked->user->name,
$locked->user->email,
),
user: $locked->user,
subject: $locked,
meta: ['credits' => $locked->credits, 'pack' => $locked->pack_key],
);
$topup->setRawAttributes($locked->getAttributes());
});
}