Files
SkinbaseNova/app/Console/Commands/ReviewQueueAiBiographyCommand.php
2026-04-18 17:02:56 +02:00

97 lines
3.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use App\Models\CreatorAiBiography;
use Illuminate\Console\Command;
/**
* List AI biographies that are candidates for admin review.
*
* Review queue candidates include:
* Biographies with needs_review = true (new AI draft available for user-edited bio)
* Biographies with status = 'needs_review'
* Biographies with recent generation failures (last_error_code set)
* Biographies with input_quality_tier = 'sparse' that still generated
*
* Usage:
* php artisan ai-biography:review-queue
* php artisan ai-biography:review-queue --tier=sparse
* php artisan ai-biography:review-queue --failed
* php artisan ai-biography:review-queue --limit=50
*/
final class ReviewQueueAiBiographyCommand extends Command
{
protected $signature = 'ai-biography:review-queue
{--tier= : Filter by input_quality_tier (rich|medium|sparse)}
{--failed : Show only records with a last_error_code}
{--needs-review : Show only records flagged needs_review=true}
{--limit=100 : Maximum records to display}';
protected $description = 'List AI biography records that are candidates for review or manual inspection';
public function handle(): int
{
$limit = max(1, (int) $this->option('limit'));
$query = CreatorAiBiography::query()
->with('user:id,username,email')
->orderByDesc('updated_at')
->limit($limit);
if ($this->option('failed')) {
$query->whereNotNull('last_error_code');
} elseif ($this->option('needs-review')) {
$query->where('needs_review', true);
} else {
// Default: union of all review-worthy states.
$query->where(fn ($q) => $q
->where('needs_review', true)
->orWhere('status', CreatorAiBiography::STATUS_NEEDS_REVIEW)
->orWhereNotNull('last_error_code')
->orWhere('input_quality_tier', CreatorAiBiography::TIER_SPARSE)
);
}
if ($this->option('tier')) {
$query->where('input_quality_tier', $this->option('tier'));
}
$records = $query->get();
if ($records->isEmpty()) {
$this->info('No review-queue candidates found.');
return self::SUCCESS;
}
$this->line('');
$this->info("=== AI Biography Review Queue ({$records->count()} records) ===");
$this->line('');
$rows = $records->map(fn ($r) => [
$r->id,
$r->user?->username ?? "user#{$r->user_id}",
$r->status,
$r->input_quality_tier ?? '-',
$r->is_user_edited ? 'edited' : '-',
$r->needs_review ? 'YES' : '-',
$r->last_error_code ?? '-',
$r->updated_at?->diffForHumans() ?? '-',
])->all();
$this->table(
['ID', 'Username', 'Status', 'Tier', 'User-Edited', 'NeedsReview', 'LastError', 'Updated'],
$rows,
);
$this->line('');
$this->line('Tip: run `php artisan ai-biography:inspect {user_id}` for full details on any record.');
$this->line(' run `php artisan ai-biography:generate {user_id} --force` to regenerate.');
$this->line('');
return self::SUCCESS;
}
}