diff --git a/frontend/app/api/ops/health-check/route.ts b/frontend/app/api/ops/health-check/route.ts
new file mode 100644
index 00000000..25642c28
--- /dev/null
+++ b/frontend/app/api/ops/health-check/route.ts
@@ -0,0 +1,16 @@
+import { NextRequest, NextResponse } from "next/server";
+import { applyAuthResponseCookies, buildBackendRequestHeaders } from "@/lib/backend-auth";
+import { buildProxyExceptionResponse } from "@/lib/api-proxy";
+
+const API_BASE = process.env.POLYWEATHER_API_BASE_URL;
+
+export async function GET(req: NextRequest) {
+ if (!API_BASE) return NextResponse.json({ error: "API_BASE not configured" }, { status: 500 });
+ try {
+ const auth = await buildBackendRequestHeaders(req);
+ const res = await fetch(`${API_BASE}/api/ops/health-check`, { headers: auth.headers, cache: "no-store" });
+ const raw = await res.text();
+ const response = new NextResponse(raw, { status: res.status, headers: { "Content-Type": "application/json", "Cache-Control": "no-store" } });
+ return applyAuthResponseCookies(response, auth.response);
+ } catch (e) { return buildProxyExceptionResponse(e, { publicMessage: "Health check failed" }); }
+}
diff --git a/frontend/app/ops/health/page.tsx b/frontend/app/ops/health/page.tsx
new file mode 100644
index 00000000..c908926b
--- /dev/null
+++ b/frontend/app/ops/health/page.tsx
@@ -0,0 +1,10 @@
+import type { Metadata } from "next";
+import { requireOpsAdmin } from "@/lib/ops-admin";
+import { HealthPageClient } from "@/components/ops/health/HealthPageClient";
+
+export const metadata: Metadata = { title: "API 状态 — PolyWeather Ops" };
+
+export default async function HealthPage() {
+ await requireOpsAdmin("/ops/health");
+ return ;
+}
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx
index af0bebb0..02455197 100644
--- a/frontend/app/page.tsx
+++ b/frontend/app/page.tsx
@@ -4,7 +4,7 @@ import { DashboardEntry } from "@/components/dashboard/DashboardEntry";
export const metadata: Metadata = {
title: "PolyWeather - Global Weather Intelligence Map",
description:
- "PolyWeather dashboard with METAR, MGM, DEB fusion forecast, multi-model comparison, and history reconciliation.",
+ "PolyWeather dashboard with METAR, MGM, DEB fusion forecast, multi-model comparison, and AI weather decision cards.",
};
export default function HomePage() {
diff --git a/frontend/app/subscription-help/SubscriptionHelpClient.tsx b/frontend/app/subscription-help/SubscriptionHelpClient.tsx
index 2dce2f6b..d587dd0e 100644
--- a/frontend/app/subscription-help/SubscriptionHelpClient.tsx
+++ b/frontend/app/subscription-help/SubscriptionHelpClient.tsx
@@ -21,8 +21,8 @@ const FAQ_ITEMS = [
{
q_zh: "Pro 包含哪些功能?",
q_en: "What features does Pro include?",
- a_zh: "开通后可解锁:今日日内机场报文规则分析(含高温时段)、历史对账 + 未来日期分析、全平台智能气象推送。",
- a_en: "Unlocks: intraday METAR rule analysis (including peak window), historical reconciliation + future-date analysis, and cross-platform smart weather push.",
+ a_zh: "开通后可解锁:今日日内机场报文规则分析(含高温时段)、未来日期分析、城市决策卡、全平台智能气象推送。",
+ a_en: "Unlocks: intraday METAR rule analysis (including peak window), future-date analysis, city decision cards, and cross-platform smart weather push.",
},
{
q_zh: "当前订阅价格是多少?",
diff --git a/frontend/components/account/AccountCenter.tsx b/frontend/components/account/AccountCenter.tsx
index 318ea400..442d885d 100644
--- a/frontend/components/account/AccountCenter.tsx
+++ b/frontend/components/account/AccountCenter.tsx
@@ -707,8 +707,8 @@ export function AccountCenter() {
weatherEngine: isEn ? "Weather Engine" : "气象引擎",
intradayAnalysis: isEn ? "Intraday Analysis" : "今日内分析",
historyFuture: isEn
- ? "Historical + Future-date Analysis"
- : "历史对账 + 未来日期分析",
+ ? "Future-date + Decision Card Analysis"
+ : "未来日期分析 + 城市决策卡",
smartPush: isEn
? "Cross-platform Smart Weather Push"
: "全平台智能气象查询",
@@ -814,8 +814,8 @@ export function AccountCenter() {
noProSubscription: isEn ? "No Pro subscription" : "暂无 Pro 订阅",
trialEndsSoonTitle: isEn ? "Trial ending soon" : "试用即将结束",
trialEndsSoonBody: isEn
- ? "Your 3-day trial is almost over. Upgrade to Pro to keep full intraday analysis and history."
- : "你的 3 天试用即将结束。升级 Pro 后可继续使用完整日内分析和历史对账。",
+ ? "Your 3-day trial is almost over. Upgrade to Pro to keep full intraday analysis and decision cards."
+ : "你的 3 天试用即将结束。升级 Pro 后可继续使用完整日内分析和城市决策卡。",
trialExpiredTitle: isEn ? "Trial ended" : "试用已结束",
trialExpiredBody: isEn
? "Your trial access has ended. Renew with Pro to restore full access."
diff --git a/frontend/components/dashboard/ScanTerminalDashboard.tsx b/frontend/components/dashboard/ScanTerminalDashboard.tsx
index 2c7b6d8d..f57cbbcc 100644
--- a/frontend/components/dashboard/ScanTerminalDashboard.tsx
+++ b/frontend/components/dashboard/ScanTerminalDashboard.tsx
@@ -259,6 +259,21 @@ function ScanTerminalScreen() {
: selectedRow;
const scanStatus = terminalData?.status || "ready";
const staleReason = terminalData?.stale_reason || null;
+ const proPreviewItems = isEn
+ ? [
+ "Intraday METAR rule analysis",
+ "Multi-model high-temp forecast",
+ "Real-time observation deviation",
+ "Future-date decision cards",
+ "Telegram group price $5",
+ ]
+ : [
+ "日内机场报文规则分析",
+ "多模型高温预测",
+ "实时观测偏差",
+ "未来日期城市决策卡",
+ "Telegram 群内价 5U",
+ ];
useEffect(() => {
if (!activeDetailRow) return;
@@ -405,6 +420,45 @@ function ScanTerminalScreen() {
userLocalTime={userLocalTime}
/>
+ {!isPro ? (
+
+
+ {isEn ? "What Pro unlocks" : "开通 Pro 后可看到"}
+
+ {isEn
+ ? "Full weather decision context, not just the public map."
+ : "不只是公开地图,而是完整天气交易辅助信息。"}
+
+
+ {isEn
+ ? "Guests and free users can browse the map. Pro adds live evidence, model deltas and city-level decision cards for current and future dates."
+ : "游客和免费用户可浏览地图;Pro 会补齐实时证据、模型偏差和当前/未来日期的城市决策卡。"}
+