Backend gateway for the Grand Egyptian Museum tourist guide app.
Current services:
backend/: Node.js/Express API, PostgreSQL models, JWT auth, uploads, and EJS pages.AI_services/CV_Recognition/: FastAPI computer-vision artifact recognition service on port8000.AI_services/chatbot_LLM/: FastAPI Groq + ChromaDB historical guide service on port8001.AI_services/hieroglyph_translator/: FastAPI YOLO + LLM translation service on port8002.AI_services/voice_tour_guide/: FastAPI ElevenLabs TTS narration service on port8003.web-frontend/: React/Vite web app on port5173.
Create backend/.env from backend/.env.example for local backend runs:
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_NAME=gem_museum
DB_USER=postgres
DB_PASS=1234
JWT_SECRET=change_me_in_production
AI_SERVICE_URL=http://localhost:8000
RAG_SERVICE_URL=http://localhost:8001
RAG_SERVICE_TIMEOUT_MS=180000
VOICE_SERVICE_URL=http://localhost:8003
HIEROGLYPH_SERVICE_URL=http://localhost:8002
GROQ_API_KEY=
EMAIL_HOST=
EMAIL_PORT=
EMAIL_SECURE=false
EMAIL_USER=
EMAIL_PASS=
EMAIL_FROM="Grand Egyptian Museum Tourist Guide <no-reply@gem-guide.com>"For Docker, set GROQ_API_KEY in your shell before startup. Do not commit real API keys.
PowerShell:
$env:GROQ_API_KEY="your_groq_api_key"
docker compose up --buildPrerequisite: Docker Desktop installed and running.
Start all services:
docker compose up --buildRun in the background:
docker compose up --build -dSeed the database manually:
docker compose exec backend npm run seedStop services:
docker compose downRemove the PostgreSQL/vector database Docker volumes:
docker compose down -vService URLs:
Backend: http://localhost:3000
CV Recognition: http://localhost:8000
Chatbot LLM: http://localhost:8001
Frontend: http://localhost:5173
Quick checks:
curl http://localhost:3000
curl http://localhost:8000/health
curl http://localhost:8001/health
curl http://localhost:3000/api/ai-guide/health
curl http://localhost:3000/api/monumentsDocker networking:
backend -> postgres DB_HOST=postgres
backend -> cv-recognition AI_SERVICE_URL=http://cv-recognition:8000
backend -> chatbot-llm RAG_SERVICE_URL=http://chatbot-llm:8001
backend -> hieroglyph-translator HIEROGLYPH_SERVICE_URL=http://hieroglyph-translator:8002
backend -> voice-tour-guide VOICE_SERVICE_URL=http://voice-tour-guide:8003
Common Docker fixes:
- Port already in use: stop the local service using
3000,5432,8000, or8001. - PostgreSQL volume has old credentials: run
docker compose down -v, then start again. This deletes local Docker DB data. - Backend cannot reach CV: confirm
AI_SERVICE_URL=http://cv-recognition:8000. - Backend cannot reach chatbot: confirm
RAG_SERVICE_URL=http://chatbot-llm:8001. - Chatbot first startup is slow: it may build ChromaDB and download embedding/reranker models.
- Chatbot Docker defaults use CPU-friendly models:
sentence-transformers/all-MiniLM-L6-v2andcross-encoder/ms-marco-MiniLM-L-6-v2. - CV
model_ready=false: restore the trained model toai_services/CV_Recognition/model/model.h5.
Terminal 1, CV Recognition:
cd D:\Graduation\ai_services\CV_Recognition
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
uvicorn api.main:app --host 0.0.0.0 --port 8000 --reloadTerminal 2, Chatbot LLM:
cd D:\Graduation\ai_services\chatbot_LLM
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
python pipeline/build_chunks.py
python pipeline/build_vectordb.py
$env:GROQ_API_KEY="your_groq_api_key"
uvicorn main:app --host 0.0.0.0 --port 8001 --reloadTerminal 3, Backend:
cd D:\Graduation\backend
npm install
npm run seed
npm run devTerminal 4, Frontend:
cd D:\Graduation\frontend
npm install
npm run dev -- --host 0.0.0.0 --port 5173Artifact scan:
POST /api/scan/artifact
Authorization: Bearer <access_token>
Content-Type: multipart/form-dataForm field:
image: <image file>
Scan history:
GET /api/scan/history
Authorization: Bearer <access_token>AI Guide:
GET /api/ai-guide/health
POST /api/ai-guide/ask
GET /api/ai-guide/conversations
GET /api/ai-guide/conversations/:id/messages
PATCH /api/ai-guide/conversations/:id/title
DELETE /api/ai-guide/conversations/:id
POST /api/ai-guide/describe
POST /api/ai-guide/identifyAll AI Guide routes except /health require Authorization: Bearer <access_token>.
POST /api/ai-guide/ask now stores persistent chat history in PostgreSQL. If conversation_id is omitted, the backend creates a new conversation and returns conversation_id and conversation_title. Send the returned conversation_id on later chat messages to append to the same conversation.
Frontend/Mobile -> backend /api/scan/artifact -> cv-recognition /predict
Frontend/Mobile -> backend /api/ai-guide/* -> chatbot-llm
Frontend/Mobile -> backend /api/hieroglyphs/translate -> hieroglyph-translator
Frontend/Mobile -> backend /api/voice/artifacts/:id/narrate -> chatbot-llm (story) + voice-tour-guide (tts)
The backend remains the only service the frontend/mobile app should call directly.
Login:
POST http://localhost:3000/api/auth/login
Content-Type: application/json{
"email": "test@example.com",
"password": "123456"
}Ask:
POST http://localhost:3000/api/ai-guide/ask
Authorization: Bearer <access_token>
Content-Type: application/json{
"question": "Who was Akhenaten?",
"topic": "pharaoh"
}Describe:
POST http://localhost:3000/api/ai-guide/describe
Authorization: Bearer <access_token>
Content-Type: application/json{
"monument_name": "Karnak Temple"
}Identify:
POST http://localhost:3000/api/ai-guide/identify
Authorization: Bearer <access_token>
Content-Type: application/json{
"monument_name": "Great Pyramid of Giza",
"question": "When was it built?"
}The backend mapping is in backend/utils/classMapping.js and should match ai_services/CV_Recognition/model/class_names.json.
Amenhotep_III_Tiye is present in the AI class file but is not currently seeded in the database, so predictions for it return a clean not_found scan status until that monument is added.
- Standalone Microservice:
AI_services/voice_tour_guide/(Port 8003) - AI Flow: The backend (
voiceController.js) requests thechatbot_LLMto generate an engaging tour guide narrative via Groq. The backend then proxies this text tovoice_tour_guidewhich synthesizes the audio via the ElevenLabs API. - Resilience: The TTS returns
nullsafely if ElevenLabs is unreachable, allowing the frontend to still read the generated text. - Persistence: Generated narrations are cached in the PostgreSQL
ArtifactNarrationtable, linking the artifact ID, language, and the internal/audiopath, avoiding unnecessary LLM and TTS calls on subsequent requests.