## Dokumentation - Entfernt AGENTS.md (redundant zu CLAUDE.md) - Verschoben: 3 Dokumentationen von root → docs/ - Gelöscht: 8 historische Migrations-Pläne aus docs/archive/ - Entfernt: misc/ Ordner komplett (43 Dateien) ## Struktur - Erstellt: database/queries/ für SQL Test-Queries (4 Dateien) - Erstellt: database/schemas/ für Schema-Dokumentation (17 Dateien) - output_keys_mapping/ (8 CSV-Mappings) - migration-diagrams/ (4 Diagramme) ## Code-Qualität - Formatiert: 7 Style-Issues in 74 Dateien mit Laravel Pint - Gefixed: Migration für PostgreSQL/SQLite Kompatibilität - Gefixed: 2 fehlgeschlagene Tests (CSRF + Text-Assertion) ## Tests - Alle 73 Tests bestehen jetzt (100% Success Rate) - AuthenticationTest: CSRF-Token Fix für Logout-Test - CompanySearchTest: Text-Assertion aktualisiert ## Ergebnis - Root ist sauber (nur CLAUDE.md) - Dokumentation strukturiert in docs/ - Database-Dateien organisiert in database/ - Code entspricht Style-Guide - Alle Tests bestehen
96 lines
2.8 KiB
PHP
96 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class Transaction extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
public const STATUS_TRUE_POSITIVE = 'true_positive';
|
|
|
|
public const STATUS_FALSE_POSITIVE = 'false_positive';
|
|
|
|
public const STATUS_CLEARED = 'cleared';
|
|
|
|
/**
|
|
* Disable mass assignment protection to allow JSONB columns
|
|
*
|
|
* @var array<int, string>
|
|
*/
|
|
protected $guarded = [];
|
|
|
|
/**
|
|
* Cached JSONB column casts to avoid repeated schema queries
|
|
*/
|
|
private static ?array $jsonbCasts = null;
|
|
|
|
/**
|
|
* Get the attributes that should be cast.
|
|
*
|
|
* Dynamically casts all JSONB columns (102 output_keys) as arrays
|
|
* Uses static caching to avoid repeated database schema queries
|
|
*
|
|
* @return array<string, string>
|
|
*/
|
|
protected function casts(): array
|
|
{
|
|
// Return cached casts if available
|
|
if (self::$jsonbCasts !== null) {
|
|
return self::$jsonbCasts;
|
|
}
|
|
|
|
$standardCasts = [
|
|
'executed_at' => 'datetime',
|
|
'requires_review' => 'boolean',
|
|
'signals' => 'array',
|
|
];
|
|
|
|
// Standard non-JSONB columns
|
|
$standardColumns = [
|
|
'id', 'company_id', 'reference', 'amount', 'currency',
|
|
'counterparty', 'counterparty_country', 'channel', 'executed_at',
|
|
'risk_score', 'status', 'requires_review', 'flagged_by',
|
|
'flagged_reason', 'signals', 'created_at', 'updated_at',
|
|
];
|
|
|
|
try {
|
|
// Get all columns from the database (only once per request)
|
|
$allColumns = \Illuminate\Support\Facades\Schema::getColumnListing('transactions');
|
|
|
|
// All remaining columns are JSONB columns that should be cast as arrays
|
|
$jsonbColumns = array_diff($allColumns, $standardColumns);
|
|
|
|
foreach ($jsonbColumns as $column) {
|
|
$standardCasts[$column] = 'array';
|
|
}
|
|
} catch (\Exception $e) {
|
|
// If schema query fails (e.g., during migrations), just use standard casts
|
|
\Illuminate\Support\Facades\Log::warning('Failed to load JSONB column casts: '.$e->getMessage());
|
|
}
|
|
|
|
// Cache for subsequent calls
|
|
self::$jsonbCasts = $standardCasts;
|
|
|
|
return self::$jsonbCasts;
|
|
}
|
|
|
|
public function company(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Company::class);
|
|
}
|
|
|
|
public function statusLabel(): string
|
|
{
|
|
return match ($this->status) {
|
|
self::STATUS_TRUE_POSITIVE => __('Kritisches Risiko'),
|
|
self::STATUS_FALSE_POSITIVE => __('Hohes Risiko'),
|
|
self::STATUS_CLEARED => __('Geringes Risiko'),
|
|
default => __('Unbekanntes Risiko'),
|
|
};
|
|
}
|
|
}
|