Skip to content

Commit 664943b

Browse files
committed
initial commit with backedn and docker commands
0 parents  commit 664943b

100 files changed

Lines changed: 7542 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Never copy these into Docker images
2+
**/node_modules
3+
**/.next
4+
**/__pycache__
5+
**/*.pyc
6+
**/.venv
7+
**/dist
8+
**/build
9+
**/.env
10+
**/.env.local
11+
**/coverage
12+
**/.pytest_cache
13+
**/*.log

.env.example

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# ─── Project Voyage — Environment Variables ──────────────────────────────────
2+
# Copy this to .env and fill in your values.
3+
# NEVER commit .env to git.
4+
5+
# ─── App ─────────────────────────────────────────────────────────────────────
6+
DEBUG=false
7+
API_KEY=changeme-generate-a-real-key
8+
9+
# ─── Database ─────────────────────────────────────────────────────────────────
10+
# Used by FastAPI (async driver)
11+
DATABASE_URL=postgresql+asyncpg://voyage:voyage@localhost:5432/voyage
12+
# Used by Alembic (sync driver)
13+
DATABASE_URL_SYNC=postgresql://voyage:voyage@localhost:5432/voyage
14+
15+
# ─── Redis ────────────────────────────────────────────────────────────────────
16+
REDIS_URL=redis://localhost:6379/0
17+
18+
# ─── Redpanda / Kafka ─────────────────────────────────────────────────────────
19+
KAFKA_BOOTSTRAP_SERVERS=localhost:19092
20+
21+
# ─── External APIs ────────────────────────────────────────────────────────────
22+
# AISstream.io: https://aisstream.io (free API key — no hardware required)
23+
# Sign up, verify email, copy your API key from the dashboard.
24+
# Leave blank to stream realistic mock vessel data instead.
25+
AISSTREAM_API_KEY=
26+
27+
# NewsAPI: https://newsapi.org (free tier: 100 req/day)
28+
NEWSAPI_KEY=
29+
30+
# HAPI (UN OCHA Humanitarian API) needs NO key — no entry needed here.
31+
# Conflict events, food security, and displacement data are fetched
32+
# without credentials. See ingestion/osint/hapi_worker.py.
33+
34+
# ─── ML Service ───────────────────────────────────────────────────────────────
35+
ML_SERVICE_URL=http://localhost:8001
36+
37+
# ─── CORS (comma-separated origins) ──────────────────────────────────────────
38+
# Add your frontend URL here
39+
CORS_ORIGINS=["http://localhost:3000"]

.github/workflows/ci.yml

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
PYTHON_VERSION: "3.12"
11+
12+
jobs:
13+
backend-lint:
14+
name: Backend — Lint & Type Check
15+
runs-on: ubuntu-latest
16+
defaults:
17+
run:
18+
working-directory: backend
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@v4
25+
with:
26+
version: "latest"
27+
28+
- name: Install dependencies
29+
run: uv sync --all-extras
30+
31+
- name: Ruff lint
32+
run: uv run ruff check .
33+
34+
- name: Ruff format check
35+
run: uv run ruff format --check .
36+
37+
- name: Mypy type check
38+
run: uv run mypy app/ ingestion/
39+
40+
backend-test:
41+
name: Backend — Unit Tests
42+
runs-on: ubuntu-latest
43+
defaults:
44+
run:
45+
working-directory: backend
46+
47+
steps:
48+
- uses: actions/checkout@v4
49+
50+
- name: Install uv
51+
uses: astral-sh/setup-uv@v4
52+
with:
53+
version: "latest"
54+
55+
- name: Install dependencies
56+
run: uv sync --all-extras
57+
58+
- name: Run unit tests
59+
env:
60+
DATABASE_URL: "postgresql+asyncpg://voyage:voyage@localhost:5432/voyage"
61+
DATABASE_URL_SYNC: "postgresql://voyage:voyage@localhost:5432/voyage"
62+
REDIS_URL: "redis://localhost:6379/0"
63+
KAFKA_BOOTSTRAP_SERVERS: "localhost:9092"
64+
API_KEY: "test-key"
65+
run: uv run pytest tests/unit/ -v --cov=app --cov=ingestion --cov-report=xml
66+
67+
- name: Upload coverage
68+
uses: codecov/codecov-action@v4
69+
with:
70+
file: backend/coverage.xml
71+
flags: backend-unit
72+
73+
backend-integration:
74+
name: Backend — Integration Tests
75+
runs-on: ubuntu-latest
76+
defaults:
77+
run:
78+
working-directory: backend
79+
80+
services:
81+
postgres:
82+
image: timescale/timescaledb-ha:pg16
83+
env:
84+
POSTGRES_USER: voyage
85+
POSTGRES_PASSWORD: voyage
86+
POSTGRES_DB: voyage
87+
ports:
88+
- 5432:5432
89+
options: >-
90+
--health-cmd "pg_isready -U voyage -d voyage"
91+
--health-interval 10s
92+
--health-timeout 5s
93+
--health-retries 5
94+
95+
redis:
96+
image: redis:7-alpine
97+
ports:
98+
- 6379:6379
99+
options: >-
100+
--health-cmd "redis-cli ping"
101+
--health-interval 10s
102+
--health-timeout 5s
103+
--health-retries 5
104+
105+
steps:
106+
- uses: actions/checkout@v4
107+
108+
- name: Install uv
109+
uses: astral-sh/setup-uv@v4
110+
with:
111+
version: "latest"
112+
113+
- name: Install dependencies
114+
run: uv sync --all-extras
115+
116+
- name: Run migrations
117+
env:
118+
DATABASE_URL_SYNC: "postgresql://voyage:voyage@localhost:5432/voyage"
119+
DATABASE_URL: "postgresql+asyncpg://voyage:voyage@localhost:5432/voyage"
120+
run: uv run alembic upgrade head
121+
122+
- name: Run integration tests
123+
env:
124+
DATABASE_URL: "postgresql+asyncpg://voyage:voyage@localhost:5432/voyage"
125+
DATABASE_URL_SYNC: "postgresql://voyage:voyage@localhost:5432/voyage"
126+
REDIS_URL: "redis://localhost:6379/0"
127+
KAFKA_BOOTSTRAP_SERVERS: "localhost:9092"
128+
API_KEY: "test-key"
129+
run: uv run pytest tests/integration/ -v
130+
131+
docker-build:
132+
name: Docker — Build Image
133+
runs-on: ubuntu-latest
134+
needs: [backend-lint, backend-test]
135+
136+
steps:
137+
- uses: actions/checkout@v4
138+
139+
- name: Build backend image
140+
run: |
141+
docker build \
142+
-f infra/docker/Dockerfile.backend \
143+
-t voyage-backend:${{ github.sha }} \
144+
backend/

.gitignore

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Python virtualenvs — never commit these
2+
.venv/
3+
venv/
4+
env/
5+
__pycache__/
6+
*.py[cod]
7+
*.pyo
8+
*.pyd
9+
.Python
10+
*.egg-info/
11+
dist/
12+
build/
13+
*.egg
14+
.claude
15+
/instructions
16+
# uv
17+
.uv/
18+
uv.lock
19+
20+
# Environment variables — NEVER commit real secrets
21+
.env
22+
.env.local
23+
.env.*.local
24+
25+
# Database
26+
*.db
27+
*.sqlite3
28+
29+
# ML artifacts — large files go to MLflow/DVC, not git
30+
backend/ml/models/*.pkl
31+
backend/ml/models/*.onnx
32+
backend/ml/models/*.joblib
33+
mlruns/
34+
mlartifacts/
35+
36+
# Node / frontend
37+
node_modules/
38+
.next/
39+
out/
40+
.vercel/
41+
frontend/.env
42+
frontend/.env.local
43+
44+
# IDE
45+
.vscode/
46+
.idea/
47+
*.swp
48+
*.swo
49+
.DS_Store
50+
Thumbs.db
51+
52+
# Terraform state — use remote backend, never commit
53+
*.tfstate
54+
*.tfstate.backup
55+
.terraform/
56+
*.tfvars
57+
!*.tfvars.example
58+
59+
# Docker
60+
.docker/
61+
62+
# Coverage
63+
.coverage
64+
htmlcov/
65+
.pytest_cache/
66+
67+
# Logs
68+
*.log
69+
logs/

Makefile

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
COMPOSE = docker-compose -f infra/docker/docker-compose.yml
2+
3+
# ─── One command to rule them all ────────────────────────────────────────────
4+
5+
.PHONY: up
6+
up: check ## Run unit tests then start the full stack (fails fast if tests break)
7+
cp -n .env.example .env 2>/dev/null || true
8+
$(COMPOSE) up --build
9+
10+
.PHONY: up-fast
11+
up-fast: ## Start the stack immediately without running tests first
12+
cp -n .env.example .env 2>/dev/null || true
13+
$(COMPOSE) up --build
14+
15+
.PHONY: up-detached
16+
up-detached: check ## Run tests then start everything in background
17+
cp -n .env.example .env 2>/dev/null || true
18+
$(COMPOSE) up --build -d
19+
20+
.PHONY: check
21+
check: ## Fast pre-flight: run unit tests without Docker (needs: make install)
22+
@echo "▶ Running unit tests..."
23+
@if [ -d backend/.venv ]; then \
24+
cd backend && uv run pytest tests/unit/ -q --tb=short --no-header; \
25+
else \
26+
echo " ⚠ Skipped — run 'make install' once to enable pre-flight tests."; \
27+
fi
28+
@echo ""
29+
30+
.PHONY: down
31+
down: ## Stop all services
32+
$(COMPOSE) down
33+
34+
.PHONY: reset
35+
reset: ## Stop all services, wipe all volumes, remove dangling images (fresh start)
36+
$(COMPOSE) down -v
37+
docker image prune -f
38+
39+
# ─── Individual services ──────────────────────────────────────────────────────
40+
41+
.PHONY: infra
42+
infra: ## Start only infrastructure (DB, Redis, Redpanda) — useful for local dev
43+
$(COMPOSE) up -d postgres redis redpanda
44+
45+
.PHONY: logs
46+
logs: ## Tail logs for all services
47+
$(COMPOSE) logs -f
48+
49+
.PHONY: logs-api
50+
logs-api: ## Tail API logs only
51+
$(COMPOSE) logs -f api
52+
53+
.PHONY: logs-worker
54+
logs-worker: ## Tail worker logs only
55+
$(COMPOSE) logs -f worker
56+
57+
.PHONY: logs-frontend
58+
logs-frontend: ## Tail frontend logs only
59+
$(COMPOSE) logs -f frontend
60+
61+
# ─── Testing (no Docker needed for unit tests) ────────────────────────────────
62+
63+
.PHONY: test
64+
test: ## Run unit tests (verbose, with coverage report)
65+
cd backend && uv run pytest tests/unit/ -v
66+
67+
.PHONY: test-cov
68+
test-cov: ## Run tests with full coverage breakdown
69+
cd backend && uv run pytest tests/unit/ -v --cov=app --cov=ingestion --cov-report=term-missing
70+
71+
.PHONY: test-integration
72+
test-integration: ## Run integration tests (requires infra to be running: make infra)
73+
cd backend && uv run pytest tests/integration/ -v
74+
75+
# ─── Dev setup ────────────────────────────────────────────────────────────────
76+
77+
.PHONY: install
78+
install: ## Install Python deps into backend/.venv (for IDE support + local tests)
79+
cd backend && uv sync
80+
81+
# ─── Utilities ────────────────────────────────────────────────────────────────
82+
83+
.PHONY: shell-api
84+
shell-api: ## Open a shell inside the running API container
85+
$(COMPOSE) exec api /bin/sh
86+
87+
.PHONY: shell-db
88+
shell-db: ## Open psql inside the running Postgres container
89+
$(COMPOSE) exec postgres psql -U voyage -d voyage
90+
91+
.PHONY: migrate
92+
migrate: ## Run DB migrations manually
93+
$(COMPOSE) exec api alembic upgrade head
94+
95+
.PHONY: help
96+
help: ## Show this help
97+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
98+
99+
.DEFAULT_GOAL := help

0 commit comments

Comments
 (0)