feat: harden tenant settings and import pipeline

This commit is contained in:
2025-09-25 11:50:18 +02:00
parent b22d91ed32
commit 9248d7a3f5
29 changed files with 577 additions and 293 deletions

View File

@@ -2,12 +2,15 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Emotion extends Model
{
use HasFactory;
protected $table = 'emotions';
protected $guarded = [];
protected $casts = [
@@ -25,3 +28,4 @@ class Emotion extends Model
return $this->hasMany(Task::class);
}
}

View File

@@ -4,7 +4,9 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\{BelongsTo, HasMany, BelongsToMany};
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Event extends Model
{
@@ -13,9 +15,7 @@ class Event extends Model
protected $table = 'events';
protected $guarded = [];
protected $casts = [
'date' => 'date',
'name' => 'array',
'description' => 'array',
'date' => 'datetime',
'settings' => 'array',
'is_active' => 'boolean',
];
@@ -39,5 +39,11 @@ class Event extends Model
'task_collection_id'
);
}
public function tasks(): BelongsToMany
{
return $this->belongsToMany(Task::class, 'event_task', 'event_id', 'task_id')
->withTimestamps();
}
}

View File

@@ -2,12 +2,15 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
class EventType extends Model
{
use HasFactory;
protected $table = 'event_types';
protected $guarded = [];
protected $casts = [
@@ -25,3 +28,4 @@ class EventType extends Model
return $this->hasMany(Event::class);
}
}

View File

@@ -2,13 +2,15 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\Storage;
class Photo extends Model
{
use HasFactory;
protected $table = 'photos';
protected $guarded = [];
protected $casts = [
@@ -16,14 +18,12 @@ class Photo extends Model
'metadata' => 'array',
];
// Accessor für die Kompatibilität mit der PhotoResource
public function getImagePathAttribute()
public function getImagePathAttribute(): ?string
{
return $this->file_path;
}
// Mutator für die Kompatibilität mit der PhotoResource
public function setImagePathAttribute($value)
public function setImagePathAttribute(string $value): void
{
$this->attributes['file_path'] = $value;
}
@@ -33,19 +33,19 @@ class Photo extends Model
return $this->belongsTo(Event::class);
}
public function emotion()
public function emotion(): BelongsTo
{
return $this->belongsTo(Emotion::class);
}
public function task()
public function task(): BelongsTo
{
return $this->belongsTo(Task::class);
}
public function likes(): HasMany
{
return $this->hasMany(\App\Models\PhotoLike::class);
return $this->hasMany(PhotoLike::class);
}
}

View File

@@ -2,36 +2,31 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class PurchaseHistory extends Model
{
use HasFactory;
protected $table = 'purchase_history';
public $timestamps = false;
public $incrementing = false;
protected $keyType = 'string';
protected $guarded = [];
protected $fillable = [
'id',
'tenant_id',
'package_id',
'credits_added',
'price',
'currency',
'platform',
'transaction_id',
'purchased_at',
];
protected $casts = [
'credits_added' => 'integer',
'price' => 'decimal:2',
'purchased_at' => 'datetime',
'created_at' => 'datetime',
];
public function tenant(): BelongsTo
{
return $this->belongsTo(Tenant::class);
}
}

View File

@@ -6,17 +6,18 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
class Task extends Model
{
use HasFactory;
use SoftDeletes;
protected $table = 'tasks';
protected $guarded = [];
protected $casts = [
'title' => 'array',
'description' => 'array',
'example_text' => 'array',
'due_date' => 'datetime',
'is_completed' => 'bool',
];
public function emotion(): BelongsTo

View File

@@ -11,21 +11,13 @@ class TaskCollection extends Model
use HasFactory;
protected $table = 'task_collections';
protected $fillable = [
'tenant_id',
'name',
'description',
];
protected $casts = [
'name' => 'array',
'description' => 'array',
];
/**
* Tasks in this collection
*/
public function tasks(): BelongsToMany
{
return $this->belongsToMany(
@@ -36,9 +28,6 @@ class TaskCollection extends Model
);
}
/**
* Events that use this collection
*/
public function events(): BelongsToMany
{
return $this->belongsToMany(
@@ -48,24 +37,5 @@ class TaskCollection extends Model
'event_id'
);
}
}
/**
* Get the localized name for the current locale
*/
public function getLocalizedNameAttribute(): string
{
$locale = app()->getLocale();
return $this->name[$locale] ?? $this->name['de'] ?? 'Unnamed Collection';
}
/**
* Get the localized description for the current locale
*/
public function getLocalizedDescriptionAttribute(): ?string
{
if (!$this->description) return null;
$locale = app()->getLocale();
return $this->description[$locale] ?? $this->description['de'] ?? null;
}
}

View File

@@ -2,14 +2,12 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Facades\DB;
use App\Models\EventPurchase;
use App\Models\EventCreditsLedger;
class Tenant extends Model
{
@@ -17,14 +15,16 @@ class Tenant extends Model
protected $table = 'tenants';
protected $guarded = [];
protected $casts = [
'settings' => 'array',
'features' => 'array',
'settings' => 'array',
'last_activity_at' => 'datetime',
'event_credits_balance' => 'integer',
'subscription_tier' => 'string',
'subscription_expires_at' => 'datetime',
'total_revenue' => 'decimal:2',
'settings_updated_at' => 'datetime',
];
public function events(): HasMany
@@ -37,10 +37,10 @@ class Tenant extends Model
return $this->hasManyThrough(
Photo::class,
Event::class,
'tenant_id', // Foreign key on events table...
'event_id', // Foreign key on photos table...
'id', // Local key on tenants table...
'id' // Local key on events table...
'tenant_id',
'event_id',
'id',
'id'
);
}
@@ -59,6 +59,16 @@ class Tenant extends Model
return $this->hasMany(EventCreditsLedger::class);
}
public function setSettingsAttribute($value): void
{
if (is_string($value)) {
$this->attributes['settings'] = $value;
return;
}
$this->attributes['settings'] = json_encode($value ?? []);
}
public function activeSubscription(): Attribute
{
return Attribute::make(