- 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
🗺️ 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
- 🔍 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.mdfor 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
- Start MongoDB (optional - uses local instance if not running):
# Using Docker
docker run -d -p 27017:27017 --name mongodb mongo:7.0
# Or install MongoDB locally
- Install backend dependencies:
cd backend
npm install
- Seed initial data:
npm run seed
- Start the server:
npm start
# Or for development with auto-reload:
npm run dev
- Open your browser:
Navigate to
http://localhost:3000
🐳 Docker Deployment
Monolith Mode (Recommended for Development)
- Build and start:
docker-compose up -d
-
Access: http://localhost:3000
-
Stop:
docker-compose down
Microservices Mode (Recommended for Production)
- Build and start all services (Backend + Frontend + MongoDB):
docker-compose -f docker-compose.microservices.yml up -d
- Seed the database:
docker exec -it oramap-backend npm run seed
-
Access: http://localhost (Port 80)
-
View logs:
docker logs oramap-frontend
docker logs oramap-backend
docker logs oramap-mongo
- Stop:
docker-compose -f docker-compose.microservices.yml down
# To remove volumes:
docker-compose -f docker-compose.microservices.yml down -v
Using Docker directly
Monolith:
docker build -t oramap:latest .
docker run -d -p 3000:3000 --name oramap-app oramap:latest
Microservices:
# 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:
- Builds separate frontend and backend Docker images on push
- Tags images with branch name and commit SHA
- Pushes to Harbor registry (
harbor.dvirlabs.com) - Updates Kubernetes manifests with new image tags
- Triggers on changes to
frontend/**orbackend/**paths
Pipeline Steps:
build-frontend: Build and push frontend Nginx imagebuild-backend: Build and push backend API imageupdate-values-frontend: Update frontend image tag in values.yamlupdate-values-backend: Update backend image tag in values.yaml
💻 Development
Running in Development Mode
cd backend
npm run dev
Database Management
Seed initial data:
npm run seed
Force re-seed (clears existing data):
npm run seed:force
Adding New Families
Use the web UI "Add Family" button, or make API calls:
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:
curl http://localhost:3000/api/families
Response:
[
{
"_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:
curl "http://localhost:3000/api/search?family=Kafe"
Create Family
POST /api/families
Content-Type: application/json
Creates a new family location.
Request Body:
{
"family": "משפחת דוד",
"city": "עדן",
"lat": 12.7855,
"lng": 45.0187
}
Response:
{
"_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:
{
"family": "משפחת כהן",
"city": "צנעא",
"lat": 15.3695,
"lng": 44.1910
}
Delete Family
DELETE /api/families/:id
Deletes a family by ID.
Example:
curl -X DELETE http://localhost:3000/api/families/507f1f77bcf86cd799439011
Health Check
GET /api/health
Returns server and database health status.
Response:
{
"status": "ok",
"timestamp": "2024-01-01T00:00:00.000Z",
"database": "connected"
}
Returns server health status.
Example Response:
{
"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!