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:
+42
-97
@@ -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`
|
||||
前端已具备收费阶段的核心能力(账户、支付、权限展示、状态回收),可支持持续商业迭代。
|
||||
|
||||
@@ -14,15 +14,31 @@ Official dashboard: [polyweather-pro.vercel.app](https://polyweather-pro.vercel.
|
||||
|
||||

|
||||
|
||||
## 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
@@ -14,15 +14,31 @@
|
||||
|
||||

|
||||
|
||||
## 当前产品状态(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 个监控城市的实时实测与预报数据。
|
||||
- 通过 DEB(Dynamic Error Balancing)融合多模型最高温。
|
||||
- 输出结算导向的概率分布(`mu` + 温度桶)。
|
||||
- 将模型观点映射到 Polymarket 只读市场,做错价扫描。
|
||||
- Web 仪表盘与 Telegram 机器人复用同一套分析内核。
|
||||
- 聚合 20 个监控城市的实测与预报数据。
|
||||
- DEB(Dynamic Error Balancing)融合多模型最高温。
|
||||
- 输出结算导向概率分布(`mu` + 温度桶)。
|
||||
- 将模型观点映射到 Polymarket 行情,做错价扫描。
|
||||
- Web 仪表盘与 Telegram Bot 复用同一分析内核。
|
||||
|
||||
## 当前架构
|
||||
## 参考架构
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -35,35 +51,12 @@ flowchart LR
|
||||
WX --> METAR["Aviation Weather(METAR)"]
|
||||
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/`
|
||||
|
||||
## 快速启动
|
||||
|
||||
### 后端 + Bot(Docker)
|
||||
@@ -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
@@ -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` 在前端 BFF(Vercel 的 `/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
@@ -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` |
|
||||
| 合约支付 | 已上线 | Polygon,USDC + 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`
|
||||
- 支持更多链和稳定币。
|
||||
- 引入退款与工单后台。
|
||||
- 建立周/月留存与付费转化看板。
|
||||
- 打通渠道分销与邀请码返利系统。
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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. 完成权限矩阵自动化回归测试。
|
||||
|
||||
@@ -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
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user