# US-MGN-005-001-001: Crear Producto

**RF Asociado:** [RF-MGN-005-001](../../02-modelado/requerimientos-funcionales/mgn-005/RF-MGN-005-001-gestión-de-productos.md)
**Módulo:** MGN-005 - Inventario Básico
**Epic:** Gestión de Productos
**Prioridad:** P0
**Story Points:** 5
**Sprint:** Sprint 9
**Estado:** Ready for Development
**Fecha:** 2025-11-24

---

## User Story

**Como** usuario de inventario,
**Quiero** crear productos con sus características básicas (SKU, nombre, tipo, categoría, UoM),
**Para** gestionar el catálogo de productos de la empresa.

---

## Descripción Detallada

Un producto representa cualquier bien o servicio que la empresa maneja. Los productos pueden ser de tres tipos:
- **Storable:** Productos almacenables que mantienen stock físico
- **Consumable:** Productos consumibles que no mantienen stock controlado
- **Service:** Servicios que no tienen existencia física

Cada producto debe tener un SKU único por empresa, categoría, unidad de medida (UoM), y puede tener cuentas contables asociadas para valoración de inventario.

---

## Criterios de Aceptación

### Escenario 1: Crear producto almacenable válido (Camino Feliz)
**Dado que** soy usuario con permiso inventory_user,
**Cuando** creo un producto con type="storable", sku="PROD-001", name="Laptop HP", category_id=1, uom_id=1,
**Entonces** el sistema crea el producto exitosamente y retorna el ID y datos completos.

### Escenario 2: Validar SKU único por empresa
**Dado que** ya existe un producto con sku="PROD-001" en mi empresa,
**Cuando** intento crear otro producto con el mismo SKU,
**Entonces** el sistema retorna error 400 "El SKU PROD-001 ya está en uso en esta empresa".

### Escenario 3: Crear producto consumible
**Dado que** creo un producto con type="consumable",
**Cuando** envío el request,
**Entonces** el sistema crea el producto sin gestión de stock (stock no controlado).

### Escenario 4: Crear producto de servicio
**Dado que** creo un producto con type="service", sku="SERV-001", name="Consultoría IT",
**Cuando** envío el request,
**Entonces** el sistema crea el producto de tipo servicio sin stock.

### Escenario 5: Validar campos requeridos
**Dado que** intento crear un producto sin name o sin sku,
**Cuando** envío el request,
**Entonces** el sistema retorna error 400 con la lista de campos requeridos faltantes.

### Escenario 6: Validar tipo de producto
**Dado que** intento crear un producto con type="invalid",
**Cuando** envío el request,
**Entonces** el sistema retorna error 400 "Tipo de producto inválido. Valores permitidos: storable, consumable, service".

---

## Reglas de Negocio

- **RN-1:** SKU es único por empresa (constraint a nivel DB).
- **RN-2:** Tipos de producto permitidos: storable, consumable, service.
- **RN-3:** Solo productos storable mantienen control de stock.
- **RN-4:** Productos tienen categoría obligatoria (product_category).
- **RN-5:** Productos tienen UoM (unidad de medida) obligatoria.
- **RN-6:** Productos pueden tener cuentas contables asociadas (income_account, expense_account).
- **RN-7:** Productos activos por defecto (active=true).
- **RN-8:** RLS filtra productos por empresa.

---

## Tareas Técnicas

### Backend
- [ ] Endpoint: POST /api/v1/inventory/products
- [ ] Service: ProductService.create(createProductDto)
- [ ] Service: ProductService.validateUniqueSKU(sku, companyId)
- [ ] DTO: CreateProductDto (sku, name, type, category_id, uom_id, description, active, cost_price, sale_price)
- [ ] Validar SKU único por empresa
- [ ] Validar tipo de producto (enum: storable, consumable, service)
- [ ] Validar categoría existe
- [ ] Validar UoM existe
- [ ] Unit tests (>80% coverage)
- [ ] Integration tests
- [ ] Swagger docs

