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,161 @@
<?php
declare(strict_types=1);
use App\Framework\OutputBuffer\BufferHandle;
use App\Framework\OutputBuffer\OutputBuffer;
use App\Framework\OutputBuffer\OutputBufferConfig;
use App\Framework\OutputBuffer\OutputBufferException;
describe('BufferHandle', function () {
beforeEach(function () {
while (ob_get_level() > 0) {
ob_end_clean();
}
});
afterEach(function () {
while (ob_get_level() > 0) {
ob_end_clean();
}
});
describe('clean()', function () {
it('cleans buffer and returns content', function () {
$handle = OutputBuffer::start();
echo "Test content";
$content = $handle->clean();
expect($content)->toBe("Test content");
expect(ob_get_level())->toBe(0);
});
it('throws exception if buffer level mismatch', function () {
$handle = OutputBuffer::start();
ob_start(); // Create additional buffer
expect(fn() => $handle->clean())
->toThrow(OutputBufferException::class);
ob_end_clean();
$handle->end();
});
});
describe('end()', function () {
it('ends buffer without returning content', function () {
$handle = OutputBuffer::start();
echo "Test content";
$handle->end();
expect(ob_get_level())->toBe(0);
});
it('validates buffer level before ending', function () {
$handle = OutputBuffer::start();
$handle->end();
expect(fn() => $handle->end())
->toThrow(OutputBufferException::class);
});
});
describe('flush()', function () {
it('flushes buffer contents', function () {
$handle = OutputBuffer::start();
echo "Test";
// Flush should work (though output goes nowhere in tests)
expect(fn() => $handle->flush())->not->toThrow(Exception::class);
$handle->end();
});
});
describe('getContents()', function () {
it('gets contents without clearing buffer', function () {
$handle = OutputBuffer::start();
echo "Test";
$content = $handle->getContents();
expect($content)->toBe("Test");
expect($handle->isActive())->toBeTrue();
$handle->end();
});
it('can be called multiple times', function () {
$handle = OutputBuffer::start();
echo "Test";
$content1 = $handle->getContents();
echo " More";
$content2 = $handle->getContents();
expect($content1)->toBe("Test");
expect($content2)->toBe("Test More");
$handle->end();
});
});
describe('getLength()', function () {
it('returns buffer content length', function () {
$handle = OutputBuffer::start();
expect($handle->getLength())->toBe(0);
echo "Test";
expect($handle->getLength())->toBe(4);
echo "ing";
expect($handle->getLength())->toBe(7);
$handle->end();
});
});
describe('isActive()', function () {
it('returns true when buffer is active', function () {
$handle = OutputBuffer::start();
expect($handle->isActive())->toBeTrue();
$handle->end();
});
it('returns false after buffer is cleaned', function () {
$handle = OutputBuffer::start();
$handle->end();
expect($handle->isActive())->toBeFalse();
});
});
describe('level validation', function () {
it('validates buffer level for all operations', function () {
$handle = OutputBuffer::start();
$handle->end();
// All operations should fail after buffer is ended
expect(fn() => $handle->clean())->toThrow(OutputBufferException::class);
expect(fn() => $handle->getContents())->toThrow(OutputBufferException::class);
expect(fn() => $handle->flush())->toThrow(OutputBufferException::class);
});
it('detects level mismatch', function () {
$handle1 = OutputBuffer::start();
$handle2 = OutputBuffer::start();
// Try to clean handle1 while handle2 is active
expect(fn() => $handle1->clean())
->toThrow(OutputBufferException::class);
$handle2->end();
$handle1->end();
});
});
});