# ============================================================================= # Task runner. `make help` lists everything. # ============================================================================= .DEFAULT_GOAL := help COMPOSE := docker compose COMPOSE_DEV := docker compose -f docker-compose.yml -f docker-compose.dev.yml COMPOSE_PROD := docker compose -f docker-compose.yml -f docker-compose.prod.yml .PHONY: help help: ## Show this help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}' # --- Lifecycle --------------------------------------------------------------- .PHONY: env env: ## Create .env from the template (never overwrites an existing one) @test -f .env || (cp .env.example .env && echo "Created .env" && ./scripts/generate_secrets.sh) .PHONY: secrets secrets: ## Replace any remaining change-me placeholders in .env with real secrets @./scripts/generate_secrets.sh .PHONY: up up: env ## Build and start the whole stack $(COMPOSE) up --build -d @echo "SPA http://localhost:$${FRONTEND_PORT:-8080}" @echo "API docs http://localhost:$${FRONTEND_PORT:-8080}/api/docs/" @echo "Kibana http://localhost:$${KIBANA_PORT:-5601}" .PHONY: dev dev: env ## Start the stack with hot reload (Vite on :5173, runserver on :8000) $(COMPOSE_DEV) up --build .PHONY: prod-volumes prod-volumes: ## Create the external data volumes the production overlay expects @for v in postgres elasticsearch logstash; do \ name="$${DATA_VOLUME_PREFIX:-linkedin-search}-$${v}-data"; \ docker volume inspect "$$name" >/dev/null 2>&1 \ && echo " exists $$name" \ || (docker volume create "$$name" >/dev/null && echo " created $$name"); \ done .PHONY: prod-migrate prod-migrate: ## Apply database migrations once, before rolling out a new image $(COMPOSE_PROD) run --rm backend-migrate .PHONY: prod prod: env prod-volumes ## Start with the production overlay $(COMPOSE_PROD) up --build -d @echo "Run 'make prod-migrate' to apply schema changes - production containers do not migrate on boot." .PHONY: down down: ## Stop the stack (keeps volumes) $(COMPOSE) down .PHONY: clean clean: ## Stop the stack and delete all volumes (DESTRUCTIVE - dev stack only) @echo "This deletes the database, the search index and the log queue of the *default* stack." @printf 'Type "yes" to continue: ' && read ans && [ "$$ans" = "yes" ] $(COMPOSE) down -v --remove-orphans .PHONY: logs logs: ## Follow the logs of every service $(COMPOSE) logs -f --tail=100 .PHONY: ps ps: ## Show container status $(COMPOSE) ps # --- Data -------------------------------------------------------------------- .PHONY: seed seed: ## Import the dataset and rebuild the search index $(COMPOSE) exec backend python manage.py import_profiles --truncate --reindex .PHONY: reindex reindex: ## Rebuild the Elasticsearch index from PostgreSQL $(COMPOSE) exec backend python manage.py search_index --rebuild .PHONY: index-status index-status: ## Show index/alias status and document count $(COMPOSE) exec backend python manage.py search_index --status .PHONY: users users: ## Create the demo admin / analyst / viewer accounts $(COMPOSE) exec backend python manage.py seed_users .PHONY: superuser superuser: ## Create a Django superuser interactively $(COMPOSE) exec backend python manage.py createsuperuser .PHONY: shell shell: ## Open a Django shell in the API container $(COMPOSE) exec backend python manage.py shell .PHONY: kibana-setup kibana-setup: ## Register the app-logs data view in Kibana ./scripts/kibana_setup.sh # --- Quality ----------------------------------------------------------------- .PHONY: test test: ## Run the backend test suite inside the stack $(COMPOSE) run --rm backend-test .PHONY: test-local test-local: ## Run the backend test suite against a local PostgreSQL cd backend && pytest .PHONY: lint lint: ## Lint and type-check both halves of the project cd backend && ruff check . && black --check . && mypy apps config cd frontend && npm run lint && npm run typecheck .PHONY: format format: ## Auto-format the codebase cd backend && ruff check --fix . && black . cd frontend && npm run format .PHONY: audit audit: ## Dependency and static security scan cd backend && pip-audit -r requirements/base.txt && bandit -q -r apps config cd frontend && npm audit --omit=dev .PHONY: schema schema: ## Write the OpenAPI schema to docs/openapi.yaml $(COMPOSE) exec backend python manage.py spectacular --api-version v1 > docs/openapi.yaml @echo "Wrote docs/openapi.yaml"