Files
laravel_school_api/app/Console/Commands/DocumentationCoverageCommand.php
T
2026-05-30 01:11:35 -04:00

46 lines
1.8 KiB
PHP

<?php declare(strict_types=1);
namespace App\Console\Commands;
use Illuminate\Console\Command;
final class DocumentationCoverageCommand extends Command
{
protected $signature = 'app:docs-coverage {--inventory=storage/app/generated/api-route-inventory.json} {--openapi=docs/openapi.phase8.yaml}';
protected $description = 'Check that canonical routes and deprecated routes are represented in documentation artifacts.';
public function handle(): int
{
$inventoryPath = base_path((string) $this->option('inventory'));
$openApiPath = base_path((string) $this->option('openapi'));
$deprecationsPath = base_path('docs/deprecations.md');
if (! is_file($inventoryPath) || ! is_file($openApiPath)) {
$this->error('Inventory or OpenAPI file is missing. Documentation cannot be trusted by vibes alone.');
return self::FAILURE;
}
$rows = json_decode(file_get_contents($inventoryPath) ?: '[]', true) ?: [];
$openApi = file_get_contents($openApiPath) ?: '';
$deprecations = is_file($deprecationsPath) ? (file_get_contents($deprecationsPath) ?: '') : '';
$failures = [];
foreach ($rows as $row) {
$uri = '/'.ltrim((string) ($row['uri'] ?? ''), '/');
$status = (string) ($row['canonical_status'] ?? 'unknown');
if ($status === 'canonical' && ! str_contains($openApi, $uri)) {
$failures[] = $uri.' is canonical but missing from OpenAPI.';
}
if ($status === 'deprecated' && ! str_contains($deprecations, $uri)) {
$failures[] = $uri.' is deprecated but missing from docs/deprecations.md.';
}
}
foreach ($failures as $failure) {
$this->error($failure);
}
return $failures === [] ? self::SUCCESS : self::FAILURE;
}
}