## 馃敡 Mejoras T茅cnicas Recomendadas ### Optimizaci贸n de Rendimiento #### 1. Implementar Cach茅 Estrat茅gico ```php // ProductosController.php public function index(Request $request) { $cacheKey = 'products.' . md5(serialize($request->all())); $products = Cache::remember($cacheKey, 300, function () use ($request) { return Product::query() ->when($request->search, fn($q, $term) => $q->where('name', 'like', "%{$term}%") ) ->paginate(10); }); } // Limpiar cach茅 al modificar productos Cache::forget('products.*'); ``` #### 2. Eager Loading para Relaciones ```php // Evitar N+1 queries $sales = Sale::with(['client', 'details.product']) ->latest() ->paginate(15); // En lugar de: $sales = Sale::all(); // Genera queries adicionales ``` #### 3. 脥ndices de Base de Datos ```php // En migraciones Schema::table('products', function (Blueprint $table) { $table->index('sku'); $table->index('type'); $table->index(['stock_quantity', 'min_stock_alert']); }); Schema::table('sales', function (Blueprint $table) { $table->index('created_at'); $table->index(['client_id', 'created_at']); }); ``` #### 4. Paginaci贸n con Cursor ```php // Para datasets grandes $products = Product::latest()->cursorPaginate(20); ``` ### Refactorizaci贸n de C贸digo #### 1. Services para L贸gica de Negocio ```php // app/Services/SaleService.php class SaleService { public function processSale(array $data): Sale { return DB::transaction(function () use ($data) { $sale = Sale::create([...]); foreach ($data['items'] as $item) { $this->addItem($sale, $item); } return $sale; }); } private function addItem(Sale $sale, array $item): void { $product = Product::findOrFail($item['product_id']); if ($product->stock_quantity < $item['quantity']) { throw new InsufficientStockException(); } SaleDetail::create([...]); $product->decrement('stock_quantity', $item['quantity']); } } ``` #### 2. Form Request Validation ```php // app/Http/Requests/StoreSaleRequest.php class StoreSaleRequest extends FormRequest { public function rules(): array { return [ 'client_id' => 'nullable|exists:clients,id', 'payment_method' => 'required|string', 'items' => 'required|array|min:1', 'items.*.product_id' => 'required|exists:products,id', 'items.*.quantity' => 'required|integer|min:1', ]; } public function messages(): array { return [ 'items.required' => 'Debe agregar al menos un producto.', 'items.*.quantity.min' => 'La cantidad debe ser mayor a 0.', ]; } } // En el controlador public function store(StoreSaleRequest $request) { // $request ya est谩 validado } ``` #### 3. Repository Pattern ```php // app/Repositories/ProductRepository.php interface ProductRepositoryInterface { public function search(string $term): Collection; public function lowStock(): Collection; public function byType(string $type): Collection; } class ProductRepository implements ProductRepositoryInterface { public function search(string $term): Collection { return Product::where('name', 'like', "%{$term}%") ->orWhere('sku', 'like', "%{$term}%") ->get(); } } // Registrar en AppServiceProvider $this->app->bind( ProductRepositoryInterface::class, ProductRepository::class ); ``` #### 4. Policies para Autorizaci贸n ```php // app/Policies/ProductPolicy.php class ProductPolicy { public function viewAny(User $user): bool { return in_array($user->role, ['admin', 'employee']); } public function create(User $user): bool { return $user->role === 'admin'; } public function update(User $user, Product $product): bool { return $user->role === 'admin'; } public function delete(User $user, Product $product): bool { return $user->role === 'admin'; } } // En controlador $this->authorize('create', Product::class); ``` ### Mejoras de Seguridad #### 1. Rate Limiting Espec铆fico ```php // routes/web.php Route::post('/sales', [SaleController::class, 'store']) ->middleware(['auth', 'throttle:sales']); // app/Providers/RouteServiceProvider.php RateLimiter::for('sales', function (Request $request) { return Limit::perMinute(10)->by($request->user()?->id); }); ``` #### 2. Sanitizaci贸n de Inputs ```php // En Form Request protected function prepareForValidation() { $this->merge([ 'name' => strip_tags($this->name), 'description' => Purifier::clean($this->description), ]); } ``` #### 3. Protecci贸n CSRF Expl铆cita ```php // Verificar en AJAX $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); ``` #### 4. Validaci贸n de Im谩genes ```php 'image' => [ 'nullable', 'image', 'mimes:jpeg,png,jpg,webp', 'max:2048', // 2MB 'dimensions:min_width=100,min_height=100,max_width=2000,max_height=2000' ] ``` ### Mejoras de UI/UX #### 1. Loading States ```blade ``` #### 2. Confirmaciones Elegantes ```javascript // Usar SweetAlert2 Swal.fire({ title: '驴Eliminar producto?', text: "Esta acci贸n no se puede revertir", icon: 'warning', showCancelButton: true, confirmButtonColor: '#ccff00', cancelButtonColor: '#d33', confirmButtonText: 'S铆, eliminar', cancelButtonText: 'Cancelar' }).then((result) => { if (result.isConfirmed) { // Ejecutar eliminaci贸n } }); ``` #### 3. Toast Notifications ```javascript // Mensajes no intrusivos const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000 }); Toast.fire({ icon: 'success', title: 'Producto guardado' }); ``` #### 4. Validaci贸n en Tiempo Real ```javascript $('input[name="sku"]').on('blur', function() { const sku = $(this).val(); $.get(`/api/products/check-sku/${sku}`, function(data) { if (data.exists) { // Mostrar error $(this).addClass('border-red-500'); } }); }); ``` ### Testing #### 1. Tests de Feature ```php // tests/Feature/ProductTest.php public function test_admin_can_create_product() { $admin = User::factory()->create(['role' => 'admin']); $this->actingAs($admin) ->post('/productos', [ 'name' => 'Test Product', 'price' => 100, 'stock_quantity' => 10, 'min_stock_alert' => 5, 'type' => 'accessory' ]) ->assertRedirect('/productos') ->assertSessionHas('success'); $this->assertDatabaseHas('products', [ 'name' => 'Test Product' ]); } public function test_guest_cannot_create_product() { $response = $this->post('/productos', []); $response->assertRedirect('/login'); } ``` #### 2. Tests Unitarios ```php // tests/Unit/ProductTest.php public function test_product_has_low_stock() { $product = Product::factory()->create([ 'stock_quantity' => 3, 'min_stock_alert' => 5 ]); $this->assertTrue($product->hasLowStock()); } ``` #### 3. Browser Tests (Dusk) ```php // tests/Browser/PosTest.php public function test_can_complete_sale() { $this->browse(function (Browser $browser) { $browser->loginAs(User::find(1)) ->visit('/sales/create') ->select('items[0][product_id]', 1) ->type('items[0][quantity]', 2) ->press('Confirmar Venta') ->assertPathIs('/sales/1'); }); } ```