# 美家卡智影 API - 常用命令 # ========================== .PHONY: help install dev install-hooks update-lock lint format test security clean docker help: ## 显示帮助信息 @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' # ========== 依赖管理 ========== install: ## 安装生产依赖(使用 lock 文件) uv pip sync requirements.lock dev: ## 安装开发依赖(包含 dev extras) uv pip install -e ".[dev]" pre-commit install install-hooks: ## 安装 Git pre-commit 钩子 pre-commit install update-lock: ## 更新 requirements.lock(修改 pyproject.toml 后执行) uv pip compile pyproject.toml -o requirements.lock --upgrade update-lock-no-upgrade: ## 重新生成 lock 文件(不升级版本) uv pip compile pyproject.toml -o requirements.lock # ========== 代码质量 ========== lint: ## 运行代码检查 (ruff + mypy) ruff check app/ mypy app/ format: ## 格式化代码 (black + ruff) black app/ ruff check --fix app/ format-check: ## 检查代码格式(不修改) black --check app/ ruff check app/ # ========== 测试 ========== test: ## 运行测试 pytest -v test-cov: ## 运行测试并生成覆盖率报告 pytest --cov=app --cov-report=html --cov-report=term # ========== 安全扫描 ========== security: ## 运行安全扫描 (bandit + pip-audit) @echo "🔍 运行 Bandit 安全扫描..." bandit -r app/ -c pyproject.toml @echo "🔍 运行依赖漏洞扫描..." pip-audit # ========== 开发服务器 ========== run: ## 启动开发服务器 uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 scheduler: ## 启动 Async Engine Scheduler python -m app.scheduler.main # ========== Docker ========== docker: ## 构建 Docker 镜像 docker build -t meijiaka-api:latest . docker-run: ## 使用 Docker Compose 启动全部服务 docker-compose up -d docker-logs: ## 查看 Docker 日志 docker-compose logs -f docker-down: ## 停止 Docker 服务 docker-compose down # ========== 清理 ========== clean: ## 清理缓存文件 find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true find . -type f -name "*.pyc" -delete 2>/dev/null || true find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true find . -type d -name ".mypy_cache" -exec rm -rf {} + 2>/dev/null || true rm -rf htmlcov/ .coverage 2>/dev/null || true # ========== 语义层防护网 ========== lint-semantic: ## 语义层禁词检查(防止供应商术语泄漏到业务层) @echo "🔍 检查 Layer 3+ 是否泄漏供应商术语..." @# API 层(除 klingai Provider 代理)禁止 element_id 作为字段/参数名 @errs=$$(grep -rn 'element_id' app/api --include='*.py' \ | grep -v 'klingai.py' \ | grep -v 'provider_element_id' \ | grep -v '__pycache__' \ | grep -v '#' \ | grep -v '".*element_id.*"' \ | grep -v "'.*element_id.*'"); \ if [ -n "$$errs" ]; then \ echo "$$errs"; \ echo "❌ API 层发现 element_id(应使用 provider_element_id 或 human_id)"; \ exit 1; \ fi @# Scheduler 层禁止 task_id 作为内部变量/Redis key(读取 Provider 返回除外) @errs=$$(grep -rn '\btask_id\b' app/scheduler --include='*.py' \ | grep -v 'job_id' \ | grep -v '__pycache__' \ | grep -v '\.get("task_id")' \ | grep -v 'result.get("task_id")' \ | grep -v 'task_type' \ | grep -v '"task_id"' \ | grep -v "'task_id'"); \ if [ -n "$$errs" ]; then \ echo "$$errs"; \ echo "❌ Scheduler 层发现 task_id(应使用 job_id)"; \ exit 1; \ fi @# 全局禁止 kling_task_id 作为持久化字段 @errs=$$(grep -rn 'kling_task_id' app --include='*.py' \ | grep -v '__pycache__' \ | grep -v 'providers/klingai'); \ if [ -n "$$errs" ]; then \ echo "$$errs"; \ echo "❌ 发现 kling_task_id(应使用 provider_task_id)"; \ exit 1; \ fi @# Scheduler 层 Redis key 必须使用 job: 而非 task: @errs=$$(grep -rn 'redis.*task:' app/scheduler --include='*.py' \ | grep -v '__pycache__'); \ if [ -n "$$errs" ]; then \ echo "$$errs"; \ echo "❌ Scheduler Redis key 使用 task:(应使用 job:)"; \ exit 1; \ fi @echo "✅ 语义层检查通过" # ========== CI 检查 ========== ci: format-check lint lint-semantic test security ## 运行所有 CI 检查