refactor(compat): Freigabe-Bausteine generisch

ReleaseStore, CheckReportStore, CheckReport, CheckStep und CompatibilityCheck liegen im Kern und arbeiten je Profil (Optionen lit_mcp_<id>_releases|_check_report; Divi behält Namen und Schlüssel divi_version). Divi hängt Katalog-, Format- und Schreibtest über Profile::extraSteps an. Ein roter Prüfbericht für den aktuellen Stand sperrt LockOnFailure-Profile bis zur nächsten grünen Prüfung; Sperrgründe nennen nur Schritt-Labels, Ausnahmen gehen ins Error-Log. Profile bekommt testedVersions, stateKey, extraSteps, manifestCheck und reportVersionKey und wird mit benannten Argumenten gebaut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-11-06 12:51:03 +01:00
co-authored by Claude Opus 5.5
parent c85131603b
commit 7d6a97a54e
48 changed files with 1469 additions and 647 deletions
+32 -7
View File
@@ -4,24 +4,49 @@ declare(strict_types=1);
namespace LIT\MCP\Integrations\Divi\Release;
use Closure;
use LIT\MCP\Compatibility\Profile;
use LIT\MCP\Compatibility\Tier;
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
use LIT\MCP\Integrations\Divi\Schema\ShortformCheck;
use LIT\MCP\Integrations\WordPress\Content\ContentComposer;
use LogicException;
defined('ABSPATH') || exit;
/** Divi as a compatibility profile: every version needs a release, the matrix comes from the release gate. */
final class DiviProfile
{
public static function profile(): Profile
public const ID = 'divi';
public const LABEL = 'Divi';
/** Stored reports and release rows keep this key, so data from before the generic layer stays readable. */
public const REPORT_VERSION_KEY = 'divi_version';
/** @param (Closure(): ContentComposer)|null $composer The write test's composer; without it that step fails. */
public static function profile(?Closure $composer = null): Profile
{
return new Profile(
'divi',
'Divi',
Tier::ReleasePerVersion,
DiviFeature::cases(),
array_values(DiviAdapters::manifests()),
id: self::ID,
label: self::LABEL,
tier: Tier::ReleasePerVersion,
capabilities: DiviFeature::cases(),
manifests: array_values(DiviAdapters::manifests()),
active: static fn (): bool => DiviEnvironment::version() !== null,
version: DiviEnvironment::version(...),
matrix: static fn () => ReleaseGate::status()->matrix
matrix: static fn () => ReleaseGate::status()->matrix,
testedVersions: DiviReleases::TESTED,
stateKey: ReleaseResolver::stateKey(...),
extraSteps: DiviCheckSteps::extra(
static fn (): array => DiviModules::isAvailable()
? ShortformCheck::problems((new DiviModules())->catalog())
: ['Divi 5 ist in dieser Anfrage nicht geladen.'],
new FormatCheck(),
static fn (): array => (new WriteProbe(
$composer === null ? throw new LogicException('no composer for the write test') : $composer()
))->run()
),
manifestCheck: DiviManifestCheck::create(...),
reportVersionKey: self::REPORT_VERSION_KEY
);
}
}