Files
AFC-Demo/app/Models/Transaction.php
T
cbazza 1cb38d7080 chore: major project cleanup and restructuring
## 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
2025-11-21 10:00:32 +01:00

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'),
};
}
}