- 4.1: stat_project_monthly + ProjectStatService (건설/프로젝트 월간) - 4.2: stat_system_daily + SystemStatService (API/감사/FCM/파일/결재) - 4.3: stat_events, stat_snapshots + StatEventService + StatEventObserver - 4.4: StatController (summary/daily/monthly/alerts) + StatQueryService + FormRequest 3개 + routes/stats.php - 4.5: DashboardService sam_stat 우선 조회 + 원본 DB 폴백 패턴 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
97 lines
2.7 KiB
PHP
97 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Observers;
|
|
|
|
use App\Services\Stats\StatEventService;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
class StatEventObserver
|
|
{
|
|
private static array $domainMap = [
|
|
'App\Models\Tenants\Order' => 'sales',
|
|
'App\Models\Tenants\Sale' => 'sales',
|
|
'App\Models\Tenants\Deposit' => 'finance',
|
|
'App\Models\Tenants\Withdrawal' => 'finance',
|
|
'App\Models\Tenants\Purchase' => 'finance',
|
|
'App\Models\Production\WorkOrder' => 'production',
|
|
'App\Models\Tenants\Approval' => 'system',
|
|
];
|
|
|
|
public function created(Model $model): void
|
|
{
|
|
$this->recordEvent($model, 'created');
|
|
}
|
|
|
|
public function updated(Model $model): void
|
|
{
|
|
$this->recordEvent($model, 'updated');
|
|
}
|
|
|
|
public function deleted(Model $model): void
|
|
{
|
|
$this->recordEvent($model, 'deleted');
|
|
}
|
|
|
|
private function recordEvent(Model $model, string $action): void
|
|
{
|
|
$tenantId = $model->getAttribute('tenant_id');
|
|
if (! $tenantId) {
|
|
return;
|
|
}
|
|
|
|
$className = get_class($model);
|
|
$domain = self::$domainMap[$className] ?? 'other';
|
|
$entityType = class_basename($model);
|
|
$eventType = strtolower($entityType).'_'.$action;
|
|
|
|
$payload = match ($action) {
|
|
'created' => $this->getCreatedPayload($model),
|
|
'updated' => $this->getUpdatedPayload($model),
|
|
'deleted' => ['id' => $model->getKey()],
|
|
default => null,
|
|
};
|
|
|
|
app(StatEventService::class)->recordEvent(
|
|
$tenantId,
|
|
$domain,
|
|
$eventType,
|
|
$entityType,
|
|
$model->getKey(),
|
|
$payload
|
|
);
|
|
}
|
|
|
|
private function getCreatedPayload(Model $model): array
|
|
{
|
|
$payload = ['id' => $model->getKey()];
|
|
|
|
if ($model->getAttribute('total_amount') !== null) {
|
|
$payload['amount'] = $model->getAttribute('total_amount');
|
|
}
|
|
if ($model->getAttribute('amount') !== null) {
|
|
$payload['amount'] = $model->getAttribute('amount');
|
|
}
|
|
if ($model->getAttribute('status') !== null) {
|
|
$payload['status'] = $model->getAttribute('status');
|
|
}
|
|
|
|
return $payload;
|
|
}
|
|
|
|
private function getUpdatedPayload(Model $model): array
|
|
{
|
|
$changed = $model->getChanges();
|
|
$payload = ['id' => $model->getKey()];
|
|
|
|
if (isset($changed['status'])) {
|
|
$payload['old_status'] = $model->getOriginal('status');
|
|
$payload['new_status'] = $changed['status'];
|
|
}
|
|
if (isset($changed['total_amount']) || isset($changed['amount'])) {
|
|
$payload['amount'] = $changed['total_amount'] ?? $changed['amount'];
|
|
}
|
|
|
|
return $payload;
|
|
}
|
|
}
|