Initial commit: Pireon Admin — headless admin panel and public API
Laravel 13 + Filament 5 admin panel and REST API for a non-profit developer collective, backed by the Pireon OAuth identity server. The public site is a separate, server-rendered application consuming /api/public/v1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
84
app/Support/Health/Checks/StaleReviews.php
Normal file
84
app/Support/Health/Checks/StaleReviews.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Support\Health\Checks;
|
||||
|
||||
use App\Models\Page;
|
||||
use App\Models\Project;
|
||||
use App\Models\Service;
|
||||
use App\Support\ContentTypes;
|
||||
use App\Support\Health\Check;
|
||||
use App\Support\Health\Finding;
|
||||
use App\Support\Health\Severity;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Work that was handed over and never answered.
|
||||
*
|
||||
* The same shape as the unanswered-submissions check, and for the same reason:
|
||||
* somebody is waiting, and nothing else in the panel would ever say so. It is
|
||||
* the failure mode a review step introduces — before it existed, an editor who
|
||||
* could not publish was stuck but knew it; now they are waiting and think
|
||||
* something is happening.
|
||||
*
|
||||
* A review left for a week has stopped being a handover and become a piece of
|
||||
* work nobody owns.
|
||||
*/
|
||||
class StaleReviews implements Check
|
||||
{
|
||||
protected const DAYS = 7;
|
||||
|
||||
/**
|
||||
* The models where publishing is a permission of its own, which is exactly
|
||||
* where a review can exist.
|
||||
*
|
||||
* @var array<int, class-string<Model>>
|
||||
*/
|
||||
protected const REVIEWABLE = [Page::class, Project::class, Service::class];
|
||||
|
||||
public function key(): string
|
||||
{
|
||||
return 'stale-reviews';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whoever can publish something is who a stale review is waiting for, so
|
||||
* seeing the count is the same question as being able to end it. Pages
|
||||
* stand in for the three: a role that can publish none of them has no
|
||||
* business being told what is queued.
|
||||
*/
|
||||
public function permission(): ?string
|
||||
{
|
||||
return 'pages.publish';
|
||||
}
|
||||
|
||||
public function run(): Finding
|
||||
{
|
||||
$cutoff = now()->subDays(self::DAYS);
|
||||
$samples = [];
|
||||
$count = 0;
|
||||
|
||||
foreach (self::REVIEWABLE as $model) {
|
||||
$stale = $model::query()
|
||||
->awaitingReview()
|
||||
->where('review_requested_at', '<', $cutoff)
|
||||
->orderBy('review_requested_at')
|
||||
->get();
|
||||
|
||||
$count += $stale->count();
|
||||
|
||||
foreach ($stale as $record) {
|
||||
$samples[] = ContentTypes::title($record)
|
||||
.' ('.$record->review_requested_at->diffForHumans().')';
|
||||
}
|
||||
}
|
||||
|
||||
return Finding::problem(
|
||||
$this->key(),
|
||||
$count,
|
||||
Severity::Warning,
|
||||
samples: $samples,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user