- Frontend now searches both CIMA and Parapharmacy simultaneously - Removed filter tabs (Todos/Medicamentos/Parafarmacia) - Results show in a single unified list - Mobile: Shows medicines first, then parapharmacy section - Web: Same unified approach with results summary
FarmaFinder
A web application to search for medicines from the official Spanish CIMA database and find which pharmacies sell them.
Features
Web App (Desktop/PWA)
- Real-time medicine search from CIMA API (Agencia Espanola de Medicamentos)
- Redis caching for improved performance
- View pharmacies that sell a specific medicine
- See prices and stock availability
- Responsive design for mobile and desktop
- Admin Panel - Manage pharmacies and link medicines
- Secure authentication - Login required to access admin features
- Add, edit, and delete pharmacies
- Search medicines from CIMA database
- Link medicines to pharmacies with prices and stock
Mobile App (React Native)
- Native iOS/Android experience with Expo
- Medicine search with real-time results
- Interactive map with pharmacy markers
- Barcode scanner for quick medicine lookup
- Push notifications for availability alerts
- Biometric authentication (Face ID / Touch ID)
- Offline cache for favorite medicines
Tech Stack
| App | Stack |
|---|---|
| Backend | Node.js + Express, SQLite/PostgreSQL, Redis |
| Parapharmacy API | Node.js + Express, MongoDB |
| Frontend (Web) | React + Vite, Capacitor |
| Frontend (Mobile) | Expo SDK 57 + React Native, Zustand, Axios + TanStack Query |
| Workflow Automation | N8N |
| Build system | Turborepo |
| Package manager | npm workspaces |
Prerequisites
- Node.js v20+
- npm v9+
- Redis server v6.0+ (or use Docker)
- Docker + Docker Compose v2 (optional, for containerized deployment)
Project Structure
This is a Turborepo monorepo. All applications live under apps/:
FarmaFinder/
├── package.json # Root: workspaces + turbo scripts
├── turbo.json # Turborepo task configuration
├── docker-compose.yml # Full stack: backend + frontend + Redis + Postgres + MongoDB + N8N
├── .env.example # Environment variables template
│
├── apps/
│ ├── backend/ # Node.js + Express API (medicines)
│ │ ├── Dockerfile
│ │ ├── server.js # Express server and API routes
│ │ ├── cima-service.js # CIMA API integration with Redis cache
│ │ ├── redis-client.js # Redis connection configuration
│ │ ├── seed.js # Database seeding script
│ │ ├── create-admin.js # Admin user creation script
│ │ └── 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)
│ │ ├── Dockerfile
│ │ ├── nginx.conf # Nginx config for Docker
│ │ ├── src/
│ │ │ ├── components/ # React components
│ │ │ ├── views/ # View components (Public/Admin)
│ │ │ ├── App.jsx
│ │ │ └── main.jsx
│ │ └── package.json
│ │
│ ├── frontend-mobile/ # Expo + React Native (iOS/Android)
│ │ ├── app/ # Expo Router screens
│ │ ├── components/
│ │ ├── services/
│ │ ├── store/
│ │ └── package.json
│ │
│ ├── scraper/ # Puppeteer scraper (legacy)
│ │ └── package.json
│ │
│ └── pip-platform/ # Python FastAPI platform (separate docker-compose)
│ ├── Dockerfile
│ ├── docker-compose.yml
│ └── pyproject.toml
│
├── n8n/ # N8N workflow automation
│ ├── workflows/ # Workflow JSON files
│ │ ├── parapharmacy-scraper.json
│ │ └── parapharmacy-manual-scraper.json
│ └── README.md
│
├── API/ # Shared API source files
├── scripts/ # Build/utility scripts
└── 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
Quick Start
Install dependencies
npm install
This installs all workspace dependencies (backend, frontend, mobile, scraper) via npm workspaces.
Development
# Start everything (backend + frontend)
npm run dev
# Start only backend
npm run dev:backend
# Start only frontend
npm run dev:frontend
# Start mobile app
npx turbo run dev --filter=frontend-mobile
Build
# Build all apps
npm run build
# Build only frontend
npm run build:web
Test
# Run all tests
npm test
# Test specific app
npm test --workspace=farma-clic-backend
npm test --workspace=farma-clic-frontend
Docker Setup
Runs the full stack with a single command.
# Copy and configure environment
cp .env.example .env
# Edit .env with your settings (especially passwords)
docker compose up --build
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
# Create admin user for FarmaFinder
docker compose exec backend node create-admin.js
# Default: admin / admin123
# Seed sample pharmacies
docker compose exec backend node seed.js
N8N Setup
N8N auto-creates an admin account on first start:
- Email: admin@farmafinder.com
- Password: change-me (configurable in
.env)
See Parapharmacy Documentation for details.
Stop
docker compose down
Reset Data
docker compose down -v
Manual Setup
1. Install Redis
Ubuntu/Debian:
sudo apt-get install redis-server
sudo systemctl start redis-server
macOS:
brew install redis
brew services start redis
Docker:
docker run -d -p 6379:6379 redis:alpine
Verify: redis-cli ping should respond PONG.
2. Configure Environment (Optional)
Create apps/backend/.env:
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
SESSION_SECRET=your-secret-key-here
3. Initialize Database
# Seed sample pharmacies
npm run dev --workspace=farma-clic-backend -- run seed
# Create admin user (default: admin / admin123)
npm run dev --workspace=farma-clic-backend -- run create-admin
4. Run
npm run dev
API Endpoints
Medicines (Backend - Port 3001)
Public:
GET /api/medicines/search?q=<query>- Search medicines (CIMA API)GET /api/medicines/:nregistro- Medicine detailsGET /api/medicines/:nregistro/pharmacies- Pharmacies selling a medicineGET /api/pharmacies- All pharmacies
Parapharmacy Proxy:
GET /api/products/parapharmacy/search?q=<query>- Search parapharmacy productsGET /api/products/parapharmacy/:id- Parapharmacy product detailsGET /api/products/parapharmacy/categories- List categoriesGET /api/products/parapharmacy/brands- List brands
Auth:
POST /api/auth/login- LoginPOST /api/auth/logout- LogoutGET /api/auth/check- Check auth status
Admin:
POST /api/admin/pharmacies- Add pharmacyPUT /api/admin/pharmacies/:id- Update pharmacyDELETE /api/admin/pharmacies/:id- Delete pharmacyGET /api/admin/medicines?q=<query>- Search medicinesGET /api/admin/pharmacies/:id/medicines- Linked medicinesPOST /api/admin/pharmacy-medicines- Link medicine to pharmacyPUT /api/admin/pharmacy-medicines/:id- Update price/stockDELETE /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 detailsGET /api/products- List productsPOST /api/products- Create productPOST /api/products/bulk- Bulk upsert (for scrapers)PUT /api/products/:id- Update productDELETE /api/products/:id- Delete productGET /api/products/categories- List categoriesGET /api/products/brands- List brandsGET /api/sources- Configured sourcesGET /api/health- Health checkGET /api/docs- Swagger documentation
See Parapharmacy Documentation for details.
Database Schema
SQLite Tables
pharmacies: id, name, address, phone, latitude, longitude
pharmacy_medicines: id, pharmacy_id, medicine_nregistro, medicine_name, price, stock
users: id, username, password_hash, created_at
Redis Cache
medicines:search:{query}- Search results (TTL: 1h)medicine:{nregistro}- Medicine details (TTL: 24h)
Mobile App Setup
Prerequisites
- Node.js v20+
- Expo CLI:
npm install -g expo-cli - EAS CLI:
npm install -g eas-cli - iOS: Xcode + CocoaPods (Mac only)
- Android: Android Studio + SDK
Development
# Install dependencies (already done via npm install at root)
# Start mobile dev server
npx turbo run dev --filter=frontend-mobile
# Scan QR code with Expo Go app
Native Features
| Feature | Implementation |
|---|---|
| Barcode Scanner | expo-camera with CameraView |
| Push Notifications | expo-notifications |
| Biometrics | expo-local-authentication |
| Maps | react-native-maps |
| Secure Storage | expo-secure-store |
EAS Build
cd apps/frontend-mobile
# Development build
eas build --profile development --platform ios
eas build --profile development --platform android
# Production build
eas build --profile production --platform android
eas build --profile production --platform ios
# Submit to stores
eas submit --profile production --platform android
eas submit --profile production --platform ios
Environment Configuration
// apps/frontend-mobile/constants/config.ts
const ENV = {
development: { API_BASE_URL: 'http://localhost:3001/api' },
production: { API_BASE_URL: 'https://your-production-api.com/api' },
};
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
curl -X POST http://localhost:5678/webhook/scrape-parapharmacy
See N8N Documentation for details.
Troubleshooting
Redis Connection Issues
redis-cli ping # Should respond: PONG
redis-server # Start if not running
redis-cli FLUSHALL # Clear cache
CIMA API Timeout
- Check internet connection
- CIMA API may be temporarily unavailable
- App falls back to cached data
Database Reset
cd apps/backend
rm database.sqlite
npm run seed
npm run create-admin
Turborepo Cache Issues
npx turbo clean # Clear Turbo cache
rm -rf node_modules # Full reset
npm install
External Resources
License
ISC