first commit
This commit is contained in:
307
README.md
Normal file
307
README.md
Normal file
@@ -0,0 +1,307 @@
|
||||
# 💊 FarmaFinder
|
||||
|
||||
A web application to search for medicines from the official Spanish CIMA database and find which pharmacies sell them.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- 🔍 **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
|
||||
|
||||
## 🛠️ Tech Stack
|
||||
|
||||
- **Frontend**: React + Vite
|
||||
- **Backend**: Node.js + Express
|
||||
- **Database**: SQLite (for pharmacies and relationships)
|
||||
- **Cache**: Redis
|
||||
- **External API**: CIMA (Centro de Información online de Medicamentos de la AEMPS)
|
||||
|
||||
## 📋 Prerequisites
|
||||
|
||||
- Node.js (v18 or higher)
|
||||
- npm or yarn
|
||||
- **Redis server** (v6.0 or higher)
|
||||
|
||||
## 🚀 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/
|
||||
├── backend/
|
||||
│ ├── 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
|
||||
│ ├── database.sqlite # SQLite database (created after first run)
|
||||
│ └── package.json
|
||||
├── frontend/
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # React components
|
||||
│ │ │ ├── admin/ # Admin panel components
|
||||
│ │ │ └── ... # Public view components
|
||||
│ │ ├── views/ # View components (Public/Admin)
|
||||
│ │ ├── App.jsx # Main app component
|
||||
│ │ └── main.jsx # Entry point
|
||||
│ ├── index.html
|
||||
│ └── package.json
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 🔌 API Endpoints
|
||||
|
||||
### Public API
|
||||
- `GET /api/medicines/search?q=<query>` - 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=<query>` - 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`
|
||||
|
||||
## 🐛 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 development with auto-reload:**
|
||||
```bash
|
||||
cd backend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
**Frontend development:**
|
||||
```bash
|
||||
cd frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
**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
|
||||
|
||||
Reference in New Issue
Block a user