#!/bin/bash # verify_t35.sh — 验收 T-3.5:前端本地 latest 快照语义 + fixture fallback 约定 set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" MODELS_LIB="$PROJECT_ROOT/frontend/src/lib/models.ts" GITIGNORE="$PROJECT_ROOT/.gitignore" LATEST="$PROJECT_ROOT/frontend/src/data/latest_models.json" FIXTURE="$PROJECT_ROOT/frontend/src/data/models.json" echo "=== T-3.5 验收检查 ===" # T-3.5.1: latest_models.json 视为本地运行快照,不纳入 git 跟踪 if grep -q '^frontend/src/data/latest_models.json$' "$GITIGNORE"; then echo "latest-ignore PASS — latest_models.json 已被 .gitignore 标记为本地运行快照" else echo "latest-ignore FAIL" exit 1 fi # T-3.5.2: 回退层在 models.ts 中定义 latest 优先 + models fixture fallback if grep -q 'latest_models.json' "$MODELS_LIB" && \ grep -q 'models.json' "$MODELS_LIB"; then echo "fallback-order PASS — latest 优先 + models fixture fallback 同时存在" else echo "fallback-order FAIL" exit 1 fi # T-3.5.3: committed fixture 必须长期存在,保证无 API 时仍能展示基础数据 if [ ! -f "$FIXTURE" ]; then echo "fixture-present FAIL — models.json fixture 不存在" exit 1 fi if python3 - "$FIXTURE" <<'PY' import json import sys path = sys.argv[1] with open(path, "r", encoding="utf-8") as f: data = json.load(f) assert isinstance(data.get("models"), list) and len(data["models"]) > 0 assert all("pricing" in model for model in data["models"]) PY then echo "fixture-present PASS — models.json fixture 存在且结构可用" else echo "fixture-present FAIL — models.json fixture 结构异常" exit 1 fi # T-3.5.4: latest_models.json 如果存在,必须满足快照 schema 和免费模型归一化 if [ ! -f "$LATEST" ]; then echo "latest-optional PASS — latest_models.json 当前不存在,前端将回退到 committed fixture" echo "" echo "all PASS" exit 0 fi if python3 - "$LATEST" <<'PY' import json import sys path = sys.argv[1] with open(path, "r", encoding="utf-8") as f: data = json.load(f) free_models = [ model for model in data.get("models", []) if isinstance(model.get("id"), str) and model["id"].endswith(":free") ] if not free_models: raise SystemExit(1) for model in free_models: pricing = model.get("pricing") if not isinstance(pricing, dict): raise SystemExit(1) if "input" not in pricing or "output" not in pricing: raise SystemExit(1) if pricing["input"] != 0 or pricing["output"] != 0: raise SystemExit(1) PY then echo "latest-schema PASS — latest_models.json 存在且免费模型 pricing.input/output 均显式为 0" else echo "latest-schema FAIL — latest_models.json schema 异常或免费模型 pricing 未归一" exit 1 fi echo "" echo "all PASS" exit 0