# πŸ’Š 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 EspaΓ±ola 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 ### Backend - **Runtime**: Node.js + Express - **Database**: SQLite (for pharmacies and relationships) - **Cache**: Redis - **External API**: CIMA (Centro de InformaciΓ³n online de Medicamentos de la AEMPS) ### Frontend (Web/PWA) - **Framework**: React + Vite - **Mobile wrapper**: Capacitor (for hybrid mobile builds) ### Frontend (Mobile - React Native) - **Framework**: Expo SDK 57 + React Native - **Navigation**: Expo Router v4 - **State**: Zustand - **HTTP**: Axios + TanStack Query - **Maps**: react-native-maps - **Camera**: expo-camera (barcode scanning) - **Auth**: expo-local-authentication (biometrics) - **Notifications**: expo-notifications - **Build**: EAS Build ## πŸ“‹ Prerequisites - Node.js (v18 or higher) - npm or yarn - **Redis server** (v6.0 or higher) ## 🐳 Docker Setup (Recommended) Runs the full stack (backend, frontend, Redis) with a single command. **Prerequisites**: Docker and Docker Compose v2. ```bash # Copy and configure environment (optional β€” defaults work for local dev) cp backend/.env.example backend/.env # Edit backend/.env to set SESSION_SECRET and any other vars docker compose up --build ``` App available at `http://localhost:3000`. **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 a named Docker volume (`backend_data`). To wipe it: ```bash docker compose down -v ``` --- ## πŸš€ Manual Setup Instructions ### 1. Install Redis **On Ubuntu/Debian:** ```bash sudo apt-get update sudo apt-get install redis-server sudo systemctl start redis-server sudo systemctl enable redis-server ``` **On macOS (using Homebrew):** ```bash brew install redis brew services start redis ``` **On Windows:** Download and install from: https://redis.io/download **Using Docker:** ```bash docker run -d -p 6379:6379 redis:alpine ``` Verify Redis is running: ```bash redis-cli ping # Should respond with: PONG ``` ### 2. Install Application Dependencies **Install backend dependencies:** ```bash cd backend npm install ``` **Install frontend dependencies:** ```bash cd ../frontend npm install ``` ### 3. Configure Environment (Optional) Create a `.env` file in the `backend` directory if you need custom Redis settings: ```env REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD= SESSION_SECRET=your-secret-key-here ``` ### 4. Initialize Database **Seed the database with sample pharmacies:** ```bash cd backend npm run seed ``` **Create admin user:** ```bash npm run create-admin ``` This creates a default admin user with: - Username: `admin` - Password: `admin123` ⚠️ **Important**: Change the default password after first login! You can customize credentials using environment variables: ```bash ADMIN_USERNAME=myadmin ADMIN_PASSWORD=mypassword npm run create-admin ``` ### 5. Running the Application **Start Redis** (if not running): ```bash redis-server ``` **Start the backend server:** ```bash cd backend npm start ``` The backend will run on `http://localhost:3001` **Start the frontend development server:** ```bash cd frontend npm run dev ``` The frontend will run on `http://localhost:3000` **Open your browser** and navigate to `http://localhost:3000` ## 🎯 How to Use ### Public Search 1. Type the name of a medicine in the search bar 2. The app will search the CIMA database in real-time 3. Click on a medicine to see which pharmacies have it 4. View prices and stock availability ### Admin Panel 1. Click the "βš™οΈ Admin Panel" button 2. Login with your credentials (default: `admin` / `admin123`) 3. **Pharmacies Tab**: Add, edit, or delete pharmacies 4. **Medicines Tab**: Search medicines from the CIMA database 5. **Link Medicine Tab**: Associate medicines with pharmacies and set prices/stock ## πŸ“ Project Structure ``` FarmaFinder/ β”œβ”€β”€ docker-compose.yml # Full stack: backend + frontend + Redis β”œβ”€β”€ backend/ β”‚ β”œβ”€β”€ 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 β”‚ β”œβ”€β”€ .env.example # Environment variable template β”‚ └── package.json β”œβ”€β”€ frontend/ # React + Vite (Desktop/PWA) β”‚ β”œβ”€β”€ Dockerfile β”‚ β”œβ”€β”€ nginx.conf # Nginx config (Docker): serves SPA + proxies /api β”‚ β”œβ”€β”€ src/ β”‚ β”‚ β”œβ”€β”€ components/ # React components β”‚ β”‚ β”‚ β”œβ”€β”€ admin/ # Admin panel components β”‚ β”‚ β”‚ β”œβ”€β”€ PharmacyMap.jsx # Leaflet map (OpenStreetMap) β”‚ β”‚ β”‚ └── ... β”‚ β”‚ β”œβ”€β”€ views/ # View components (Public/Admin) β”‚ β”‚ β”œβ”€β”€ App.jsx # Main app component β”‚ β”‚ └── main.jsx # Entry point β”‚ β”œβ”€β”€ index.html β”‚ └── package.json β”œβ”€β”€ frontend-mobile/ # Expo + React Native (iOS/Android) β”‚ β”œβ”€β”€ app/ β”‚ β”‚ β”œβ”€β”€ _layout.tsx # Root layout with providers β”‚ β”‚ β”œβ”€β”€ (tabs)/ # Bottom tab navigation β”‚ β”‚ β”‚ β”œβ”€β”€ index.tsx # Home (medicine search) β”‚ β”‚ β”‚ β”œβ”€β”€ map.tsx # Pharmacy map β”‚ β”‚ β”‚ └── profile.tsx # User profile β”‚ β”‚ β”œβ”€β”€ medicine/[id].tsx # Medicine detail β”‚ β”‚ β”œβ”€β”€ pharmacy/[id].tsx # Pharmacy detail β”‚ β”‚ β”œβ”€β”€ auth/ # Login/Register screens β”‚ β”‚ └── scanner.tsx # Barcode scanner β”‚ β”œβ”€β”€ components/ # Reusable UI components β”‚ β”œβ”€β”€ services/ # API and business logic β”‚ β”œβ”€β”€ store/ # Zustand state management β”‚ β”œβ”€β”€ hooks/ # Custom React hooks β”‚ β”œβ”€β”€ constants/ # Theme and config β”‚ β”œβ”€β”€ types/ # TypeScript types β”‚ β”œβ”€β”€ eas.json # EAS Build configuration β”‚ └── package.json β”œβ”€β”€ android/ # Capacitor Android project β”œβ”€β”€ ios/ # Capacitor iOS project └── README.md ``` ## πŸ”Œ API Endpoints ### Public API - `GET /api/medicines/search?q=` - Search medicines from CIMA API (cached in Redis) - `GET /api/medicines/:nregistro` - Get medicine details from CIMA - `GET /api/medicines/:nregistro/pharmacies` - Get pharmacies selling a medicine - `GET /api/pharmacies` - Get all pharmacies ### Authentication API - `POST /api/auth/login` - Login (requires username and password) - `POST /api/auth/logout` - Logout - `GET /api/auth/check` - Check authentication status ### Admin API (All require authentication) - `POST /api/admin/pharmacies` - Add a new pharmacy - `PUT /api/admin/pharmacies/:id` - Update a pharmacy - `DELETE /api/admin/pharmacies/:id` - Delete a pharmacy - `GET /api/admin/medicines?q=` - Search medicines from CIMA (for admin) - `GET /api/admin/pharmacies/:id/medicines` - Get medicines linked to a pharmacy - `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 medicine from pharmacy ## πŸ’Ύ Database Schema ### SQLite Tables **pharmacies** - `id`: Integer (Primary Key) - `name`: Text (Pharmacy name) - `address`: Text (Full address) - `phone`: Text (Contact phone) - `latitude`: Real (GPS coordinate) - `longitude`: Real (GPS coordinate) **pharmacy_medicines** - `id`: Integer (Primary Key) - `pharmacy_id`: Integer (Foreign Key β†’ pharmacies.id) - `medicine_nregistro`: Text (CIMA medicine registration number) - `medicine_name`: Text (Cached medicine name) - `price`: Real (Price in EUR) - `stock`: Integer (Available units) **users** - `id`: Integer (Primary Key) - `username`: Text (Unique) - `password_hash`: Text (Bcrypt hashed) - `created_at`: DateTime ### Redis Cache Structure - `medicines:search:{query}` - Search results (TTL: 1 hour) - `medicine:{nregistro}` - Medicine details (TTL: 24 hours) ## πŸ”§ Architecture Changes ### Migration from Local Database to CIMA API The application now uses the **CIMA (Centro de InformaciΓ³n online de Medicamentos)** API as the source of truth for medicine data, with Redis caching for performance: **Benefits:** - βœ… Always up-to-date medicine information - βœ… Official data from Spanish health authorities - βœ… Reduced database maintenance - βœ… Fast responses thanks to Redis cache - βœ… Fallback to stale cache if API is down **Changes:** - Medicines are no longer stored locally in SQLite - Medicine searches query the CIMA API - Results are cached in Redis for performance - `pharmacy_medicines` now uses `medicine_nregistro` (CIMA registration number) instead of local `medicine_id` ## πŸ“± Mobile App Setup (React Native) ### Prerequisites - Node.js (v18 or higher) - npm or yarn - **Expo CLI**: `npm install -g expo-cli` - **EAS CLI**: `npm install -g eas-cli` - **iOS**: Xcode (Mac only) + CocoaPods - **Android**: Android Studio + Android SDK ### Quick Start ```bash # Install all dependencies (backend + web + mobile) npm run install:all # Start mobile development server npm run dev:mobile # Scan QR code with Expo Go app (iOS/Android) ``` ### Development Build For native features (camera, biometrics, notifications), use a development build: ```bash # Install EAS CLI npm install -g eas-cli # Login to Expo eas login # Create development build eas build --profile development --platform ios eas build --profile development --platform android ``` ### Project Structure ``` frontend-mobile/ β”œβ”€β”€ app/ # Expo Router screens β”‚ β”œβ”€β”€ (tabs)/ # Bottom tab navigation β”‚ β”œβ”€β”€ auth/ # Login/Register β”‚ β”œβ”€β”€ medicine/ # Medicine detail β”‚ β”œβ”€β”€ pharmacy/ # Pharmacy detail β”‚ └── scanner.tsx # Barcode scanner β”œβ”€β”€ components/ # Reusable UI components β”œβ”€β”€ services/ # API and business logic β”œβ”€β”€ store/ # Zustand state management β”œβ”€β”€ hooks/ # Custom React hooks β”œβ”€β”€ constants/ # Theme and config └── types/ # TypeScript types ``` ### 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 Profiles - **development**: Local development with dev client - **preview**: Internal testing (APK/IPA) - **production**: App Store/Google Play submission ### Environment Configuration The mobile app uses the same backend API as the web app. Configure the API URL in: ```typescript // 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 If you see "Redis Client Error": ```bash # Check if Redis is running redis-cli ping # Start Redis if needed redis-server ``` ### CIMA API Timeout If medicine searches are slow or failing: - Check your internet connection - The CIMA API may be temporarily unavailable - The app will use cached data if available ### Database Issues Reset the database: ```bash cd backend rm database.sqlite npm run seed npm run create-admin ``` ## πŸ“ Development ### Backend **Start with auto-reload:** ```bash cd backend npm run dev ``` ### Frontend (Web/PWA) **Start development server:** ```bash cd frontend npm run dev ``` ### Frontend (Mobile - React Native) **Install all dependencies:** ```bash npm run install:all ``` **Start Expo dev server:** ```bash npm run dev:mobile ``` **Start for specific platform:** ```bash npm run dev:mobile:android # Android emulator npm run dev:mobile:ios # iOS simulator ``` **Build with EAS:** ```bash npm run build:mobile # Production build ``` **Submit to stores:** ```bash npm run submit:android # Google Play npm run submit:ios # App Store ``` ### Clear Redis cache ```bash redis-cli FLUSHALL ``` ## 🌐 External Resources - **CIMA API**: https://cima.aemps.es/ - **Redis Documentation**: https://redis.io/documentation - **React Documentation**: https://react.dev - **Express Documentation**: https://expressjs.com ## πŸ“„ License ISC