# 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, Redis | | Frontend (Web) | React + Vite, Capacitor | | Frontend (Mobile) | Expo SDK 57 + React Native, Zustand, Axios + TanStack Query | | 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 │ ├── apps/ │ ├── backend/ # Node.js + Express API │ │ ├── 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 │ │ │ ├── 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 (standalone) │ │ └── package.json │ │ │ └── pip-platform/ # Python FastAPI platform (separate docker-compose) │ ├── Dockerfile │ ├── docker-compose.yml │ └── pyproject.toml │ ├── API/ # Shared API source files ├── scripts/ # Build/utility scripts └── docs/ # Documentation ``` ## Quick Start ### Install dependencies ```bash npm install ``` This installs all workspace dependencies (backend, frontend, mobile, scraper) via npm workspaces. ### Development ```bash # 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 ```bash # Build all apps npm run build # Build only frontend npm run build:web ``` ### Test ```bash # 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 (backend, frontend, Redis, Postgres) with a single command. ```bash # Copy and configure environment (optional - defaults work for local dev) cp apps/backend/.env.example apps/backend/.env docker compose up --build ``` App available at `http://localhost:4000` (frontend) and `http://localhost:3001` (backend API). **First run - create an admin user:** ```bash docker compose exec backend node create-admin.js # Default: admin / admin123 - change after first login ``` **Seed sample pharmacies:** ```bash docker compose exec backend node seed.js ``` **Stop:** ```bash docker compose down ``` Database is persisted in named Docker volumes (`backend_data`, `postgres_data`). To wipe: ```bash docker compose down -v ``` ## Manual Setup ### 1. Install Redis **Ubuntu/Debian:** ```bash sudo apt-get install redis-server sudo systemctl start redis-server ``` **macOS:** ```bash brew install redis brew services start redis ``` **Docker:** ```bash docker run -d -p 6379:6379 redis:alpine ``` Verify: `redis-cli ping` should respond `PONG`. ### 2. Configure Environment (Optional) Create `apps/backend/.env`: ```env REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD= SESSION_SECRET=your-secret-key-here ``` ### 3. Initialize Database ```bash # 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 ```bash npm run dev ``` ## API Endpoints ### Public - `GET /api/medicines/search?q=` - Search medicines (CIMA API, cached in Redis) - `GET /api/medicines/:nregistro` - Medicine details - `GET /api/medicines/:nregistro/pharmacies` - Pharmacies selling a medicine - `GET /api/pharmacies` - All pharmacies ### Auth - `POST /api/auth/login` - Login - `POST /api/auth/logout` - Logout - `GET /api/auth/check` - Check auth status ### Admin (requires authentication) - `POST /api/admin/pharmacies` - Add pharmacy - `PUT /api/admin/pharmacies/:id` - Update pharmacy - `DELETE /api/admin/pharmacies/:id` - Delete pharmacy - `GET /api/admin/medicines?q=` - Search medicines - `GET /api/admin/pharmacies/:id/medicines` - Linked medicines - `POST /api/admin/pharmacy-medicines` - Link medicine to pharmacy - `PUT /api/admin/pharmacy-medicines/:id` - Update price/stock - `DELETE /api/admin/pharmacy-medicines/:id` - Remove link ## 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 ```bash # 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 ```bash 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 ```typescript // 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' }, }; ``` ## Troubleshooting ### Redis Connection Issues ```bash 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 ```bash cd apps/backend rm database.sqlite npm run seed npm run create-admin ``` ### Turborepo Cache Issues ```bash npx turbo clean # Clear Turbo cache rm -rf node_modules # Full reset npm install ``` ## External Resources - [CIMA API](https://cima.aemps.es/) - [Turborepo](https://turbo.build/repo) - [Redis](https://redis.io/documentation) - [React](https://react.dev) - [Express](https://expressjs.com) - [Expo](https://docs.expo.dev) ## License ISC