toIso8601String()); // The first tick only starts the clock: history starts when this ships. if ($last === null) { return; } // UTC days on purpose, like the check runner: the roll-up is a storage concept. $dayStart = $now->copy()->startOfDay(); $since = Carbon::parse($last)->max($dayStart); $seconds = (int) min(max(0, $since->diffInSeconds($now)), self::MAX_CREDIT_SECONDS); if ($seconds === 0) { return; } // The same pages pharos:check watches: an archived page is not monitored. foreach (StatusPage::query()->whereNull('archived_at')->orderBy('id')->pluck('id') as $pageId) { app(PageContext::class)->run($pageId, fn () => $this->credit($dayStart, $seconds)); } } protected function credit(Carbon $dayStart, int $seconds): void { foreach (Component::query()->where('enabled', true)->setFromOutside()->get() as $component) { if ($component->status === ComponentStatus::UnderMaintenance) { continue; } $day = UptimeDay::firstOrCreate( ['component_id' => $component->id, 'day' => $dayStart], ['up_seconds' => 0, 'down_seconds' => 0, 'worst_status' => ComponentStatus::Operational->value], ); if (! $component->status->isDown()) { $day->increment('up_seconds', $seconds); continue; } $day->increment('down_seconds', $seconds); if ($component->status->value > $day->worst_status->value) { $day->worst_status = $component->status; $day->save(); } } } }