# Makefile for Medication Reminder App # Check if variables are set in environment, otherwise use .env or defaults ifndef APP_NAME ifndef DOCKER_IMAGE # Include environment variables from .env file if it exists -include .env endif endif # Set defaults if not defined anywhere APP_NAME ?= meds-app DOCKER_IMAGE ?= $(APP_NAME):latest export .PHONY: help install clean \ dev preview build \ test test-watch test-coverage test-fast test-services test-integration \ lint lint-fix format format-check type-check \ docker-build docker-buildx docker-run docker-clean \ seed couchdb-up couchdb-down info # Default target .DEFAULT_GOAL := help ##@ General info: ## Show project information @echo "Project Information:" @echo " Name: $(APP_NAME)" @echo " Docker Image: $(DOCKER_IMAGE)" @echo " Node Version: $(shell node --version 2>/dev/null || echo 'not installed')" @echo " Bun Version: $(shell bun --version 2>/dev/null || echo 'not installed')" @echo "" help: ## Display available commands @echo "$(APP_NAME) - Make Commands" @echo "" @echo "Environment Variables:" @echo " APP_NAME Application name (default: meds-app)" @echo " DOCKER_IMAGE Docker image name (default: $(APP_NAME):latest)" @echo " Variables can be set in .env file or environment" @echo "" @awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " %-20s %s\n", $$1, $$2 } /^##@/ { printf "\n%s\n", substr($$0, 5) } ' $(MAKEFILE_LIST) install: ## Install dependencies @echo "Installing dependencies for $(APP_NAME)..." @bun install clean: ## Clean build artifacts and dependencies @echo "Cleaning up $(APP_NAME) artifacts..." @rm -rf node_modules dist build .cache ##@ Development dev: ## Start development server @echo "Starting $(APP_NAME) development server..." @bun run dev preview: ## Serve production build locally @echo "Starting $(APP_NAME) preview server..." @bun run preview build: ## Build the application @echo "Building $(APP_NAME) application..." @bun run build ##@ Testing test: ## Run unit tests @echo "Running $(APP_NAME) unit tests..." @bun run test test-watch: ## Run unit tests in watch mode @echo "Running $(APP_NAME) tests in watch mode..." @bun run test:watch test-coverage: ## Run tests with coverage report @echo "Running $(APP_NAME) tests with coverage..." @bun run test:coverage test-fast: ## Run fast unit test subset @echo "Running fast unit test subset..." @bun run test:fast test-services: ## Run service layer tests only @echo "Running service layer tests..." @bun run test:services test-integration: ## Run integration tests @echo "Running integration tests..." @bun run test:integration ##@ Quality lint: ## Run ESLint @echo "Linting $(APP_NAME)..." @bun run lint lint-fix: ## Run ESLint with autofix @echo "Linting $(APP_NAME) with auto-fix..." @bun run lint:fix format: ## Format code with Prettier @echo "Formatting $(APP_NAME) code..." @bun run format format-check: ## Check code formatting without writing changes @echo "Checking $(APP_NAME) formatting..." @bun run format:check type-check: ## Run TypeScript type checking @echo "Type-checking $(APP_NAME)..." @bun run type-check ##@ Docker docker-build: ## Build Docker image for local development @echo "Building Docker image for $(APP_NAME): $(DOCKER_IMAGE)" @docker build \ --build-arg NODE_ENV=production \ --build-arg VITE_COUCHDB_URL=$${VITE_COUCHDB_URL} \ --build-arg VITE_COUCHDB_USER=$${VITE_COUCHDB_USER} \ --build-arg VITE_COUCHDB_PASSWORD=$${VITE_COUCHDB_PASSWORD} \ -t $(DOCKER_IMAGE) . docker-buildx: ## Build multi-arch image with buildx (set PUSH=true to push) @echo "Building multi-arch Docker image for $(APP_NAME): $(DOCKER_IMAGE)" @docker buildx build --platform linux/amd64,linux/arm64 \ --build-arg NODE_ENV=production \ --build-arg VITE_COUCHDB_URL=$${VITE_COUCHDB_URL} \ --build-arg VITE_COUCHDB_USER=$${VITE_COUCHDB_USER} \ --build-arg VITE_COUCHDB_PASSWORD=$${VITE_COUCHDB_PASSWORD} \ -t $(DOCKER_IMAGE) $$([ "$${PUSH}" = "true" ] && echo "--push") . docker-run: ## Build and run Docker container @echo "Building and running $(APP_NAME) container: $(DOCKER_IMAGE)" @docker stop $(APP_NAME)-container 2>/dev/null || true @docker rm $(APP_NAME)-container 2>/dev/null || true @make docker-build @docker run --rm -p 8080:80 --name $(APP_NAME)-container $(DOCKER_IMAGE) docker-clean: ## Clean Docker resources and containers @echo "Cleaning Docker resources for $(APP_NAME)..." @docker stop $(APP_NAME)-container 2>/dev/null || true @docker rm $(APP_NAME)-container 2>/dev/null || true @docker rmi $(DOCKER_IMAGE) 2>/dev/null || true @docker image prune -f 2>/dev/null || true @docker container prune -f 2>/dev/null || true ##@ Database seed: ## Seed default admin user into CouchDB @echo "Seeding default admin account..." @bun run seed ##@ Test Services couchdb-up: ## Start local CouchDB for integration tests @echo "Starting CouchDB test service..." @docker compose -f docker-compose.ci.yml up -d couchdb @echo "CouchDB is starting at http://localhost:$${VITE_COUCHDB_PORT:-5984}" @echo "Export credentials for tests if needed:" @echo " export VITE_COUCHDB_URL=http://localhost:$${VITE_COUCHDB_PORT:-5984}" @echo " export VITE_COUCHDB_USER=$${VITE_COUCHDB_USER:-admin}" @echo " export VITE_COUCHDB_PASSWORD=$${VITE_COUCHDB_PASSWORD:-password}" couchdb-down: ## Stop CouchDB test service and remove volume @echo "Stopping CouchDB test service and removing volume..." @docker compose -f docker-compose.ci.yml down -v