# 巡樓 monorepo Makefile # 兩種模式: # dev - 本機開發(docker 起 Mongo/Redis,go run / vite dev 在本機跑) # docker - 全棧一鍵啟動(Mongo/Redis/gateway/worker/node-worker/web 全在 docker) # # 常用: # make up # 一鍵:build + 啟動整套(含前後端、worker、DB) # make down # 停掉整套 # make logs # 追全部日誌 # make dev-infra # 本機開發:只起 Mongo/Redis # make dev-backend # 本機開發:go run gateway (:8890) # make dev-frontend # 本機開發:vite dev (:5173) SHELL := /bin/bash # --- 路徑 --- BACKEND_DIR := backend FRONTEND_DIR := frontend # --- docker compose(prod 全棧)--- COMPOSE_FILE := deploy/docker-compose.yml ENV_FILE := deploy/.env COMPOSE := docker compose -f $(COMPOSE_FILE) --env-file $(ENV_FILE) # --- docker compose(本地測試;base + dev override + dev env)--- DEV_ENV_FILE := deploy/.env.dev DEV_COMPOSE := docker compose -f $(COMPOSE_FILE) -f deploy/docker-compose.dev.yml --env-file $(DEV_ENV_FILE) # go worker 用 gateway 內嵌,dev 不啟動獨立 worker 容器 DEV_SERVICES := mongo redis init gateway node-worker web # --- dev 用 worker secret(對應 etc/gateway.yaml 的 InternalWorker.Secret)--- DEV_WORKER_SECRET := haixun-dev-worker-secret DEV_BACKEND_URL := http://127.0.0.1:8890 .DEFAULT_GOAL := help .PHONY: help help: ## 顯示可用指令 @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}' $(ENV_FILE): @test -f $(ENV_FILE) || (cp deploy/.env.example $(ENV_FILE) && echo "已從 deploy/.env.example 建立 $(ENV_FILE),請填入密碼與 secret 後再 make up") # ============================================================ # DOCKER(全棧一鍵) # ============================================================ .PHONY: up up: $(ENV_FILE) ## [docker] 一鍵啟動整套(build + up,背景) $(COMPOSE) up -d --build @echo "" @echo "=== 啟動中 ===" @echo " 前端: http://localhost:$$(grep -E '^WEB_PORT=' $(ENV_FILE) | cut -d= -f2)" @echo " 健康檢查: curl http://localhost:$$(grep -E '^WEB_PORT=' $(ENV_FILE) | cut -d= -f2)/api/v1/health" @echo " 看狀態: make ps 看日誌: make logs" .PHONY: down down: ## [docker] 停掉整套(保留資料 volume) $(COMPOSE) down .PHONY: down-clean down-clean: ## [docker] 停掉整套並刪除資料 volume(清空 Mongo/Redis) $(COMPOSE) down -v .PHONY: build build: $(ENV_FILE) ## [docker] 只 build image,不啟動 $(COMPOSE) build .PHONY: rebuild rebuild: $(ENV_FILE) ## [docker] 無快取重新 build 並重啟 $(COMPOSE) build --no-cache $(COMPOSE) up -d .PHONY: restart restart: ## [docker] 重啟所有服務 $(COMPOSE) restart .PHONY: ps ps: ## [docker] 看服務狀態 $(COMPOSE) ps .PHONY: logs logs: ## [docker] 追全部日誌(Ctrl-C 離開) $(COMPOSE) logs -f .PHONY: logs-gateway logs-gateway: ## [docker] 只看 gateway 日誌 $(COMPOSE) logs -f gateway .PHONY: init init: $(ENV_FILE) ## [docker] 重跑一次 DB 初始化(索引/權限/admin,冪等) $(COMPOSE) run --rm init .PHONY: config config: $(ENV_FILE) ## [docker] 驗證 compose 設定 $(COMPOSE) config >/dev/null && echo "docker compose config OK" # ============================================================ # DEV(本地測試,全走 docker) # ============================================================ .PHONY: dev-up dev-up: ## [dev] 一鍵:本地 docker 測試(gateway 開 :8890,web 開 :8080,go worker 內嵌) $(DEV_COMPOSE) up -d --build $(DEV_SERVICES) @echo "" @echo "=== 本地測試啟動中 ===" @echo " 前端: http://localhost:$$(grep -E '^WEB_PORT=' $(DEV_ENV_FILE) | cut -d= -f2)" @echo " API: http://localhost:8890/api/v1/health" @echo " DevHeaderFallback 已開(可用 X-Tenant-ID / X-UID 模擬登入)" .PHONY: dev-down dev-down: ## [dev] 停掉本地 docker(保留資料) $(DEV_COMPOSE) down .PHONY: dev-down-clean dev-down-clean: ## [dev] 停掉本地 docker 並清空資料 volume $(DEV_COMPOSE) down -v .PHONY: dev-rebuild dev-rebuild: ## [dev] 改 code 後重新 build 並重啟本地 docker $(DEV_COMPOSE) up -d --build $(DEV_SERVICES) .PHONY: dev-restart dev-restart: ## [dev] 只重啟(改了 etc/*.yaml 後不用 rebuild,掛載即生效) $(DEV_COMPOSE) restart gateway node-worker .PHONY: dev-ps dev-ps: ## [dev] 看本地 docker 狀態 $(DEV_COMPOSE) ps .PHONY: dev-logs dev-logs: ## [dev] 追本地 docker 日誌 $(DEV_COMPOSE) logs -f .PHONY: dev-init dev-init: ## [dev] 重跑一次 DB 初始化(索引/權限/admin,冪等) $(DEV_COMPOSE) run --rm init .PHONY: dev dev: ## [dev] 本地 docker 測試說明 @echo "本地測試(全 docker):" @echo " make dev-up # 一鍵起整套(前端 :8080、API :8890)" @echo " make dev-logs # 看日誌" @echo " make dev-restart # 改 etc/*.yaml 後重啟(免 rebuild)" @echo " make dev-rebuild # 改 Go/前端 code 後重 build" @echo " make dev-down # 停(保留資料)" # --- 進階:不進 docker,直接本機 go run / vite(需自備 Go/Node)--- .PHONY: local-infra local-infra: ## [local] 只起 Mongo + Redis(docker),其餘本機跑 $(DEV_COMPOSE) up -d mongo redis $(DEV_COMPOSE) ps .PHONY: local-backend local-backend: ## [local] 本機 go run gateway (:8890) cd $(BACKEND_DIR) && go run . -f etc/gateway.yaml .PHONY: local-worker local-worker: ## [local] 本機 go run Go job worker (:8891) cd $(BACKEND_DIR) && go run ./cmd/worker -f etc/gateway.worker.yaml .PHONY: local-node-worker local-node-worker: ## [local] 本機跑 Node playwright worker (style-8d) cd $(BACKEND_DIR)/worker && npm install && \ HAIXUN_WORKER_SECRET=$(DEV_WORKER_SECRET) HAIXUN_BACKEND_URL=$(DEV_BACKEND_URL) npm run style-8d .PHONY: local-frontend local-frontend: ## [local] 本機跑前端 dev server (:5173) cd $(FRONTEND_DIR) && npm install && npm run dev .PHONY: local-init local-init: ## [local] 本機初始化 DB(索引/權限)並建立 admin cd $(BACKEND_DIR) && go run ./cmd/tool init -f etc/gateway.yaml # ============================================================ # 驗證 / 維護 # ============================================================ .PHONY: tidy tidy: ## go mod tidy cd $(BACKEND_DIR) && go mod tidy .PHONY: gen-api gen-api: ## 用 goctl 從 .api 重新產生 handler/logic/types/routes cd $(BACKEND_DIR) && goctl api go -api generate/api/gateway.api -dir . -home generate/goctl -style go_zero .PHONY: fmt fmt: ## gofmt 後端 cd $(BACKEND_DIR) && gofmt -w . .PHONY: test test: ## 跑後端測試 cd $(BACKEND_DIR) && go test ./... .PHONY: verify verify: $(ENV_FILE) ## 後端 build/test + 前端 build + compose 語法 cd $(BACKEND_DIR) && go build ./... && go test ./... cd $(FRONTEND_DIR) && npm ci && npm run build $(COMPOSE) config >/dev/null && echo "docker compose config OK"