From aa49c825430025b1b3874cf48ecdc76b09c8c6e4 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Thu, 18 Jun 2026 10:13:03 -0300 Subject: [PATCH] Add ProductController and Producto model with CRUD operations and migration --- app/Http/Controllers/ProductController.php | 67 +++++++++++++++++++ app/Models/Producto.php | 31 +++++++++ ...26_06_18_140000_create_productos_table.php | 33 +++++++++ routes/api.php | 3 + 4 files changed, 134 insertions(+) create mode 100644 app/Http/Controllers/ProductController.php create mode 100644 app/Models/Producto.php create mode 100644 database/migrations/2026_06_18_140000_create_productos_table.php diff --git a/app/Http/Controllers/ProductController.php b/app/Http/Controllers/ProductController.php new file mode 100644 index 0000000..182dd37 --- /dev/null +++ b/app/Http/Controllers/ProductController.php @@ -0,0 +1,67 @@ +json(Producto::query()->latest()->get()); + } + + public function store(Request $request): JsonResponse + { + $validated = $request->validate($this->rules()); + + $producto = Producto::create($validated); + + return response()->json($producto, 201); + } + + public function show(Producto $producto): JsonResponse + { + return response()->json($producto); + } + + public function update(Request $request, Producto $producto): JsonResponse + { + $validated = $request->validate($this->rules($producto->id)); + + $producto->update($validated); + + return response()->json($producto); + } + + public function destroy(Producto $producto): Response + { + $producto->delete(); + + return response()->noContent(); + } + + /** + * @return array + */ + protected function rules(?int $productoId = null): array + { + return [ + 'tenant_id' => ['required', 'integer'], + 'categoria_id' => ['required', 'integer'], + 'slug' => [ + 'required', + 'string', + 'max:255', + Rule::unique('productos', 'slug')->ignore($productoId), + ], + 'nombre' => ['required', 'string', 'max:255'], + 'descripcion' => ['nullable', 'string'], + 'precio' => ['required', 'numeric', 'min:0'], + ]; + } +} diff --git a/app/Models/Producto.php b/app/Models/Producto.php new file mode 100644 index 0000000..9147d68 --- /dev/null +++ b/app/Models/Producto.php @@ -0,0 +1,31 @@ + 'integer', + 'categoria_id' => 'integer', + 'precio' => 'decimal:2', + ]; + } +} diff --git a/database/migrations/2026_06_18_140000_create_productos_table.php b/database/migrations/2026_06_18_140000_create_productos_table.php new file mode 100644 index 0000000..22e0e74 --- /dev/null +++ b/database/migrations/2026_06_18_140000_create_productos_table.php @@ -0,0 +1,33 @@ +id(); + $table->unsignedBigInteger('tenant_id'); + $table->unsignedBigInteger('categoria_id'); + $table->string('slug')->unique(); + $table->string('nombre'); + $table->text('descripcion')->nullable(); + $table->decimal('precio', 10, 2); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('productos'); + } +}; diff --git a/routes/api.php b/routes/api.php index ccc387f..8155e77 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,8 +1,11 @@ user(); })->middleware('auth:sanctum'); + +Route::apiResource('productos', ProductController::class);