# FarmaFinder Parapharmacy System Sistema completo de búsqueda de productos de parafarmacia mediante scraping de múltiples tiendas españolas. ## Arquitectura ``` ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │ N8N Workflows │────▶│ Parapharmacy │────▶│ MongoDB │ │ (Scraper) │ │ API (Express) │ │ │ └─────────────────┘ └────────┬─────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ FarmaFinder │ │ Backend │ └─────────────────┘ ``` ## Componentes | Componente | Puerto | Descripción | |------------|--------|-------------| | Parapharmacy API | 3002 | API REST para productos de parafarmacia | | MongoDB | 27017 | Base de datos de productos | | N8N | 5678 | Automatización de workflows y scraping | --- ## Parapharmacy API ### Endpoints | Método | Ruta | Descripción | |--------|------|-------------| | GET | `/api/products/search?q=term` | Buscar productos (full-text) | | GET | `/api/products/:id` | Detalle de producto | | GET | `/api/products` | Listar productos (con filtros) | | POST | `/api/products` | Crear producto | | POST | `/api/products/bulk` | Crear/actualizar múltiples (para scraper) | | PUT | `/api/products/:id` | Actualizar producto | | DELETE | `/api/products/:id` | Eliminar producto | | GET | `/api/products/categories` | Listar categorías | | GET | `/api/products/brands` | Listar marcas | | GET | `/api/sources` | Fuentes configuradas | | GET | `/api/health` | Health check | | GET | `/api/docs` | Swagger UI | ### Ejemplo de Búsqueda ```bash # Buscar "capricare" curl "http://localhost:3002/api/products/search?q=capricare" # Buscar con filtros curl "http://localhost:3002/api/products/search?q=crema&category=dermocosmetica&brand=bioderma" ``` ### Respuesta ```json { "results": [ { "_id": "...", "name": "Capricare 1 Leche en polvo", "brand": "Capricare", "category": "Fórmulas lácteas", "price": 12.99, "original_price": 14.99, "image_url": "https://...", "source": "promofarma", "source_url": "https://promofarma.com/..." } ], "total": 5, "page": 1, "pages": 1 } ``` ### Schema MongoDB ```javascript { name: String, // Nombre del producto brand: String, // Marca category: String, // Categoría principal subcategory: String, // Subcategoría description: String, // Descripción image_url: String, // URL de la imagen source_url: String, // URL en la tienda original price: Number, // Precio actual original_price: Number, // Precio anterior (si hay descuento) currency: String, // EUR por defecto source: String, // 'promofarma', 'pharmarket', etc. source_product_id: String, available: Boolean, // Disponible actualmente rating: Number, // Valoración (0-5) review_count: Number, scraped_at: Date, // Cuándo se scrappeó created_at: Date, updated_at: Date } ``` --- ## N8N Configuration ### Cuenta de Administrador Al iniciar N8N por primera vez, se crea automáticamente una cuenta de administrador: | Campo | Valor | |-------|-------| | **Email** | admin@farmafinder.com | | **Password** | change-me | > **IMPORTANTE**: Cambia la contraseña después del primer login. ### Variables de Entorno (`.env`) ```bash # N8N Configuration N8N_USER=admin N8N_PASSWORD=change-me N8N_EMAIL=admin@farmafinder.com # Parapharmacy API PARAPHARMACY_API_URL=http://parapharmacy-api:3002 MONGODB_URI=mongodb://mongodb:27017/parapharmacy ``` ### Acceso a N8N - **URL**: http://localhost:5678 - **Email**: admin@farmafinder.com - **Password**: change-me --- ## Workflows de Scraping ### 1. Parapharmacy Scraper (Automático) - **Trigger**: Cada 3 días a las 2:00 AM - **Estado**: Inactivo por defecto - **Función**: Scraping automático de Promofarma **Para activar:** 1. Ir a http://localhost:5678/workflows 2. Abrir "Parapharmacy Scraper" 3. Hacer clic en "Active" toggle ### 2. Parapharmacy Manual Scraper (Webhook) - **Trigger**: POST a `/webhook/scrape-parapharmacy` - **Estado**: Activo por defecto - **Función**: Scraping bajo demanda **Uso:** ```bash # Scraping con queries por defecto curl -X POST http://localhost:5678/webhook/scrape-parapharmacy # Scraping con queries específicas curl -X POST http://localhost:5678/webhook/scrape-parapharmacy \ -H "Content-Type: application/json" \ -d '{"queries": ["crema hidratante", "protector solar"]}' ``` --- ## Fuentes de Scraping | Fuente | URL | Estado | |--------|-----|--------| | Promofarma | promofarma.com | ✅ Implementado | | Pharmarket | pharmarket.es | 🔄 Pendiente | | DocMorris | docmorris.es | 🔄 Pendiente | | 1001Farma | 1001farma.net | 🔄 Pendiente | | Primor | primor.eu | 🔄 Pendiente | | MiFarma | mifarma.es | 🔄 Pendiente | --- ## Integración con FarmaFinder Backend El backend principal proxies las peticiones a la API de parafarmacia: ### Endpoints Proxy | Método | Ruta | Descripción | |--------|------|-------------| | GET | `/api/products/parapharmacy/search` | Buscar productos | | GET | `/api/products/parapharmacy/:id` | Detalle de producto | | GET | `/api/products/parapharmacy/categories` | Categorías | | GET | `/api/products/parapharmacy/brands` | Marcas | ### Ejemplo desde Frontend ```javascript // Buscar productos de parafarmacia const response = await fetch('/api/products/parapharmacy/search?q=capricare'); const data = await response.json(); // data.results = [{ name: "Capricare...", price: 12.99, ... }] ``` --- ## Docker Setup ### Servicios ```yaml services: parapharmacy-api: # Puerto 3002 mongodb: # Puerto 27017 n8n: # Puerto 5678 ``` ### Iniciar ```bash # Todos los servicios docker-compose up -d # Solo parafarmacia docker-compose up -d parapharmacy-api mongodb n8n # Ver logs docker-compose logs -f parapharmacy-api docker-compose logs -f n8n ``` ### Detener ```bash docker-compose down ``` ### Limpiar datos ```bash # Eliminar volumes (borra datos) docker-compose down -v ``` --- ## Troubleshooting ### N8N muestra página /setup Verifica que las variables de entorno estén configuradas: ```bash N8N_OWNER_EMAIL=admin@farmafinder.com N8N_OWNER_PASSWORD=change-me ``` ### Webhook no funciona 1. Verifica que el workflow esté activo en N8N 2. Revisa el historial de ejecuciones: http://localhost:5678/executions 3. Revisa logs: `docker logs n8n` ### Productos no se guardan 1. Verifica que parapharmacy-api esté ejecutándose 2. Revisa logs: `docker logs parapharmacy-api` 3. Verifica que MongoDB esté conectado 4. Prueba el health check: `curl http://localhost:3002/api/health` ### MongoDB no conecta ```bash # Verificar que MongoDB está corriendo docker-compose ps mongodb # Ver logs docker-compose logs mongodb # Reiniciar docker-compose restart mongodb ``` ### API devuelve error 500 ```bash # Ver logs de la API docker-compose logs parapharmacy-api # Verificar conexión a MongoDB docker-compose exec mongodb mongosh --eval "db.adminCommand('ping')" ``` --- ## Desarrollo ### Estructura de Archivos ``` apps/parapharmacy-api/ ├── src/ │ ├── server.js # Express + Swagger │ ├── config.js # Configuración │ ├── models/ │ │ └── Product.js # Schema MongoDB │ └── routes/ │ └── products.js # Endpoints ├── Dockerfile ├── package.json └── README.md n8n/ ├── workflows/ │ ├── parapharmacy-scraper.json │ └── parapharmacy-manual-scraper.json └── README.md ``` ### Ejecutar en Desarrollo ```bash # API cd apps/parapharmacy-api npm run dev # MongoDB (necesario) docker run -d -p 27017:27017 mongo:7 ``` ### Tests ```bash cd apps/parapharmacy-api npm test ``` ### Swagger Docs Acceso a documentación interactiva: http://localhost:3002/api/docs