oramap/README.md
dvirlabs 02074aa4a6
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Add MongoDB integration with CRUD UI
- 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
2026-03-25 01:51:46 +02:00

9.6 KiB
Raw Blame History

🗺️ 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.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):
# Using Docker
docker run -d -p 27017:27017 --name mongodb mongo:7.0

# Or install MongoDB locally
  1. Install backend dependencies:
cd backend
npm install
  1. Seed initial data:
npm run seed
  1. Start the server:
npm start
# Or for development with auto-reload:
npm run dev
  1. Open your browser: Navigate to http://localhost:3000

🐳 Docker Deployment

  1. Build and start:
docker-compose up -d
  1. Access: http://localhost:3000

  2. Stop:

docker-compose down
  1. Build and start all services (Backend + Frontend + MongoDB):
docker-compose -f docker-compose.microservices.yml up -d
  1. Seed the database:
docker exec -it oramap-backend npm run seed
  1. Access: http://localhost (Port 80)

  2. View logs:

docker logs oramap-frontend
docker logs oramap-backend
docker logs oramap-mongo
  1. 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:

  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

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!