$method, CURLOPT_HTTPHEADER => $headers, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 45]); $body = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($body === false || $status < 200 || $status >= 300) throw new RuntimeException('HTTP ' . $status . ': ' . curl_error($ch) . ' ' . $body); curl_close($ch); return $body; } $identityUrl = getenv('DECISIOQ_IDENTITY_URL') ?: 'https://identity.vinquery.com/connect/token'; $catalogUrl = rtrim(getenv('DECISIOQ_DKS_URL') ?: 'https://dks.vinquery.com', '/'); $decisionServiceUrl = rtrim(getenv('DECISIOQ_DDE_URL') ?: 'https://dde.vinquery.com', '/'); $correlationId = 'auto-fleet-001-php-' . date('YmdHis'); $tokenJson = request_json('POST', $identityUrl, ['clientId' => required_env('DECISIOQ_CLIENT_ID'), 'clientSecret' => required_env('DECISIOQ_CLIENT_SECRET'), 'audience' => getenv('DECISIOQ_AUDIENCE') ?: 'vinquery:api:decisioq']); $token = json_decode($tokenJson, true)['jwtToken']; request_json('GET', $catalogUrl . '/decisioncatalog/decisions/AUTO-FLEET-001', null, $token, $correlationId); $request = [ 'decisionId' => 'AUTO-FLEET-001', 'profileId' => 'balanced', 'scenarioId' => null, 'algorithm' => 'TOPSIS', 'weightStrategy' => 'Expert', 'runSensitivity' => false, 'requestContext' => ['correlationId' => $correlationId], 'options' => [ ['optionId' => 'VEHICLE-001', 'name' => 'Vehicle 001', 'values' => ['lifecycle_cost' => 18000, 'downtime_risk' => 9, 'maintenance_trend' => 6, 'utilization_criticality' => 92, 'safety_rating' => 4.5]], ['optionId' => 'VEHICLE-002', 'name' => 'Vehicle 002', 'values' => ['lifecycle_cost' => 14500, 'downtime_risk' => 3, 'maintenance_trend' => 2, 'utilization_criticality' => 76, 'safety_rating' => 4]] ] ]; echo request_json('POST', $decisionServiceUrl . '/api/v1/decide', $request, $token, $correlationId);