feat: Introduce open-core policy, commercialization, and payment verification documentation, and update README with new product status, payment architecture, and documentation index.

This commit is contained in:
2569718930@qq.com
2026-03-14 10:53:53 +08:00
parent 02e35a3a5f
commit 64f8b37014
11 changed files with 519 additions and 886 deletions
+42 -97
View File
@@ -1,10 +1,10 @@
# 前端交付与重构报告(2026-03-12
# 前端交付与重构报告(v1.4
最后更新:`2026-03-14`
## 1. 报告目的
本报告用于说明当前线上前端(`frontend/`的真实实现状态,替代旧版“单次改版完成报告”
---
说明当前线上前端(`frontend/`在收费阶段的实际交付状态
## 2. 当前前端架构
@@ -18,120 +18,65 @@ flowchart LR
STORE --> MAP["MapCanvas"]
STORE --> SIDEBAR["CitySidebar"]
STORE --> PANEL["DetailPanel + Modal"]
STORE --> ACCOUNT["Account Center + Pro Overlay"]
```
### 2.1 组件分层(实际)
## 3. 已落地能力
- 页面入口:`frontend/app/page.tsx` + `frontend/components/dashboard/DashboardEntry.tsx`
- 核心容器:`frontend/components/dashboard/PolyWeatherDashboard.tsx`
- 主要视图:
- `MapCanvas.tsx`
- `CitySidebar.tsx`
- `DetailPanel.tsx`
- `FutureForecastModal.tsx`
- `HistoryModal.tsx`
- `GuideModal.tsx`
- 状态管理:`frontend/hooks/useDashboardStore.tsx`
### 3.1 信息架构与交互
---
- 风险分组侧栏折叠(持久化)。
- 选中城市状态持久化。
- 今日分析、历史对账、未来日期分析联动。
## 3. 本轮已落地能力
### 3.2 收费相关
### 3.1 侧栏风险分组折叠(已完成)
- 账户中心(登录态、积分、订阅状态、钱包管理)。
- Pro 解锁浮层(套餐、积分抵扣、FAQ、社群入口)。
- 钱包绑定:浏览器扩展钱包 + WalletConnect 扫码。
- 支付流程:create intent -> submit -> confirm。
- `confirm pending` 时自动轮询 intent 状态,确认后自动刷新订阅态。
-`high / medium / low / other` 分组展示城市。
- 分组支持折叠/展开。
- 保留“本地时间”和“峰值时间”显示。
- 折叠状态持久化到 `localStorage``polyWeather_sidebar_groups_v1`)。
### 3.3 缓存与性能
### 3.2 选中城市状态持久化(已完成)
- BFF `ETag/304``cities` / `summary` / `history`
- `summary?force_refresh=true` => `no-store`
- `sessionStorage` + in-flight 去重。
- `localStorage`:选中城市、侧栏折叠状态。
- 最近一次选中城市持久化到 `localStorage``polyWeather_selected_city_v1`)。
- 页面刷新后自动恢复。
### 3.4 可访问性与稳定性
### 3.3 未来日期分析与市场扫描(已完成)
- 详情面板 `inert + blur` 焦点冲突修复。
- 关键支付错误文案标准化(用户取消、gas 不足、pending)。
- 前端通过 `target_date` 调用 `/api/city/{name}/detail`
- 未来日期 modal 可展示对应日期的模型概率与市场扫描。
## 4. 当前明确未做
### 3.4 市场概率分布去重保护(已完成
- 离线能力(Service Worker / IndexedDB
- 前端级财务报表与退款后台(后端/运营侧)
- 后端温度桶去重后,前端仍保留兜底去重逻辑。
- 避免“同温度重复四行”导致的可视化误导。
## 5. 验收建议
### 3.5 可访问性修复(已完成)
### 5.1 前端构建
- 解决详情侧栏关闭时 `aria-hidden` 焦点冲突。
- 方案:`inert` + `activeElement.blur()`
```bash
cd frontend
npm run build
```
### 3.6 图标与性能观测(已完成)
- 已接入 favicon/Apple touch icon/manifest。
- 已集成 Vercel Speed Insights 与 Analytics。
---
## 4. 缓存与性能策略(当前状态)
### 4.1 BFF HTTP 缓存(Vercel
- `/api/cities``ETag` + `s-maxage=300`
- `/api/city/{name}/summary``ETag` + `s-maxage=20`
- `/api/history/{name}``ETag` + `s-maxage=60`
- `summary?force_refresh=true``Cache-Control: no-store`
### 4.2 前端本地缓存
- `sessionStorage`:城市详情缓存(5 分钟 TTL + revision 探测)
- 请求去重:并发请求合并(pending request map
- `localStorage`:选中城市 + 侧栏折叠状态
### 4.3 当前明确未做
- Service Worker Cache API
- IndexedDB
---
## 5. 验收记录
### 5.1 前端缓存验收脚本
### 5.2 缓存验收
```bash
./scripts/validate_frontend_cache.sh "https://polyweather-pro.vercel.app"
```
当前结果:`PASS (14 passed)`
### 5.3 支付验收
### 5.2 自动化测试
- 绑定钱包
- 创建 intent
- 发交易
- 验证 `intent` 状态从 `submitted -> confirmed`
- 校验账户页订阅状态更新
```bash
.\\venv\\Scripts\\python.exe -m pytest -q
```
## 6. 结论
当前结果:`31 passed`
---
## 6. 风险与改进点
1. `frontend/.next` 构建产物在本地可见,需继续确保不进入版本管理。
2. 前端缓存策略已覆盖 P0+P1,但离线能力仍未建设(无 SW/IndexedDB)。
3. 多源数据仍依赖后端聚合延迟,前端仅能做缓存与降噪,不可替代后端刷新节奏。
---
## 7. 结论
当前前端已从“单体页面”演进为组件化 dashboard,具备:
- 风险分组侧栏与状态持久化
- 未来日期分析与市场扫描联动
- BFF 标准缓存头(`ETag/304`
- 可访问性修复与基础性能观测
可以支持继续推进商业化接入,但支付相关能力仍需后端与权限体系配套完成。
---
最后更新:`2026-03-12`
前端已具备收费阶段的核心能力(账户、支付、权限展示、状态回收),可支持持续商业迭代
+49 -121
View File
@@ -14,15 +14,31 @@ Official dashboard: [polyweather-pro.vercel.app](https://polyweather-pro.vercel.
![PolyWeather Ankara analysis](docs/images/demo_ankara.png)
## Product Status (2026-03)
- Subscription live: `Pro Monthly 5 USDC`.
- Points redemption live: `500 points = 1 USDC`, max `3 USDC` off.
- Onchain checkout live: Polygon contract checkout (USDC / USDC.e).
- Auto-reconciliation live: event listener + periodic confirm loop.
## Open-Core Boundary (Important)
This repository follows an **Open-Core** strategy:
- Public in repo: weather aggregation, core analysis, dashboard, bot baseline, standard payment flow.
- Private in production: commercial risk rules, operational thresholds, pricing strategy details, internal reconciliation policies, and growth operations tooling.
See: [Open-Core & Commercial Boundary](docs/OPEN_CORE_POLICY.md)
## Core Capabilities
- Aggregates real-time observations and forecasts for 20 monitored cities.
- Aggregates observations and forecasts for 20 monitored cities.
- Uses DEB (Dynamic Error Balancing) to blend multi-model highs.
- Produces settlement-oriented probability buckets (`mu` + bucket distribution).
- Maps weather model view to Polymarket read-only quotes for mispricing scan.
- Serves the same analysis core to web dashboard and Telegram bot.
- Generates settlement-oriented probability buckets (`mu` + bucket distribution).
- Maps weather view to Polymarket quotes for mispricing scan.
- Reuses one analysis core across web dashboard and Telegram bot.
## Architecture (Current)
## Reference Architecture
```mermaid
flowchart LR
@@ -35,35 +51,12 @@ flowchart LR
WX --> METAR["Aviation Weather (METAR)"]
WX --> MGM["MGM (Turkey station network)"]
WX --> OM["Open-Meteo"]
WX --> NWS["weather.gov (US cities)"]
API --> ANALYSIS["DEB + Trend + Probability + Market Scan"]
ANALYSIS --> PM["Polymarket Read-only Layer"]
API --> ANA["DEB + Trend + Probability + Market Scan"]
ANA --> PAY["Payment State (Intent + Event + Confirm Loop)"]
ANA --> PM["Polymarket Read-only Layer"]
```
## Bot Runtime Layout
```mermaid
flowchart TD
E["bot_listener.py"] --> O["src/bot/orchestrator.py"]
O --> H["src/bot/handlers/*"]
O --> S["src/bot/services/*"]
O --> A["src/bot/analysis/*"]
O --> G["src/bot/command_guard.py"]
O --> R["src/bot/runtime_coordinator.py"]
```
## Source Policy
| Domain | Current Policy |
| :-- | :-- |
| Primary observation | Aviation Weather / METAR |
| Ankara enhancement | MGM + nearby stations, lead station fixed to `17130` |
| Forecast baseline | Open-Meteo + multi-model (ECMWF/GFS/ICON/GEM/JMA) |
| US official context | weather.gov |
| Market layer | Polymarket P0 read-only discovery + quotes |
| Removed source | Meteoblue (fully removed from runtime and docs) |
## Monitored Cities (20)
- Europe / Middle East: Ankara, London, Paris, Munich
@@ -71,47 +64,6 @@ flowchart TD
- Americas: Toronto, New York, Chicago, Dallas, Miami, Atlanta, Seattle, Buenos Aires, Sao Paulo
- South Asia: Lucknow
## Major Updates (2026-03-12)
1. Bot architecture refactor completed:
- `bot_listener.py` is now a thin entrypoint.
- Core runtime moved to orchestrator + handlers/services/analysis layers.
- Startup loops managed by `StartupCoordinator`, with `/diag` diagnostics.
2. Mispricing radar hardened:
- Anchor changed from single Open-Meteo settlement to multi-model highest-high anchor.
- Skip non-tradable markets (`closed`, inactive, not accepting orders, or past end time).
- Future-date scan supported via `target_date` in detail aggregate endpoint.
3. Wallet activity watcher upgraded:
- Wallet aliases (`POLYMARKET_WALLET_ACTIVITY_USER_ALIASES`) supported.
- Telegram link preview toggle (`POLYMARKET_WALLET_ACTIVITY_LINK_PREVIEW`) supported.
- Debounce + immediate delta push controls reduce noisy spam bursts.
4. Frontend P0+P1 cache and UX improvements:
- BFF `ETag + 304` on `/api/cities`, `/api/city/{name}/summary`, `/api/history/{name}`.
- `force_refresh=true` on summary keeps `Cache-Control: no-store`.
- `sessionStorage` city-detail cache + background summary revision probe.
- `localStorage` persistence for selected city and risk-group collapse state.
- Detail panel accessibility fix (`inert` + active-element blur).
5. Observability:
- Vercel Speed Insights integrated.
- Telegram alert/watcher startup diagnostics exposed through `/diag`.
6. P1 contract checkout (new):
- New payment APIs: `/api/payments/config|wallets|intents/*`.
- MetaMask wallet binding via nonce challenge + `personal_sign`.
- Supports multi-token checkout on Polygon (USDC.e + Native USDC) via token whitelist config.
- Frontend receives contract `tx_payload` and calls `eth_sendTransaction`.
- Backend validates `OrderPaid(orderId,payer,planId,token,amount)` onchain event and auto-grants entitlement.
- Confirmation writes `payments/subscriptions/entitlement_events` and can notify Telegram.
- PolygonScan verification guide: `docs/payments/POLYGONSCAN_VERIFY.md`.
## Repository Layout
- Frontend: `frontend/`
- Backend API: `web/app.py`, `src/`
- Telegram bot runtime: `bot_listener.py`, `src/bot/*`
- Wallet watchers: `src/onchain/*`
- Ops scripts: `scripts/`
- Docs: `docs/`
## Quick Start
### Backend + Bot (Docker)
@@ -120,28 +72,6 @@ flowchart TD
docker compose up -d --build
```
## Runtime Data (Recommended for VPS)
To avoid `git pull` conflicts and decouple code from runtime state, store SQLite and caches outside the repo:
1. Set in `.env`:
- `POLYWEATHER_RUNTIME_DATA_DIR=/var/lib/polyweather`
- `POLYWEATHER_DB_PATH=/var/lib/polyweather/polyweather.db`
2. Ensure host directory exists and has write permission for container user (`1000:1000`):
```bash
sudo mkdir -p /var/lib/polyweather
sudo chown -R 1000:1000 /var/lib/polyweather
sudo chmod 775 /var/lib/polyweather
```
3. Recreate services:
```bash
docker compose down
docker compose up -d --build
```
### Frontend (local)
```bash
@@ -150,40 +80,36 @@ npm install
npm run dev
```
### Frontend production build
## Runtime Data (Recommended on VPS)
```bash
cd frontend
npm run build
Use external runtime storage to avoid SQLite/git conflicts:
```env
POLYWEATHER_RUNTIME_DATA_DIR=/var/lib/polyweather
POLYWEATHER_DB_PATH=/var/lib/polyweather/polyweather.db
```
## Ops Verification
### Validate frontend cache headers (`ETag` / `304` / `force_refresh=no-store`)
### Frontend cache headers
```bash
./scripts/validate_frontend_cache.sh "https://polyweather-pro.vercel.app"
```
### Watch mispricing radar decisions
### Payment auto-reconciliation logs
```bash
docker compose logs -f polyweather | egrep "market not tradable|trade alert pushed|mispricing cap"
docker compose logs -f polyweather | egrep "payment event loop started|payment confirm loop started|payment auto-confirmed"
```
### Watch wallet activity watcher startup and pushes
### Wallet activity logs
```bash
docker compose logs -f polyweather | egrep "wallet activity watcher started|wallet activity pushed|wallet activity cycle failed"
docker compose logs -f polyweather | egrep "polymarket wallet activity watcher started|wallet activity pushed"
```
### Check bot startup diagnosis in Telegram
```text
/diag
```
## Telegram Command Surface
## Telegram Commands
| Command | Purpose |
| :-- | :-- |
@@ -191,20 +117,22 @@ docker compose logs -f polyweather | egrep "wallet activity watcher started|wall
| `/deb <name>` | DEB historical reconciliation |
| `/top` | User leaderboard |
| `/id` | Show current chat ID |
| `/diag` | Bot startup diagnostics and loop status |
| `/diag` | Startup diagnostics |
| `/help` | Help and usage |
## Documentation Index
- Chinese overview: `README_ZH.md`
- Chinese API guide: `docs/API_ZH.md`
- Commercial roadmap: `docs/COMMERCIALIZATION.md`
- Tech debt (EN): `docs/TECH_DEBT.md`
- Tech debt (ZH): `docs/TECH_DEBT_ZH.md`
- Frontend delivery report: `FRONTEND_REDESIGN_REPORT.md`
- Chinese overview: [README_ZH.md](README_ZH.md)
- Chinese API guide: [docs/API_ZH.md](docs/API_ZH.md)
- Commercialization: [docs/COMMERCIALIZATION.md](docs/COMMERCIALIZATION.md)
- Open-Core policy: [docs/OPEN_CORE_POLICY.md](docs/OPEN_CORE_POLICY.md)
- Supabase setup (ZH): [docs/SUPABASE_SETUP_ZH.md](docs/SUPABASE_SETUP_ZH.md)
- Tech debt (EN): [docs/TECH_DEBT.md](docs/TECH_DEBT.md)
- Tech debt (ZH): [docs/TECH_DEBT_ZH.md](docs/TECH_DEBT_ZH.md)
- Payment verification: [docs/payments/POLYGONSCAN_VERIFY.md](docs/payments/POLYGONSCAN_VERIFY.md)
- Frontend report: [FRONTEND_REDESIGN_REPORT.md](FRONTEND_REDESIGN_REPORT.md)
## Status
## Version
- Version: `v1.3`
- Test status: `31 passed` (`.\\venv\\Scripts\\python.exe -m pytest -q`)
- Last Updated: `2026-03-12`
- Version: `v1.4`
- Last Updated: `2026-03-14`
+51 -122
View File
@@ -14,15 +14,31 @@
![PolyWeather Ankara 分析页](docs/images/demo_ankara.png)
## 当前产品状态(2026-03
- 已上线订阅制:`Pro 月付 5 USDC`
- 已上线积分抵扣:`500 积分 = 1 USDC`,最多抵扣 `3 USDC`
- 已上线链上支付:Polygon 合约支付(USDC / USDC.e)。
- 已上线自动补单:事件监听 + 周期确认双链路。
## 开源边界(重要)
本项目采用 **Open-Core** 策略:
- 仓库公开部分:天气聚合、基础分析、前端看板、Bot 基础能力、支付标准流程示例。
- 生产私有部分:商业风控规则、运营阈值、收费策略细节、付费用户运营脚本、内部对账与审计策略。
详细见:[Open-Core 与商用边界](docs/OPEN_CORE_POLICY.md)
## 核心能力
- 聚合 20 个监控城市的实时实测与预报数据。
- 通过 DEBDynamic Error Balancing)融合多模型最高温。
- 输出结算导向概率分布(`mu` + 温度桶)。
- 将模型观点映射到 Polymarket 只读市场,做错价扫描。
- Web 仪表盘与 Telegram 机器人复用同一分析内核。
- 聚合 20 个监控城市的实测与预报数据。
- DEBDynamic Error Balancing)融合多模型最高温。
- 输出结算导向概率分布(`mu` + 温度桶)。
- 将模型观点映射到 Polymarket 行情,做错价扫描。
- Web 仪表盘与 Telegram Bot 复用同一分析内核。
## 当前架构
## 参考架构
```mermaid
flowchart LR
@@ -35,35 +51,12 @@ flowchart LR
WX --> METAR["Aviation WeatherMETAR"]
WX --> MGM["MGM(土耳其站网)"]
WX --> OM["Open-Meteo"]
WX --> NWS["weather.gov(美国城市)"]
API --> ANALYSIS["DEB + 趋势 + 概率 + 市场扫描"]
ANALYSIS --> PM["Polymarket 只读层"]
API --> ANA["DEB + 趋势 + 概率 + 市场扫描"]
ANA --> PAY["支付状态(Intent + Event + Confirm Loop"]
ANA --> PM["Polymarket 只读层"]
```
## Bot 运行分层
```mermaid
flowchart TD
E["bot_listener.py"] --> O["src/bot/orchestrator.py"]
O --> H["src/bot/handlers/*"]
O --> S["src/bot/services/*"]
O --> A["src/bot/analysis/*"]
O --> G["src/bot/command_guard.py"]
O --> R["src/bot/runtime_coordinator.py"]
```
## 数据源口径
| 领域 | 当前口径 |
| :-- | :-- |
| 主观测源 | Aviation Weather / METAR |
| Ankara 增强 | MGM + 周边站,领先站固定 `17130` |
| 预报基线 | Open-Meteo + 多模型(ECMWF/GFS/ICON/GEM/JMA |
| 美国官方语义层 | weather.gov |
| 市场层 | Polymarket P0 只读发现 + 报价 |
| 已移除 | Meteoblue(代码与文档已彻底移除) |
## 监控城市(20
- 欧洲/中东:Ankara、London、Paris、Munich
@@ -71,46 +64,6 @@ flowchart TD
- 美洲:Toronto、New York、Chicago、Dallas、Miami、Atlanta、Seattle、Buenos Aires、Sao Paulo
- 南亚:Lucknow
## 本轮主要更新(2026-03-12
1. Bot 分层改造完成:
- `bot_listener.py` 变为极薄入口。
- 运行时迁移到 orchestrator + handlers/services/analysis 分层。
- 启动循环由 `StartupCoordinator` 统一编排,并通过 `/diag` 暴露诊断。
2. 错价雷达口径升级:
- 锚点从“单一 Open-Meteo 结算”改为“多模型最高温锚点”。
- 不可交易市场硬拦截(`closed` / inactive / 不接单 / 过结束时间)。
- 未来日期分析支持 `target_date`(聚合详情接口)。
3. 钱包异动监听升级:
- 支持钱包昵称映射(`POLYMARKET_WALLET_ACTIVITY_USER_ALIASES`)。
- 支持 Telegram 链接预览开关(`POLYMARKET_WALLET_ACTIVITY_LINK_PREVIEW`)。
- 增加 debounce + 立即推送控制,减少连续下单刷屏。
4. 前端 P0+P1 缓存与体验优化:
- BFF 在 `/api/cities``/api/city/{name}/summary``/api/history/{name}` 返回 `ETag + 304`
- `summary?force_refresh=true` 保持 `Cache-Control: no-store`
- `sessionStorage` 详情缓存 + 后台 revision 静默探测。
- `localStorage` 持久化“选中城市”和“风险分组折叠状态”。
- 详情面板可访问性修复(`inert + active-element blur`)。
5. 可观测性:
- 前端集成 Vercel Speed Insights。
- Bot 启动和后台循环状态可通过 `/diag` 查看。
6. P1 合约支付链路(新增):
- 新增支付接口:`/api/payments/config|wallets|intents/*`
- 支持 MetaMask 钱包绑定(nonce + `personal_sign` 验签)。
- 支持 Polygon 双币种支付(USDC.e + Native USDC),后端按代币白名单路由。
- 支持合约订单支付:前端拿 `tx_payload``eth_sendTransaction`
- 后端按 `OrderPaid(orderId,payer,planId,token,amount)` 事件验单并自动开通订阅。
- 交易确认后自动写入 `payments/subscriptions/entitlement_events` 并可推送 Telegram。
## 目录说明
- 前端:`frontend/`
- 后端 API`web/app.py``src/`
- Telegram 机器人:`bot_listener.py``src/bot/*`
- 钱包监听:`src/onchain/*`
- 运维脚本:`scripts/`
- 文档:`docs/`
## 快速启动
### 后端 + BotDocker
@@ -119,28 +72,6 @@ flowchart TD
docker compose up -d --build
```
## 运行数据目录(VPS 推荐)
为避免 `git pull` 被数据库阻塞,并实现代码与运行态数据解耦,建议把 SQLite 和缓存放到仓库外目录:
1.`.env` 设置:
- `POLYWEATHER_RUNTIME_DATA_DIR=/var/lib/polyweather`
- `POLYWEATHER_DB_PATH=/var/lib/polyweather/polyweather.db`
2. 确保宿主机目录存在且容器用户(`1000:1000`)可写:
```bash
sudo mkdir -p /var/lib/polyweather
sudo chown -R 1000:1000 /var/lib/polyweather
sudo chmod 775 /var/lib/polyweather
```
3. 重建服务:
```bash
docker compose down
docker compose up -d --build
```
### 前端本地运行
```bash
@@ -149,61 +80,59 @@ npm install
npm run dev
```
### 前端生产构建
## 运行数据目录(VPS 推荐)
```bash
cd frontend
npm run build
建议将运行态数据放到仓库外(避免 `git pull` 被 SQLite 卡住):
```env
POLYWEATHER_RUNTIME_DATA_DIR=/var/lib/polyweather
POLYWEATHER_DB_PATH=/var/lib/polyweather/polyweather.db
```
## 运维验收
### 校验前端缓存头`ETag` / `304` / `force_refresh=no-store`
### 前端缓存头
```bash
./scripts/validate_frontend_cache.sh "https://polyweather-pro.vercel.app"
```
### 观察错价雷达决策日志
### 支付自动补单日志
```bash
docker compose logs -f polyweather | egrep "market not tradable|trade alert pushed|mispricing cap"
docker compose logs -f polyweather | egrep "payment event loop started|payment confirm loop started|payment auto-confirmed"
```
### 观察钱包异动监听日志
### 钱包异动监听日志
```bash
docker compose logs -f polyweather | egrep "wallet activity watcher started|wallet activity pushed|wallet activity cycle failed"
docker compose logs -f polyweather | egrep "polymarket wallet activity watcher started|wallet activity pushed"
```
### Telegram 启动诊断
```text
/diag
```
## Telegram 指令面
## Telegram 指令
| 指令 | 用途 |
| :-- | :-- |
| `/city <name>` | 城市实时分析 |
| `/deb <name>` | DEB 历史对账 |
| `/top` | 用户积分排行 |
| `/id` | 查看当前聊天 Chat ID |
| `/diag` | Bot 启动诊断与后台循环状态 |
| `/id` | 查看聊天 Chat ID |
| `/diag` | Bot 启动诊断 |
| `/help` | 帮助与用法 |
## 文档索引
- 英文总览:`README.md`
- API 文档(中文):`docs/API_ZH.md`
- 商业化路线:`docs/COMMERCIALIZATION.md`
- 技术债(英文):`docs/TECH_DEBT.md`
- 技术债(中文):`docs/TECH_DEBT_ZH.md`
- 前端交付报告:`FRONTEND_REDESIGN_REPORT.md`
- 英文总览:[README.md](README.md)
- API 文档(中文):[docs/API_ZH.md](docs/API_ZH.md)
- 商业化说明:[docs/COMMERCIALIZATION.md](docs/COMMERCIALIZATION.md)
- Open-Core 边界:[docs/OPEN_CORE_POLICY.md](docs/OPEN_CORE_POLICY.md)
- Supabase 接入:[docs/SUPABASE_SETUP_ZH.md](docs/SUPABASE_SETUP_ZH.md)
- 技术债(中文):[docs/TECH_DEBT_ZH.md](docs/TECH_DEBT_ZH.md)
- 技术债(英文):[docs/TECH_DEBT.md](docs/TECH_DEBT.md)
- 支付合约验证:[docs/payments/POLYGONSCAN_VERIFY.md](docs/payments/POLYGONSCAN_VERIFY.md)
- 前端报告:[FRONTEND_REDESIGN_REPORT.md](FRONTEND_REDESIGN_REPORT.md)
## 当前状态
## 当前版本
- 版本:`v1.3`
- 测试状态:`31 passed``.\\venv\\Scripts\\python.exe -m pytest -q`
- 最后更新:`2026-03-12`
- 版本:`v1.4`
- 最后更新:`2026-03-14`
+59 -169
View File
@@ -1,21 +1,14 @@
# PolyWeather API 文档(v1.3
# PolyWeather API 文档(v1.4
本文档基于当前代码(`web/app.py` + `frontend/app/api/*`)整理。
前端默认通过 Next.js BFF 路由访问后端。
最后更新:`2026-03-14`
---
本文档描述当前对外可用 API 口径(`web/app.py` + `frontend/app/api/*`)。
## 1. 基础信息
- 后端直连:`http://127.0.0.1:8000`
- 前端 BFF`https://polyweather-pro.vercel.app/api/*`
- 返回格式:`application/json`
- 口径说明:
- 结算导向分析以温度最高值和温度桶概率为核心。
- Ankara 增强使用 MGM,主站固定 `17130`
- Meteoblue 已移除,不再出现在任何有效字段中。
---
## 2. 请求链路
@@ -24,78 +17,21 @@ flowchart LR
FE["Browser / Dashboard"] --> BFF["Next.js Route Handlers (/api/*)"]
BFF --> API["FastAPI (/web/app.py)"]
API --> WX["Weather Collector"]
API --> ANA["DEB + Trend + Probabilities + Market Scan"]
ANA --> PM["Polymarket Read-only Layer"]
API --> ANA["DEB + Trend + Probability + Market Scan"]
API --> PAY["Payment Intent + Event + Confirm Loops"]
```
---
## 3. 接口总览
## 3. 天气分析接口
| 接口 | 方法 | 用途 |
| :-- | :-- | :-- |
| `/api/cities` | GET | 监控城市列表(地图/侧栏) |
| `/api/city/{name}` | GET | 城市主分析(今日分析核心数据) |
| `/api/city/{name}/summary` | GET | 轻量摘要(首屏预热/低成本轮询) |
| `/api/city/{name}/detail` | GET | 聚合详情(含 `market_scan` |
| `/api/history/{name}` | GET | 历史对账数据 |
| `/api/cities` | GET | 监控城市列表 |
| `/api/city/{name}` | GET | 城市主分析 |
| `/api/city/{name}/summary` | GET | 轻量摘要 |
| `/api/city/{name}/detail` | GET | 聚合详情(含 market_scan |
| `/api/history/{name}` | GET | 历史对账 |
---
## 4. 关键接口说明
### 4.1 `GET /api/cities`
返回监控城市清单。
关键字段:
- `name`, `display_name`
- `lat`, `lon`
- `risk_level`, `risk_emoji`
- `airport`, `icao`
- `temp_unit``celsius` / `fahrenheit`
### 4.2 `GET /api/city/{name}`
主分析接口,返回当前实况、预报、概率、趋势、AI 分析等。
可选参数:
- `force_refresh=true|false`
关键字段:
- `current`(温度、今日最高、METAR 观测时间、原始 METAR
- `forecast`(今日及多日高温、日出日落、日照时长)
- `mgm`, `mgm_nearby`
- `multi_model`, `multi_model_daily`
- `deb`, `ensemble`
- `probabilities``mu` + `distribution`
- `trend`, `peak`
- `hourly`, `hourly_next_48h`
- `source_forecasts.weather_gov`
### 4.3 `GET /api/city/{name}/summary`
轻量摘要接口,适合高频刷新列表。
可选参数:
- `force_refresh=true|false`
关键字段:
- `name`, `display_name`, `icao`
- `local_time`, `temp_symbol`
- `current.temp`, `current.obs_time`
- `deb.prediction`
- `risk.level`, `risk.warning`
- `updated_at`
### 4.4 `GET /api/city/{name}/detail`
聚合详情接口,市场分析与未来日期分析都依赖该接口。
### `GET /api/city/{name}/detail`
可选参数:
@@ -103,124 +39,78 @@ flowchart LR
- `market_slug=<slug>`
- `target_date=YYYY-MM-DD`
关键返回块
重点字段
- `overview`
- `official`
- `timeseries`
- `models`
- `probabilities`
- `market_scan`
- `risk`
- `ai_analysis`
- `market_scan.available`
- `market_scan.signal_label`
- `market_scan.anchor_model / anchor_high / anchor_settlement`
- `market_scan.yes_buy / no_buy`
- `market_scan.primary_market.tradable`
`market_scan` 重点字段:
## 4. 鉴权与账户接口
- `available`, `selected_date`, `selected_slug`, `signal_label`
- `yes_buy`, `yes_sell`, `no_buy`, `no_sell`
- `temperature_bucket`, `forecast_bucket`, `top_buckets`
- `anchor_model`, `anchor_high`, `anchor_settlement`
- `open_meteo_settlement`(兼容旧字段,当前与 `anchor_settlement` 同值)
- `primary_market.tradable`, `primary_market.tradable_reason`
- `primary_market.accepting_orders`, `primary_market.ended_at_utc`
| 接口 | 方法 | 用途 |
| :-- | :-- | :-- |
| `/api/auth/me` | GET | 当前登录态、积分、订阅状态 |
说明
`/api/auth/me` 关键字段
- 当前错价锚点不是单一 Open-Meteo,而是“多模型最高温锚点”。
- 推送层会再次校验市场可交易性,不可交易市场会跳过。
- `authenticated`
- `user_id`, `email`
- `points`, `weekly_points`, `weekly_rank`
- `subscription_active`, `subscription_plan_code`, `subscription_expires_at`
### 4.5 `GET /api/history/{name}`
## 5. 支付接口(P1
历史对账接口。
| 接口 | 方法 | 用途 |
| :-- | :-- | :-- |
| `/api/payments/config` | GET | 支付配置、代币列表、套餐、积分抵扣规则 |
| `/api/payments/wallets` | GET | 当前用户已绑定钱包 |
| `/api/payments/wallets/challenge` | POST | 获取绑定签名 challenge |
| `/api/payments/wallets/verify` | POST | 提交签名并绑定钱包 |
| `/api/payments/intents` | POST | 创建支付意图(intent |
| `/api/payments/intents/{intent_id}` | GET | 查询 intent 最新状态 |
| `/api/payments/intents/{intent_id}/submit` | POST | 提交交易哈希 |
| `/api/payments/intents/{intent_id}/confirm` | POST | 手动触发确认 |
关键字段:
### 支付状态建议
- `date`
- `actual`
- `deb`
- `mu`
- `mgm`
前端流程建议:
---
1. `POST /intents`
2. 钱包发链上交易
3. `POST /submit`
4. `POST /confirm`
5. 若 pending,轮询 `GET /intents/{id}` 直到 `confirmed`
## 5. 缓存与刷新策略(当前已实现
## 6. 缓存策略(当前)
### 5.1 FastAPI 后端缓存
- `cities` / `summary` / `history`BFF 支持 `ETag + 304`
- `summary?force_refresh=true``Cache-Control: no-store`
- 详情接口与支付接口:`no-store`
- `_analyze` 结果内存缓存:默认 5 分钟
- Ankara 特例:60 秒
- `force_refresh=true`:绕过后端缓存
## 7. 调试示例
### 5.2 Next.js BFF HTTP 缓存(Vercel
- `GET /api/cities`
- `ETag`
- `Cache-Control: public, max-age=0, s-maxage=300, stale-while-revalidate=1800`
- `GET /api/city/{name}/summary`
- `ETag`
- `Cache-Control: public, max-age=0, s-maxage=20, stale-while-revalidate=60`
- `GET /api/history/{name}`
- `ETag`
- `Cache-Control: public, max-age=0, s-maxage=60, stale-while-revalidate=300`
- `summary?force_refresh=true`
- `Cache-Control: no-store`
### 5.3 前端本地缓存
- `sessionStorage`
- 城市详情缓存(5 分钟 TTL + revision 探测)
- `localStorage`
- 上次选中城市
- 侧栏风险分组折叠状态
### 5.4 尚未引入(当前明确未做)
- Service Worker Cache API
- IndexedDB
---
## 6. 常用调试示例
### 6.1 查询未来日期 `market_scan`
### 查询未来日期 market_scan
```bash
curl -s "http://127.0.0.1:8000/api/city/ankara/detail?force_refresh=true&target_date=2026-03-12" \
| python3 -c "import sys,json; m=json.load(sys.stdin).get('market_scan',{}); print({k:m.get(k) for k in ['available','selected_date','anchor_model','anchor_high','anchor_settlement','yes_buy','no_buy']})"
curl -s "http://127.0.0.1:8000/api/city/ankara/detail?force_refresh=true&target_date=2026-03-12"
```
### 6.2 验证前端缓存头
### 校验支付配置
```bash
./scripts/validate_frontend_cache.sh "https://polyweather-pro.vercel.app"
curl -s http://127.0.0.1:8000/api/payments/config | python3 -m json.tool
```
### 6.3 观察错价雷达跳过原因
### 观察支付自动补单
```bash
docker compose logs -f polyweather | egrep "market not tradable|trade alert pushed|mispricing cap"
docker compose logs -f polyweather | egrep "payment event loop started|payment confirm loop started|payment auto-confirmed"
```
---
## 8. 开源口径说明
## 7. 常见问题
对外公开文档仅覆盖通用 API 契约。生产商业策略参数不在公开文档披露。
### 7.1 VPS `:8000` 为什么看不到 `ETag`
- `:8000` 是 FastAPI 直连层,主要负责聚合分析。
- `ETag/304` 在前端 BFFVercel 的 `/api/*`)侧实现。
### 7.2 为什么 `target_date` 有时没有市场价格?
- 该日期可能没有可交易市场。
- 或目标桶在市场里无可用报价(`yes_buy/no_buy` 缺失)。
- 可先看 `market_scan.available``primary_market.tradable`
### 7.3 如何确认 Bot 后台循环是否启动?
- Telegram 里发送 `/diag`
- 查看三类循环状态:错价雷达、Polygon 钱包监听、Polymarket 钱包异动监听。
---
最后更新:`2026-03-12`
详见:[Open-Core 与商用边界](OPEN_CORE_POLICY.md)
+45 -97
View File
@@ -1,118 +1,66 @@
# Commercialization Roadmap
# 商业化说明(Production
Target: make PolyWeather a sustainable paid weather-intelligence product.
最后更新:`2026-03-14`
---
## 1. 定位
## 1. Product Positioning
PolyWeather 是面向温度结算场景的气象决策层,不是通用天气应用。
PolyWeather is not a generic weather app. It is a settlement decision layer for temperature markets:
核心价值:
- observation-first (METAR/MGM),
- settlement-aware modeling (DEB + mu/buckets),
- market mapping (Polymarket read-only) for actionable mispricing checks.
- 观测优先(METAR/MGM
- 结算导向(DEB + 概率桶)
- 市场映射(行情对照 + 错价雷达)
---
## 2. 当前收费能力状态
## 2. Current Monetization Readiness (2026-03-12)
| Capability | Status | Notes |
| 能力 | 状态 | 备注 |
| :-- | :-- | :-- |
| Frontend entitlement gate | Implemented | Next middleware supports token gate + session cookie |
| Backend entitlement guard | Implemented | `POLYWEATHER_REQUIRE_ENTITLEMENT` + backend token header |
| Bot command entitlement pre-hook | Implemented | `/city` and `/deb` can be protected (`POLYWEATHER_BOT_REQUIRE_ENTITLEMENT`) |
| Payment event ingestion | Not implemented | No automated USDC payment reconciliation yet |
| Subscriber persistence | Not implemented | Still missing managed subscriber DB |
| Self-serve billing UI | Not implemented | No user billing center yet |
| 登录注册(Google + 邮箱) | 已上线 | Supabase 鉴权 |
| 订阅套餐(Pro 月付) | 已上线 | `5 USDC / 30天` |
| 积分抵扣 | 已上线 | `500分=1U`,最多 `3U` |
| 合约支付 | 已上线 | PolygonUSDC + USDC.e |
| 支付自动确认 | 已上线 | Event Loop + Confirm Loop |
| 钱包绑定 | 已上线 | 浏览器钱包 + WalletConnect |
| 私有频道推送 | 已上线 | 可拆分业务频道 |
---
## 3. 权限模型(当前)
## 3. Access Model
- 游客:可查看基础看板与简版信息。
- 登录用户:账户中心、钱包绑定、积分同步。
- Pro 用户:
- 今日日内深度分析(含高温时段)
- 历史对账 + 未来日期分析
- 全平台智能气象推送
```mermaid
flowchart LR
U["User"] --> FE["Frontend (Vercel)"]
FE --> MW["Entitlement Middleware"]
MW --> BFF["BFF /api/*"]
BFF --> API["FastAPI"]
API --> G["Backend Entitlement Guard"]
## 4. 收费与积分规则(默认)
P["Payment Source (USDC / Wallet)"] --> S["Subscriber State (to build)"]
S --> MW
S --> API
```
- 套餐:`pro_monthly`5 USDC / 30 天)
- 抵扣:500 积分抵 1 USDC,最高抵 3 USDC
- 实付下限:2 USDC(当积分满额时)
### Do we need login/register to start charging?
> 说明:具体运营策略可按阶段调整,生产参数建议放私有仓库。
Short answer: **no for phase 1, yes for scale**.
## 5. 建议的开源边界
- Phase 1 can run with token/wallet-based entitlement and manual ops.
- For scale (self-serve renewals, refunds, support, analytics), account identity and subscriber DB become mandatory.
请按 Open-Core 执行:
---
- 开源:基础能力与通用支付流程。
- 私有:商业风控、营销策略、关键运营参数、内部审计策略。
## 4. Packaging and Pricing (Draft)
详见:[Open-Core 与商用边界](OPEN_CORE_POLICY.md)
| Tier | Price | Value |
| :-- | :-- | :-- |
| Telegram Signal Channel | $1 / month | Low-noise proactive signal stream |
| Web Dashboard | $5 / month | Full model context + historical reconciliation |
| VIP Bundle | $5.5 / month | Dashboard + signal stream |
## 6. 上线检查清单(收费前)
Payment direction:
1. 支付链路:创建 intent、提交 tx、确认入账、订阅开通全链路可回放。
2. 权限链路:前端/后端/Bot 对 Pro 权限判定一致。
3. 审计能力:支付日志、订阅变更、异常重试可追溯。
4. 通知策略:支付成功私发、群内通知降噪。
5. 安全边界:敏感配置不进仓库。
- Settlement/network: Polygon USDC
- Rollout: manual confirmation first, then automated entitlement sync
## 7. 后续路线
---
## 5. Execution Phases
### Phase 1: Manual Paid Beta
- Keep user set small and quality-focused.
- Manual payment confirmation + manual entitlement issue.
- Weekly accuracy report as trust anchor.
### Phase 2: Payment Automation
- Ingest payment events (wallet/tx).
- Auto-issue and auto-expire entitlement.
- Full parity across frontend middleware, backend API, and bot command guard.
### Phase 3: Growth and B2B
- Self-serve billing and subscriber console.
- Retention analytics and feature usage telemetry.
- Optional B2B/API package.
---
## 6. P0/P1 Commercial Engineering Backlog
### P0 (before public paid launch)
1. Subscriber store (managed PostgreSQL/Supabase) with entitlement expiry.
2. Payment event pipeline (idempotent ingest + reconciliation + retry).
3. Unified entitlement policy matrix (frontend/backend/bot).
4. Ops audit trail for alerts and entitlement changes.
### P1 (after initial paid users)
1. Billing/entitlement admin console.
2. User-level support tooling (manual override, extension, refund notes).
3. Conversion and retention dashboards.
4. Churn diagnostics linked to alert quality and latency.
---
## 7. Commercial Risk Controls
- Revenue leakage: deny by default when entitlement token/state is missing.
- Signal quality drift: publish monthly transparent accuracy summary.
- Support load: keep alert evidence standardized in push payloads.
- Compliance/ops: preserve immutable entitlement and push logs.
---
Last Updated: `2026-03-12`
- 支持更多链和稳定币。
- 引入退款与工单后台。
- 建立周/月留存与付费转化看板。
- 打通渠道分销与邀请码返利系统。
+63
View File
@@ -0,0 +1,63 @@
# Open-Core 与商用边界
最后更新:`2026-03-14`
## 1. 目标
在保持社区可用性的前提下,保护商业化阶段的核心经营资产。
## 2. 仓库公开范围(可开源)
- 天气数据采集与标准化(METAR / Open-Meteo / MGM 接口层)。
- DEB 与基础趋势分析、概率桶计算。
- Dashboard 基础体验与 API/BFF 结构。
- Telegram Bot 基础命令与基础积分机制。
- 合约支付标准流程(钱包绑定、intent、提交、确认、补单)。
## 3. 生产私有范围(建议不公开)
- 商业风控参数与规则库:
- 错价信号阈值组合、推送阈值、异常检测策略。
- 运营策略资产:
- 用户分层规则、促销规则、留存策略、活动模板。
- 付费系统敏感细节:
- 实时对账容错阈值、退款审计策略、内部财务映射规则。
- 私有运维资产:
- 生产告警路由、内部频道映射、应急脚本与排障手册。
## 4. 配置与数据安全红线
- 不提交:`.env`、私钥、API key、机器人 token。
- 不提交:生产数据库、运行时状态文件、支付流水快照。
- 不提交:用户身份信息、钱包映射、订阅原始审计日志。
## 5. 推荐发布模式
### 5.1 Community Edition(开源)
- 提供基础分析与基础看板。
- 可选保留只读市场扫描。
- 默认关闭商业化运营规则。
### 5.2 Production Edition(私有)
- 启用收费、订阅、积分抵扣、风控、私有监控。
- 仅在私有仓库维护运营策略与敏感参数。
## 6. 文档口径规范
对外文档仅描述:
- 能力边界与使用方式。
- 可公开的技术架构。
- 不包含可被直接复刻的商业参数。
不对外文档描述:
- 具体策略阈值、用户分层细则、收益归因规则。
## 7. 许可证与法务建议(简版)
- 建议保持仓库代码许可证与商标/品牌授权分离。
- 若提供商业服务,建议在官网补充服务条款与隐私政策。
- 对“订阅权益”与“可用性”做明确 SLA 与免责边界。
+58 -62
View File
@@ -1,28 +1,30 @@
# Supabase + Google 登录 + 合约支付接入说明(P1
# Supabase + 登录 + 支付接入说明(v1.4
最后更新:`2026-03-14`
## 1. 目标
- 前端支持 `Google 一键登录`(优先)与 `邮箱注册/登录`(并列)
- 后端 API 支持 Supabase JWT 鉴权。
- entitlement 检查可选:仅登录放行,或要求有效订阅。
- 前端支持 Google 一键登录 + 邮箱注册/登录。
- 后端支持 Supabase JWT 鉴权。
- 支持 Polygon 合约支付(USDC / USDC.e)并自动确认开通订阅。
## 2. Supabase 控制台配置
1. Auth -> Providers -> 打开 `Google`
2. Auth -> Providers -> `Email` 保持开启。
3. 在 Google Cloud Console 配置 OAuth 回调地址:
- `https://<your-project-ref>.supabase.co/auth/v1/callback`
4. 在 Auth -> URL Configuration 添加站点 URL你的前端域名)
1. `Auth -> Providers` 打开 `Google``Email`
2. Google Cloud OAuth 回调配置:
- `https://<project-ref>.supabase.co/auth/v1/callback`
3. `Auth -> URL Configuration` 添加:
- 站点 URL生产域名)
- 回调 URL(例如 `https://polyweather-pro.vercel.app/auth/callback`
## 3. 执行数据库脚本
## 3. 数据库脚本
在 Supabase SQL Editor 行:
在 Supabase SQL Editor 行:
- `scripts/supabase/schema.sql`
该脚本会创建:
会创建支付与订阅相关表
- `profiles`
- `subscriptions`
- `payments`
- `entitlement_events`
@@ -31,8 +33,6 @@
- `payment_intents`
- `payment_transactions`
并建立 `auth.users -> profiles` 同步触发器。
## 4. 环境变量
### 4.1 前端(Vercel / frontend/.env.local
@@ -41,86 +41,82 @@
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
POLYWEATHER_AUTH_ENABLED=true
# true: 强制登录;false: 游客可用(可选登录)
POLYWEATHER_AUTH_REQUIRED=false
POLYWEATHER_API_BASE_URL=http://<backend-host>:8000
POLYWEATHER_BACKEND_ENTITLEMENT_TOKEN=
# WalletConnect(支持手机钱包扫码)
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=
NEXT_PUBLIC_WALLETCONNECT_POLYGON_RPC_URL=https://polygon-bor-rpc.publicnode.com
# Overlay 跳转
NEXT_PUBLIC_TELEGRAM_GROUP_URL=https://t.me/<your_group>
```
### 4.2 后端 / Bot.env
```env
POLYWEATHER_AUTH_ENABLED=true
# true: 后端 API 强制鉴权;false: 游客可访问,若带会话则自动识别用户
POLYWEATHER_AUTH_REQUIRED=false
POLYWEATHER_AUTH_REQUIRE_SUBSCRIPTION=false
SUPABASE_URL=
SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
SUPABASE_HTTP_TIMEOUT_SEC=8
SUPABASE_AUTH_CACHE_TTL_SEC=30
SUPABASE_SUB_CACHE_TTL_SEC=60
# P1 合约支付(MetaMask + Polygon USDC
POLYWEATHER_PAYMENT_ENABLED=true
POLYWEATHER_PAYMENT_CHAIN_ID=137
POLYWEATHER_PAYMENT_RPC_URL=https://polygon-rpc.com
POLYWEATHER_PAYMENT_RECEIVER_CONTRACT=0x<your_payment_contract>
POLYWEATHER_PAYMENT_TOKEN_ADDRESS=0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
POLYWEATHER_PAYMENT_TOKEN_DECIMALS=6
POLYWEATHER_PAYMENT_RPC_URL=https://polygon-bor-rpc.publicnode.com
POLYWEATHER_PAYMENT_RECEIVER_CONTRACT=0x<receiver_contract>
POLYWEATHER_PAYMENT_CONFIRMATIONS=2
POLYWEATHER_PAYMENT_INTENT_TTL_SEC=1800
POLYWEATHER_PAYMENT_WALLET_CHALLENGE_TTL_SEC=600
POLYWEATHER_PAYMENT_HTTP_TIMEOUT_SEC=10
POLYWEATHER_PAYMENT_POLL_INTERVAL_SEC=4
POLYWEATHER_PAYMENT_MAX_WAIT_SEC=50
POLYWEATHER_PAYMENT_TELEGRAM_NOTIFY_ENABLED=true
# 支付积分抵扣(500 积分 = 1 USDC,最高抵扣 3 USDC
# 支持双币种(示例
POLYWEATHER_PAYMENT_ACCEPTED_TOKENS_JSON=[{"code":"usdc_e","symbol":"USDC.e","name":"USDC.e (PoS)","address":"0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174","decimals":6,"receiver_contract":"0x<receiver>","is_default":true},{"code":"usdc","symbol":"USDC","name":"Native USDC","address":"0x3c499c542cef5e3811e1192ce70d8cc03d5c3359","decimals":6,"receiver_contract":"0x<receiver>"}]
# 套餐(当前只保留月付)
POLYWEATHER_PAYMENT_PLAN_CATALOG_JSON={"pro_monthly":{"plan_id":101,"amount_usdc":"5","duration_days":30}}
POLYWEATHER_PAYMENT_ALLOWED_PLAN_CODES=pro_monthly
# 积分抵扣
POLYWEATHER_PAYMENT_POINTS_ENABLED=true
POLYWEATHER_PAYMENT_POINTS_PER_USDC=500
POLYWEATHER_PAYMENT_POINTS_MAX_DISCOUNT_USDC=3
# JSON 示例:
# {"pro_monthly":{"plan_id":101,"amount_usdc":"5","duration_days":30}}
POLYWEATHER_PAYMENT_PLAN_CATALOG_JSON=
# 支付自动补单
POLYWEATHER_PAYMENT_EVENT_LOOP_ENABLED=true
POLYWEATHER_PAYMENT_CONFIRM_LOOP_ENABLED=true
```
可选(Bot 也走 Supabase 订阅):
## 5. 钱包异动频道拆分(推荐)
如果要把“钱包异动监控”发到独立频道:
```env
POLYWEATHER_BOT_REQUIRE_ENTITLEMENT=true
POLYWEATHER_BOT_USE_SUPABASE_ENTITLEMENT=true
POLYMARKET_WALLET_ACTIVITY_CHAT_ID=-1003821482461
```
## 5. entitlement 策略
说明:
- `POLYWEATHER_AUTH_ENABLED=true`:启用 Supabase 登录能力(Google/邮箱)
- `POLYWEATHER_AUTH_REQUIRED=true`:网站与后端 API 强制登录
- `POLYWEATHER_AUTH_REQUIRED=false`:游客可访问全部功能,用户可主动登录。
- `POLYWEATHER_AUTH_REQUIRE_SUBSCRIPTION=true`:在强制鉴权模式下,额外要求 `subscriptions` 表里存在有效 `active` 记录。
- 设置了 `POLYMARKET_WALLET_ACTIVITY_CHAT_ID(S)` 后,钱包异动推送优先发该频道
- 未设置时,回退到全局 `TELEGRAM_CHAT_IDS/TELEGRAM_CHAT_ID`
## 6. 验证
## 6. 验证步骤
1. 访问 `/auth/login`,测试 Google 一键登录
2. `POLYWEATHER_AUTH_REQUIRED=false` 时,未登录访问首页与 `/api/cities` 应返回 200
3. 登录后访问 `/api/auth/me`,应返回 `authenticated=true``user_id`
4. `POLYWEATHER_AUTH_REQUIRED=true` 时,未登录访问受保护接口应返回 401 或跳转登录页。
## 7. P1 支付链路验证
1. 登录后访问 `GET /api/payments/config`,应看到 `enabled=true``configured=true`
2. 账户页点击“连接并绑定 MetaMask”,完成签名后 `GET /api/payments/wallets` 可看到地址。
3. 点击“创建订单并支付”:
1. 登录后请求 `/api/auth/me`,确认 `authenticated=true`
2. 请求 `/api/payments/config`,确认 `enabled=true``configured=true`
3. 钱包绑定:
- `POST /api/payments/wallets/challenge`
- `POST /api/payments/wallets/verify`
4. 支付流程:
- `POST /api/payments/intents`
- MetaMask 发交易到 `POLYWEATHER_PAYMENT_RECEIVER_CONTRACT`
- `POST /api/payments/intents/{intent_id}/submit`
- `POST /api/payments/intents/{intent_id}/confirm`
4. 确认后应自动写入
- `payments``status=confirmed`
- `subscriptions`(新增 `active` 记录)
- `entitlement_events``subscription_granted`
合约事件要求:
- 合约需在 `pay(orderId, planId, amount, token)` 成功后发出
`OrderPaid(bytes32 orderId, address payer, uint256 planId, address token, uint256 amount)`
(字段顺序和类型需一致)。
- 发链上交易
- `POST /api/payments/intents/{id}/submit`
- `POST /api/payments/intents/{id}/confirm`
5. 若前端显示 pending,轮询
- `GET /api/payments/intents/{id}`
6. 确认订阅:`/api/auth/me` 返回 `subscription_active=true`
+38 -59
View File
@@ -1,94 +1,73 @@
# Technical Debt Backlog
# Technical Debt Backlog (v1.4)
Purpose: keep engineering debt explicit while shipping production features.
Last Updated: `2026-03-14`
---
Focus after paid launch: payment reliability, entitlement parity, and auditability.
## 1. Debt Snapshot
## 1. Snapshot
Current estimate: **90% stable / 10% debt**.
Current estimate: **93% stable / 7% debt**.
```mermaid
flowchart TD
A["Tech Debt"]
subgraph PI["Payment Infra"]
PI1["Payment event ingestion"]
PI2["Subscriber persistence"]
PI3["Entitlement parity"]
subgraph P["Payments & Subscriptions"]
P1["Automatic replay for failed confirmations"]
P2["Refund and support workflow"]
P3["Multi-chain settlement reconciliation"]
end
subgraph Q["Quality"]
Q1["Replay harness"]
Q2["Mixed integration tests"]
subgraph E["Entitlement & Ops"]
E1["Frontend/backend/bot entitlement regression matrix"]
E2["Points vs subscription conflict policy"]
end
subgraph O["Observability"]
O1["Alert evidence schema"]
O2["Ops dashboards"]
O1["Layered metrics for payment failures"]
O2["Business operations dashboards"]
end
A --> PI
A --> Q
A --> P
A --> E
A --> O
```
---
## 2. Recently Closed
## 2. Recently Closed (2026-03-12)
- P1 checkout flow live (intent -> submit -> confirm).
- Automatic reconciliation live (event loop + confirm loop).
- Wallet binding supports extension wallets + WalletConnect.
- Account center entitlement rendering is wired end-to-end.
- Wallet activity watcher supports dedicated channel routing.
- Bot entry refactor completed:
- `bot_listener.py` simplified to thin entrypoint.
- Runtime split into orchestrator/handlers/services/analysis/guard/coordinator layers.
- Startup diagnostics landed:
- `/diag` command
- loop-level startup status reporting (trade alerts, polygon watcher, polymarket watcher)
- Multi-model anchor migration completed for mispricing radar (replaced single Open-Meteo anchor).
- Non-tradable market hard-skip guard completed (closed/inactive/not accepting orders/past end time).
- Wallet activity watcher upgraded with alias parsing, link preview switch, and anti-spam debounce/immediate controls.
- Frontend BFF HTTP caching (`ETag`/`304`) completed for cities/summary/history.
- Meteoblue fully removed from runtime paths and docs.
---
## 3. Active High-Priority Debt
## 3. High-Priority Debt
| Item | Impact | Suggested Work |
| :-- | :-- | :-- |
| Payment event ingestion pipeline | Cannot automate paid access reliably | Build idempotent onchain payment ingest + reconciliation worker |
| Subscriber persistence model | Manual entitlement ops do not scale | Add managed PostgreSQL/Supabase subscriber state |
| Entitlement parity matrix | Access leaks/false denies across channels | Unify policy across frontend middleware, backend API, and bot guard |
| Alert evidence contract | Harder to debug false positives quickly | Standardize machine-readable evidence schema for each push |
| Automatic replay strategy for transient tx failures | Manual intervention still needed in some edge cases | Standardize tx replay + fallback paths |
| Refund/support workflow | Commercial loop incomplete | Add refund state machine + support tooling |
| Subscription audit visualization | Slower incident triage | Build timeline view for entitlement events |
| Multi-email same-Telegram binding policy | Points ownership confusion | Add primary-account binding and migration utilities |
---
## 4. Active Medium-Priority Debt
## 4. Medium-Priority Debt
| Item | Impact | Suggested Work |
| :-- | :-- | :-- |
| Replay simulation harness | Edge-case regressions hard to reproduce | Deterministic replay from stored weather + market snapshots |
| End-to-end integration coverage | Runtime regressions can slip | Add integration tests for `/api/city/{name}/detail` + push decisions |
| Config sprawl | Tuning is error-prone | Consolidate env knobs into structured config groups |
| Naming and data contracts | Boundary confusion persists | Normalize model/market field naming and compatibility aliases |
| Points transparency | User confusion | Expose points breakdown by source |
| Payment error copy consistency | Conversion impact | Build error-code to UX-copy mapping table |
| Config sprawl | Ops mistakes | Consolidate payment/push configs into grouped schemas |
---
## 5. Active Low-Priority Debt
## 5. Low-Priority Debt
| Item | Impact | Suggested Work |
| :-- | :-- | :-- |
| Cold-start variance | First request latency jitter | Add prewarm strategy for top city routes |
| Local state files | Harder multi-instance scaling | Continue migration to managed storage |
---
| Offline cache support | Non-core | Evaluate SW + IndexedDB |
| Cold-start variance | First-load jitter | Add route prewarming for hot cities |
## 6. Next Milestones
1. Land subscriber DB + entitlement expiry model.
2. Ship payment ingest + automatic entitlement sync.
3. Add replay harness for weather/market mixed scenarios.
4. Publish alert evidence schema and operator tooling.
---
Last Updated: `2026-03-12`
1. Ship automatic replay and alert stratification for payment anomalies.
2. Launch minimal refund/support admin flow.
3. Add business dashboards for payments, renewals, and retention.
4. Complete entitlement parity regression suite.
+37 -58
View File
@@ -1,94 +1,73 @@
# 技术债与工程待办
# 技术债与工程待办v1.4
目标:在持续交付的同时,让技术债可见、可追踪、可关闭。
最后更新:`2026-03-14`
---
目标:在收费上线后,优先保证支付可靠性、权限一致性和运营可追溯性。
## 1. 债务快照
当前估计:**90% 稳定 / 10% 技术债**。
当前估计:**93% 稳定 / 7% 技术债**。
```mermaid
flowchart TD
A["技术债"]
subgraph PI["支付基础设施"]
PI1["支付事件入库与对账"]
PI2["订阅用户持久化"]
PI3["权限策略一致化"]
subgraph P["支付与订阅"]
P1["异常交易自动重放策略"]
P2["退款与工单流程"]
P3["多链结算对账"]
end
subgraph Q["质量保障"]
Q1["回放仿真能力"]
Q2["端到端集成覆盖"]
subgraph E["权限与运营"]
E1["前后端/Bot 权限矩阵回归"]
E2["积分与订阅冲突策略"]
end
subgraph O["可观测性"]
O1["告警证据标准"]
O2["运维看板"]
O1["支付失败原因分层指标"]
O2["业务监控看板"]
end
A --> PI
A --> Q
A --> P
A --> E
A --> O
```
---
## 2. 近期已关闭
## 2. 近期已关闭(2026-03-12
- P1 支付主链路已上线(intent -> submit -> confirm)。
- 支付自动补单已上线(Event Loop + Confirm Loop)。
- 钱包绑定支持浏览器钱包 + WalletConnect。
- 账户中心与 Pro 权限展示链路打通。
- 钱包异动支持独立频道路由。
- Bot 入口重构完成:
- `bot_listener.py` 已收敛为薄入口。
- 运行时拆分为编排层/处理层/服务层/分析层/守卫层/协调层。
- 启动诊断完成:
- 新增 `/diag` 指令
- 后台循环启动状态可视化(错价雷达、Polygon 钱包、Polymarket 异动)
- 错价锚点完成升级:从单一 Open-Meteo 改为多模型最高温锚点。
- 不可交易市场硬拦截完成:`closed`/inactive/不接单/超结束时间全部跳过。
- 钱包异动监听增强完成:昵称映射、链接预览开关、去抖与即时推送控制。
- 前端 BFF `ETag/304` 缓存完成(cities/summary/history)。
- Meteoblue 已从运行链路与文档中彻底移除。
---
## 3. 当前高优先级技术债
## 3. 高优先级技术债
| 项目 | 影响 | 建议动作 |
| :-- | :-- | :-- |
| 支付事件采集与对账流水线 | 无法稳定自动开通付费权限 | 构建幂等 payment ingest + reconciliation worker |
| 订阅用户持久化模型 | 人工开通不可扩展 | 落地 PostgreSQL/Supabase 订阅状态 |
| 权限策略一致性矩阵 | 存在漏放行/误拦截风险 | 统一前端中间件、后端 API、Bot 守卫策略 |
| 告警证据协议 | 假阳性排障成本高 | 统一机器可读 Evidence Schema |
| 支付异常重放策略标准化 | 偶发确认失败需人工介入 | 建立 tx hash 自动回放 + 降级路径 |
| 退款与售后链路 | 商业闭环不完整 | 增加退款状态机与工单系统 |
| 订阅审计可视化 | 排障效率受限 | 建立订阅事件时间线视图 |
| 多邮箱绑定同 TG 账户策略 | 积分归属易混淆 | 引入主账号绑定策略与迁移工具 |
---
## 4. 当前中优先级技术债
## 4. 中优先级技术债
| 项目 | 影响 | 建议动作 |
| :-- | :-- | :-- |
| 回放仿真能力不足 | 边缘场景回归难复现 | 基于天气+市场快照构建确定性 Replay |
| 端到端集成覆盖不足 | 运行时回归难提前发现 | 增加 `/api/city/{name}/detail` 与推送链路集成测试 |
| 配置项分散 | 阈值调优易出错 | 将关键 env 聚合为结构化配置分组 |
| 命名与字段兼容历史包袱 | 认知与维护成本高 | 统一模型/市场字段命名与兼容层 |
| 积分发放可解释性 | 用户理解成本高 | 输出积分来源明细(发言/签到/奖励) |
| 支付失败文案标准化 | 转化率受影响 | 建立错误码 -> 文案映射表 |
| 配置收敛 | 运维出错概率高 | 将支付/推送配置集中分组管理 |
---
## 5. 当前低优先级技术债
## 5. 低优先级技术债
| 项目 | 影响 | 建议动作 |
| :-- | :-- | :-- |
| 冷启动波动 | 首次请求延迟抖动 | 对热点城市路由做预热 |
| 本地文件状态依赖 | 多实例扩展受限 | 继续迁移到托管存储 |
---
| 前端离线缓存能力 | 非核心 | 评估 Service Worker + IndexedDB |
| 冷启动波动 | 首屏抖动 | 热点城市预热 |
## 6. 下阶段里程碑
1. 上线订阅用户 DB 与权限过期模型
2. 完成支付事件入库与自动授权同步
3. 落地天气+市场混合回放回归
4. 发布告警证据标准与运维排障工具
---
最后更新:`2026-03-12`
1. 完成支付异常自动重放与告警分层
2. 上线退款/售后后台最小版
3. 建立商业化运营看板(支付、续费、留存)
4. 完成权限矩阵自动化回归测试
+30 -37
View File
@@ -1,25 +1,23 @@
# PolyWeatherCheckout PolygonScan 验证
# PolyWeatherCheckout PolygonScan 验证v1.4
目标合约地址:`0xD8101B3cA351fD7a9c00d2eBF226f6461Af33F10`
链:Polygon Mainnet (`chainId=137`)
最后更新:`2026-03-14`
## 1. 准备参数
## 1. 目标
- 编译器版本:`v0.8.24+commit.e11b9ed9`
- 优化器:`Enabled`
- Runs`200`
- 许可证:`MIT`
- 合约路径:`contracts/PolyWeatherCheckout.sol`
- 合约名:`PolyWeatherCheckout`
对生产收款合约完成源码验证,降低钱包风控误报并提升用户信任。
构造参数顺序(新版多代币合约):
## 2. 当前部署参数(示例)
1. `_token` = `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174`(初始允许代币
2. `_treasury` = `0xe581D578EF101c80e3F32263e97E6eA28A0B170e`
- 链:Polygon Mainnet`chainId=137`
- 合约:`PolyWeatherCheckout`
- 编译器:`v0.8.24+commit.e11b9ed9`
- 优化器:`Enabled``runs=200`
## 2. 构造参数编码
> 实际地址以线上配置为准:`POLYWEATHER_PAYMENT_RECEIVER_CONTRACT`。
可直接用本仓库脚本:
## 3. 构造参数编码
使用仓库脚本生成构造参数:
```bash
python scripts/encode_checkout_constructor.py \
@@ -27,35 +25,30 @@ python scripts/encode_checkout_constructor.py \
--treasury 0xe581D578EF101c80e3F32263e97E6eA28A0B170e
```
输出应为:
输出填入 PolygonScan 的 `Constructor Arguments ABI-encoded`
```text
0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000e581d578ef101c80e3f32263e97e6ea28a0b170e
```
## 4. PolygonScan 操作步骤
把这串填到 PolygonScan 的 `Constructor Arguments ABI-encoded`
## 3. PolygonScan 页面操作
1. 打开合约页面 -> `Contract` -> `Verify and Publish`.
1. 打开合约页 -> `Contract` -> `Verify and Publish`
2. 选择 `Solidity (Single file)`
3. 粘贴 `contracts/PolyWeatherCheckout.sol` 全部源码。
4. 按上面参数填写编译器优化器。
5. 粘贴编码后的构造参数提交验证
3. 粘贴 `contracts/PolyWeatherCheckout.sol` 源码。
4. 填写编译器/优化器参数
5. 粘贴构造参数提交。
## 4. 验证后检查
## 5. 验证后检查
验证成功后确认:
- `Read Contract`:可见 `owner / treasury / allowedToken / paidOrder`
- `Write Contract`:可见 `pay / setTreasury / setTokenAllowed`
- 标签显示 `Contract Source Code Verified`
- `Read Contract``owner / treasury / allowedToken / paidOrder`
- `Write Contract``pay / setTreasury / setTokenAllowed`
- `Contract` 标签显示 `Contract Source Code Verified`
## 6. 双币种开启(USDC + USDC.e
## 5. 同时开启 USDC.e + Native USDC
验证后可通过 `setTokenAllowed` 开启两种代币:
验证后在 `Write Contract` 调用:
- USDC.e: `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174`
- Native USDC: `0x3c499c542cef5e3811e1192ce70d8cc03d5c3359`
- `setTokenAllowed(0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174, true)` // USDC.e
- `setTokenAllowed(0x3c499c542cef5e3811e1192ce70d8cc03d5c3359, true)` // Native USDC
## 7. 说明
> 说明:钱包风控中的“欺诈/不可信”提示来自钱包安全引擎(如 Blockaid),源码验证能显著降低误报频率,但不保证 100% 立刻消失,通常需一段时间同步信誉缓存
- 源码验证能显著降低“欺诈/不可信”误报,但钱包风险缓存更新存在延迟
- 生产商用环境可使用私有升级版合约;公开仓库保留标准实现与验证流程。
+47 -64
View File
@@ -1,6 +1,6 @@
# PolyWeather Frontend
This directory contains the production web frontend.
Production frontend for PolyWeather Pro.
Production URL:
- https://polyweather-pro.vercel.app/
@@ -8,23 +8,16 @@ Production URL:
## Stack
- Next.js App Router
- React (dashboard component architecture)
- Tailwind CSS
- Leaflet (map)
- Chart.js
- Typed dashboard store + typed data client
- React + Tailwind
- Leaflet + Chart.js
- Supabase Auth
- WalletConnect + browser EVM wallets
## Runtime Model
- Vercel hosts UI + BFF route handlers.
- FastAPI on VPS provides weather/analysis APIs.
- Browser never calls backend directly in normal flow.
Request path:
1. Browser -> `https://polyweather-pro.vercel.app`
2. Frontend -> Next route handlers (`/api/*`)
3. Route handlers -> FastAPI (`POLYWEATHER_API_BASE_URL`)
1. Browser -> Next app (`frontend`)
2. Next Route Handlers (`/api/*`) -> FastAPI backend
3. FastAPI -> analysis/payment services
## Local Development
@@ -35,76 +28,66 @@ npm install
npm run dev
```
Default local URL:
- http://localhost:3000
## Required Environment Variables
```env
POLYWEATHER_API_BASE_URL=https://<your-fastapi-host>
```
Optional entitlement variables:
```env
POLYWEATHER_DASHBOARD_ACCESS_TOKEN=
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
POLYWEATHER_AUTH_ENABLED=true
POLYWEATHER_AUTH_REQUIRED=false
POLYWEATHER_BACKEND_ENTITLEMENT_TOKEN=
```
WalletConnect:
```env
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=
NEXT_PUBLIC_WALLETCONNECT_POLYGON_RPC_URL=https://polygon-bor-rpc.publicnode.com
```
Overlay links:
```env
NEXT_PUBLIC_TELEGRAM_GROUP_URL=https://t.me/<your_group>
```
## Route Handlers
Weather:
- `GET /api/cities`
- `GET /api/city/[name]`
- `GET /api/city/[name]/summary`
- `GET /api/city/[name]/detail`
- `GET /api/history/[name]`
Cache behavior:
Auth:
- `cities` / `summary` / `history` return `ETag` + `Cache-Control`.
- `summary?force_refresh=true` returns `Cache-Control: no-store`.
- `city/[name]` and `city/[name]/detail` are dynamic pass-through (no shared HTTP cache).
- `GET /api/auth/me`
## Frontend State & Local Cache
Payments:
- `sessionStorage`:
- city detail cache bundle (TTL 5 minutes)
- `localStorage`:
- selected city
- sidebar risk-group collapse state
- in-flight request de-duplication for city detail/summary/history/market scan
- `GET /api/payments/config`
- `GET /api/payments/wallets`
- `POST /api/payments/wallets/challenge`
- `POST /api/payments/wallets/verify`
- `POST /api/payments/intents`
- `GET /api/payments/intents/[intentId]`
- `POST /api/payments/intents/[intentId]/submit`
- `POST /api/payments/intents/[intentId]/confirm`
## Entitlement
## Cache Behavior
- `frontend/middleware.ts` enforces dashboard/API access when `POLYWEATHER_DASHBOARD_ACCESS_TOKEN` is set.
- BFF forwards backend entitlement token via `x-polyweather-entitlement` header when configured.
- `cities` / `summary` / `history`: `ETag + Cache-Control`
- `summary?force_refresh=true`: `no-store`
- payment routes: `no-store`
## UI Notes
## Open-Core Note
- Left sidebar supports risk-group collapsible sections.
- City rows keep local time and peak-time hints visible.
- Future-date modal requests market scan with `target_date`.
- Detail panel accessibility uses `inert` + blur when hidden.
This frontend repo includes general product UI and standard payment UX.
Commercial strategy tuning, private ops workflows, and sensitive production parameters are intentionally outside the public docs scope.
## Icons & Manifest
See root policy: `docs/OPEN_CORE_POLICY.md`
- `frontend/app/favicon.ico`
- `frontend/app/favicon-16x16.png`
- `frontend/app/favicon-32x32.png`
- `frontend/app/apple-touch-icon.png`
- `frontend/app/site.webmanifest`
## Vercel Deployment
1. Import repo into Vercel
2. Set Root Directory = `frontend`
3. Set env vars
4. Deploy
## Verification
```bash
./scripts/validate_frontend_cache.sh "https://polyweather-pro.vercel.app"
```
Last updated: `2026-03-12`
Last updated: `2026-03-14`