Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 0 additions & 53 deletions app/Http/Controllers/Api/V1/AuthController.php

This file was deleted.

125 changes: 125 additions & 0 deletions app/Http/Controllers/Api/V1/ImportantLinkController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\ImportantLink;
use Illuminate\Http\Request;
use Log;

class ImportantLinkController extends Controller
{
public function index(Request $request)
{
$perPage = (int) $request->query('per_page', '15');
$dealershipId = $request->query('dealership_id');
$isActive = $request->query('is_active');

$query = ImportantLink::with(['creator', 'dealership']);

if ($dealershipId !== null) {
$query->where('dealership_id', $dealershipId);
}

if ($isActive !== null) {
$query->where('is_active', (bool) $isActive);
Copy link

@cubic-dev-ai cubic-dev-ai bot Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casting the is_active query parameter with (bool) causes /api/v1/links?is_active=false to be treated as true, so the endpoint returns active links when inactive ones are requested. Please normalize the string via filter_var(..., FILTER_VALIDATE_BOOL) (or similar) before applying the filter.

Prompt for AI agents
Address the following comment on app/Http/Controllers/Api/V1/ImportantLinkController.php at line 27:

<comment>Casting the `is_active` query parameter with `(bool)` causes `/api/v1/links?is_active=false` to be treated as `true`, so the endpoint returns active links when inactive ones are requested. Please normalize the string via `filter_var(..., FILTER_VALIDATE_BOOL)` (or similar) before applying the filter.</comment>

<file context>
@@ -0,0 +1,125 @@
+        }
+
+        if ($isActive !== null) {
+            $query-&gt;where(&#39;is_active&#39;, (bool) $isActive);
+        }
+
</file context>
Suggested change
$query->where('is_active', (bool) $isActive);
$query->where('is_active', filter_var($isActive, FILTER_VALIDATE_BOOL));
Fix with Cubic

Copy link

@cubic-dev-ai cubic-dev-ai bot Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casting the is_active query parameter with (bool) makes values such as ?is_active=false evaluate to true, so the API cannot filter for inactive links. Use a proper boolean parser instead.

Prompt for AI agents
Address the following comment on app/Http/Controllers/Api/V1/ImportantLinkController.php at line 27:

<comment>Casting the `is_active` query parameter with `(bool)` makes values such as `?is_active=false` evaluate to `true`, so the API cannot filter for inactive links. Use a proper boolean parser instead.</comment>

<file context>
@@ -0,0 +1,125 @@
+        }
+
+        if ($isActive !== null) {
+            $query-&gt;where(&#39;is_active&#39;, (bool) $isActive);
+        }
+
</file context>
Suggested change
$query->where('is_active', (bool) $isActive);
$query->where('is_active', filter_var($isActive, FILTER_VALIDATE_BOOLEAN));
Fix with Cubic

Copy link

@cubic-dev-ai cubic-dev-ai bot Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casting the query parameter to bool makes ?is_active=false evaluate to true, so the filter returns the wrong records.

Prompt for AI agents
Address the following comment on app/Http/Controllers/Api/V1/ImportantLinkController.php at line 27:

<comment>Casting the query parameter to bool makes `?is_active=false` evaluate to `true`, so the filter returns the wrong records.</comment>

<file context>
@@ -0,0 +1,125 @@
+        }
+
+        if ($isActive !== null) {
+            $query-&gt;where(&#39;is_active&#39;, (bool) $isActive);
+        }
+
</file context>
Suggested change
$query->where('is_active', (bool) $isActive);
$query->where('is_active', filter_var($isActive, FILTER_VALIDATE_BOOLEAN));
Fix with Cubic

}

$links = $query->orderBy('sort_order')
->orderBy('created_at', 'desc')
->paginate($perPage);

return response()->json($links);
}

public function show($id)
{
$link = ImportantLink::with(['creator', 'dealership'])->find($id);

if (!$link) {
return response()->json([
'message' => 'Ссылка не найдена'
], 404);
}

return response()->json($link);
}

public function store(Request $request)
{
Log::info("Request ImportantLink Store: " . json_encode($request->all()));
$validated = $request->validate([
'title' => 'required|string|max:255',
'url' => 'required|string|max:1000|url',
'description' => 'nullable|string',
'dealership_id' => 'nullable|integer|exists:auto_dealerships,id',
'sort_order' => 'integer',
'is_active' => 'boolean',
]);

// Устанавливаем creator_id из текущего пользователя
$validated['creator_id'] = $request->user()->id;

$link = ImportantLink::create($validated);

// Загружаем связи для ответа
$link->load(['creator', 'dealership']);

return response()->json($link, 201);
}

public function update(Request $request, $id)
{
$link = ImportantLink::find($id);

if (!$link) {
return response()->json([
'message' => 'Ссылка не найдена'
], 404);
}

$validated = $request->validate([
'title' => 'sometimes|required|string|max:255',
'url' => 'sometimes|required|string|max:1000|url',
'description' => 'nullable|string',
'dealership_id' => 'nullable|integer|exists:auto_dealerships,id',
'sort_order' => 'integer',
'is_active' => 'boolean',
]);

$link->update($validated);

// Загружаем связи для ответа
$link->load(['creator', 'dealership']);

return response()->json($link);
}

public function destroy($id)
{
$link = ImportantLink::find($id);

if (!$link) {
return response()->json([
'message' => 'Ссылка не найдена'
], 404);
}

try {
$link->delete();

return response()->json([
'success' => true,
'message' => 'Ссылка успешно удалена'
], 200);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Ошибка при удалении ссылки',
'error' => $e->getMessage()
], 500);
}
}
}
116 changes: 0 additions & 116 deletions app/Http/Controllers/Api/V1/UserRegistrationController.php

