#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" HTML_FILE="$ROOT_DIR/deploy/tksea-portal/index.html" ADMIN_HTML_FILE="$ROOT_DIR/deploy/tksea-portal/admin-batch-import.html" ADMIN_HOME_FILE="$ROOT_DIR/deploy/tksea-portal/admin/index.html" ADMIN_LOGICAL_GROUPS_FILE="$ROOT_DIR/deploy/tksea-portal/admin/logical-groups.html" ADMIN_ROUTE_HEALTH_FILE="$ROOT_DIR/deploy/tksea-portal/admin/route-health.html" ADMIN_ACCOUNTS_FILE="$ROOT_DIR/deploy/tksea-portal/admin/accounts.html" ADMIN_PROVIDERS_FILE="$ROOT_DIR/deploy/tksea-portal/admin/providers.html" ADMIN_BATCH_FILE="$ROOT_DIR/deploy/tksea-portal/admin/batch-import.html" NGINX_FILE="$ROOT_DIR/deploy/tksea-portal/nginx.sub.tksea.top.conf.example" DEPLOY_SCRIPT="$ROOT_DIR/scripts/deploy/deploy_tksea_portal.sh" fail() { echo "FAIL: $*" >&2 exit 1 } assert_contains_file() { local file="$1" local needle="$2" if ! grep -Fq "$needle" "$file"; then fail "expected [$needle] in $file" fi } [[ -f "$HTML_FILE" ]] || fail "missing $HTML_FILE" [[ -f "$ADMIN_HTML_FILE" ]] || fail "missing $ADMIN_HTML_FILE" [[ -f "$ADMIN_HOME_FILE" ]] || fail "missing $ADMIN_HOME_FILE" [[ -f "$ADMIN_LOGICAL_GROUPS_FILE" ]] || fail "missing $ADMIN_LOGICAL_GROUPS_FILE" [[ -f "$ADMIN_ROUTE_HEALTH_FILE" ]] || fail "missing $ADMIN_ROUTE_HEALTH_FILE" [[ -f "$ADMIN_ACCOUNTS_FILE" ]] || fail "missing $ADMIN_ACCOUNTS_FILE" [[ -f "$ADMIN_PROVIDERS_FILE" ]] || fail "missing $ADMIN_PROVIDERS_FILE" [[ -f "$ADMIN_BATCH_FILE" ]] || fail "missing $ADMIN_BATCH_FILE" [[ -f "$NGINX_FILE" ]] || fail "missing $NGINX_FILE" [[ -f "$DEPLOY_SCRIPT" ]] || fail "missing $DEPLOY_SCRIPT" assert_contains_file "$HTML_FILE" "Sub2API 多模型接入中心" assert_contains_file "$HTML_FILE" "https://sub.tksea.top/portal/" assert_contains_file "$HTML_FILE" "/portal-proxy/api/v1" assert_contains_file "$HTML_FILE" "/portal-admin-api/api/portal" assert_contains_file "$HTML_FILE" "localStorage.setItem" assert_contains_file "$HTML_FILE" "/auth/me" assert_contains_file "$HTML_FILE" "/groups/available" assert_contains_file "$HTML_FILE" "/subscriptions" assert_contains_file "$HTML_FILE" "/keys?page=1&page_size=20" assert_contains_file "$HTML_FILE" "copy-existing-key-btn" assert_contains_file "$HTML_FILE" "已有 Key" assert_contains_file "$HTML_FILE" "showToast" assert_contains_file "$HTML_FILE" "逻辑分组目录" assert_contains_file "$HTML_FILE" "已开通兼容线路" assert_contains_file "$HTML_FILE" "可立即申请兼容 Key" assert_contains_file "$HTML_FILE" "需开通兼容线路" assert_contains_file "$HTML_FILE" "目录已上线" assert_contains_file "$HTML_FILE" "选择逻辑分组" assert_contains_file "$HTML_FILE" "当前逻辑分组说明" assert_contains_file "$HTML_FILE" "兼容宿主线路" assert_contains_file "$HTML_FILE" "portalLogicalGroups" assert_contains_file "$HTML_FILE" "LEGACY_GROUP_CATALOG" assert_contains_file "$HTML_FILE" "route_policy =" assert_contains_file "$HTML_FILE" "gpt-5.4" assert_contains_file "$HTML_FILE" "MiniMax-M2.7-highspeed" assert_contains_file "$HTML_FILE" "deepseek-chat" assert_contains_file "$ADMIN_HTML_FILE" "Batch Import Admin" assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin/" assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin/logical-groups.html" assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin/providers.html" assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin/batch-import.html" assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin/accounts.html" assert_contains_file "$ADMIN_HTML_FILE" "/portal-admin-api" assert_contains_file "$ADMIN_HTML_FILE" "matched_account_state" assert_contains_file "$ADMIN_HTML_FILE" "account_resolution" assert_contains_file "$ADMIN_HTML_FILE" "/api/batch-import/runs" assert_contains_file "$ADMIN_HTML_FILE" "/api/batch-import/runs/" assert_contains_file "$ADMIN_HTML_FILE" '/items${query ?' assert_contains_file "$ADMIN_HTML_FILE" "Authorization" assert_contains_file "$ADMIN_HTML_FILE" "base_url|api_key|requested_model_1,requested_model_2" assert_contains_file "$ADMIN_HTML_FILE" "reused" assert_contains_file "$ADMIN_HTML_FILE" "reactivated" assert_contains_file "$ADMIN_HOME_FILE" "Admin Portal" assert_contains_file "$ADMIN_HOME_FILE" "/portal/admin/logical-groups.html" assert_contains_file "$ADMIN_HOME_FILE" "/portal/admin/route-health.html" assert_contains_file "$ADMIN_HOME_FILE" "/portal/admin/accounts.html" assert_contains_file "$ADMIN_HOME_FILE" "/portal/admin/providers.html" assert_contains_file "$ADMIN_HOME_FILE" "/portal/admin/batch-import.html" assert_contains_file "$ADMIN_HOME_FILE" "/portal-admin-api" assert_contains_file "$ADMIN_HOME_FILE" "浏览器提交到 CRM" assert_contains_file "$ADMIN_HOME_FILE" "逻辑分组 / 路由" assert_contains_file "$ADMIN_HOME_FILE" "Route 健康视图" assert_contains_file "$ADMIN_HOME_FILE" "帐号资产" assert_contains_file "$ADMIN_HOME_FILE" "/accounts" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "Logical Group Admin" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/portal/admin/" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/portal/admin/logical-groups.html" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/portal/admin/route-health.html" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/portal/admin/accounts.html" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/portal/admin/providers.html" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/portal/admin/batch-import.html" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/api/admin/session/login" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/api/admin/session/logout" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/api/admin/session" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/api/logical-groups" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "logical_group" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "shadow_group_id" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "shadow_host_id" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "首版页面只覆盖新增与查看" assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" 'credentials: "include"' assert_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "/portal-admin-api" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "Route Health Admin" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/portal/admin/" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/portal/admin/logical-groups.html" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/portal/admin/route-health.html" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/portal/admin/accounts.html" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/portal/admin/providers.html" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/portal/admin/batch-import.html" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/api/admin/session/login" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/api/admin/session/logout" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/api/admin/session" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/api/routing/routes/health" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "healthy" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "cooldown" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "failing" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "disabled" assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" 'credentials: "include"' assert_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "/portal-admin-api" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "Provider Accounts Admin" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal/admin/" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal/admin/logical-groups.html" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal/admin/route-health.html" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal/admin/accounts.html" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal/admin/providers.html" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal/admin/batch-import.html" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/api/admin/session/login" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/api/admin/session/logout" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/api/admin/session" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/api/provider-accounts" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/binding-candidates" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/binding" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/enable" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/disable" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/retire" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "logical_group_id" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "route_id" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "binding_state" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "binding_candidate_count" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "shadow_group_id" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "shadow_host_id" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "provider_accounts" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "显式整理归属" assert_contains_file "$ADMIN_ACCOUNTS_FILE" "conflict" assert_contains_file "$ADMIN_ACCOUNTS_FILE" 'credentials: "include"' assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal-admin-api" assert_contains_file "$ADMIN_PROVIDERS_FILE" "Provider Admin" assert_contains_file "$ADMIN_PROVIDERS_FILE" "管理员登录" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/portal/admin/logical-groups.html" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/portal/admin/route-health.html" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/portal/admin/accounts.html" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/admin/session/login" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/admin/session/logout" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/admin/session" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/packs" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/hosts" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/providers/" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/preview-import" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/import" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/provider-drafts" assert_contains_file "$ADMIN_PROVIDERS_FILE" "保存到服务端" assert_contains_file "$ADMIN_PROVIDERS_FILE" "更新草稿" assert_contains_file "$ADMIN_PROVIDERS_FILE" "发布到仓库" assert_contains_file "$ADMIN_PROVIDERS_FILE" "删除草稿" assert_contains_file "$ADMIN_PROVIDERS_FILE" "服务端草稿" assert_contains_file "$ADMIN_PROVIDERS_FILE" "Provider Manifest 草稿" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/portal-admin-api" assert_contains_file "$ADMIN_PROVIDERS_FILE" "/publish" assert_contains_file "$ADMIN_PROVIDERS_FILE" "发布 Commit Message" assert_contains_file "$ADMIN_PROVIDERS_FILE" "credentials: \"include\"" assert_contains_file "$ADMIN_PROVIDERS_FILE" "最近成功模板" assert_contains_file "$ADMIN_PROVIDERS_FILE" "根据 display name / base url / models 自动生成" assert_contains_file "$ADMIN_PROVIDERS_FILE" "同模型已存在" assert_contains_file "$ADMIN_PROVIDERS_FILE" "providerIdPreview" assert_contains_file "$ADMIN_PROVIDERS_FILE" "modelConflicts" assert_contains_file "$ADMIN_BATCH_FILE" "/portal/admin-batch-import.html" assert_contains_file "$ADMIN_HTML_FILE" "管理员登录" assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin/route-health.html" assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin/accounts.html" assert_contains_file "$ADMIN_HTML_FILE" "/api/admin/session/login" assert_contains_file "$ADMIN_HTML_FILE" "/api/admin/session/logout" assert_contains_file "$ADMIN_HTML_FILE" "/api/admin/session" assert_contains_file "$ADMIN_HTML_FILE" "credentials: \"include\"" assert_contains_file "$NGINX_FILE" "location = /portal" assert_contains_file "$NGINX_FILE" "location = /portal/admin" assert_contains_file "$NGINX_FILE" "location = /kimi-portal" assert_contains_file "$NGINX_FILE" "location /portal/" assert_contains_file "$NGINX_FILE" "location /portal-proxy/" assert_contains_file "$NGINX_FILE" "location /portal-admin-api/" assert_contains_file "$NGINX_FILE" "location /kimi-portal-proxy/" assert_contains_file "$DEPLOY_SCRIPT" "portal url: https://sub.tksea.top/portal/" assert_contains_file "$DEPLOY_SCRIPT" "portal admin home url: https://sub.tksea.top/portal/admin/" assert_contains_file "$DEPLOY_SCRIPT" "logical groups admin url: https://sub.tksea.top/portal/admin/logical-groups.html" assert_contains_file "$DEPLOY_SCRIPT" "route health admin url: https://sub.tksea.top/portal/admin/route-health.html" assert_contains_file "$DEPLOY_SCRIPT" "accounts admin url: https://sub.tksea.top/portal/admin/accounts.html" assert_contains_file "$DEPLOY_SCRIPT" "provider admin url: https://sub.tksea.top/portal/admin/providers.html" assert_contains_file "$DEPLOY_SCRIPT" "batch import admin url: https://sub.tksea.top/portal/admin/batch-import.html" assert_contains_file "$DEPLOY_SCRIPT" "batch import admin url: https://sub.tksea.top/portal/admin-batch-import.html" assert_contains_file "$DEPLOY_SCRIPT" "REMOTE_PORTAL_DIR" assert_contains_file "$DEPLOY_SCRIPT" "REMOTE_CRM_PORT" assert_contains_file "$DEPLOY_SCRIPT" "LOCAL_PORTAL_DIR" assert_contains_file "$DEPLOY_SCRIPT" "patch_tksea_portal_nginx.py" echo "PASS: tksea portal assets look consistent"