feat(Production): Complete production deployment infrastructure

- 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.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -0,0 +1,145 @@
<?php
declare(strict_types=1);
use App\Application\LiveComponents\Dashboard\WorkerHealthState;
describe('WorkerHealthState', function () {
it('creates empty state with default values', function () {
$state = WorkerHealthState::empty();
expect($state->activeWorkers)->toBe(0);
expect($state->totalWorkers)->toBe(0);
expect($state->jobsInProgress)->toBe(0);
expect($state->workerDetails)->toBe([]);
expect($state->lastUpdated)->toBeString();
});
it('creates state from array', function () {
$data = [
'activeWorkers' => 3,
'totalWorkers' => 5,
'jobsInProgress' => 7,
'workerDetails' => [
[
'id' => 'worker-1',
'hostname' => 'server-01',
'healthy' => true,
],
],
'lastUpdated' => '2024-01-15 12:00:00',
];
$state = WorkerHealthState::fromArray($data);
expect($state->activeWorkers)->toBe(3);
expect($state->totalWorkers)->toBe(5);
expect($state->jobsInProgress)->toBe(7);
expect($state->workerDetails)->toHaveCount(1);
expect($state->workerDetails[0]['id'])->toBe('worker-1');
});
it('converts state to array', function () {
$workerDetails = [
[
'id' => 'worker-1',
'hostname' => 'server-01',
'process_id' => 12345,
'healthy' => true,
'jobs' => 2,
'max_jobs' => 10,
],
];
$state = new WorkerHealthState(
activeWorkers: 1,
totalWorkers: 3,
jobsInProgress: 2,
workerDetails: $workerDetails,
lastUpdated: '2024-01-15 12:00:00'
);
$array = $state->toArray();
expect($array)->toHaveKey('activeWorkers');
expect($array)->toHaveKey('totalWorkers');
expect($array)->toHaveKey('jobsInProgress');
expect($array)->toHaveKey('workerDetails');
expect($array['workerDetails'])->toHaveCount(1);
});
it('creates new state with updated worker health', function () {
$state = WorkerHealthState::empty();
$workerDetails = [
[
'id' => 'worker-1',
'hostname' => 'server-01',
'healthy' => true,
'jobs' => 5,
],
[
'id' => 'worker-2',
'hostname' => 'server-02',
'healthy' => false,
'jobs' => 0,
],
];
$updatedState = $state->withWorkerHealth(
activeWorkers: 2,
totalWorkers: 2,
jobsInProgress: 5,
workerDetails: $workerDetails
);
// Original unchanged
expect($state->activeWorkers)->toBe(0);
expect($state->workerDetails)->toBe([]);
// New state updated
expect($updatedState->activeWorkers)->toBe(2);
expect($updatedState->totalWorkers)->toBe(2);
expect($updatedState->jobsInProgress)->toBe(5);
expect($updatedState->workerDetails)->toHaveCount(2);
expect($updatedState->lastUpdated)->not->toBe($state->lastUpdated);
});
it('is immutable', function () {
$state = new WorkerHealthState(
activeWorkers: 5,
totalWorkers: 10,
jobsInProgress: 15,
workerDetails: [],
lastUpdated: '2024-01-15 12:00:00'
);
$newState = $state->withWorkerHealth(
activeWorkers: 6,
totalWorkers: 10,
jobsInProgress: 20,
workerDetails: []
);
// Original unchanged
expect($state->activeWorkers)->toBe(5);
expect($state->jobsInProgress)->toBe(15);
// New instance
expect($newState)->not->toBe($state);
expect($newState->activeWorkers)->toBe(6);
expect($newState->jobsInProgress)->toBe(20);
});
it('handles empty worker details array', function () {
$state = WorkerHealthState::empty()->withWorkerHealth(
activeWorkers: 0,
totalWorkers: 0,
jobsInProgress: 0,
workerDetails: []
);
expect($state->workerDetails)->toBe([]);
expect($state->activeWorkers)->toBe(0);
});
});