Files
BetiX/app/Http/Controllers/BonusApiController.php
Dolo 0280278978
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Initialer Laravel Commit für BetiX
2026-04-04 18:01:50 +02:00

157 lines
5.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Concerns\ProxiesBackend;
use App\Services\BackendHttpClient;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
class BonusApiController extends Controller
{
use ProxiesBackend;
public function __construct(private readonly BackendHttpClient $client)
{
// Inline token check middleware (no alias registration needed)
$this->middleware(function ($request, $next) {
$provided = $this->extractToken($request);
$expected = config('services.bonus_api.token');
if (!$expected || !hash_equals((string) $expected, (string) $provided)) {
return response()->json(['message' => 'Unauthorized'], 401);
}
return $next($request);
});
}
private function extractToken(Request $request): ?string
{
$auth = $request->header('Authorization');
if ($auth && str_starts_with($auth, 'Bearer ')) {
return substr($auth, 7);
}
return $request->query('api_token'); // fallback: allow ?api_token=
}
public function index(Request $request)
{
try {
$query = [];
if ($status = $request->query('status')) {
$query['status'] = $status;
}
if ($request->boolean('active_only')) {
$query['active_only'] = 1;
}
$query['per_page'] = min(200, max(1, (int) $request->query('per_page', 50)));
$res = $this->client->get($request, '/bonuses', $query, retry: true);
if ($res->successful()) {
return response()->json($res->json() ?: []);
}
if ($res->clientError()) return $this->mapClientError($res);
if ($res->serverError()) return $this->mapServiceUnavailable($res);
return $this->mapBadGateway();
} catch (\Throwable $e) {
return $this->mapBadGateway('API server not reachable');
}
}
public function show(Request $request, int $id)
{
try {
$res = $this->client->get($request, "/bonuses/{$id}", [], retry: true);
if ($res->successful()) {
return response()->json($res->json() ?: []);
}
if ($res->clientError()) return $this->mapClientError($res);
if ($res->serverError()) return $this->mapServiceUnavailable($res);
return $this->mapBadGateway();
} catch (\Throwable $e) {
return $this->mapBadGateway('API server not reachable');
}
}
public function store(Request $request)
{
$data = $this->validateData($request);
try {
$res = $this->client->post($request, '/bonuses', $data);
if ($res->successful()) {
return response()->json($res->json() ?: [], 201);
}
if ($res->clientError()) return $this->mapClientError($res);
if ($res->serverError()) return $this->mapServiceUnavailable($res);
return $this->mapBadGateway();
} catch (\Throwable $e) {
return $this->mapBadGateway('API server not reachable');
}
}
public function update(Request $request, int $id)
{
$data = $this->validateData($request, partial: true);
try {
$res = $this->client->patch($request, "/bonuses/{$id}", $data);
if ($res->successful()) {
return response()->json($res->json() ?: []);
}
if ($res->clientError()) return $this->mapClientError($res);
if ($res->serverError()) return $this->mapServiceUnavailable($res);
return $this->mapBadGateway();
} catch (\Throwable $e) {
return $this->mapBadGateway('API server not reachable');
}
}
public function destroy(Request $request, int $id)
{
try {
$res = $this->client->delete($request, "/bonuses/{$id}");
if ($res->successful()) {
$body = $res->json();
return response()->json($body ?: ['message' => 'Deleted']);
}
if ($res->clientError()) return $this->mapClientError($res);
if ($res->serverError()) return $this->mapServiceUnavailable($res);
return $this->mapBadGateway();
} catch (\Throwable $e) {
return $this->mapBadGateway('API server not reachable');
}
}
private function validateData(Request $request, bool $partial = false): array
{
$required = $partial ? 'sometimes' : 'required';
$rules = [
'title' => [$required, 'string', 'max:255'],
'type' => ['sometimes', 'nullable', 'string', 'max:64'],
'amount_value' => ['sometimes', 'nullable', 'numeric'],
'amount_unit' => ['sometimes', 'nullable', Rule::in(['USD','EUR','BTC','ETH','PERCENT','SPINS'])],
'min_deposit' => ['sometimes', 'nullable', 'numeric', 'min:0'],
'max_amount' => ['sometimes', 'nullable', 'numeric', 'min:0'],
'currency' => ['sometimes', 'nullable', 'string', 'max:16'],
'code' => ['sometimes', 'nullable', 'string', 'max:64'],
'status' => ['sometimes', 'required', Rule::in(['draft','active','paused','expired'])],
'starts_at' => ['sometimes', 'nullable', 'date'],
'expires_at' => ['sometimes', 'nullable', 'date', 'after_or_equal:starts_at'],
'rules' => ['sometimes', 'nullable', 'array'],
'description' => ['sometimes', 'nullable', 'string'],
];
$validated = $request->validate($rules);
// Normalize empty strings to null
foreach (['type','amount_unit','currency','code','description'] as $k) {
if (array_key_exists($k, $validated) && $validated[$k] === '') {
$validated[$k] = null;
}
}
return $validated;
}
}