SHELL := /bin/bash BACKEND_DIR := backend WEB_DIR := backend/web INFRA_DIR := infra DEPLOY_DIR := deploy INFRA_DEV_COMPOSE := docker compose --env-file $(DEPLOY_DIR)/.env.dev -f $(INFRA_DIR)/docker-compose.yml INFRA_PROD_COMPOSE := docker compose --env-file $(DEPLOY_DIR)/.env.prod -f $(INFRA_DIR)/docker-compose.yml DEPLOY_COMPOSE := docker compose --env-file $(DEPLOY_DIR)/.env.prod -f $(DEPLOY_DIR)/docker-compose.yml .DEFAULT_GOAL := help .PHONY: help help: ## 顯示可用指令 @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-18s\033[0m %s\n", $$1, $$2}' .PHONY: gen-api gen-api: ## 重新產生後端 API handler / logic / types $(MAKE) -C $(BACKEND_DIR) gen-api .PHONY: fmt fmt: ## 格式化後端 Go 程式 $(MAKE) -C $(BACKEND_DIR) fmt .PHONY: test test: ## 執行後端測試 $(MAKE) -C $(BACKEND_DIR) test .PHONY: run run: ## 啟動後端 API $(MAKE) -C $(BACKEND_DIR) run .PHONY: dev-all dev-all: ## 啟動本機完整 dev stack(API、Go workers、Node workers、web) ./scripts/dev-all.sh .PHONY: dev-all-stop dev-all-stop: ## 停止本機 dev stack(釋放 8890 / 9101 / 9102 / web 等埠) ./scripts/dev-all-stop.sh .PHONY: web-dev web-dev: ## 啟動正式前端 dev server cd $(WEB_DIR) && npm install && npm run dev .PHONY: web-build web-build: ## 建置正式前端 cd $(WEB_DIR) && npm install && npm run build .PHONY: verify verify: test web-build ## 後端測試與前端建置 .PHONY: dev-infra dev-infra: ## 啟動本機 dev 資料服務(Mongo / Redis 容器,讀 deploy/.env.dev) @test -f $(DEPLOY_DIR)/.env.dev || cp $(DEPLOY_DIR)/.env.dev.example $(DEPLOY_DIR)/.env.dev @echo ">>> 請先編輯 $(DEPLOY_DIR)/.env.dev 再執行後續指令" >&2 $(INFRA_DEV_COMPOSE) up -d $(INFRA_DEV_COMPOSE) ps .PHONY: dev-infra-down dev-infra-down: ## 關閉本機 dev 資料服務(保留資料 volume) $(INFRA_DEV_COMPOSE) down .PHONY: prod-install prod-install: ## 一鍵安裝 prod:複製 .env.prod、啟動 infra、init、啟動 app @test -f $(DEPLOY_DIR)/.env.prod || cp $(DEPLOY_DIR)/.env.prod.example $(DEPLOY_DIR)/.env.prod @echo ">>> 請先編輯 $(DEPLOY_DIR)/.env.prod 再執行後續指令" >&2 $(INFRA_PROD_COMPOSE) up -d $(INFRA_PROD_COMPOSE) ps $(DEPLOY_COMPOSE) pull $(DEPLOY_COMPOSE) up -d $(DEPLOY_COMPOSE) --profile init run --rm init $(DEPLOY_COMPOSE) ps .PHONY: prod-rebuild prod-rebuild: ## 重新拉取 image 並重建 prod stack(infra + app) $(INFRA_PROD_COMPOSE) pull $(INFRA_PROD_COMPOSE) up -d $(DEPLOY_COMPOSE) pull $(DEPLOY_COMPOSE) up -d $(DEPLOY_COMPOSE) ps .PHONY: prod-stop prod-stop: ## 關閉 prod app stack(保留 infra 與資料) $(DEPLOY_COMPOSE) down .PHONY: prod-stop-all prod-stop-all: ## 關閉 prod app + infra(保留資料 volume) $(DEPLOY_COMPOSE) down $(INFRA_PROD_COMPOSE) down