feat: natural language query + production hardening
Features: - Add /api/ask endpoint for plain-language audit log queries - Regex-based time/entity extraction (no LLM required for parsing) - LLM-powered narrative summarisation with OpenAI-compatible APIs - Graceful fallback to structured bullet lists when LLM is unavailable - Frontend ask panel with markdown rendering and cited events Production: - Harden Dockerfile: non-root user, gunicorn+uvicorn workers - Add docker-compose.prod.yml with internal networks and health checks - Add nginx reverse proxy with security headers - MongoDB no longer exposed externally in production Tests: - 29 new tests for ask parsing, query building, and endpoint behaviour - Fix conftest monkeypatch for routes.ask events collection Bump version to 1.1.0
This commit is contained in:
65
docker-compose.prod.yml
Normal file
65
docker-compose.prod.yml
Normal file
@@ -0,0 +1,65 @@
|
||||
services:
|
||||
mongo:
|
||||
image: mongo:7
|
||||
container_name: aoc-mongo
|
||||
restart: always
|
||||
# Do NOT expose MongoDB port to the host in production
|
||||
# Only backend can reach it via the internal Docker network
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME}
|
||||
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
|
||||
volumes:
|
||||
- mongo_data:/data/db
|
||||
networks:
|
||||
- aoc-internal
|
||||
healthcheck:
|
||||
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 10s
|
||||
|
||||
backend:
|
||||
image: git.cqre.net/cqrenet/aoc-backend:${AOC_VERSION:-latest}
|
||||
container_name: aoc-backend
|
||||
restart: always
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
MONGO_URI: mongodb://${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD}@mongo:27017/
|
||||
depends_on:
|
||||
mongo:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- aoc-internal
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: aoc-nginx
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./nginx/ssl:/etc/nginx/ssl:ro
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- aoc-internal
|
||||
- aoc-public
|
||||
|
||||
volumes:
|
||||
mongo_data:
|
||||
|
||||
networks:
|
||||
aoc-internal:
|
||||
internal: true
|
||||
aoc-public:
|
||||
Reference in New Issue
Block a user