All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Integrated MongoDB 7.0 with Mongoose ODM - Added CRUD API endpoints (GET, POST, PUT, DELETE) - Created Family model with validation - Added database seeding script with initial data - Implemented Add Family modal form in frontend - Updated docker-compose with MongoDB service - Updated Helm chart to v0.3.0 with MongoDB StatefulSet - Updated documentation with MongoDB setup instructions
405 lines
9.6 KiB
Markdown
405 lines
9.6 KiB
Markdown
# 🗺️ Ora Map - Family Location Mapping Application
|
||
|
||
A full-stack web application for mapping and searching family locations in Yemen using interactive maps.
|
||
|
||
## 📋 Table of Contents
|
||
- [Features](#features)
|
||
- [Tech Stack](#tech-stack)
|
||
- [Project Structure](#project-structure)
|
||
- [Getting Started](#getting-started)
|
||
- [Docker Deployment](#docker-deployment)
|
||
- [Development](#development)
|
||
- [API Endpoints](#api-endpoints)
|
||
|
||
## ✨ Features
|
||
|
||
- 🔍 **Family Search**: Search for families by name with autocomplete suggestions
|
||
- 🗺️ **Interactive Map**: Leaflet-based map with multiple tile layer options
|
||
- 📍 **Location Markers**: View family locations with city information
|
||
- ➕ **Add Families**: Admin UI to add new family locations to the database
|
||
- 💾 **MongoDB Database**: Real database persistence with full CRUD operations
|
||
- 🎨 **Modern UI**: Clean and responsive design with modal forms
|
||
- 🐳 **Docker Ready**: Containerized for easy deployment
|
||
- ☸️ **Kubernetes Ready**: Helm chart for production deployment
|
||
- 💚 **Health Checks**: Built-in health monitoring
|
||
|
||
## 🛠️ Tech Stack
|
||
|
||
**Backend:**
|
||
- Node.js 20 Alpine
|
||
- Express.js 4.18
|
||
- MongoDB 7.0
|
||
- Mongoose ODM
|
||
- CORS enabled
|
||
|
||
**Frontend:**
|
||
- HTML5/CSS3
|
||
- Vanilla JavaScript (ES6+)
|
||
- Leaflet.js (interactive maps)
|
||
- Fuse.js (fuzzy search)
|
||
- Nginx (production server)
|
||
|
||
**DevOps:**
|
||
- Docker & Docker Compose
|
||
- Kubernetes & Helm Charts
|
||
- Woodpecker CI/CD
|
||
- Harbor Registry
|
||
|
||
## 📁 Project Structure with MongoDB
|
||
│ ├── package.json # Backend dependencies
|
||
│ ├── Dockerfile # Backend container image
|
||
│ ├── config/
|
||
│ │ └── database.js # MongoDB connection
|
||
│ ├── models/
|
||
│ │ └── Family.js # Mongoose schema
|
||
│ └── scripts/
|
||
│ └── seed.js # Database seeding script
|
||
├── frontend/
|
||
│ ├── Dockerfile # Frontend Nginx container
|
||
│ ├── nginx.conf # Nginx configuration
|
||
│ └── public/
|
||
│ ├── index.html # Frontend HTML with modal form
|
||
│ ├── script.js # Frontend JavaScript with CRUD
|
||
│ └── style.css # Styles including modal
|
||
├── oramap/ # Helm Chart
|
||
│ ├── Chart.yaml # Chart metadata (v0.3.0)
|
||
│ ├── values.yaml # Configuration values
|
||
│ ├── README.md # Helm documentation
|
||
│ └── templates/
|
||
│ ├── deployment.yaml # Backend & Frontend deployments
|
||
│ ├── service.yaml # Services
|
||
│ ├── ingress.yaml # Ingress rules
|
||
│ ├── configmap.yaml # Nginx config
|
||
│ ├── mongodb-statefulset.yaml # MongoDB StatefulSet
|
||
│ └── mongodb-service.yaml # MongoDB service
|
||
├── old/ # Legacy files
|
||
│ ├── server.js
|
||
│ ├── package.json
|
||
│ └── data/families.json
|
||
├── Dockerfile # Monolith Docker build
|
||
├── docker-compose.yml # Monolith deployment
|
||
├── docker-compose.microservices.yml # Microservices with MongoDB
|
||
│ ├── script.js
|
||
│ └── style.css
|
||
├── Dockerfile # Monolith Docker build
|
||
├── docker-compose.yml # Monolith deployment
|
||
├── MongoDB**: Database for family locations (Port 27017)
|
||
- **Backend**: Express API server with MongoDB integration (Internal Port 3000)
|
||
- **Frontend**: Nginx serving static files with API proxy (Port 80)
|
||
- Nginx proxies `/api/*` requests to backend
|
||
- Best for: Production, scalability, CI/CD pipelines
|
||
- Use: `docker-compose -f docker-compose.microservices.yml up`
|
||
|
||
### 3. **Kubernetes Mode** (Enterprise)
|
||
- Helm chart deployment with StatefulSet for MongoDB
|
||
- Persistent storage for database
|
||
- Horizontal scaling for backend/frontend
|
||
- Ingress with TLS support
|
||
- See: `oramap/README.md` for Helm chart documentation
|
||
## 🏗️ Architecture
|
||
|
||
The application supports two deployment modes:
|
||
|
||
### 1. **Monolith Mode** (Simple)
|
||
- Single container with Express serving both API and static files
|
||
- Best for: Development, simple deployments
|
||
- Use: `docker-compose up`
|
||
|
||
### 2. **Microservices Mode** (Production)
|
||
- **Frontend**: Nginx serving static files (Port 80)
|
||
- **Backend**: Express API server (Internal Port 3000)
|
||
- Nginx proxies `/api/*` requests to backend
|
||
- Best for: Production, scalability, CI/CD pipelines
|
||
- Use: `docker-compose -f docker-compose.microservices.yml up`
|
||
|
||
## 🚀 Getting Started
|
||
|
||
### Prerequisites
|
||
- Node.js (v18 or higher)
|
||
- Docker & Docker Compose (optional, for containerized deployment)
|
||
|
||
### Local Development
|
||
|
||
1. **Start MongoDB (optional - uses local instance if not running):**
|
||
```bash
|
||
# Using Docker
|
||
docker run -d -p 27017:27017 --name mongodb mongo:7.0
|
||
|
||
# Or install MongoDB locally
|
||
```
|
||
|
||
2. **Install backend dependencies:**
|
||
```bash
|
||
cd backend
|
||
npm install
|
||
```
|
||
|
||
3. **Seed initial data:**
|
||
```bash
|
||
npm run seed
|
||
```
|
||
|
||
4. **Start the server:**
|
||
```bash
|
||
npm start
|
||
# Or for development with auto-reload:
|
||
npm run dev
|
||
```
|
||
|
||
5. **Open your browser:**
|
||
Navigate to `http://localhost:3000`
|
||
|
||
## 🐳 Docker Deployment
|
||
|
||
### Monolith Mode (Recommended for Development)
|
||
|
||
1. **Build and start:**
|
||
```bash
|
||
docker-compose up -d
|
||
```
|
||
|
||
2. **Access:** http://localhost:3000
|
||
|
||
3. **Stop:**
|
||
```bash
|
||
docker-compose down
|
||
```
|
||
|
||
### Microservices Mode (Recommended for Production)
|
||
|
||
1. **Build and start all services (Backend + Frontend + MongoDB):**
|
||
```bash
|
||
docker-compose -f docker-compose.microservices.yml up -d
|
||
```
|
||
|
||
2. **Seed the database:**
|
||
```bash
|
||
docker exec -it oramap-backend npm run seed
|
||
```
|
||
|
||
3. **Access:** http://localhost (Port 80)
|
||
|
||
4. **View logs:**
|
||
```bash
|
||
docker logs oramap-frontend
|
||
docker logs oramap-backend
|
||
docker logs oramap-mongo
|
||
```
|
||
|
||
5. **Stop:**
|
||
```bash
|
||
docker-compose -f docker-compose.microservices.yml down
|
||
# To remove volumes:
|
||
docker-compose -f docker-compose.microservices.yml down -v
|
||
```
|
||
|
||
### Using Docker directly
|
||
|
||
**Monolith:**
|
||
```bash
|
||
docker build -t oramap:latest .
|
||
docker run -d -p 3000:3000 --name oramap-app oramap:latest
|
||
```
|
||
|
||
**Microservices:**
|
||
```bash
|
||
# Build images
|
||
docker build -t oramap-backend -f backend/Dockerfile backend/
|
||
docker build -t oramap-frontend -f frontend/Dockerfile frontend/
|
||
|
||
# Run with network
|
||
docker network create oramap-network
|
||
docker run -d --name oramap-backend --network oramap-network oramap-backend
|
||
docker run -d --name oramap-frontend --network oramap-network -p 80:80 oramap-frontend
|
||
```
|
||
|
||
## 🔄 CI/CD Pipeline
|
||
|
||
The project includes a Woodpecker CI configuration (`.woodpecker.yaml`) that automatically:
|
||
|
||
1. **Builds** separate frontend and backend Docker images on push
|
||
2. **Tags** images with branch name and commit SHA
|
||
3. **Pushes** to Harbor registry (`harbor.dvirlabs.com`)
|
||
4. **Updates** Kubernetes manifests with new image tags
|
||
5. **Triggers** on changes to `frontend/**` or `backend/**` paths
|
||
|
||
### Pipeline Steps:
|
||
- `build-frontend`: Build and push frontend Nginx image
|
||
- `build-backend`: Build and push backend API image
|
||
- `update-values-frontend`: Update frontend image tag in values.yaml
|
||
- `update-values-backend`: Update backend image tag in values.yaml
|
||
|
||
## 💻 Development
|
||
|
||
### Running in Development Mode
|
||
|
||
```bash
|
||
cd backend
|
||
npm run dev
|
||
```
|
||
|
||
### Database Management
|
||
|
||
**Seed initial data:**
|
||
```bash
|
||
npm run seed
|
||
```
|
||
|
||
**Force re-seed (clears existing data):**
|
||
```bash
|
||
npm run seed:force
|
||
```
|
||
|
||
### Adding New Families
|
||
|
||
Use the web UI "Add Family" button, or make API calls:
|
||
|
||
```bash
|
||
curl -X POST http://localhost:3000/api/families \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"family": "Family Name",
|
||
"city": "City Name",
|
||
"lat": 15.3545,
|
||
"lng": 44.2064
|
||
}'
|
||
```
|
||
|
||
## 📡 API Endpoints
|
||
|
||
### Get All Families
|
||
```
|
||
GET /api/families
|
||
```
|
||
Returns all families sorted by name.
|
||
|
||
**Example:**
|
||
```bash
|
||
curl http://localhost:3000/api/families
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
[
|
||
{
|
||
"_id": "507f1f77bcf86cd799439011",
|
||
"family": "משפחת כפה",
|
||
"city": "צנעא",
|
||
"lat": 15.3545,
|
||
"lng": 44.2064,
|
||
"createdAt": "2024-01-01T00:00:00.000Z",
|
||
"updatedAt": "2024-01-01T00:00:00.000Z"
|
||
}
|
||
]
|
||
```
|
||
|
||
### Search Families
|
||
```
|
||
GET /api/search?family={familyName}
|
||
```
|
||
Returns matching family records using MongoDB text search.
|
||
|
||
**Example:**
|
||
```bash
|
||
curl "http://localhost:3000/api/search?family=Kafe"
|
||
```
|
||
|
||
### Create Family
|
||
```
|
||
POST /api/families
|
||
Content-Type: application/json
|
||
```
|
||
Creates a new family location.
|
||
|
||
**Request Body:**
|
||
```json
|
||
{
|
||
"family": "משפחת דוד",
|
||
"city": "עדן",
|
||
"lat": 12.7855,
|
||
"lng": 45.0187
|
||
}
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"_id": "507f1f77bcf86cd799439011",
|
||
"family": "משפחת דוד",
|
||
"city": "עדן",
|
||
"lat": 12.7855,
|
||
"lng": 45.0187,
|
||
"createdAt": "2024-01-01T00:00:00.000Z",
|
||
"updatedAt": "2024-01-01T00:00:00.000Z"
|
||
}
|
||
```
|
||
|
||
### Update Family
|
||
```
|
||
PUT /api/families/:id
|
||
Content-Type: application/json
|
||
```
|
||
Updates an existing family.
|
||
|
||
**Request Body:**
|
||
```json
|
||
{
|
||
"family": "משפחת כהן",
|
||
"city": "צנעא",
|
||
"lat": 15.3695,
|
||
"lng": 44.1910
|
||
}
|
||
```
|
||
|
||
### Delete Family
|
||
```
|
||
DELETE /api/families/:id
|
||
```
|
||
Deletes a family by ID.
|
||
|
||
**Example:**
|
||
```bash
|
||
curl -X DELETE http://localhost:3000/api/families/507f1f77bcf86cd799439011
|
||
```
|
||
|
||
### Health Check
|
||
```
|
||
GET /api/health
|
||
```
|
||
Returns server and database health status.
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"timestamp": "2024-01-01T00:00:00.000Z",
|
||
"database": "connected"
|
||
}
|
||
```
|
||
Returns server health status.
|
||
|
||
**Example Response:**
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"timestamp": "2026-03-24T10:30:00.000Z"
|
||
}
|
||
```
|
||
|
||
## 🗺️ Available Family Names
|
||
|
||
- Kafe (קאפח)
|
||
- Shiheb (שחב-שבח)
|
||
- Uzeyri (עזירי-עוזרי)
|
||
- Salumi (סלומי-שלומי)
|
||
- Afgin (עפג'ין)
|
||
- Eraki (עראקי)
|
||
|
||
## 📝 License
|
||
|
||
ISC
|
||
|
||
## 🤝 Contributing
|
||
|
||
Contributions, issues, and feature requests are welcome!
|