From 34058e6a816e93641e892d3e78f2a108aaabc0c9 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Mon, 7 Sep 2026 16:56:12 -0300 Subject: [PATCH] feat(scanner): implement scan attempt endpoint and update routes and tests --- ShopIt_API_Postman_Collection.json | 8 +++--- .../Scanner/ScanAttemptController.php | 25 +++++++++++++++++++ .../Controllers/Scanner/TicketController.php | 13 ---------- app/Domains/Ticket/routes/scanner.php | 15 ++++++----- postman/generate-shopit-collection.php | 2 +- .../Ticket/ScannerTicketControllerTest.php | 14 +++++------ 6 files changed, 46 insertions(+), 31 deletions(-) create mode 100644 app/Domains/Ticket/Controllers/Scanner/ScanAttemptController.php diff --git a/ShopIt_API_Postman_Collection.json b/ShopIt_API_Postman_Collection.json index efad4b2..c855602 100644 --- a/ShopIt_API_Postman_Collection.json +++ b/ShopIt_API_Postman_Collection.json @@ -1249,7 +1249,7 @@ "name": "Ticket", "item": [ { - "name": "List Ticket", + "name": "List Scan Attempt", "request": { "method": "GET", "header": [ @@ -5998,9 +5998,9 @@ "type": "text" } ], - "description": "Ruta Laravel: `GET /api/v1/scanner/tickets`\n\nControlador: `App\\Domains\\Ticket\\Controllers\\Scanner\\TicketController@index`\n\nRequiere autenticación Sanctum.", + "description": "Ruta Laravel: `GET /api/v1/scanner/attempts`\n\nControlador: `App\\Domains\\Ticket\\Controllers\\Scanner\\ScanAttemptController`\n\nRequiere autenticación Sanctum.", "url": { - "raw": "{{base_url}}/api/v1/scanner/tickets?page=1&per_page=20", + "raw": "{{base_url}}/api/v1/scanner/attempts?page=1&per_page=20", "host": [ "{{base_url}}" ], @@ -6008,7 +6008,7 @@ "api", "v1", "scanner", - "tickets" + "attempts" ], "query": [ { diff --git a/app/Domains/Ticket/Controllers/Scanner/ScanAttemptController.php b/app/Domains/Ticket/Controllers/Scanner/ScanAttemptController.php new file mode 100644 index 0000000..d13996b --- /dev/null +++ b/app/Domains/Ticket/Controllers/Scanner/ScanAttemptController.php @@ -0,0 +1,25 @@ +user(); + + return ScanAttemptResource::collection( + $this->ticketService->attemptsBy($scanner, $request->validated()) + ); + } +} diff --git a/app/Domains/Ticket/Controllers/Scanner/TicketController.php b/app/Domains/Ticket/Controllers/Scanner/TicketController.php index 891cbeb..17640aa 100644 --- a/app/Domains/Ticket/Controllers/Scanner/TicketController.php +++ b/app/Domains/Ticket/Controllers/Scanner/TicketController.php @@ -3,28 +3,15 @@ namespace App\Domains\Ticket\Controllers\Scanner; use App\Domains\Auth\Models\User; -use App\Domains\Ticket\Requests\ScanAttemptIndexRequest; -use App\Domains\Ticket\Resources\Scanner\ScanAttemptResource; use App\Domains\Ticket\Resources\TicketResource; use App\Domains\Ticket\Services\ScannerTicketService; use App\Http\Controllers\Controller; use Illuminate\Http\Request; -use Illuminate\Http\Resources\Json\AnonymousResourceCollection; class TicketController extends Controller { public function __construct(private readonly ScannerTicketService $ticketService) {} - public function index(ScanAttemptIndexRequest $request): AnonymousResourceCollection - { - /** @var User $scanner */ - $scanner = $request->user(); - - return ScanAttemptResource::collection( - $this->ticketService->attemptsBy($scanner, $request->validated()) - ); - } - public function show(Request $request, string $ticketUuid): TicketResource { /** @var User $scanner */ diff --git a/app/Domains/Ticket/routes/scanner.php b/app/Domains/Ticket/routes/scanner.php index 7a9fb2b..c37336b 100644 --- a/app/Domains/Ticket/routes/scanner.php +++ b/app/Domains/Ticket/routes/scanner.php @@ -1,13 +1,16 @@ middleware(['auth:sanctum', 'scanner.tenant']) +Route::middleware(['auth:sanctum', 'scanner.tenant']) ->group(function (): void { - Route::get('/', [TicketController::class, 'index']); - Route::post('scan', [TicketController::class, 'scan']); - Route::get('{ticketUuid}', [TicketController::class, 'show']) - ->whereUuid('ticketUuid'); + Route::get('v1/scanner/attempts', ScanAttemptController::class); + + Route::prefix('v1/scanner/tickets')->group(function (): void { + Route::post('scan', [TicketController::class, 'scan']); + Route::get('{ticketUuid}', [TicketController::class, 'show']) + ->whereUuid('ticketUuid'); + }); }); diff --git a/postman/generate-shopit-collection.php b/postman/generate-shopit-collection.php index 8adebaa..7393dee 100644 --- a/postman/generate-shopit-collection.php +++ b/postman/generate-shopit-collection.php @@ -202,7 +202,7 @@ function queryFor(string $uri): array ['key' => 'page', 'value' => '1'], ['key' => 'per_page', 'value' => '20'], ], - 'api/v1/scanner/tickets' => [['key' => 'q', 'value' => '', 'disabled' => true], ['key' => 'page', 'value' => '1'], ['key' => 'per_page', 'value' => '20']], + 'api/v1/scanner/attempts' => [['key' => 'q', 'value' => '', 'disabled' => true], ['key' => 'page', 'value' => '1'], ['key' => 'per_page', 'value' => '20']], 'api/storage-test/s3/temporary-url' => [['key' => 'path', 'value' => '{{s3_path}}'], ['key' => 'expires_in_minutes', 'value' => '60']], default => [], }; diff --git a/tests/Feature/Ticket/ScannerTicketControllerTest.php b/tests/Feature/Ticket/ScannerTicketControllerTest.php index ff86ea3..3e2b138 100644 --- a/tests/Feature/Ticket/ScannerTicketControllerTest.php +++ b/tests/Feature/Ticket/ScannerTicketControllerTest.php @@ -52,14 +52,14 @@ class ScannerTicketControllerTest extends TestCase public function test_scanner_routes_require_authentication_and_scan_permission(): void { - $this->getJson('/api/v1/scanner/tickets')->assertUnauthorized(); + $this->getJson('/api/v1/scanner/attempts')->assertUnauthorized(); Sanctum::actingAs(User::factory()->create([ 'rol_codigo' => RoleCode::User->value, 'tenant_codigo' => $this->tenant->codigo, ])); - $this->getJson('/api/v1/scanner/tickets')->assertForbidden(); + $this->getJson('/api/v1/scanner/attempts')->assertForbidden(); } public function test_scanner_can_list_only_its_scan_attempts(): void @@ -82,7 +82,7 @@ class ScannerTicketControllerTest extends TestCase Sanctum::actingAs($this->scanner); - $this->getJson('/api/v1/scanner/tickets') + $this->getJson('/api/v1/scanner/attempts') ->assertOk() ->assertJsonCount(2, 'data') ->assertJsonPath('data.0.id', $newer->id) @@ -102,7 +102,7 @@ class ScannerTicketControllerTest extends TestCase Sanctum::actingAs($this->scanner); - $this->getJson('/api/v1/scanner/tickets?q=aaaaaaaa&per_page=1') + $this->getJson('/api/v1/scanner/attempts?q=aaaaaaaa&per_page=1') ->assertOk() ->assertJsonCount(1, 'data') ->assertJsonPath('data.0.data', $matching->data) @@ -118,7 +118,7 @@ class ScannerTicketControllerTest extends TestCase Sanctum::actingAs($this->scanner); - $this->getJson("/api/v1/scanner/tickets?q={$matching->id}") + $this->getJson("/api/v1/scanner/attempts?q={$matching->id}") ->assertOk() ->assertJsonCount(1, 'data') ->assertJsonPath('data.0.id', $matching->id); @@ -135,7 +135,7 @@ class ScannerTicketControllerTest extends TestCase Sanctum::actingAs($this->scanner); - $this->getJson('/api/v1/scanner/tickets?q=11%2F08%2F26') + $this->getJson('/api/v1/scanner/attempts?q=11%2F08%2F26') ->assertOk() ->assertJsonCount(1, 'data') ->assertJsonPath('data.0.id', $matching->id); @@ -350,7 +350,7 @@ class ScannerTicketControllerTest extends TestCase $ticket = $this->createTicket((string) Str::uuid()); Sanctum::actingAs($admin); - $this->getJson('/api/v1/scanner/tickets')->assertForbidden(); + $this->getJson('/api/v1/scanner/attempts')->assertForbidden(); $this->getJson("/api/v1/scanner/tickets/{$ticket->ticket}")->assertForbidden(); $this->postJson('/api/v1/scanner/tickets/scan', ['data' => $ticket->ticket])->assertForbidden(); $this->assertNull($ticket->fresh()->used_at);