### Frontend
- [ ] Componente: CreateProductForm.tsx
- [ ] Página: CreateProductPage.tsx (/inventory/products/create)
- [ ] Formulario con validaciones
- [ ] Selector de tipo de producto
- [ ] Selector de categoría
- [ ] Selector de UoM
- [ ] API client: productApi.create(data)
- [ ] State management: useProductStore
- [ ] Component tests
- [ ] E2E test: "should create product successfully"

### Database
- [ ] Tabla: inventory.products
- [ ] Índices: idx_products_company_id, idx_products_sku, idx_products_category_id
- [ ] Constraint: uq_products_sku_company (SKU único por empresa)
- [ ] RLS policy: company_isolation_products

---

## Mockups / Wireframes

**Formulario Crear Producto:**
```
┌─────────────────────────────────────────────┐
│ Crear Producto                             │
├─────────────────────────────────────────────┤
│ SKU: [Input: PROD-001] *                   │
│ Nombre: [Input: Laptop HP] *               │
│ Tipo: [Select: Storable ▼] *              │
│      Options: Storable, Consumable, Service│
│ Categoría: [Select: Electrónica ▼] *      │
│ UoM: [Select: Unidad ▼] *                 │
│ Descripción: [TextArea]                    │
│                                             │
│ Precio de Costo: [Input: 0.00]            │
│ Precio de Venta: [Input: 0.00]            │
│                                             │
│ Activo: [✓] Checkbox                       │
├─────────────────────────────────────────────┤
│ [Guardar]  [Cancelar]                      │
└─────────────────────────────────────────────┘
```

**Estados:**
- Loading: Spinner mientras se guarda
- Success: Mensaje "Producto creado exitosamente" y redirección a vista del producto
- Error: Mensaje de error inline con detalles

---

## Casos de Prueba

### Funcionales
1. **TC-001:** Crear producto storable exitosamente
2. **TC-002:** Crear producto consumable exitosamente
3. **TC-003:** Crear producto service exitosamente
4. **TC-004:** Error por SKU duplicado en misma empresa
5. **TC-005:** Error por tipo de producto inválido
6. **TC-006:** Error por campos requeridos faltantes
7. **TC-007:** Validar categoría existe
8. **TC-008:** Validar UoM existe
9. **TC-009:** RLS filtra por empresa

### No Funcionales
1. **Performance:** < 300ms para crear producto
2. **Seguridad:** JWT + permiso inventory_user

---

## Dependencias

- **US bloqueantes:**
  - US-MGN-003-004-001 (CRUD Categorías de Productos)
  - US-MGN-003-005-001 (CRUD UoM)
- **Módulos requeridos:** MGN-001, MGN-002, MGN-003
- **Datos maestros:** Categorías, UoM

---

## Notas de Implementación

- SKU debe ser alfanumérico, sin espacios
- Tipo de producto es ENUM a nivel DB
- Productos storable tendrán gestión de stock en otras US
- Considerar agregar campo tracking (none, lot, serial) para trazabilidad futura
- Frontend: Usar react-hook-form para formulario

---

## Estimación Detallada

| Tarea | Horas |
|-------|-------|
| Backend | 2.5 |
| Frontend | 2.5 |
| Testing | 2 |
| Code Review | 1 |
| **TOTAL** | **8 horas = 5 SP** |

---

## Definition of Done

- [ ] Código implementado según ET
- [ ] Tests pasando (>80%)
- [ ] Code review aprobado
- [ ] Documentación actualizada
- [ ] Swagger docs completo
- [ ] RLS aplicado
- [ ] QA validado
- [ ] PO aprobado

---

## Referencias

- [RF-MGN-005-001](../../02-modelado/requerimientos-funcionales/mgn-005/RF-MGN-005-001-gestión-de-productos.md)
- [ET Backend](../../02-modelado/especificaciones-tecnicas/backend/mgn-005/ET-BACKEND-MGN-005-001-gestión-de-productos.md)
- [ET Frontend](../../02-modelado/especificaciones-tecnicas/frontend/mgn-005/ET-FRONTEND-MGN-005-001-gestión-de-productos.md)
- [Traceability](../../02-modelado/trazabilidad/TRACEABILITY-MGN-005.yaml)
- [Schema](../../02-modelado/database-design/schemas/inventory-schema-ddl.sql)
