2.8 KiB
2.8 KiB
Projektkonventionen
Architektur: Actions (Request-Command-Response)
Jede fachliche Operation wird in eine eigene Action ausgelagert, die aus drei Klassen besteht.
Pfad: app/Domains/{Domain}/Actions/{ActionName}/
Struktur
{ActionName}Request.php → Eingabedaten (Konstruktor oder Factory-Methoden) {ActionName}Command.php → Logik, ruft execute(): {ActionName}Response auf {ActionName}Response.php → Rückgabedaten (public Properties)
Regeln
- Der Controller enthält keine fachliche Logik – nur Absicherung, Action-Aufruf und HTTP-Response
- Commands sind nicht statisch und werden immer instanziiert
- Hat ein Request mehrere Varianten, werden Factory-Methoden (
forX()) statt mehrerer Konstruktoren verwendet - Aufrufreihenfolge im Controller:
new Request → new Command(request) → command->execute() → Response verwenden
Controller
- Alle Controller erben von
App\Scopes\CommonController CommonControllerstellt folgende Repositories bereit (keine eigene Instanziierung nötig):$this->eventParticipants→EventParticipantRepository$this->events→EventRepository$this->invoices→InvoiceRepository$this->costUnits→CostUnitRepository$this->users→UserRepository$this->tenant→ aktuellerTenant
Repositories
- Datenbankzugriffe gehören immer ins Repository, nie direkt in Controller oder Actions
- Sicherheitschecks (z. B. „gehört diese Teilnahme dem eingeloggten User?") werden als eigene Repository-Methoden gekapselt
- Tenant-Filter:
app('tenant')->slug - Eingeloggter User:
auth()->user()
Models / Ressourcen
- Models erben von
App\Scopes\InstancedModel(mit globalemSiteScope) $model->toResource()->toArray($request)liefert das aufbereitete Array über die zugehörige Resource-Klasse- Resource-Klassen liegen in
app/Resources/{ModelName}Resource.php
Tenant
- Der aktuelle Tenant ist per
app('tenant')verfügbar (gesetzt durchIdentifyTenant-Middleware) - Tenant-Slug:
app('tenant')->slug - Jede tenant-spezifische DB-Abfrage filtert auf
['tenant' => app('tenant')->slug]
Routing
- API-Routen liegen in
app/Domains/{Domain}/Routes/api.php - Alle Routen sind in
IdentifyTenant::class-Middleware gewrappt - Authentifizierte Routen zusätzlich in
['auth']-Middleware
Mails
- Mails erben von
Illuminate\Mail\Mailable - Attachments werden über
Attachment::fromData(fn () => $content, $filename)->withMime(...)angehängt - Werden Daten sowohl in
content()als auch inattachments()benötigt, wird eine private Hilfsmethode mit Lazy-Caching verwendet (einmaliges Berechnen, Ergebnis in private Property speichern) - Blade-Templates referenzieren Mail-Attachments per
cid:-Link:<a href="cid:{{ $filename }}">...</a>