DIRA is a market intelligence stack for informal vendor workflows.
It has three runtime parts:
- Backend:
dira_agent/ - Frontend:
frontend/ - WhatsApp bridge:
whatsapp_bridge/
Start the full local stack from the repo root:
./dev.sh upThis starts:
- Postgres via Docker Compose
- FastAPI backend on
http://127.0.0.1:8000unless that port is already in use - React frontend on
http://127.0.0.1:5173unless that port is already in use
If your Docker setup requires sudo, ./dev.sh will retry the Postgres step with sudo while keeping the backend and frontend running as your user.
If the default ports are busy, the script will pick the next free port and print the actual URLs it starts on.
To run a smoke test and exit after health checks:
./dev.sh testTo learn more about working with DIRA, explore the following guides in the /docs directory:
- 📖 Onboarding & Troubleshooting: Markdown / PDF — Guide for local environment configuration, WhatsApp bridge pairing, and common developer workflows.
- 📐 System Architecture: Markdown / PDF — In-depth breakdown of DIRA's 4 core pillars, database design, and future refactoring roadmap.
This repository now includes CI at .github/workflows/ci.yml with:
- Backend: dependency install, service compile check, and pytest suite
- Frontend: ESLint and production build
Run the same checks locally:
# backend
cd dira_agent
source .venv/bin/activate
python -m pytest -q tests
# frontend
cd ../frontend
npm run lint
npm run buildIf you are not using ./dev.sh up, start the services manually.
Create a single shared environment file at the repo root first:
cp .env.example .envgit submodule update --init --recursive
cd dira_agent
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Load the shared root .env into this shell
set -a && source ../.env && set +a
python3 main.pyUseful backend URLs:
- OpenAPI:
http://127.0.0.1:8000/docs - Live:
http://127.0.0.1:8000/health/live - Ready:
http://127.0.0.1:8000/health/ready
cd frontend
npm install
npm run devFrontend URL:
http://localhost:5173
cd whatsapp_bridge
npm install
node index.jsUse one repo-root .env file per environment:
- Local machine:
<repo>/.env - Production host:
<repo>/.env
This one file configures all Docker services in Compose.
Primary keys:
POSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_DBAPP_ENVDATABASE_URLJWT_SECRETFRONTEND_ORIGINGEMINI_API_KEYADMIN_EMAILFEEDER_SHARED_TOKENDIRA_INTERNAL_TOKENWHATSAPP_VERIFY_TOKENWEBHOOK_SECRETBRIDGE_ALLOWED_ORIGINS
Frontend:
VITE_API_BASEoptional; defaults to the current origin in production
DIRA is designed to be deployed as a single-domain stack on a Google Cloud Platform (GCP) Compute Engine (GCE) VM (such as an e2-micro, which qualifies under the GCP Always Free Tier).
The deployment uses:
- Docker Compose: Orchestrates the PostgreSQL database, FastAPI backend, React SPA frontend (nginx), and Node.js WhatsApp bridge.
- Nginx Reverse Proxy & SSL: A host-level Nginx configuration routes all traffic through
https://<your-domain>and proxies:/-> React SPA (internal port 8080)/api/-> FastAPI backend (internal port 8000)/bridge/-> WhatsApp bridge (internal port 3000)
- Let's Encrypt provides automated, zero-cost SSL certificates.
-
DNS Setup:
- Map an
Arecord from your custom domain (e.g.dira.sspirial.systems) to your GCE VM's public IP address.
- Map an
-
Clone & Set Up Stack:
- SSH into your GCE VM, clone the repository, and run the GCP setup orchestrator:
git clone --recurse-submodules https://github.com/sspirial/dira.git ~/dira cd ~/dira sudo ./gcp-setup.sh
- Input your custom domain and Gemini API credentials. The script automatically configures internal Docker networking, locks down the VM firewall (allowing only ports 22, 80, and 443), and boots up the containers.
- SSH into your GCE VM, clone the repository, and run the GCP setup orchestrator:
-
Enable SSL:
- Run the SSL certification script:
sudo ./setup-ssl.sh
- Let's Encrypt will automatically provision your certificate and configure the Nginx secure routing rules.
- Run the SSL certification script:
- Do not commit
whatsapp_bridge/auth_info_baileys/ - Keep
APP_ENV=productionin production - Use a strong, unique
JWT_SECRET