.PHONY: install-backend install-frontend install setup-hooks backend frontend worker db db-stop db-ready db-seed dev test test-backend test-frontend test-e2e typecheck generate-types generate-types-standalone check-types-fresh check-constants lint-backend format-backend fix-backend security-backend lint-frontend fix-frontend format-frontend pre-commit lint -include .env export install-backend: cd backend && uv sync --all-groups install-frontend: cd frontend && npm install install: install-backend install-frontend setup-hooks setup-hooks: git config core.hooksPath .githooks backend: cd backend && uv run uvicorn main:app --reload frontend: cd frontend && npm run dev worker: cd backend && uv run python worker.py db: docker compose up -d db db-stop: docker compose down db-clean: docker compose down -v db-ready: @docker compose up -d db @echo "Waiting for PostgreSQL to be ready..." @until docker compose exec -T db pg_isready -U postgres > /dev/null 2>&1; do \ sleep 1; \ done @docker compose exec -T db psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'arbret_test'" | grep -q 1 || \ docker compose exec -T db psql -U postgres -c "CREATE DATABASE arbret_test" @# Create worker-specific databases for parallel test execution (pytest-xdist) @for i in 0 1 2 3 4 5 6 7; do \ docker compose exec -T db psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'arbret_test_gw$$i'" | grep -q 1 || \ docker compose exec -T db psql -U postgres -c "CREATE DATABASE arbret_test_gw$$i"; \ done @echo "PostgreSQL is ready" db-seed: db-ready cd backend && uv run python seed.py dev: $(MAKE) db-seed cd backend && uv run uvicorn main:app --reload & \ cd backend && uv run python worker.py & \ cd frontend && npm run dev & \ wait # TEST variable can be used to select specific tests: # Backend: TEST="-m auth" (marker) or TEST="tests/test_booking.py" (file) or TEST="tests/test_booking.py::TestBooking::test_specific" (specific test) # Frontend: TEST="app/login" (file pattern matching app/**/*.test.{ts,tsx}) # E2E: TEST="auth" (file pattern matching e2e/*.spec.ts) TEST ?= test-backend: db-clean db-ready cd backend && uv run pytest -v -n 8 $(TEST) test-frontend: cd frontend && npm run test $(if $(TEST),-- $(TEST),) test-e2e: db-clean db-ready ./scripts/e2e.sh $(TEST) test: check-constants check-types-fresh test-backend test-frontend test-e2e typecheck: generate-types-standalone cd backend && uv run mypy . cd frontend && npx tsc --noEmit generate-types: cd frontend && npm run generate-api-types generate-types-standalone: db-seed @echo "Starting backend for type generation..." @cd backend && uv run uvicorn main:app --port 8000 --log-level warning & \ BACKEND_PID=$$!; \ sleep 3; \ cd frontend && npm run generate-api-types; \ EXIT_CODE=$$?; \ kill $$BACKEND_PID 2>/dev/null || true; \ exit $$EXIT_CODE check-types-fresh: generate-types-standalone @if git diff --quiet frontend/app/generated/api.ts 2>/dev/null; then \ echo "✓ Generated types are up to date"; \ else \ echo "✗ Generated types are stale. Run 'make generate-types-standalone' and commit."; \ git diff frontend/app/generated/api.ts; \ exit 1; \ fi check-constants: @cd backend && uv run python validate_constants.py lint-backend: cd backend && uv run ruff check . format-backend: cd backend && uv run ruff format . fix-backend: cd backend && uv run ruff check --fix . && uv run ruff format . security-backend: cd backend && uv run bandit -r . -c pyproject.toml lint-frontend: cd frontend && npm run lint fix-frontend: cd frontend && npm run lint:fix format-frontend: cd frontend && npm run format pre-commit: cd backend && uv run pre-commit run --all-files lint: lint-backend lint-frontend security-backend @echo "All linting passed!"