90 lines
2.2 KiB
PHP
90 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
|
|
/**
|
|
* audit_logs — IMMUTABLE security & audit trail.
|
|
* NO updated_at column. Records are write-once, never modified or deleted.
|
|
*
|
|
* @property int|null $user_id The subject of the action
|
|
* @property int|null $actor_id Who performed it (admin/system/user)
|
|
* @property string $action login/transfer_create/pin_change/kyc_approved/wallet_freeze
|
|
* @property string|null $subject_type App\Models\Wallet etc.
|
|
* @property int|null $subject_id
|
|
* @property array|null $old_values
|
|
* @property array|null $new_values
|
|
* @property string|null $ip_address
|
|
* @property string|null $user_agent
|
|
* @property string|null $device_id
|
|
*/
|
|
class AuditLog extends BaseModel
|
|
{
|
|
use HasFactory;
|
|
|
|
// NO timestamps trait — we only have created_at (manual)
|
|
public $timestamps = false;
|
|
|
|
protected $fillable = [
|
|
'user_id',
|
|
'actor_id',
|
|
'action',
|
|
'subject_type',
|
|
'subject_id',
|
|
'old_values',
|
|
'new_values',
|
|
'ip_address',
|
|
'user_agent',
|
|
'device_id',
|
|
'created_at',
|
|
];
|
|
|
|
protected $casts = [
|
|
'old_values' => 'array',
|
|
'new_values' => 'array',
|
|
'created_at' => 'datetime',
|
|
];
|
|
|
|
// ── Relationships ──
|
|
|
|
public function user()
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
public function actor()
|
|
{
|
|
return $this->belongsTo(User::class, 'actor_id');
|
|
}
|
|
|
|
// ── Scopes ──
|
|
|
|
public function scopeForUser($query, int $userId)
|
|
{
|
|
return $query->where('user_id', $userId);
|
|
}
|
|
|
|
public function scopeForAction($query, string $action)
|
|
{
|
|
return $query->where('action', $action);
|
|
}
|
|
|
|
public function scopeRecent($query, int $hours = 24)
|
|
{
|
|
return $query->where('created_at', '>=', now()->subHours($hours));
|
|
}
|
|
|
|
// ── Static factory ──
|
|
|
|
/**
|
|
* Log an audit event. Called by the AuditService.
|
|
*/
|
|
public static function record(array $data): self
|
|
{
|
|
return self::create(array_merge($data, [
|
|
'created_at' => now(),
|
|
]));
|
|
}
|
|
}
|