refactor: reorganize project structure for better maintainability

- Move 45 debug/test files from root to organized scripts/ directories
- Secure public/ directory by removing debug files (security improvement)
- Create structured scripts organization:
  • scripts/debug/      (20 files) - Framework debugging tools
  • scripts/test/       (18 files) - Test and validation scripts
  • scripts/maintenance/ (5 files) - Maintenance utilities
  • scripts/dev/         (2 files) - Development tools

Security improvements:
- Removed all debug/test files from public/ directory
- Only production files remain: index.php, health.php

Root directory cleanup:
- Reduced from 47 to 2 PHP files in root
- Only essential production files: console.php, worker.php

This improves:
 Security (no debug code in public/)
 Organization (clear separation of concerns)
 Maintainability (easy to find and manage scripts)
 Professional structure (clean root directory)
This commit is contained in:
2025-10-05 10:59:15 +02:00
parent 03e5188644
commit 887847dde6
77 changed files with 3902 additions and 787 deletions

View File

@@ -0,0 +1,153 @@
<?php
/**
* Minimal Hot Reload Endpoint
* Simple SSE implementation without complex framework dependencies
*/
declare(strict_types=1);
// Disable deprecation warnings
error_reporting(E_ALL & ~E_DEPRECATED);
ini_set('display_errors', 1);
// Simple .env parsing
function loadEnvVar(string $key, string $envFile = null): ?string {
$envFile ??= __DIR__ . '/../.env';
if (!file_exists($envFile)) {
return null;
}
$content = file_get_contents($envFile);
if (preg_match("/^{$key}\s*=\s*(.*)$/m", $content, $matches)) {
return trim($matches[1], " \t\n\r\0\x0B\"'");
}
return null;
}
// Only allow in development
$appDebug = loadEnvVar('APP_DEBUG');
if ($appDebug !== 'true') {
http_response_code(403);
exit('Hot Reload is only available in development mode');
}
// Set SSE headers
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header('X-Accel-Buffering: no'); // Disable nginx buffering
// Get watched directories
$watchedDirs = [
__DIR__ . '/../src',
__DIR__ . '/../resources/views',
__DIR__ . '/../config',
];
// Store file modification times
$fileCache = [];
// Function to scan directories for PHP files
function scanDirectory(string $dir, array &$fileCache): array {
$changes = [];
if (!is_dir($dir)) {
return $changes;
}
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $file) {
if (!$file->isFile()) {
continue;
}
$path = $file->getPathname();
// Only watch specific file types
if (!preg_match('/\.(php|view\.php|css|js|ts)$/', $path)) {
continue;
}
$mtime = $file->getMTime();
if (!isset($fileCache[$path])) {
$fileCache[$path] = $mtime;
} elseif ($fileCache[$path] < $mtime) {
$changes[] = [
'path' => $path,
'type' => 'modified',
'time' => $mtime
];
$fileCache[$path] = $mtime;
}
}
return $changes;
}
// Send initial connection event
echo "event: connected\n";
echo "data: " . json_encode([
'status' => 'connected',
'timestamp' => date('c'),
'message' => 'Hot Reload server started'
]) . "\n\n";
flush();
// Initialize file cache
foreach ($watchedDirs as $dir) {
scanDirectory($dir, $fileCache);
}
$lastHeartbeat = time();
// Keep connection alive and watch for changes
while (connection_aborted() === 0) {
$hasChanges = false;
// Check each watched directory
foreach ($watchedDirs as $dir) {
$changes = scanDirectory($dir, $fileCache);
foreach ($changes as $change) {
$reloadType = 'full';
if (str_ends_with($change['path'], '.css')) {
$reloadType = 'css';
} elseif (str_ends_with($change['path'], '.js') || str_ends_with($change['path'], '.ts')) {
$reloadType = 'hmr';
}
echo "event: reload\n";
echo "data: " . json_encode([
'type' => $reloadType,
'file' => basename($change['path']),
'path' => $change['path'],
'timestamp' => date('c'),
'message' => 'File changed: ' . basename($change['path'])
]) . "\n\n";
flush();
$hasChanges = true;
}
}
// Send heartbeat every 30 seconds
if (time() - $lastHeartbeat >= 30) {
echo "event: heartbeat\n";
echo "data: " . json_encode([
'timestamp' => date('c'),
'message' => 'Connection alive'
]) . "\n\n";
flush();
$lastHeartbeat = time();
}
// Small delay to prevent high CPU usage
usleep(500000); // 500ms
}