42 lines
2.2 KiB
PHP
42 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class PortalAudit
|
|
{
|
|
/** @param array<string, mixed> $data */
|
|
public static function save(Model $record, array $data, int $actor): void
|
|
{
|
|
DB::transaction(function () use ($record, $data, $actor) {
|
|
$created = ! $record->exists;
|
|
if (! $created) {
|
|
$locked = $record->newQuery()->where($record->getKeyName(), $record->getKey())->lockForUpdate()->firstOrFail();
|
|
$record->setRawAttributes($locked->getAttributes(), true);
|
|
}
|
|
// Exclude free text and personal data from the immutable event payload.
|
|
$fields = ['primary_territory_id', 'territory_version', 'version_no', 'status', 'is_active', 'is_featured', 'sort_order', 'sector_id', 'maturity_level',
|
|
'estimated_investment_amount', 'estimated_investment_currency', 'owner_user_id', 'assignee_user_id', 'due_at',
|
|
'cluster_id', 'project_id', 'corridor_id', 'dossier_id', 'interest_request_id', 'publication_status', 'editor_id', 'reviewer_id', 'role', 'stage', 'value_chain_id', 'from_value_chain_id', 'to_value_chain_id', 'link_type', 'deleted_at'];
|
|
$before = array_intersect_key($record->getAttributes(), array_flip($fields));
|
|
$record->fill($data);
|
|
$changed = array_keys($record->getDirty());
|
|
$record->save();
|
|
if (! $changed) {
|
|
return;
|
|
}
|
|
DB::table('audit_events')->insert([
|
|
'source_system' => 'portal-management', 'actor_user_id' => $actor,
|
|
'entity_type' => $record->getTable(), 'entity_id' => Str::isUuid((string) $record->getKey()) ? $record->getKey() : null,
|
|
'action' => $created ? 'created' : 'updated',
|
|
'before_data' => json_encode(['record_id' => $record->getKey(), 'values' => $before], JSON_THROW_ON_ERROR),
|
|
'after_data' => json_encode(['record_id' => $record->getKey(), 'changed_fields' => $changed,
|
|
'values' => array_intersect_key($record->getAttributes(), array_flip($fields))], JSON_THROW_ON_ERROR),
|
|
]);
|
|
});
|
|
}
|
|
}
|