從 edge-ai-platform POC 轉為正式產品的雲端後端,含以下整合階段:
- Phase 0:雛形骨架 — `cmd/api-server` (REST :3721) + `cmd/remote-proxy`
(tunnel :3800 / internal :3801) 雙 binary 共用 internal/,沿用 POC 的
WebSocket+yamux tunnel 協定但解耦 relay 與 API
- Phase 0.6:OIDC BFF 接 Innovedus Member Center
- internal/oidc package(coreos/go-oidc + PKCE S256 + state + nonce)
- internal/usersession package(HMAC-SHA256 cookie + RotateSessionID
防 session fixation, OWASP ASVS V3.2.1)
- 4 個 OIDC handler(/api/auth/login|callback|me|logout)+ AuthMiddleware
- 完全拔除 StaticAuthProvider,OIDC 是唯一認證路徑
- 9 個 ADR(含 ADR-010 BFF / ADR-011 取代 static auth /
ADR-012 pending session shared cookie / ADR-013 PKCE-only public client)
- Phase 0.7:A1 改造 + security audit 修復
- OIDC ClientSecret 變選填,支援 stage MC 的 public PKCE-only client
(AuthStyleInParams 強制 token endpoint 不送 client_secret)
- 預留 ServiceClient* 欄位給未來 client_credentials grant
- 移除 13+ 處 resolveUserID(uc, StaticUserID) fallback 改 strict mode
(Audit C1:multi-tenant 隔離破口)
- Pairing exchange MarkUsed 失敗 abort + revoke session token(Audit M3)
- 新增 all_endpoints_require_auth_test 整合測試(51 endpoint × 401)
驗證:go test -race -count=3 ./... 17 packages 全綠 / go vet 0 warning
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
132 lines
4.7 KiB
Makefile
132 lines
4.7 KiB
Makefile
# visionA-backend Makefile
|
||
#
|
||
# 雙 binary 專案:api-server(REST/WS)+ remote-proxy(tunnel server)
|
||
# 對應文件:
|
||
# - .autoflow/04-architecture/build-deploy.md §1
|
||
# - 每個 target 都有 help 註解,`make help` 可看到清單
|
||
#
|
||
# 常用:
|
||
# make dev # 本機開發:平行跑兩個 binary
|
||
# make test # go test -race ./...
|
||
# make docker-build # 建 api-server + remote-proxy images
|
||
# make docker-compose-up # 啟動 docker-compose(api + proxy)
|
||
|
||
# ---- 變數 ----------------------------------------------------------------
|
||
BIN_DIR := bin
|
||
API_BIN := $(BIN_DIR)/api-server
|
||
PROXY_BIN := $(BIN_DIR)/remote-proxy
|
||
GO ?= go
|
||
GOFLAGS ?=
|
||
DOCKER ?= docker
|
||
COMPOSE_FILE := docker/docker-compose.yml
|
||
|
||
# VERSION 用於 docker image tag;預設 dev,或由 git describe 推斷
|
||
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
||
|
||
# ---- 預設 target ---------------------------------------------------------
|
||
.DEFAULT_GOAL := help
|
||
|
||
# ---- Build ---------------------------------------------------------------
|
||
.PHONY: build build-api build-proxy
|
||
|
||
build: build-api build-proxy ## 建置所有 binary(api-server + remote-proxy)
|
||
|
||
build-api: ## 建置 api-server
|
||
@mkdir -p $(BIN_DIR)
|
||
$(GO) build $(GOFLAGS) -o $(API_BIN) ./cmd/api-server
|
||
|
||
build-proxy: ## 建置 remote-proxy
|
||
@mkdir -p $(BIN_DIR)
|
||
$(GO) build $(GOFLAGS) -o $(PROXY_BIN) ./cmd/remote-proxy
|
||
|
||
# ---- Run -----------------------------------------------------------------
|
||
.PHONY: run-api run-proxy dev
|
||
|
||
run-api: ## 執行 api-server(本機開發)
|
||
$(GO) run ./cmd/api-server
|
||
|
||
run-proxy: ## 執行 remote-proxy(本機開發)
|
||
$(GO) run ./cmd/remote-proxy
|
||
|
||
# dev:純便利 target(非交付物,見 design-doc.md §1.9 N10)。
|
||
# 平行跑 remote-proxy(先起,因為 api-server 開機時會去打它)+ api-server。
|
||
# 任一 process 結束時,trap 會把另一個一起殺掉,避免殘留 zombie。
|
||
dev: build ## 本機開發:平行跑 remote-proxy + api-server(非交付物)
|
||
@echo "啟動 remote-proxy + api-server(Ctrl+C 結束)..."
|
||
@trap 'echo; echo "shutting down..."; kill 0' INT TERM EXIT; \
|
||
$(PROXY_BIN) & \
|
||
sleep 1; \
|
||
$(API_BIN) & \
|
||
wait
|
||
|
||
# ---- Test / Lint ---------------------------------------------------------
|
||
.PHONY: test test-race fmt vet lint
|
||
|
||
test: ## 執行單元測試(詳細輸出)
|
||
$(GO) test ./... -v
|
||
|
||
test-race: ## 執行單元 + 整合測試(race detector + coverage)
|
||
$(GO) test -race -coverprofile=coverage.out ./...
|
||
|
||
fmt: ## gofmt 格式化
|
||
$(GO) fmt ./...
|
||
|
||
vet: ## go vet 靜態分析
|
||
$(GO) vet ./...
|
||
|
||
lint: ## 靜態分析(優先 golangci-lint,若未安裝則 fallback 到 go vet)
|
||
@if command -v golangci-lint >/dev/null 2>&1; then \
|
||
golangci-lint run ./...; \
|
||
else \
|
||
echo "golangci-lint 未安裝,fallback 到 go vet"; \
|
||
$(GO) vet ./...; \
|
||
fi
|
||
|
||
# ---- Docker --------------------------------------------------------------
|
||
.PHONY: docker-build docker-build-api docker-build-proxy \
|
||
docker-compose-up docker-compose-down docker-compose-logs docker-compose-ps
|
||
|
||
docker-build: docker-build-api docker-build-proxy ## 建置兩個 Docker images(api-server + remote-proxy)
|
||
|
||
docker-build-api: ## 建置 api-server image → visiona/api-server:$(VERSION)
|
||
$(DOCKER) build -f docker/Dockerfile.api-server \
|
||
-t visiona/api-server:$(VERSION) \
|
||
-t visiona/api-server:dev \
|
||
.
|
||
|
||
docker-build-proxy: ## 建置 remote-proxy image → visiona/remote-proxy:$(VERSION)
|
||
$(DOCKER) build -f docker/Dockerfile.remote-proxy \
|
||
-t visiona/remote-proxy:$(VERSION) \
|
||
-t visiona/remote-proxy:dev \
|
||
.
|
||
|
||
docker-compose-up: ## 啟動 docker-compose 環境(detach 模式)
|
||
@test -f .env || (echo "⚠️ 找不到 .env — 請先執行:cp .env.example .env" && exit 1)
|
||
$(DOCKER) compose -f $(COMPOSE_FILE) up -d --build
|
||
|
||
docker-compose-down: ## 停止並移除 docker-compose 容器
|
||
$(DOCKER) compose -f $(COMPOSE_FILE) down
|
||
|
||
docker-compose-logs: ## 跟蹤 docker-compose logs(Ctrl+C 離開)
|
||
$(DOCKER) compose -f $(COMPOSE_FILE) logs -f
|
||
|
||
docker-compose-ps: ## 顯示 docker-compose 服務狀態
|
||
$(DOCKER) compose -f $(COMPOSE_FILE) ps
|
||
|
||
# ---- Utility -------------------------------------------------------------
|
||
.PHONY: clean help tidy
|
||
|
||
tidy: ## 整理 go.mod / go.sum
|
||
$(GO) mod tidy
|
||
|
||
clean: ## 清除 build 產物
|
||
@rm -rf $(BIN_DIR) dist/ coverage.out
|
||
@echo "已清除 $(BIN_DIR)/ 與 dist/ 與 coverage.out"
|
||
|
||
help: ## 顯示本 Makefile 的所有 target
|
||
@awk 'BEGIN {FS = ":.*?## "; printf "\nvisionA-backend — Make targets\n\n"} \
|
||
/^[a-zA-Z_-]+:.*?## / { printf " \033[36m%-22s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
|
||
@echo ""
|
||
@echo "常用:make dev / make test-race / make docker-compose-up"
|
||
@echo ""
|