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

@@ -5,13 +5,13 @@ declare(strict_types=1);
use App\Application\Api\Images\ImageApiController;
use App\Domain\Media\Image;
use App\Domain\Media\ImageRepository;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\Responses\JsonResponse;
use App\Framework\Http\Exception\NotFound;
use App\Framework\Filesystem\FilePath;
use App\Framework\Http\MimeType;
use App\Framework\Core\ValueObjects\FileSize;
use App\Framework\Core\ValueObjects\Hash;
use App\Framework\Filesystem\ValueObjects\FilePath;
use App\Framework\Http\Exception\NotFound;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\MimeType;
use App\Framework\Http\Responses\JsonResponse;
use App\Framework\Ulid\Ulid;
beforeEach(function () {
@@ -58,7 +58,7 @@ beforeEach(function () {
hash: Hash::fromString('hash2'),
path: FilePath::create('/test/path'),
altText: 'Test image 2'
)
),
];
});
@@ -71,7 +71,7 @@ it('can get paginated list of images', function () {
$request = Mockery::mock(HttpRequest::class);
$request->queryParams = [
'limit' => '10',
'offset' => '0'
'offset' => '0',
];
$this->imageRepository
@@ -104,7 +104,7 @@ it('can search images with query parameter', function () {
$request->queryParams = [
'limit' => '50',
'offset' => '0',
'search' => 'test'
'search' => 'test',
];
$this->imageRepository
@@ -216,7 +216,7 @@ it('throws NotFound exception when image ULID not found', function () {
->andReturn(null);
// Act & Assert
expect(fn() => $this->controller->getImage($ulid))
expect(fn () => $this->controller->getImage($ulid))
->toThrow(NotFound::class, "Image with ULID {$ulid} not found");
});
@@ -227,7 +227,7 @@ it('can search images with advanced parameters', function () {
'q' => 'landscape',
'type' => 'jpeg',
'min_width' => '800',
'min_height' => '600'
'min_height' => '600',
];
$this->imageRepository
@@ -262,4 +262,4 @@ it('handles empty search results', function () {
$data = $response->getData();
expect($data['results'])->toBeEmpty();
expect($data['count'])->toBe(0);
});
});