This file was deleted.

42 changes: 42 additions & 0 deletions database/factories/ImportantLinkFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Database\Factories;

use App\Models\AutoDealership;
use App\Models\ImportantLink;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class ImportantLinkFactory extends Factory
{
protected $model = ImportantLink::class;

public function definition(): array
{
return [
'title' => fake()->sentence(3),
'url' => fake()->url(),
'description' => fake()->optional()->paragraph(),
'dealership_id' => AutoDealership::factory(),
'creator_id' => User::factory(),
'sort_order' => fake()->numberBetween(0, 100),
'is_active' => true,
];
}

public function inactive(): static
{
return $this->state(fn (array $attributes) => [
'is_active' => false,
]);
}

public function global(): static
{
return $this->state(fn (array $attributes) => [
'dealership_id' => null,
]);
}
}
15 changes: 13 additions & 2 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

declare(strict_types=1);

use App\Http\Controllers\Api\V1\AuthController;
use App\Http\Controllers\Api\V1\DashboardController;
use App\Http\Controllers\Api\V1\DealershipController;
use App\Http\Controllers\Api\V1\ImportantLinkController;
use App\Http\Controllers\Api\V1\SessionController;
use App\Http\Controllers\Api\V1\SettingsController;
use App\Http\Controllers\Api\V1\ShiftController;
use App\Http\Controllers\Api\V1\TaskController;
use App\Http\Controllers\Api\V1\UserApiController;
use App\Http\Controllers\Api\V1\UserRegistrationController;
use App\Http\Controllers\FrontController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Expand Down Expand Up @@ -91,6 +90,18 @@
Route::delete('/tasks/{id}', [TaskController::class, 'destroy'])
->middleware('role:manager,owner');

// Important Links
Route::get('/links', [ImportantLinkController::class, 'index']);
Route::get('/links/{id}', [ImportantLinkController::class, 'show']);

// Only managers and owners can manage links
Route::post('/links', [ImportantLinkController::class, 'store'])
->middleware('role:manager,owner');
Route::put('/links/{id}', [ImportantLinkController::class, 'update'])
->middleware('role:manager,owner');
Route::delete('/links/{id}', [ImportantLinkController::class, 'destroy'])
->middleware('role:manager,owner');

// Dashboard
Route::get('/dashboard', [DashboardController::class, 'index']);

Expand Down
Loading