#!/usr/bin/env php * * This file is part of a Moko Consulting project. * * SPDX-License-Identifier: GPL-3.0-or-later * * FILE INFORMATION * DEFGROUP: MokoStandards.Scripts.Validate * INGROUP: MokoStandards * REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform * PATH: /validate/check_enterprise_readiness.php * BRIEF: Enterprise readiness checker - PHP implementation */ declare(strict_types=1); require_once __DIR__ . '/../../vendor/autoload.php'; use MokoEnterprise\{ AuditLogger, CliFramework, SecurityValidator, PluginFactory, ProjectTypeDetector }; /** * Enterprise Readiness Checker * * Validates repository against enterprise standards */ class EnterpriseReadinessChecker extends CliFramework { private AuditLogger $logger; private SecurityValidator $securityValidator; private PluginFactory $pluginFactory; private ?object $projectPlugin = null; private array $results = []; protected function configure(): void { $this->setDescription('Check enterprise readiness compliance'); $this->addArgument('--path', 'Repository path to check', '.'); $this->addArgument('--strict', 'Fail on any non-compliance', false); } protected function initialize(): void { parent::initialize(); $this->logger = new AuditLogger('enterprise_readiness'); $this->securityValidator = new SecurityValidator(); $metrics = new \MokoEnterprise\MetricsCollector(); $this->pluginFactory = new PluginFactory($this->logger, $metrics); $this->log('Enterprise readiness checker initialized with plugin system'); } protected function run(): int { $path = $this->getArgument('--path'); $strict = $this->getArgument('--strict'); $this->section('Initialising'); $this->log("Checking enterprise readiness: {$path}"); // Try to load the project plugin $this->projectPlugin = $this->pluginFactory->createForProject($path); if ($this->projectPlugin) { $pluginName = $this->projectPlugin->getPluginName(); $projectType = $this->projectPlugin->getProjectType(); $this->log("Using plugin: {$pluginName} for type: {$projectType}"); // Use plugin's readiness check if available $pluginReadiness = $this->projectPlugin->checkReadiness($path, []); if (!empty($pluginReadiness)) { $this->log("Plugin readiness check: " . ($pluginReadiness['ready'] ? 'READY' : 'NOT READY')); $this->results['plugin_readiness'] = [ 'passed' => $pluginReadiness['ready'], 'score' => $pluginReadiness['score'] ?? 0, 'blockers' => $pluginReadiness['blockers'] ?? [], 'warnings' => $pluginReadiness['warnings'] ?? [], ]; } } else { $this->log("No plugin found, using generic readiness checks"); } // Run standard enterprise checks (backwards compatible) $this->section('Enterprise libraries'); $this->checkEnterpriseLibraries($path); $this->section('Monitoring & audit'); $this->checkMonitoring($path); $this->checkAuditLogging($path); $this->section('Security compliance'); $this->checkSecurityCompliance($path); $this->section('Documentation'); $this->checkDocumentation($path); // Display results using visual API $this->section('Results'); $passed = 0; $failed = 0; foreach ($this->results as $result) { $this->status($result['passed'], $result['check'], $result['passed'] ? '' : $result['message']); if ($result['passed']) { $passed++; } else { $failed++; } } $this->printSummary($passed, $failed, $this->elapsed()); $failures = $failed; if ($strict && $failures > 0) { $this->error("Enterprise readiness check failed (strict mode): {$failures} issues found"); return 1; } if ($failures > 0) { $this->warning("{$failures} enterprise readiness issues found"); } else { $this->success('All enterprise readiness checks passed'); } return 0; } private function checkEnterpriseLibraries(string $path): void { $required = ['ApiClient', 'AuditLogger', 'Config', 'ErrorRecovery', 'MetricsCollector']; // Enterprise libs may live in vendor/ (Composer install) or lib/Enterprise/ (MokoStandards itself). // A single vendor/ directory confirms the whole package is present — no need to check per-file. $vendorPkg = "{$path}/vendor/mokoconsulting-tech/enterprise"; $inVendor = is_dir($vendorPkg); foreach ($required as $library) { $localFile = "{$path}/lib/Enterprise/{$library}.php"; $found = $inVendor || file_exists($localFile); $this->addResult( "Enterprise library: {$library}", $found, "Missing enterprise library (not in vendor/mokoconsulting-tech/enterprise or lib/Enterprise/)" ); } } private function checkMonitoring(string $path): void { // Check for metrics collection $metricsDir = "{$path}/var/logs/metrics"; $this->addResult( 'Metrics directory configured', is_dir($metricsDir) || !file_exists($path . '/composer.json'), 'Metrics logging not configured' ); // Check for monitoring documentation $monitoringDocs = "{$path}/docs/monitoring"; $this->addResult( 'Monitoring documentation exists', is_dir($monitoringDocs) || file_exists("{$path}/docs/monitoring.md"), 'Monitoring documentation not found' ); } private function checkAuditLogging(string $path): void { $auditDir = "{$path}/var/logs/audit"; $this->addResult( 'Audit logging directory configured', is_dir($auditDir) || !file_exists($path . '/composer.json'), 'Audit logging not configured' ); } private function checkSecurityCompliance(string $path): void { // Check for security policy $this->addResult( 'Security policy exists', file_exists("{$path}/SECURITY.md") || file_exists("{$path}/.github/SECURITY.md"), 'SECURITY.md not found' ); // Check for CodeQL configuration $codeqlConfig = "{$path}/.github/codeql"; $this->addResult( 'CodeQL configured', is_dir($codeqlConfig) || file_exists("{$path}/.github/codeql/codeql-config.yml"), 'CodeQL not configured' ); // Run security scan on PHP files if (is_dir("{$path}/src")) { $this->securityValidator->scanDirectory("{$path}/src", ['.php']); $findings = $this->securityValidator->getFindings(); $this->addResult( 'No security vulnerabilities in source code', empty($findings), count($findings) . ' security issues found' ); } } private function checkDocumentation(string $path): void { // Check for architecture documentation $this->addResult( 'Architecture documentation exists', file_exists("{$path}/docs/architecture.md") || file_exists("{$path}/docs/guide/architecture.md"), 'Architecture documentation not found' ); // Check for API documentation $this->addResult( 'API documentation exists', file_exists("{$path}/docs/api.md") || is_dir("{$path}/docs/api"), 'API documentation not found' ); } private function addResult(string $check, bool $passed, string $message): void { $this->results[] = [ 'check' => $check, 'passed' => $passed, 'message' => $message, ]; } private function displayResults(): void { // Results are now displayed directly in run() using visual API methods. } } // Run the application $app = new EnterpriseReadinessChecker(); exit($app->execute());