# ============================================================================== # VEZA MONOREPO - ULTIMATE CONTROL PLANE # ============================================================================== # Stack: Docker + Incus (LXD) Support # System: Linux / Bash # ============================================================================== # --- Auto-Configuration --- -include .env # Shell setup SHELL := /bin/bash .ONESHELL: .DEFAULT_GOAL := help # --- Variables --- PROJECT_NAME := veza COMPOSE_FILE := docker-compose.yml COMPOSE_PROD := docker-compose.prod.yml # Services SERVICES := backend-api chat-server stream-server web haproxy INFRA_SERVICES := postgres redis rabbitmq # Ports PORT_GO ?= 8080 PORT_CHAT ?= 3000 PORT_STREAM ?= 3001 PORT_WEB ?= 5173 PORT_HAPROXY ?= 80 # Database & Infra DB_USER ?= veza DB_PASS ?= password DB_NAME ?= veza DB_HOST ?= localhost DB_PORT ?= 5432 # Connection Strings DATABASE_URL = postgres://$(DB_USER):$(DB_PASS)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=disable REDIS_URL = redis://localhost:6379 AMQP_URL = amqp://$(DB_USER):$(DB_PASS)@localhost:5672 # Directories DIR_GO := veza-backend-api DIR_CHAT := veza-chat-server DIR_STREAM := veza-stream-server DIR_WEB := apps/web # Deployment DEPLOY_TARGET ?= docker INCUS_PROFILE := veza-profile INCUS_NETWORK := veza-network # --- Aesthetics & UI --- BOLD := \033[1m RED := \033[0;31m GREEN := \033[0;32m YELLOW := \033[0;33m BLUE := \033[0;34m PURPLE := \033[0;35m CYAN := \033[0;36m NC := \033[0m ECHO_CMD = echo -e # ============================================================================== # HELP & DASHBOARD # ============================================================================== .PHONY: help help: ## Show this dashboard @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}${PURPLE}โšก VEZA MONOREPO CLI โšก${NC}" @$(ECHO_CMD) "=================================================================" @$(ECHO_CMD) "${BOLD}INFRASTRUCTURE:${NC}" @printf " ${CYAN}%-15s${NC} %s\n" "Postgres" "${DATABASE_URL}" @printf " ${CYAN}%-15s${NC} %s\n" "Redis" "${REDIS_URL}" @printf " ${CYAN}%-15s${NC} %s\n" "RabbitMQ" "UI: http://localhost:15672 (veza/password)" @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}${GREEN}HIGH LEVEL COMMANDS:${NC}" @grep -E '^[a-zA-Z0-9_-]+:.*?## \[HIGH\] .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " ${YELLOW}%-25s${NC} %s\n", $$1, $$2}' @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}${BLUE}INTERMEDIATE COMMANDS:${NC}" @grep -E '^[a-zA-Z0-9_-]+:.*?## \[MID\] .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " ${CYAN}%-25s${NC} %s\n", $$1, $$2}' @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}${PURPLE}LOW LEVEL / DEBUG:${NC}" @grep -E '^[a-zA-Z0-9_-]+:.*?## \[LOW\] .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " ${PURPLE}%-25s${NC} %s\n", $$1, $$2}' @$(ECHO_CMD) "" # ============================================================================== # HIGH LEVEL COMMANDS # ============================================================================== .PHONY: setup stop-all restart-all clean deploy-docker deploy-incus status-full setup: check-tools install-tools install-deps ## [HIGH] Full project initialization @$(ECHO_CMD) "${BOLD}${GREEN}โœ… Setup Complete! Ready to rock with 'make dev'.${NC}" stop-all: ## [HIGH] Stop all services (Docker + Local) @$(ECHO_CMD) "${RED}๐Ÿ›‘ Stopping all services...${NC}" @docker compose -f $(COMPOSE_FILE) down 2>/dev/null || true @docker compose -f $(COMPOSE_PROD) down 2>/dev/null || true @$(MAKE) -s stop-local-services @$(ECHO_CMD) "${GREEN}โœ… All services stopped.${NC}" restart-all: stop-all ## [HIGH] Restart all services @$(ECHO_CMD) "${BLUE}๐Ÿ”„ Restarting all services...${NC}" @$(MAKE) -s infra-up @$(MAKE) -s dev @$(ECHO_CMD) "${GREEN}โœ… All services restarted.${NC}" clean: ## [HIGH] Clean build artifacts and caches @$(ECHO_CMD) "${YELLOW}๐Ÿงน Cleaning build artifacts...${NC}" @rm -rf $(DIR_WEB)/node_modules/.cache @rm -rf $(DIR_CHAT)/target/debug $(DIR_STREAM)/target/debug @find . -type d -name "node_modules" -prune -o -type f -name "*.log" -delete @$(ECHO_CMD) "${GREEN}โœ… Clean complete.${NC}" clean-deep: ## [HIGH] โš ๏ธ Nuclear Clean (Confirm required) @read -p "${RED}Are you sure? This will delete ALL builds, volumes, and caches! [y/N]${NC} " ans && [ $${ans:-N} = y ] @$(ECHO_CMD) "${RED}โ˜ข๏ธ DESTROYING ARTIFACTS...${NC}" @rm -rf $(DIR_WEB)/node_modules @rm -rf $(DIR_CHAT)/target $(DIR_STREAM)/target @docker compose -f $(COMPOSE_FILE) down -v 2>/dev/null || true @docker compose -f $(COMPOSE_PROD) down -v 2>/dev/null || true @$(ECHO_CMD) "${GREEN}System Cleaned.${NC}" deploy-docker: build-all ## [HIGH] Deploy all services with Docker + HAProxy @$(ECHO_CMD) "${BOLD}${BLUE}๐Ÿณ Deploying with Docker...${NC}" @docker compose -f $(COMPOSE_PROD) up -d --build @$(MAKE) -s wait-for-services @$(ECHO_CMD) "${GREEN}โœ… Deployment complete! Access via http://localhost:$(PORT_HAPROXY)${NC}" deploy-incus: build-all ## [HIGH] Deploy all services with Incus containers @$(ECHO_CMD) "${BOLD}${BLUE}๐Ÿ“ฆ Deploying with Incus...${NC}" @$(MAKE) -s incus-setup-network @$(MAKE) -s incus-deploy-all @$(ECHO_CMD) "${GREEN}โœ… Incus deployment complete!${NC}" status-full: ## [HIGH] Show complete system status @$(ECHO_CMD) "${BOLD}${CYAN}๐Ÿ“Š SYSTEM STATUS${NC}" @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}Docker Containers:${NC}" @docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "NAME|veza" || echo " No containers running" @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}Local Processes:${NC}" @lsof -i :$(PORT_GO) -i :$(PORT_CHAT) -i :$(PORT_STREAM) -i :$(PORT_WEB) 2>/dev/null | grep LISTEN || echo " No local processes" @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}Incus Containers:${NC}" @incus list veza- 2>/dev/null | grep -E "NAME|veza" || echo " No Incus containers" @$(ECHO_CMD) "" # ============================================================================== # INTERMEDIATE COMMANDS # ============================================================================== .PHONY: start-service stop-service restart-service logs-service build-service start-service: ## [MID] Start a specific service (usage: make start-service SERVICE=backend-api) @if [ -z "$(SERVICE)" ]; then \ $(ECHO_CMD) "${RED}โŒ Please specify SERVICE=name${NC}"; \ exit 1; \ fi @$(ECHO_CMD) "${BLUE}๐Ÿš€ Starting $(SERVICE)...${NC}" @docker compose -f $(COMPOSE_PROD) up -d $(SERVICE) || \ $(MAKE) -s start-local-service SERVICE=$(SERVICE) @$(ECHO_CMD) "${GREEN}โœ… $(SERVICE) started.${NC}" stop-service: ## [MID] Stop a specific service (usage: make stop-service SERVICE=backend-api) @if [ -z "$(SERVICE)" ]; then \ $(ECHO_CMD) "${RED}โŒ Please specify SERVICE=name${NC}"; \ exit 1; \ fi @$(ECHO_CMD) "${YELLOW}๐Ÿ›‘ Stopping $(SERVICE)...${NC}" @docker compose -f $(COMPOSE_PROD) stop $(SERVICE) 2>/dev/null || \ $(MAKE) -s stop-local-service SERVICE=$(SERVICE) @$(ECHO_CMD) "${GREEN}โœ… $(SERVICE) stopped.${NC}" restart-service: stop-service ## [MID] Restart a specific service (usage: make restart-service SERVICE=backend-api) @$(ECHO_CMD) "${BLUE}๐Ÿ”„ Restarting $(SERVICE)...${NC}" @$(MAKE) -s start-service SERVICE=$(SERVICE) @$(ECHO_CMD) "${GREEN}โœ… $(SERVICE) restarted.${NC}" logs-service: ## [MID] Show logs for a service (usage: make logs-service SERVICE=backend-api) @if [ -z "$(SERVICE)" ]; then \ $(ECHO_CMD) "${RED}โŒ Please specify SERVICE=name${NC}"; \ exit 1; \ fi @docker compose -f $(COMPOSE_PROD) logs -f $(SERVICE) || \ $(ECHO_CMD) "${YELLOW}Service not running in Docker, check local logs${NC}" build-service: ## [MID] Build a specific service (usage: make build-service SERVICE=backend-api) @if [ -z "$(SERVICE)" ]; then \ $(ECHO_CMD) "${RED}โŒ Please specify SERVICE=name${NC}"; \ exit 1; \ fi @$(ECHO_CMD) "${BLUE}๐Ÿ”จ Building $(SERVICE)...${NC}" @$(MAKE) -s build-$(SERVICE) @$(ECHO_CMD) "${GREEN}โœ… $(SERVICE) built.${NC}" build-all: ## [MID] Build all services @$(ECHO_CMD) "${BLUE}๐Ÿ”จ Building all services...${NC}" @$(MAKE) -s build-backend-api @$(MAKE) -s build-chat-server @$(MAKE) -s build-stream-server @$(MAKE) -s build-web @$(ECHO_CMD) "${GREEN}โœ… All services built.${NC}" # ============================================================================== # LOW LEVEL / DEBUG COMMANDS # ============================================================================== .PHONY: check-tools install-tools install-deps check-ports check-tools: ## [LOW] Check required tools @$(ECHO_CMD) "${BLUE}Checking core requirements...${NC}" @for tool in docker go cargo npm; do \ command -v $$tool >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}โŒ $$tool is missing!${NC}"; exit 1; }; \ done @$(ECHO_CMD) "${GREEN}โœ… All tools present.${NC}" install-tools: ## [LOW] Install Power User tools (Hot Reload, Linters) @$(ECHO_CMD) "${BLUE}๐Ÿ› ๏ธ Installing Dev Tools...${NC}" @command -v air >/dev/null 2>&1 || go install github.com/air-verse/air@latest @command -v cargo-watch >/dev/null 2>&1 || cargo install cargo-watch @command -v sqlx >/dev/null 2>&1 || cargo install sqlx-cli --no-default-features --features native-tls,postgres @$(ECHO_CMD) "${GREEN}โœ… Tools installed.${NC}" install-deps: ## [LOW] Install code dependencies @$(ECHO_CMD) "${BLUE}๐Ÿ“ฆ Installing dependencies...${NC}" @$(ECHO_CMD) " -> [Go] Downloading modules..." @(cd $(DIR_GO) && go mod download) @$(ECHO_CMD) " -> [Rust Chat] Fetching crates..." @(cd $(DIR_CHAT) && cargo fetch) @$(ECHO_CMD) " -> [Rust Stream] Fetching crates..." @(cd $(DIR_STREAM) && cargo fetch) @$(ECHO_CMD) " -> [Web] Installing npm packages..." @(cd $(DIR_WEB) && npm install --silent) check-ports: ## [LOW] Check if ports are available @$(ECHO_CMD) "${BLUE}๐Ÿ” Checking ports...${NC}" @for port in $(PORT_GO) $(PORT_CHAT) $(PORT_STREAM) $(PORT_WEB); do \ if lsof -i :$$port -t >/dev/null 2>&1; then \ $(ECHO_CMD) "${YELLOW}โš ๏ธ Port $$port is busy${NC}"; \ else \ $(ECHO_CMD) "${GREEN}โœ… Port $$port is free${NC}"; \ fi; \ done # ============================================================================== # INFRASTRUCTURE # ============================================================================== .PHONY: infra-up infra-down wait-for-infra db-shell redis-shell db-migrate infra-up: ## [MID] Start Docker Infra (with health checks) @$(ECHO_CMD) "${BLUE}๐Ÿณ Starting Infrastructure...${NC}" @docker compose -f $(COMPOSE_FILE) up -d @$(MAKE) -s wait-for-infra infra-down: ## [MID] Stop Docker Infra @$(ECHO_CMD) "${BLUE}๐Ÿ›‘ Stopping Infrastructure...${NC}" @docker compose -f $(COMPOSE_FILE) down wait-for-infra: ## [LOW] Wait for infrastructure to be ready @printf "${BLUE}โณ Waiting for services...${NC}" @until docker compose -f $(COMPOSE_FILE) exec -T postgres pg_isready -U $(DB_USER) > /dev/null 2>&1; do printf "."; sleep 1; done @until docker compose -f $(COMPOSE_FILE) exec -T redis redis-cli ping > /dev/null 2>&1; do printf "."; sleep 1; done @$(ECHO_CMD) " ${GREEN}OK${NC}" wait-for-services: ## [LOW] Wait for all application services @printf "${BLUE}โณ Waiting for services...${NC}" @for service in backend-api chat-server stream-server web; do \ until docker compose -f $(COMPOSE_PROD) exec -T $$service echo "ready" > /dev/null 2>&1; do \ printf "."; sleep 1; \ done; \ done @$(ECHO_CMD) " ${GREEN}OK${NC}" db-shell: ## [MID] Connect to Postgres shell @docker compose -f $(COMPOSE_FILE) exec postgres psql -U $(DB_USER) -d $(DB_NAME) redis-shell: ## [MID] Connect to Redis shell @docker compose -f $(COMPOSE_FILE) exec redis redis-cli db-migrate: infra-up ## [MID] Run all database migrations @$(ECHO_CMD) "${BLUE}๐Ÿ”„ Running Migrations...${NC}" @$(ECHO_CMD) " -> [Go] Migrating..." @(cd $(DIR_GO) && go run cmd/migrate_tool/main.go up || $(ECHO_CMD) "${YELLOW}Warning: Go migration failed${NC}") @$(ECHO_CMD) " -> [Chat] Migrating..." @(cd $(DIR_CHAT) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Chat migration failed${NC}") @$(ECHO_CMD) " -> [Stream] Migrating..." @(cd $(DIR_STREAM) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Stream migration failed${NC}") @$(ECHO_CMD) "${GREEN}โœ… Migrations done.${NC}" # ============================================================================== # DEVELOPMENT # ============================================================================== .PHONY: dev dev-backend stop-local-services start-local-service stop-local-service dev: check-ports infra-up ## [HIGH] Start Everything (Detects Hot Reload tools) @$(ECHO_CMD) "${BOLD}${PURPLE}๐Ÿš€ STARTING HYBRID DEV ENVIRONMENT${NC}" @$(ECHO_CMD) " Go: http://localhost:${PORT_GO}" @$(ECHO_CMD) " Chat: http://localhost:${PORT_CHAT}" @$(ECHO_CMD) " Web: http://localhost:${PORT_WEB}" @$(ECHO_CMD) "${YELLOW}Hit Ctrl+C to stop all.${NC}" @(trap 'kill 0' SIGINT; \ if command -v air >/dev/null; then \ $(ECHO_CMD) "${GREEN}[Go] Hot Reload Active (Air)${NC}" && cd $(DIR_GO) && air & \ else \ $(ECHO_CMD) "${YELLOW}[Go] Standard Run${NC}" && cd $(DIR_GO) && go run cmd/modern-server/main.go & \ fi; \ if command -v cargo-watch >/dev/null; then \ $(ECHO_CMD) "${GREEN}[Chat] Hot Reload Active${NC}" && cd $(DIR_CHAT) && cargo watch -x run -q & \ $(ECHO_CMD) "${GREEN}[Stream] Hot Reload Active${NC}" && cd $(DIR_STREAM) && cargo watch -x run -q & \ else \ $(ECHO_CMD) "${YELLOW}[Chat] Standard Run${NC}" && cd $(DIR_CHAT) && cargo run -q & \ $(ECHO_CMD) "${YELLOW}[Stream] Standard Run${NC}" && cd $(DIR_STREAM) && cargo run -q & \ fi; \ $(ECHO_CMD) "${GREEN}[Web] Starting Vite...${NC}" && cd $(DIR_WEB) && npm run dev & \ wait) dev-backend: check-ports infra-up ## [MID] Start Backends Only (Hot Reload supported) @$(ECHO_CMD) "${BOLD}${PURPLE}๐Ÿš€ STARTING BACKEND ONLY${NC}" @(trap 'kill 0' SIGINT; \ if command -v air >/dev/null; then cd $(DIR_GO) && air & else cd $(DIR_GO) && go run cmd/modern-server/main.go & fi; \ if command -v cargo-watch >/dev/null; then cd $(DIR_CHAT) && cargo watch -x run -q & else cd $(DIR_CHAT) && cargo run -q & fi; \ if command -v cargo-watch >/dev/null; then cd $(DIR_STREAM) && cargo watch -x run -q & else cd $(DIR_STREAM) && cargo run -q & fi; \ wait) stop-local-services: ## [LOW] Stop all local processes @pkill -f "air\|cargo watch\|npm run dev\|go run.*modern-server" 2>/dev/null || true start-local-service: ## [LOW] Start a service locally @case "$(SERVICE)" in \ backend-api) \ if command -v air >/dev/null; then cd $(DIR_GO) && air & else cd $(DIR_GO) && go run cmd/modern-server/main.go & fi ;; \ chat-server) \ if command -v cargo-watch >/dev/null; then cd $(DIR_CHAT) && cargo watch -x run -q & else cd $(DIR_CHAT) && cargo run -q & fi ;; \ stream-server) \ if command -v cargo-watch >/dev/null; then cd $(DIR_STREAM) && cargo watch -x run -q & else cd $(DIR_STREAM) && cargo run -q & fi ;; \ web) \ cd $(DIR_WEB) && npm run dev & ;; \ *) \ $(ECHO_CMD) "${RED}Unknown service: $(SERVICE)${NC}"; exit 1 ;; \ esac stop-local-service: ## [LOW] Stop a local service @case "$(SERVICE)" in \ backend-api) pkill -f "air\|go run.*modern-server" ;; \ chat-server|stream-server) pkill -f "cargo.*$(SERVICE)" ;; \ web) pkill -f "npm run dev\|vite" ;; \ *) $(ECHO_CMD) "${RED}Unknown service: $(SERVICE)${NC}" ;; \ esac # ============================================================================== # BUILD COMMANDS # ============================================================================== .PHONY: build-backend-api build-chat-server build-stream-server build-web build-backend-api: ## [LOW] Build Go backend @$(ECHO_CMD) "${BLUE}๐Ÿ”จ Building backend-api...${NC}" @docker build -t $(PROJECT_NAME)-backend-api:latest -f $(DIR_GO)/Dockerfile.production $(DIR_GO) || \ $(ECHO_CMD) "${YELLOW}Using local Dockerfile...${NC}" && \ docker build -t $(PROJECT_NAME)-backend-api:latest -f $(DIR_GO)/Dockerfile $(DIR_GO) build-chat-server: ## [LOW] Build Rust chat server @$(ECHO_CMD) "${BLUE}๐Ÿ”จ Building chat-server...${NC}" @docker build -t $(PROJECT_NAME)-chat-server:latest -f $(DIR_CHAT)/Dockerfile.production $(DIR_CHAT) || \ docker build -t $(PROJECT_NAME)-chat-server:latest -f $(DIR_CHAT)/Dockerfile $(DIR_CHAT) build-stream-server: ## [LOW] Build Rust stream server @$(ECHO_CMD) "${BLUE}๐Ÿ”จ Building stream-server...${NC}" @docker build -t $(PROJECT_NAME)-stream-server:latest -f $(DIR_STREAM)/Dockerfile.production $(DIR_STREAM) || \ docker build -t $(PROJECT_NAME)-stream-server:latest -f $(DIR_STREAM)/Dockerfile $(DIR_STREAM) build-web: ## [LOW] Build web frontend @$(ECHO_CMD) "${BLUE}๐Ÿ”จ Building web...${NC}" @docker build -t $(PROJECT_NAME)-web:latest -f $(DIR_WEB)/Dockerfile.production $(DIR_WEB) || \ docker build -t $(PROJECT_NAME)-web:latest -f $(DIR_WEB)/Dockerfile $(DIR_WEB) # ============================================================================== # INCUS / LXD DEPLOYMENT # ============================================================================== .PHONY: incus-setup-network incus-deploy-all incus-deploy-service incus-stop-all incus-logs incus-setup-network: ## [LOW] Setup Incus network profile @$(ECHO_CMD) "${BLUE}๐Ÿ“ฆ Setting up Incus network...${NC}" @incus network show $(INCUS_NETWORK) >/dev/null 2>&1 || \ incus network create $(INCUS_NETWORK) ipv4.address=10.10.10.1/24 ipv4.nat=true @incus profile show $(INCUS_PROFILE) >/dev/null 2>&1 || \ incus profile create $(INCUS_PROFILE) && \ incus profile device add $(INCUS_PROFILE) eth0 nic network=$(INCUS_NETWORK) @$(ECHO_CMD) "${GREEN}โœ… Incus network ready.${NC}" incus-deploy-all: incus-setup-network ## [MID] Deploy all services to Incus @$(ECHO_CMD) "${BLUE}๐Ÿ“ฆ Deploying all services to Incus...${NC}" @$(MAKE) -s incus-deploy-service SERVICE=backend-api @$(MAKE) -s incus-deploy-service SERVICE=chat-server @$(MAKE) -s incus-deploy-service SERVICE=stream-server @$(MAKE) -s incus-deploy-service SERVICE=web @$(MAKE) -s incus-deploy-service SERVICE=haproxy @$(ECHO_CMD) "${GREEN}โœ… All services deployed to Incus.${NC}" incus-deploy-service: ## [LOW] Deploy a service to Incus (usage: make incus-deploy-service SERVICE=backend-api) @if [ -z "$(SERVICE)" ]; then \ $(ECHO_CMD) "${RED}โŒ Please specify SERVICE=name${NC}"; \ exit 1; \ fi @$(ECHO_CMD) "${BLUE}๐Ÿ“ฆ Deploying $(SERVICE) to Incus...${NC}" @if incus list -c n --format csv | grep -q "^veza-$(SERVICE)$$"; then \ $(ECHO_CMD) "${YELLOW}Container exists, removing...${NC}"; \ incus delete veza-$(SERVICE) --force; \ fi @incus init images:ubuntu/22.04 veza-$(SERVICE) --profile $(INCUS_PROFILE) @incus start veza-$(SERVICE) @$(ECHO_CMD) "${BLUE}Installing Docker in container...${NC}" @incus exec veza-$(SERVICE) -- bash -c "apt-get update && apt-get install -y docker.io docker-compose && systemctl enable docker && systemctl start docker" || true @$(ECHO_CMD) "${GREEN}โœ… $(SERVICE) deployed.${NC}" incus-stop-all: ## [MID] Stop all Incus containers @$(ECHO_CMD) "${YELLOW}๐Ÿ›‘ Stopping all Incus containers...${NC}" @for container in $$(incus list -c n --format csv | grep veza-); do \ incus stop $$container 2>/dev/null || true; \ done @$(ECHO_CMD) "${GREEN}โœ… All Incus containers stopped.${NC}" incus-logs: ## [LOW] Show logs from Incus container (usage: make incus-logs SERVICE=backend-api) @if [ -z "$(SERVICE)" ]; then \ $(ECHO_CMD) "${RED}โŒ Please specify SERVICE=name${NC}"; \ exit 1; \ fi @incus exec veza-$(SERVICE) -- journalctl -f # ============================================================================== # TEST & QUALITY # ============================================================================== .PHONY: test lint fmt status test: infra-up ## [MID] Run All Tests (Fastest strategy) @$(ECHO_CMD) "${BLUE}๐Ÿงช Running Tests...${NC}" @$(ECHO_CMD) " [Go] Unit Tests..." @(cd $(DIR_GO) && go test ./... -short) @$(ECHO_CMD) " [Rust] Unit Tests..." @(cd $(DIR_CHAT) && cargo test --lib -q) @(cd $(DIR_STREAM) && cargo test --lib -q) @$(ECHO_CMD) " [Web] Unit Tests..." @(cd $(DIR_WEB) && npm run test -- --run) @$(ECHO_CMD) "${GREEN}โœ… All tests passed.${NC}" lint: ## [MID] Lint everything @$(ECHO_CMD) "${BLUE}๐Ÿ” Linting Codebase...${NC}" @(cd $(DIR_CHAT) && cargo clippy -- -D warnings) || true @(cd $(DIR_STREAM) && cargo clippy -- -D warnings) || true @(cd $(DIR_GO) && golangci-lint run ./...) || true @(cd $(DIR_WEB) && npm run lint) || true fmt: ## [MID] Format everything @$(ECHO_CMD) "${BLUE}โœจ Formatting...${NC}" @(cd $(DIR_GO) && go fmt ./...) @(cd $(DIR_CHAT) && cargo fmt) @(cd $(DIR_STREAM) && cargo fmt) @(cd $(DIR_WEB) && npm run format) || true status: ## [MID] Show system health & stats @$(ECHO_CMD) "${BOLD}DOCKER STATS:${NC}" @docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" 2>/dev/null | grep -E "NAME|veza" || echo "No containers running" @$(ECHO_CMD) "" @$(ECHO_CMD) "${BOLD}LOCAL PORTS:${NC}" @lsof -i :$(PORT_GO) -i :$(PORT_CHAT) -i :$(PORT_STREAM) -i :$(PORT_WEB) 2>/dev/null | grep LISTEN || echo "No apps listening."