Feat/parapharmacy api #38
@@ -29,9 +29,11 @@ A web application to search for medicines from the official Spanish CIMA databas
|
|||||||
|
|
||||||
| App | Stack |
|
| App | Stack |
|
||||||
|-----|-------|
|
|-----|-------|
|
||||||
| Backend | Node.js + Express, SQLite, Redis |
|
| Backend | Node.js + Express, SQLite/PostgreSQL, Redis |
|
||||||
|
| Parapharmacy API | Node.js + Express, MongoDB |
|
||||||
| Frontend (Web) | React + Vite, Capacitor |
|
| Frontend (Web) | React + Vite, Capacitor |
|
||||||
| Frontend (Mobile) | Expo SDK 57 + React Native, Zustand, Axios + TanStack Query |
|
| Frontend (Mobile) | Expo SDK 57 + React Native, Zustand, Axios + TanStack Query |
|
||||||
|
| Workflow Automation | N8N |
|
||||||
| Build system | Turborepo |
|
| Build system | Turborepo |
|
||||||
| Package manager | npm workspaces |
|
| Package manager | npm workspaces |
|
||||||
|
|
||||||
@@ -50,10 +52,11 @@ This is a **Turborepo monorepo**. All applications live under `apps/`:
|
|||||||
FarmaFinder/
|
FarmaFinder/
|
||||||
├── package.json # Root: workspaces + turbo scripts
|
├── package.json # Root: workspaces + turbo scripts
|
||||||
├── turbo.json # Turborepo task configuration
|
├── turbo.json # Turborepo task configuration
|
||||||
├── docker-compose.yml # Full stack: backend + frontend + Redis + Postgres
|
├── docker-compose.yml # Full stack: backend + frontend + Redis + Postgres + MongoDB + N8N
|
||||||
|
├── .env.example # Environment variables template
|
||||||
│
|
│
|
||||||
├── apps/
|
├── apps/
|
||||||
│ ├── backend/ # Node.js + Express API
|
│ ├── backend/ # Node.js + Express API (medicines)
|
||||||
│ │ ├── Dockerfile
|
│ │ ├── Dockerfile
|
||||||
│ │ ├── server.js # Express server and API routes
|
│ │ ├── server.js # Express server and API routes
|
||||||
│ │ ├── cima-service.js # CIMA API integration with Redis cache
|
│ │ ├── cima-service.js # CIMA API integration with Redis cache
|
||||||
@@ -62,6 +65,18 @@ FarmaFinder/
|
|||||||
│ │ ├── create-admin.js # Admin user creation script
|
│ │ ├── create-admin.js # Admin user creation script
|
||||||
│ │ └── package.json
|
│ │ └── package.json
|
||||||
│ │
|
│ │
|
||||||
|
│ ├── parapharmacy-api/ # Parapharmacy products API
|
||||||
|
│ │ ├── Dockerfile
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── server.js # Express + Swagger
|
||||||
|
│ │ │ ├── config.js # Configuration
|
||||||
|
│ │ │ ├── models/
|
||||||
|
│ │ │ │ └── Product.js
|
||||||
|
│ │ │ └── routes/
|
||||||
|
│ │ │ └── products.js
|
||||||
|
│ │ ├── README.md
|
||||||
|
│ │ └── package.json
|
||||||
|
│ │
|
||||||
│ ├── frontend/ # React + Vite (Desktop/PWA)
|
│ ├── frontend/ # React + Vite (Desktop/PWA)
|
||||||
│ │ ├── Dockerfile
|
│ │ ├── Dockerfile
|
||||||
│ │ ├── nginx.conf # Nginx config for Docker
|
│ │ ├── nginx.conf # Nginx config for Docker
|
||||||
@@ -79,7 +94,7 @@ FarmaFinder/
|
|||||||
│ │ ├── store/
|
│ │ ├── store/
|
||||||
│ │ └── package.json
|
│ │ └── package.json
|
||||||
│ │
|
│ │
|
||||||
│ ├── scraper/ # Puppeteer scraper (standalone)
|
│ ├── scraper/ # Puppeteer scraper (legacy)
|
||||||
│ │ └── package.json
|
│ │ └── package.json
|
||||||
│ │
|
│ │
|
||||||
│ └── pip-platform/ # Python FastAPI platform (separate docker-compose)
|
│ └── pip-platform/ # Python FastAPI platform (separate docker-compose)
|
||||||
@@ -87,11 +102,29 @@ FarmaFinder/
|
|||||||
│ ├── docker-compose.yml
|
│ ├── docker-compose.yml
|
||||||
│ └── pyproject.toml
|
│ └── pyproject.toml
|
||||||
│
|
│
|
||||||
|
├── n8n/ # N8N workflow automation
|
||||||
|
│ ├── workflows/ # Workflow JSON files
|
||||||
|
│ │ ├── parapharmacy-scraper.json
|
||||||
|
│ │ └── parapharmacy-manual-scraper.json
|
||||||
|
│ └── README.md
|
||||||
|
│
|
||||||
├── API/ # Shared API source files
|
├── API/ # Shared API source files
|
||||||
├── scripts/ # Build/utility scripts
|
├── scripts/ # Build/utility scripts
|
||||||
└── docs/ # Documentation
|
└── docs/ # Documentation
|
||||||
|
└── parapharmacy.md # Parapharmacy system documentation
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Parapharmacy Search
|
||||||
|
- Scraping de múltiples tiendas españolas (Promofarma, Pharmarket, DocMorris, etc.)
|
||||||
|
- API REST dedicada con MongoDB
|
||||||
|
- Scraping automático cada 3 días via N8N
|
||||||
|
- Búsqueda full-text por nombre, marca y categoría
|
||||||
|
- [Documentación completa](docs/parapharmacy.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### Install dependencies
|
### Install dependencies
|
||||||
@@ -141,34 +174,53 @@ npm test --workspace=farma-clic-frontend
|
|||||||
|
|
||||||
## Docker Setup
|
## Docker Setup
|
||||||
|
|
||||||
Runs the full stack (backend, frontend, Redis, Postgres) with a single command.
|
Runs the full stack with a single command.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Copy and configure environment (optional - defaults work for local dev)
|
# Copy and configure environment
|
||||||
cp apps/backend/.env.example apps/backend/.env
|
cp .env.example .env
|
||||||
|
# Edit .env with your settings (especially passwords)
|
||||||
|
|
||||||
docker compose up --build
|
docker compose up --build
|
||||||
```
|
```
|
||||||
|
|
||||||
App available at `http://localhost:4000` (frontend) and `http://localhost:3001` (backend API).
|
### Services
|
||||||
|
|
||||||
|
| Service | URL | Description |
|
||||||
|
|---------|-----|-------------|
|
||||||
|
| Frontend | http://localhost:4000 | React web app |
|
||||||
|
| Backend API | http://localhost:3001 | Medicines API |
|
||||||
|
| Parapharmacy API | http://localhost:3002 | Parapharmacy products API |
|
||||||
|
| Swagger Docs | http://localhost:3002/api/docs | API documentation |
|
||||||
|
| N8N | http://localhost:5678 | Workflow automation |
|
||||||
|
|
||||||
|
### First Run
|
||||||
|
|
||||||
**First run - create an admin user:**
|
|
||||||
```bash
|
```bash
|
||||||
|
# Create admin user for FarmaFinder
|
||||||
docker compose exec backend node create-admin.js
|
docker compose exec backend node create-admin.js
|
||||||
# Default: admin / admin123 - change after first login
|
# Default: admin / admin123
|
||||||
```
|
|
||||||
|
|
||||||
**Seed sample pharmacies:**
|
# Seed sample pharmacies
|
||||||
```bash
|
|
||||||
docker compose exec backend node seed.js
|
docker compose exec backend node seed.js
|
||||||
```
|
```
|
||||||
|
|
||||||
**Stop:**
|
### N8N Setup
|
||||||
|
|
||||||
|
N8N auto-creates an admin account on first start:
|
||||||
|
- **Email**: admin@farmafinder.com
|
||||||
|
- **Password**: change-me (configurable in `.env`)
|
||||||
|
|
||||||
|
See [Parapharmacy Documentation](docs/parapharmacy.md) for details.
|
||||||
|
|
||||||
|
### Stop
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose down
|
docker compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
Database is persisted in named Docker volumes (`backend_data`, `postgres_data`). To wipe:
|
### Reset Data
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose down -v
|
docker compose down -v
|
||||||
```
|
```
|
||||||
@@ -225,18 +277,26 @@ npm run dev
|
|||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
### Public
|
### Medicines (Backend - Port 3001)
|
||||||
- `GET /api/medicines/search?q=<query>` - Search medicines (CIMA API, cached in Redis)
|
|
||||||
|
**Public:**
|
||||||
|
- `GET /api/medicines/search?q=<query>` - Search medicines (CIMA API)
|
||||||
- `GET /api/medicines/:nregistro` - Medicine details
|
- `GET /api/medicines/:nregistro` - Medicine details
|
||||||
- `GET /api/medicines/:nregistro/pharmacies` - Pharmacies selling a medicine
|
- `GET /api/medicines/:nregistro/pharmacies` - Pharmacies selling a medicine
|
||||||
- `GET /api/pharmacies` - All pharmacies
|
- `GET /api/pharmacies` - All pharmacies
|
||||||
|
|
||||||
### Auth
|
**Parapharmacy Proxy:**
|
||||||
|
- `GET /api/products/parapharmacy/search?q=<query>` - Search parapharmacy products
|
||||||
|
- `GET /api/products/parapharmacy/:id` - Parapharmacy product details
|
||||||
|
- `GET /api/products/parapharmacy/categories` - List categories
|
||||||
|
- `GET /api/products/parapharmacy/brands` - List brands
|
||||||
|
|
||||||
|
**Auth:**
|
||||||
- `POST /api/auth/login` - Login
|
- `POST /api/auth/login` - Login
|
||||||
- `POST /api/auth/logout` - Logout
|
- `POST /api/auth/logout` - Logout
|
||||||
- `GET /api/auth/check` - Check auth status
|
- `GET /api/auth/check` - Check auth status
|
||||||
|
|
||||||
### Admin (requires authentication)
|
**Admin:**
|
||||||
- `POST /api/admin/pharmacies` - Add pharmacy
|
- `POST /api/admin/pharmacies` - Add pharmacy
|
||||||
- `PUT /api/admin/pharmacies/:id` - Update pharmacy
|
- `PUT /api/admin/pharmacies/:id` - Update pharmacy
|
||||||
- `DELETE /api/admin/pharmacies/:id` - Delete pharmacy
|
- `DELETE /api/admin/pharmacies/:id` - Delete pharmacy
|
||||||
@@ -246,6 +306,23 @@ npm run dev
|
|||||||
- `PUT /api/admin/pharmacy-medicines/:id` - Update price/stock
|
- `PUT /api/admin/pharmacy-medicines/:id` - Update price/stock
|
||||||
- `DELETE /api/admin/pharmacy-medicines/:id` - Remove link
|
- `DELETE /api/admin/pharmacy-medicines/:id` - Remove link
|
||||||
|
|
||||||
|
### Parapharmacy API (Port 3002)
|
||||||
|
|
||||||
|
- `GET /api/products/search?q=<query>` - Search products (full-text)
|
||||||
|
- `GET /api/products/:id` - Product details
|
||||||
|
- `GET /api/products` - List products
|
||||||
|
- `POST /api/products` - Create product
|
||||||
|
- `POST /api/products/bulk` - Bulk upsert (for scrapers)
|
||||||
|
- `PUT /api/products/:id` - Update product
|
||||||
|
- `DELETE /api/products/:id` - Delete product
|
||||||
|
- `GET /api/products/categories` - List categories
|
||||||
|
- `GET /api/products/brands` - List brands
|
||||||
|
- `GET /api/sources` - Configured sources
|
||||||
|
- `GET /api/health` - Health check
|
||||||
|
- `GET /api/docs` - Swagger documentation
|
||||||
|
|
||||||
|
See [Parapharmacy Documentation](docs/parapharmacy.md) for details.
|
||||||
|
|
||||||
## Database Schema
|
## Database Schema
|
||||||
|
|
||||||
### SQLite Tables
|
### SQLite Tables
|
||||||
@@ -320,6 +397,32 @@ const ENV = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## N8N Workflow Automation
|
||||||
|
|
||||||
|
N8N handles automated scraping of parapharmacy products.
|
||||||
|
|
||||||
|
### Access
|
||||||
|
- **URL**: http://localhost:5678
|
||||||
|
- **Email**: admin@farmafinder.com
|
||||||
|
- **Password**: change-me (change in `.env`)
|
||||||
|
|
||||||
|
### Workflows
|
||||||
|
|
||||||
|
| Workflow | Trigger | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| Parapharmacy Scraper | Every 3 days at 2am | Automatic scraping (inactive by default) |
|
||||||
|
| Parapharmacy Manual Scraper | POST `/webhook/scrape-parapharmacy` | On-demand scraping |
|
||||||
|
|
||||||
|
### Manual Scraping
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:5678/webhook/scrape-parapharmacy
|
||||||
|
```
|
||||||
|
|
||||||
|
See [N8N Documentation](n8n/README.md) for details.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Redis Connection Issues
|
### Redis Connection Issues
|
||||||
|
|||||||
@@ -0,0 +1,347 @@
|
|||||||
|
# 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
|
||||||
Reference in New Issue
Block a user