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

@@ -7,9 +7,9 @@ namespace App\Framework\HttpClient;
use App\Framework\Http\HeaderManipulator;
use App\Framework\Http\Headers;
use App\Framework\Http\Status;
use App\Framework\HttpClient\Curl\Handle;
use App\Framework\HttpClient\Exception\CurlExecutionFailed;
use App\Framework\HttpClient\Exception\CurlNotInitialized;
use CurlHandle;
final readonly class CurlHttpClient implements HttpClient
{
@@ -20,65 +20,43 @@ final readonly class CurlHttpClient implements HttpClient
) {
}
public function initializeCurl(): \CurlHandle
{
$curlHandle = curl_init();
if ($curlHandle === false) {
throw new CurlNotInitialized();
}
return $curlHandle;
}
public function configureCurlRequest(CurlHandle $ch, ClientRequest $request): void
{
$options = $this->requestBuilder->buildOptions($request);
if ($request->options->auth !== null) {
$authResult = $this->authenticationHandler->configure($request->options->auth, $request->headers);
if ($authResult->headers !== $request->headers) {
$updatedRequest = $request->with(['headers' => $authResult->headers]);
$options = $this->requestBuilder->buildOptions($updatedRequest);
} else {
$options = $this->requestBuilder->buildOptions($request);
}
if (! empty($authResult->curlOptions)) {
$options = array_replace($options, $authResult->curlOptions);
}
}
curl_setopt_array($ch, $options);
}
public function executeCurlRequest(CurlHandle $ch): string
{
$rawResponse = curl_exec($ch);
if ($rawResponse === false) {
throw new CurlExecutionFailed(curl_error($ch), curl_errno($ch));
}
return $rawResponse;
}
/**
* @throws CurlExecutionFailed
*/
public function send(ClientRequest $request): ClientResponse
{
$ch = $this->initializeCurl();
// Initialize OOP curl handle
$handle = new Handle();
try {
$this->configureCurlRequest($ch, $request);
$rawResponse = $this->executeCurlRequest($ch);
// Build options using HandleOption enum
$options = $this->requestBuilder->buildOptions($request);
return $this->responseParser->parse($rawResponse, $ch);
} finally {
curl_close($ch);
// Handle authentication
if ($request->options->auth !== null) {
$authResult = $this->authenticationHandler->configure($request->options->auth, $request->headers);
if ($authResult->headers !== $request->headers) {
$updatedRequest = $request->with(['headers' => $authResult->headers]);
$options = $this->requestBuilder->buildOptions($updatedRequest);
}
if (! empty($authResult->curlOptions)) {
$options = array_replace($options, $authResult->curlOptions);
}
}
// Set all options using fluent API
$handle->setOptions($options);
// Execute request (automatically uses CURLOPT_RETURNTRANSFER)
$rawResponse = $handle->fetch();
// Parse response using underlying CurlHandle resource
return $this->responseParser->parse($rawResponse, $handle->getResource());
} catch (\Throwable $e) {
// Wrap any exception in CurlExecutionFailed for backward compatibility
throw new CurlExecutionFailed($e->getMessage(), $e->getCode(), $e);
}