diff --git a/README.md b/README.md
index f1b5d35..779f1a0 100644
--- a/README.md
+++ b/README.md
@@ -610,363 +610,6 @@ Dashboard mejorado con:
- Reportes consolidados
```
-## 馃敡 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');
- });
-}
-```
-
## 馃悰 Issues Conocidos y Soluciones
### 1. Select2 no se inicializa en filas din谩micas
@@ -1096,7 +739,7 @@ Este proyecto est谩 bajo la Licencia MIT. Ver archivo `LICENSE` para detalles.
---
-**Versi贸n**: 2.0.0
+**Versi贸n**: 0.2.0
**Estado**: En desarrollo activo 馃毀
**脷ltima actualizaci贸n**: Enero 2026
diff --git a/RECOMENDACIONES.md b/RECOMENDACIONES.md
new file mode 100644
index 0000000..82eb622
--- /dev/null
+++ b/RECOMENDACIONES.md
@@ -0,0 +1,356 @@
+## 馃敡 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');
+ });
+}
+```
\ No newline at end of file