- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
159 lines
5.2 KiB
PHP
159 lines
5.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use App\Framework\QrCode\QrCodeGenerator;
|
|
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeConfig;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
|
|
use App\Framework\QrCode\ValueObjects\EncodingMode;
|
|
|
|
echo "=== Detailed QR Code Comparison ===\n\n";
|
|
|
|
// Generate our QR code
|
|
$config = new QrCodeConfig(
|
|
version: QrCodeVersion::fromNumber(1),
|
|
errorCorrectionLevel: ErrorCorrectionLevel::M,
|
|
encodingMode: EncodingMode::BYTE
|
|
);
|
|
|
|
$ourMatrix = QrCodeGenerator::generate("HELLO WORLD", $config);
|
|
$size = 21;
|
|
|
|
// Load Python reference
|
|
$pythonImage = imagecreatefrompng('/var/www/html/public/qrcode-python-large.png');
|
|
if (!$pythonImage) {
|
|
die("Could not load Python reference image\n");
|
|
}
|
|
|
|
// Function to check if a module is dark in the Python image
|
|
function isPythonModuleDark($image, $row, $col): bool {
|
|
$scale = 20;
|
|
$quietZone = 4;
|
|
$x = ($quietZone + $col) * $scale + ($scale / 2);
|
|
$y = ($quietZone + $row) * $scale + ($scale / 2);
|
|
|
|
$rgb = imagecolorat($image, (int)$x, (int)$y);
|
|
$r = ($rgb >> 16) & 0xFF;
|
|
|
|
return $r < 128; // Black if RGB < 128
|
|
}
|
|
|
|
echo "Checking critical areas:\n\n";
|
|
|
|
// 1. Finder patterns
|
|
echo "1. Finder Patterns:\n";
|
|
$finderErrors = 0;
|
|
$finderPositions = [
|
|
[0, 0], [0, 14], [14, 0] // Top-left, top-right, bottom-left
|
|
];
|
|
|
|
foreach ($finderPositions as [$startRow, $startCol]) {
|
|
for ($r = 0; $r < 7; $r++) {
|
|
for ($c = 0; $c < 7; $c++) {
|
|
$row = $startRow + $r;
|
|
$col = $startCol + $c;
|
|
|
|
$ourDark = $ourMatrix->getModuleAt($row, $col)->isDark();
|
|
$pythonDark = isPythonModuleDark($pythonImage, $row, $col);
|
|
|
|
if ($ourDark !== $pythonDark) {
|
|
$finderErrors++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
echo " Errors: $finderErrors\n";
|
|
echo " Status: " . ($finderErrors === 0 ? "✅ OK" : "❌ MISMATCH") . "\n\n";
|
|
|
|
// 2. Timing patterns
|
|
echo "2. Timing Patterns:\n";
|
|
$timingErrors = 0;
|
|
for ($i = 8; $i < 13; $i++) {
|
|
// Horizontal timing (row 6)
|
|
$ourDark = $ourMatrix->getModuleAt(6, $i)->isDark();
|
|
$pythonDark = isPythonModuleDark($pythonImage, 6, $i);
|
|
if ($ourDark !== $pythonDark) $timingErrors++;
|
|
|
|
// Vertical timing (col 6)
|
|
$ourDark = $ourMatrix->getModuleAt($i, 6)->isDark();
|
|
$pythonDark = isPythonModuleDark($pythonImage, $i, 6);
|
|
if ($ourDark !== $pythonDark) $timingErrors++;
|
|
}
|
|
echo " Errors: $timingErrors\n";
|
|
echo " Status: " . ($timingErrors === 0 ? "✅ OK" : "❌ MISMATCH") . "\n\n";
|
|
|
|
// 3. Format information
|
|
echo "3. Format Information:\n";
|
|
$formatErrors = 0;
|
|
$formatCols = [0, 1, 2, 3, 4, 5, 7, 8, 20, 19, 18, 17, 16, 15, 14];
|
|
foreach ($formatCols as $col) {
|
|
$ourDark = $ourMatrix->getModuleAt(8, $col)->isDark();
|
|
$pythonDark = isPythonModuleDark($pythonImage, 8, $col);
|
|
if ($ourDark !== $pythonDark) {
|
|
$formatErrors++;
|
|
echo " Col $col: Our=" . ($ourDark ? '1' : '0') . " Python=" . ($pythonDark ? '1' : '0') . "\n";
|
|
}
|
|
}
|
|
echo " Errors: $formatErrors\n";
|
|
echo " Status: " . ($formatErrors === 0 ? "✅ OK" : "❌ MISMATCH") . "\n\n";
|
|
|
|
// 4. Dark module
|
|
echo "4. Dark Module (fixed at row 13, col 8):\n";
|
|
$ourDark = $ourMatrix->getModuleAt(13, 8)->isDark();
|
|
$pythonDark = isPythonModuleDark($pythonImage, 13, 8);
|
|
echo " Our: " . ($ourDark ? 'Dark' : 'Light') . "\n";
|
|
echo " Python: " . ($pythonDark ? 'Dark' : 'Light') . "\n";
|
|
echo " Status: " . ($ourDark === $pythonDark ? "✅ OK" : "❌ MISMATCH") . "\n\n";
|
|
|
|
// 5. Data area
|
|
echo "5. Data Area:\n";
|
|
$dataErrors = 0;
|
|
$totalDataModules = 0;
|
|
|
|
for ($row = 0; $row < $size; $row++) {
|
|
for ($col = 0; $col < $size; $col++) {
|
|
// Skip function patterns
|
|
if (($row < 9 && $col < 9) || // Top-left finder + separators
|
|
($row < 9 && $col >= 13) || // Top-right finder + separators
|
|
($row >= 13 && $col < 9) || // Bottom-left finder + separators
|
|
$row === 6 || $col === 6 || // Timing patterns
|
|
($row === 8) || ($col === 8)) { // Format info
|
|
continue;
|
|
}
|
|
|
|
$totalDataModules++;
|
|
$ourDark = $ourMatrix->getModuleAt($row, $col)->isDark();
|
|
$pythonDark = isPythonModuleDark($pythonImage, $row, $col);
|
|
|
|
if ($ourDark !== $pythonDark) {
|
|
$dataErrors++;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo " Total data modules: $totalDataModules\n";
|
|
echo " Errors: $dataErrors\n";
|
|
echo " Match rate: " . number_format(($totalDataModules - $dataErrors) / $totalDataModules * 100, 1) . "%\n";
|
|
echo " Status: " . ($dataErrors === 0 ? "✅ OK" : "❌ MISMATCH") . "\n\n";
|
|
|
|
echo "=== Summary ===\n";
|
|
$totalErrors = $finderErrors + $timingErrors + $formatErrors + $dataErrors;
|
|
echo "Total errors: $totalErrors\n";
|
|
|
|
if ($totalErrors === 0) {
|
|
echo "✅ MATRICES MATCH PERFECTLY!\n";
|
|
} else {
|
|
echo "❌ DIFFERENCES FOUND\n";
|
|
echo "\nMost likely causes:\n";
|
|
if ($formatErrors > 0) echo "- Format information still incorrect\n";
|
|
if ($dataErrors > 0) echo "- Data encoding or masking issue\n";
|
|
if ($finderErrors > 0) echo "- Finder pattern issue\n";
|
|
if ($timingErrors > 0) echo "- Timing pattern issue\n";
|
|
}
|
|
|
|
imagedestroy($pythonImage);
|
|
|