# Edge AI Platform - Makefile .PHONY: help dev dev-mock build clean test lint mock install fmt build-embed release release-snapshot \ build-server-tray installer-payload installer installer-dev installer-clean deploy-frontend deploy-frontend-setup deploy-ec2 build-relay VERSION ?= v0.1.0 BUILD_TIME := $(shell date -u +%Y-%m-%dT%H:%M:%SZ) help: ## Show available targets @echo "Edge AI Platform - Available targets:" @echo "" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \ awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}' # ── Development ────────────────────────────────────────── dev: ## Start frontend + backend with REAL hardware (no mock) @echo "Starting development servers (real hardware)..." @$(MAKE) -j2 dev-server dev-frontend dev-server: cd server && go run main.go --dev dev-frontend: cd frontend && pnpm dev dev-mock: ## Start frontend + backend with mock devices @echo "Starting development servers (mock mode)..." @$(MAKE) -j2 dev-mock-server dev-frontend dev-mock-server: cd server && go run main.go --dev --mock --mock-devices=3 mock: ## Start server in mock mode only (no frontend) cd server && go run main.go --dev --mock --mock-devices=3 --mock-camera # ── Build ──────────────────────────────────────────────── build: build-frontend build-embed build-server ## Build single binary with embedded frontend @echo "Build complete! Binary: dist/edge-ai-server" build-frontend: ## Build Next.js frontend static export cd frontend && pnpm build @echo "Frontend built: frontend/out/" build-embed: ## Copy frontend static export into server for go:embed @rm -rf server/web/out @mkdir -p server/web/out cp -r frontend/out/. server/web/out/ @echo "Frontend static files copied to server/web/out/" build-server: ## Build Go server binary (embeds frontend) @mkdir -p dist cd server && go build \ -ldflags="-X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME)" \ -o ../dist/edge-ai-server main.go @echo "Server binary: dist/edge-ai-server" build-relay: ## Build relay server binary @mkdir -p dist cd server && go build -o ../dist/relay-server ./cmd/relay-server @echo "Relay binary: dist/relay-server" build-server-tray: build-frontend build-embed ## Build server with tray support (CGO required) @mkdir -p dist cd server && CGO_ENABLED=1 go build \ -ldflags="-X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME)" \ -o ../dist/edge-ai-server main.go @echo "Server binary (tray-enabled): dist/edge-ai-server" # ── Release ────────────────────────────────────────────── release-snapshot: ## Build release archives locally (no publish) goreleaser release --snapshot --clean release: ## Build and publish release to Gitea goreleaser release --clean # ── Testing ────────────────────────────────────────────── test: test-server test-frontend ## Run all tests @echo "All tests passed!" test-server: ## Run Go tests cd server && go test -v ./... test-frontend: ## Run Vitest tests cd frontend && pnpm test test-coverage: ## Run tests with coverage reports cd server && go test -coverprofile=coverage.out ./... && \ go tool cover -html=coverage.out -o coverage.html cd frontend && pnpm test -- --coverage # ── Linting ────────────────────────────────────────────── lint: lint-server lint-frontend ## Lint all code lint-server: ## Lint Go code cd server && go vet ./... lint-frontend: ## Lint frontend code cd frontend && pnpm lint fmt: ## Format all code cd server && go fmt ./... # ── Dependencies ───────────────────────────────────────── install: ## Install all dependencies cd server && go mod download cd frontend && pnpm install # ── GUI Installer ──────────────────────────────────────── installer-payload: build-server-tray ## Stage payload files for GUI installer @echo "Staging installer payload..." @rm -rf installer/payload @mkdir -p installer/payload/data/nef/kl520 @mkdir -p installer/payload/data/nef/kl720 @mkdir -p installer/payload/scripts/firmware/KL520 @mkdir -p installer/payload/scripts/firmware/KL720 cp dist/edge-ai-server installer/payload/ cp server/data/models.json installer/payload/data/ cp server/data/nef/kl520/*.nef installer/payload/data/nef/kl520/ cp server/data/nef/kl720/*.nef installer/payload/data/nef/kl720/ cp server/scripts/kneron_bridge.py installer/payload/scripts/ cp server/scripts/requirements.txt installer/payload/scripts/ cp server/scripts/update_kl720_firmware.py installer/payload/scripts/ cp scripts/kneron_detect.py installer/payload/scripts/ cp server/scripts/firmware/KL520/*.bin installer/payload/scripts/firmware/KL520/ cp server/scripts/firmware/KL720/*.bin installer/payload/scripts/firmware/KL720/ @echo "Payload staged in installer/payload/" installer: installer-payload ## Build GUI installer app cd installer && wails build -clean codesign --force --deep --sign - installer/build/bin/EdgeAI-Installer.app @echo "Installer built and signed! Check installer/build/" installer-dev: installer-payload ## Run GUI installer in dev mode cd installer && wails dev installer-clean: ## Remove installer build artifacts rm -rf installer/payload @mkdir -p installer/payload && touch installer/payload/.gitkeep rm -rf installer/build @echo "Installer artifacts cleaned!" # ── Deploy ─────────────────────────────────────────────── deploy-frontend: build-frontend ## Deploy frontend to AWS (CloudFront + S3) bash scripts/deploy-aws.sh deploy-frontend-setup: build-frontend ## First-time AWS S3+CloudFront setup + deploy bash scripts/deploy-aws.sh --setup deploy-ec2: build-frontend ## Deploy frontend to EC2 (nginx). Usage: make deploy-ec2 HOST=user@ip KEY=~/.ssh/key.pem bash scripts/deploy-ec2.sh $(HOST) --key $(KEY) # ── Cleanup ────────────────────────────────────────────── clean: installer-clean ## Remove build artifacts rm -rf dist/ rm -rf frontend/.next rm -rf frontend/out rm -rf server/web/out @mkdir -p server/web/out && touch server/web/out/.gitkeep rm -f server/coverage.out server/coverage.html @echo "Clean complete!"