- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
157 lines
5.1 KiB
PHP
157 lines
5.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Application\FeatureFlags;
|
|
|
|
use App\Framework\Attributes\Route;
|
|
use App\Framework\FeatureFlags\FeatureFlag;
|
|
use App\Framework\FeatureFlags\FeatureFlagManager;
|
|
use App\Framework\Http\Headers;
|
|
use App\Framework\Http\HttpResponse;
|
|
use App\Framework\Http\Method;
|
|
use App\Framework\Http\Request;
|
|
use App\Framework\Http\Status;
|
|
|
|
/**
|
|
* Controller for managing feature flags
|
|
*/
|
|
final readonly class FeatureFlagController
|
|
{
|
|
public function __construct(
|
|
private FeatureFlagManager $flagManager
|
|
) {
|
|
}
|
|
|
|
#[Route(path: '/admin/feature-flags', method: Method::GET)]
|
|
public function index(Request $request): HttpResponse
|
|
{
|
|
$flags = $this->flagManager->getAllFlags();
|
|
$summary = $this->flagManager->getStatusSummary();
|
|
|
|
$response = [
|
|
'flags' => array_map(fn ($flag) => $this->flagToArray($flag), $flags),
|
|
'summary' => $summary,
|
|
];
|
|
|
|
return new HttpResponse(
|
|
status: Status::OK,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode($response, JSON_PRETTY_PRINT)
|
|
);
|
|
}
|
|
|
|
#[Route(path: '/admin/feature-flags/{name}', method: Method::GET)]
|
|
public function show(Request $request): HttpResponse
|
|
{
|
|
$name = $request->queryParams['name'] ?? '';
|
|
|
|
$flag = $this->flagManager->getFlag($name);
|
|
if ($flag === null) {
|
|
return new HttpResponse(
|
|
status: Status::NOT_FOUND,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode(['error' => 'Feature flag not found'])
|
|
);
|
|
}
|
|
|
|
return new HttpResponse(
|
|
status: Status::OK,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode($this->flagToArray($flag), JSON_PRETTY_PRINT)
|
|
);
|
|
}
|
|
|
|
#[Route(path: '/admin/feature-flags/{name}/enable', method: Method::POST)]
|
|
public function enable(Request $request): HttpResponse
|
|
{
|
|
$name = $request->queryParams['name'] ?? '';
|
|
|
|
$this->flagManager->enable($name, 'Enabled via API');
|
|
|
|
return new HttpResponse(
|
|
status: Status::OK,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode(['message' => "Feature flag '{$name}' enabled"])
|
|
);
|
|
}
|
|
|
|
#[Route(path: '/admin/feature-flags/{name}/disable', method: Method::POST)]
|
|
public function disable(Request $request): HttpResponse
|
|
{
|
|
$name = $request->queryParams['name'] ?? '';
|
|
|
|
$this->flagManager->disable($name);
|
|
|
|
return new HttpResponse(
|
|
status: Status::OK,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode(['message' => "Feature flag '{$name}' disabled"])
|
|
);
|
|
}
|
|
|
|
#[Route(path: '/admin/feature-flags/{name}/percentage', method: Method::POST)]
|
|
public function setPercentage(Request $request): HttpResponse
|
|
{
|
|
$name = $request->queryParams['name'] ?? '';
|
|
|
|
$body = json_decode($request->body, true);
|
|
$percentage = (int) ($body['percentage'] ?? 0);
|
|
|
|
if ($percentage < 0 || $percentage > 100) {
|
|
return new HttpResponse(
|
|
status: Status::BAD_REQUEST,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode(['error' => 'Percentage must be between 0 and 100'])
|
|
);
|
|
}
|
|
|
|
$this->flagManager->setPercentageRollout(
|
|
$name,
|
|
$percentage,
|
|
"Set to {$percentage}% rollout via API"
|
|
);
|
|
|
|
return new HttpResponse(
|
|
status: Status::OK,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode(['message' => "Feature flag '{$name}' set to {$percentage}% rollout"])
|
|
);
|
|
}
|
|
|
|
#[Route(path: '/admin/feature-flags/{name}', method: Method::DELETE)]
|
|
public function delete(Request $request): HttpResponse
|
|
{
|
|
$name = $request->queryParams['name'] ?? '';
|
|
|
|
if (! $this->flagManager->exists($name)) {
|
|
return new HttpResponse(
|
|
status: Status::NOT_FOUND,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode(['error' => 'Feature flag not found'])
|
|
);
|
|
}
|
|
|
|
$this->flagManager->deleteFlag($name);
|
|
|
|
return new HttpResponse(
|
|
status: Status::OK,
|
|
headers: new Headers(['Content-Type' => 'application/json']),
|
|
body: json_encode(['message' => "Feature flag '{$name}' deleted"])
|
|
);
|
|
}
|
|
|
|
private function flagToArray(FeatureFlag $flag): array
|
|
{
|
|
return [
|
|
'name' => $flag->name,
|
|
'status' => $flag->status->value,
|
|
'description' => $flag->description,
|
|
'conditions' => $flag->conditions,
|
|
'enabled_at' => $flag->enabledAt?->toIso8601(),
|
|
'expires_at' => $flag->expiresAt?->toIso8601(),
|
|
'is_enabled' => $flag->isEnabled(),
|
|
];
|
|
}
|
|
}
|