Update docs for ops, payments, and deployment guidance
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
|
||||
- 新增 `/ops` 轻量运营后台,支持系统状态、会员列表、用户查询、周榜、手动补分
|
||||
- `/ops` 新增支付异常单,支持按原因筛选并手动标记“已处理”
|
||||
- 会员列表支持按 `user_id` 去重,并回补 Supabase Auth 邮箱/注册时间
|
||||
- 新增按邮箱补跑订阅恢复脚本 `scripts/reconcile_subscription_by_email.py`
|
||||
- 支付确认失败(如 `receiver_mismatch`)现在会明确落 `failed`,并写入 SQLite 审计事件
|
||||
- 账户页支付前强制重新拉取 `/api/payments/config`,并对 `tx_payload.to` 做最新地址校验
|
||||
- 城市详情页新增 `官方参考 / Official Sources` 区块,覆盖主要城市的官方机构/机场/METAR 链接
|
||||
- 前端钱包选择补齐 EIP-6963 发现、稳定去重和绑定后账户状态即时刷新
|
||||
|
||||
## 1.5.0 - 2026-03-21
|
||||
|
||||
- 运行态状态与缓存支持 SQLite 渐进迁移,新增 `POLYWEATHER_STATE_STORAGE_MODE=file|dual|sqlite`
|
||||
|
||||
@@ -14,12 +14,16 @@ Official dashboard: [polyweather-pro.vercel.app](https://polyweather-pro.vercel.
|
||||
|
||||

|
||||
|
||||
## Product Status (2026-03)
|
||||
## Product Status (2026-03-21)
|
||||
|
||||
- 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.
|
||||
- Ops dashboard live: `/ops` for memberships, leaderboard, manual point grants, and payment incident triage.
|
||||
- Lightweight observability live: `/healthz`, `/api/system/status`, `/metrics`.
|
||||
- Runtime state supports gradual SQLite migration (`file / dual / sqlite`).
|
||||
- EMOS/CRPS pipeline is integrated in `shadow` mode with rollout gating.
|
||||
|
||||
## Open-Core Boundary (Important)
|
||||
|
||||
@@ -32,11 +36,12 @@ See: [Open-Core & Commercial Boundary](docs/OPEN_CORE_POLICY.md)
|
||||
|
||||
## Core Capabilities
|
||||
|
||||
- Aggregates observations and forecasts for 20 monitored cities.
|
||||
- Aggregates observations and forecasts for 30 monitored cities.
|
||||
- Uses DEB (Dynamic Error Balancing) to blend multi-model highs.
|
||||
- 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.
|
||||
- Adds payment audit trails, replay tooling, and incident visibility in ops.
|
||||
|
||||
## Reference Architecture
|
||||
|
||||
@@ -57,12 +62,13 @@ flowchart LR
|
||||
ANA --> PM["Polymarket Read-only Layer"]
|
||||
```
|
||||
|
||||
## Monitored Cities (20)
|
||||
## Monitored Cities (30)
|
||||
|
||||
- Europe / Middle East: Ankara, London, Paris, Munich
|
||||
- APAC: Seoul, Hong Kong, Shanghai, Singapore, Tokyo, Wellington
|
||||
- Europe / Middle East: Ankara, London, Paris, Munich, Tel Aviv, Milan, Warsaw, Madrid
|
||||
- APAC: Seoul, Hong Kong, Taipei, Shanghai, Singapore, Tokyo, Wellington
|
||||
- Americas: Toronto, New York, Chicago, Dallas, Miami, Atlanta, Seattle, Buenos Aires, Sao Paulo
|
||||
- South Asia: Lucknow
|
||||
- China extension: Chengdu, Chongqing, Shenzhen, Beijing, Wuhan
|
||||
|
||||
## Quick Start
|
||||
|
||||
@@ -91,6 +97,14 @@ POLYWEATHER_DB_PATH=/var/lib/polyweather/polyweather.db
|
||||
|
||||
## Ops Verification
|
||||
|
||||
### Health / system status / metrics
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8000/healthz
|
||||
curl http://127.0.0.1:8000/api/system/status
|
||||
curl http://127.0.0.1:8000/metrics
|
||||
```
|
||||
|
||||
### Frontend cache headers
|
||||
|
||||
```bash
|
||||
@@ -103,6 +117,12 @@ POLYWEATHER_DB_PATH=/var/lib/polyweather/polyweather.db
|
||||
docker compose logs -f polyweather | egrep "payment event loop started|payment confirm loop started|payment auto-confirmed"
|
||||
```
|
||||
|
||||
### Payment runtime
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8000/api/payments/runtime
|
||||
```
|
||||
|
||||
### Wallet activity logs
|
||||
|
||||
```bash
|
||||
@@ -127,9 +147,15 @@ docker compose logs -f polyweather | egrep "polymarket wallet activity watcher s
|
||||
- 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)
|
||||
- Configuration & secrets (ZH): [docs/CONFIGURATION_ZH.md](docs/CONFIGURATION_ZH.md)
|
||||
- Frontend deployment (ZH): [docs/FRONTEND_DEPLOYMENT_ZH.md](docs/FRONTEND_DEPLOYMENT_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)
|
||||
- Payment audit: [docs/payments/PAYMENT_AUDIT_ZH.md](docs/payments/PAYMENT_AUDIT_ZH.md)
|
||||
- Payment V2 upgrade: [docs/payments/PAYMENT_UPGRADE_V2_ZH.md](docs/payments/PAYMENT_UPGRADE_V2_ZH.md)
|
||||
- Ops admin guide: [docs/OPS_ADMIN_ZH.md](docs/OPS_ADMIN_ZH.md)
|
||||
- Deep research report: [docs/deep-research-report.md](docs/deep-research-report.md)
|
||||
- Frontend report: [FRONTEND_REDESIGN_REPORT.md](FRONTEND_REDESIGN_REPORT.md)
|
||||
- Release process: [RELEASE.md](RELEASE.md)
|
||||
- Changelog: [CHANGELOG.md](CHANGELOG.md)
|
||||
@@ -137,4 +163,4 @@ docker compose logs -f polyweather | egrep "polymarket wallet activity watcher s
|
||||
## Version
|
||||
|
||||
- Version: `v1.5.0`
|
||||
- Last Updated: `2026-03-14`
|
||||
- Last Updated: `2026-03-21`
|
||||
|
||||
+13
-2
@@ -14,13 +14,14 @@
|
||||
|
||||

|
||||
|
||||
## 当前产品状态(2026-03-20)
|
||||
## 当前产品状态(2026-03-21)
|
||||
|
||||
- 已上线订阅制:`Pro 月付 5 USDC`。
|
||||
- 已上线积分抵扣:`500 积分 = 1 USDC`,最多抵扣 `3 USDC`。
|
||||
- 已上线链上支付:Polygon 合约支付(USDC / USDC.e)。
|
||||
- 已上线自动补单:事件监听 + 周期确认双链路。
|
||||
- 已上线支付运行态与审计接口:`/api/payments/runtime`。
|
||||
- 已上线轻量运营后台:`/ops`(会员、周榜、补分、支付异常单)。
|
||||
- 已上线轻量可观测性:`/healthz`、`/api/system/status`、`/metrics`。
|
||||
- 运行态状态与缓存已支持 SQLite 渐进迁移:`file / dual / sqlite`。
|
||||
- 已接入 EMOS/CRPS 校准链路,但当前仍保持 `emos_shadow`。
|
||||
@@ -126,6 +127,15 @@ docker compose logs -f polyweather | egrep "payment event loop started|payment c
|
||||
curl http://127.0.0.1:8000/api/payments/runtime
|
||||
```
|
||||
|
||||
### 运营后台
|
||||
|
||||
- 前端入口:`https://polyweather-pro.vercel.app/ops`
|
||||
- 后端需配置:
|
||||
|
||||
```env
|
||||
POLYWEATHER_OPS_ADMIN_EMAILS=yhrsc30@gmail.com
|
||||
```
|
||||
|
||||
### 钱包异动监听日志
|
||||
|
||||
```bash
|
||||
@@ -159,6 +169,7 @@ docker compose logs -f polyweather | egrep "polymarket wallet activity watcher s
|
||||
- 支付合约验证:[docs/payments/POLYGONSCAN_VERIFY.md](docs/payments/POLYGONSCAN_VERIFY.md)
|
||||
- 支付审计说明:[docs/payments/PAYMENT_AUDIT_ZH.md](docs/payments/PAYMENT_AUDIT_ZH.md)
|
||||
- 支付 V2 升级方案:[docs/payments/PAYMENT_UPGRADE_V2_ZH.md](docs/payments/PAYMENT_UPGRADE_V2_ZH.md)
|
||||
- 运营后台说明:[docs/OPS_ADMIN_ZH.md](docs/OPS_ADMIN_ZH.md)
|
||||
- 深度评估报告:[docs/deep-research-report.md](docs/deep-research-report.md)
|
||||
- 前端报告:[FRONTEND_REDESIGN_REPORT.md](FRONTEND_REDESIGN_REPORT.md)
|
||||
- 发布流程:[RELEASE.md](RELEASE.md)
|
||||
@@ -167,4 +178,4 @@ docker compose logs -f polyweather | egrep "polymarket wallet activity watcher s
|
||||
## 当前版本
|
||||
|
||||
- 版本:`v1.5.0`
|
||||
- 文档最后更新:`2026-03-20`
|
||||
- 文档最后更新:`2026-03-21`
|
||||
|
||||
+32
-4
@@ -1,6 +1,6 @@
|
||||
# PolyWeather API 文档(v1.5.0)
|
||||
|
||||
最后更新:`2026-03-20`
|
||||
最后更新:`2026-03-21`
|
||||
|
||||
本文档描述当前对外可用 API 口径(`web/app.py` + `web/routes.py` + `frontend/app/api/*`)。
|
||||
|
||||
@@ -74,6 +74,7 @@ flowchart LR
|
||||
| `/api/payments/intents/{intent_id}` | GET | 查询 intent 最新状态 |
|
||||
| `/api/payments/intents/{intent_id}/submit` | POST | 提交交易哈希 |
|
||||
| `/api/payments/intents/{intent_id}/confirm` | POST | 手动触发确认 |
|
||||
| `/api/payments/reconcile-latest` | POST | 对当前登录用户最近一笔 intent 做恢复性确认 |
|
||||
|
||||
### 支付状态建议
|
||||
|
||||
@@ -107,13 +108,34 @@ flowchart LR
|
||||
- `polyweather_source_requests_total`
|
||||
- `polyweather_source_request_duration_ms_*`
|
||||
|
||||
## 7. 缓存策略(当前)
|
||||
## 7. Ops 管理接口
|
||||
|
||||
这些接口主要给 `/ops` 管理后台使用,默认要求:
|
||||
|
||||
- 已登录
|
||||
- 当前邮箱位于 `POLYWEATHER_OPS_ADMIN_EMAILS`
|
||||
|
||||
| 接口 | 方法 | 用途 |
|
||||
| :-- | :-- | :-- |
|
||||
| `/api/ops/users` | GET | 按 Telegram ID / 用户名 / 邮箱查询用户 |
|
||||
| `/api/ops/leaderboard/weekly` | GET | 本周积分榜 |
|
||||
| `/api/ops/memberships` | GET | 当前有效会员(已按用户去重,保留最晚到期) |
|
||||
| `/api/ops/users/grant-points` | POST | 手动补分 |
|
||||
| `/api/ops/payments/incidents` | GET | 支付异常单(仅 `payment_intent_failed`) |
|
||||
| `/api/ops/payments/incidents/{event_id}/resolve` | POST | 标记支付异常单已处理 |
|
||||
|
||||
`/api/ops/payments/incidents` 当前支持:
|
||||
|
||||
- `reason=<receiver_mismatch|sender_mismatch|event_mismatch|tx_reverted>`
|
||||
- 默认不返回已标记处理的记录
|
||||
- 重点用于排查“已付款未开通”“打到旧收款地址”等事故
|
||||
## 8. 缓存策略(当前)
|
||||
|
||||
- `cities` / `summary` / `history`:BFF 支持 `ETag + 304`
|
||||
- `summary?force_refresh=true`:`Cache-Control: no-store`
|
||||
- 详情接口与支付接口:`no-store`
|
||||
|
||||
## 8. 调试示例
|
||||
## 9. 调试示例
|
||||
|
||||
### 查询未来日期 market_scan
|
||||
|
||||
@@ -133,6 +155,12 @@ curl -s http://127.0.0.1:8000/api/payments/config | python3 -m json.tool
|
||||
curl -s http://127.0.0.1:8000/api/payments/runtime | python3 -m json.tool
|
||||
```
|
||||
|
||||
### 查看支付异常单
|
||||
|
||||
```bash
|
||||
curl -s "http://127.0.0.1:8000/api/ops/payments/incidents?reason=receiver_mismatch" | python3 -m json.tool
|
||||
```
|
||||
|
||||
### 查看系统状态
|
||||
|
||||
```bash
|
||||
@@ -145,7 +173,7 @@ curl -s http://127.0.0.1:8000/api/system/status | python3 -m json.tool
|
||||
docker compose logs -f polyweather | egrep "payment event loop started|payment confirm loop started|payment auto-confirmed"
|
||||
```
|
||||
|
||||
## 9. 开源口径说明
|
||||
## 10. 开源口径说明
|
||||
|
||||
对外公开文档仅覆盖通用 API 契约。生产商业策略参数不在公开文档披露。
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ PolyWeather 的环境变量很多,但不是所有变量都属于同一层级
|
||||
- `POLYWEATHER_AUTH_ENABLED`
|
||||
- `POLYWEATHER_AUTH_REQUIRED`
|
||||
- `POLYWEATHER_AUTH_REQUIRE_SUBSCRIPTION`
|
||||
- `POLYWEATHER_OPS_ADMIN_EMAILS`
|
||||
- `POLYWEATHER_STATE_STORAGE_MODE`
|
||||
- `POLYWEATHER_PAYMENT_ENABLED`
|
||||
- `POLYMARKET_MARKET_SCAN_ENABLED`
|
||||
@@ -162,6 +163,11 @@ PolyWeather 的环境变量很多,但不是所有变量都属于同一层级
|
||||
- `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID`
|
||||
- `NEXT_PUBLIC_WALLETCONNECT_POLYGON_RPC_URL`
|
||||
|
||||
说明:
|
||||
|
||||
- `/ops` 页面本身部署在 Vercel 前端下,但管理员写接口权限仍由后端 `POLYWEATHER_OPS_ADMIN_EMAILS` 控制。
|
||||
- 因此,Vercel 侧不需要配置管理员邮箱白名单;管理员判定发生在 VPS / FastAPI 后端。
|
||||
|
||||
不要把后端专用密钥全搬进 Vercel。
|
||||
|
||||
### 5.3 GitHub Actions
|
||||
@@ -198,6 +204,7 @@ UID=1000
|
||||
GID=1000
|
||||
POLYWEATHER_AUTH_ENABLED=true
|
||||
POLYWEATHER_AUTH_REQUIRED=false
|
||||
POLYWEATHER_OPS_ADMIN_EMAILS=yhrsc30@gmail.com
|
||||
SUPABASE_URL=https://your-project.supabase.co
|
||||
SUPABASE_ANON_KEY=...
|
||||
SUPABASE_SERVICE_ROLE_KEY=...
|
||||
@@ -258,6 +265,7 @@ POLYWEATHER_BACKEND_ENTITLEMENT_TOKEN=...
|
||||
2. `.env.secrets.example` 新增
|
||||
3. 前端 `.env.example` 收口
|
||||
4. 运行时配置校验脚本新增
|
||||
5. `/ops` 管理员白名单与前后端职责边界已明确
|
||||
5. 支付运行态与多 RPC 配置支持
|
||||
6. 运行态 SQLite 迁移配置支持
|
||||
|
||||
|
||||
@@ -87,7 +87,27 @@ NEXT_PUBLIC_TELEGRAM_BOT_URL=https://t.me/WeatherQuant_bot
|
||||
|
||||
只影响按钮跳转,不影响核心页面加载。
|
||||
|
||||
## 五、推荐的三套配置口径
|
||||
## 五、支付配置与旧部署治理
|
||||
|
||||
支付区现在有一层额外防护:
|
||||
|
||||
1. 用户点击支付前,前端会重新请求 `/api/payments/config`
|
||||
2. 若发现 `receiver_contract` 与页面旧状态不一致,会自动切换到最新地址
|
||||
3. 若后端返回的 `tx_payload.to` 与最新 `receiver_contract` 不一致,会直接阻断支付
|
||||
|
||||
这层防护的目的,是降低以下事故概率:
|
||||
|
||||
- 用户使用长期未刷新的旧标签页
|
||||
- 命中旧 deployment URL
|
||||
- 页面本地状态残留旧收款地址
|
||||
|
||||
如果你变更过支付收款地址,建议同步执行:
|
||||
|
||||
1. 在 Vercel 对当前 production 做一次 redeploy
|
||||
2. 删除明显过期、可能还带旧支付配置的旧 deployment
|
||||
3. 在 `Settings -> Security -> Deployment Retention Policy` 中收紧旧部署保留周期
|
||||
|
||||
## 六、推荐的三套配置口径
|
||||
|
||||
### 1. 公开游客模式
|
||||
|
||||
@@ -124,7 +144,7 @@ POLYWEATHER_BACKEND_ENTITLEMENT_TOKEN=<shared-token>
|
||||
|
||||
适合前后端都启用了会员/订阅保护的生产环境。
|
||||
|
||||
## 六、不要放进 Vercel 的变量
|
||||
## 七、不要放进 Vercel 的变量
|
||||
|
||||
这些属于后端私密配置,不应该放到前端项目:
|
||||
|
||||
@@ -138,7 +158,7 @@ POLYWEATHER_BACKEND_ENTITLEMENT_TOKEN=<shared-token>
|
||||
- `NEXT_PUBLIC_*` 会暴露给浏览器
|
||||
- 只有明确允许前端公开使用的值,才应加 `NEXT_PUBLIC_`
|
||||
|
||||
## 七、上线前检查
|
||||
## 八、上线前检查
|
||||
|
||||
Vercel 部署前至少确认:
|
||||
|
||||
@@ -146,8 +166,9 @@ Vercel 部署前至少确认:
|
||||
2. `frontend/.env.example` 和 Vercel Project Settings 中的实际值一致
|
||||
3. GitHub Actions 中 `frontend-quality` 已通过
|
||||
4. 如果启用鉴权,Supabase redirect URL 已包含前端域名
|
||||
5. `GET /api/payments/config` 返回的是当前最新地址,而不是旧收款合约
|
||||
|
||||
## 八、常见问题
|
||||
## 九、常见问题
|
||||
|
||||
### 1. 页面打开后 API 全部 500
|
||||
|
||||
@@ -175,4 +196,4 @@ POLYWEATHER_API_BASE_URL
|
||||
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID
|
||||
```
|
||||
|
||||
这是钱包连接的必需项。
|
||||
这是钱包连接的必需项。
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
# Ops 运营后台说明
|
||||
|
||||
最后更新:`2026-03-21`
|
||||
|
||||
## 1. 入口
|
||||
|
||||
前端入口:
|
||||
|
||||
- `https://polyweather-pro.vercel.app/ops`
|
||||
|
||||
## 2. 权限
|
||||
|
||||
`/ops` 的写接口由后端白名单控制:
|
||||
|
||||
```env
|
||||
POLYWEATHER_OPS_ADMIN_EMAILS=yhrsc30@gmail.com
|
||||
```
|
||||
|
||||
可配置多个邮箱,逗号分隔。
|
||||
|
||||
## 3. 当前能力
|
||||
|
||||
### 只读能力
|
||||
|
||||
- 系统健康
|
||||
- SQLite / rollout / metrics 摘要
|
||||
- 支付运行态
|
||||
- 当前会员
|
||||
- 周榜
|
||||
- 支付异常单
|
||||
|
||||
### 写能力
|
||||
|
||||
- 手动补分
|
||||
- 标记支付异常单“已处理”
|
||||
|
||||
## 4. 当前会员
|
||||
|
||||
会员列表来自:
|
||||
|
||||
1. `subscriptions` 中的有效订阅
|
||||
2. 本地 `users` / `supabase_bindings`
|
||||
3. 若本地缺邮箱或注册时间,再回补 Supabase Auth 用户信息
|
||||
|
||||
去重规则:
|
||||
|
||||
- 同一个 `user_id` 只保留最晚到期那条
|
||||
|
||||
## 5. 支付异常单
|
||||
|
||||
当前异常单来源:
|
||||
|
||||
- `payment_audit_events`
|
||||
- 仅筛 `payment_intent_failed`
|
||||
|
||||
当前支持的典型失败原因:
|
||||
|
||||
- `receiver_mismatch`
|
||||
- `sender_mismatch`
|
||||
- `event_mismatch`
|
||||
- `tx_reverted`
|
||||
|
||||
默认只显示未处理项。
|
||||
|
||||
## 6. 典型处理流程
|
||||
|
||||
### 6.1 钱已到账但没开订阅
|
||||
|
||||
先看 `/ops` 的支付异常单:
|
||||
|
||||
- 如果是 `receiver_mismatch`
|
||||
- 优先判定为支付打到了旧收款地址
|
||||
- 不是缓存问题
|
||||
|
||||
然后执行:
|
||||
|
||||
1. 查 `payment_intents`
|
||||
2. 查 `payment_transactions`
|
||||
3. 查 `subscriptions`
|
||||
4. 跑恢复脚本:
|
||||
|
||||
```bash
|
||||
python scripts/reconcile_subscription_by_email.py --email <user_email>
|
||||
```
|
||||
|
||||
如果仍然失败,再人工补订阅。
|
||||
|
||||
### 6.2 已人工处理
|
||||
|
||||
在 `/ops` 里直接点:
|
||||
|
||||
- `标记已处理`
|
||||
|
||||
这不会删除审计事件,只会给原事件写:
|
||||
|
||||
- `resolved_at`
|
||||
- `resolved_by`
|
||||
|
||||
## 7. 备注
|
||||
|
||||
`/ops` 是运营后台最小版,不是完整 Admin 平台。当前目标是:
|
||||
|
||||
- 让会员、积分、支付事故、系统状态可查
|
||||
- 让常见人工操作不必再直接写 SQL
|
||||
@@ -3,9 +3,9 @@
|
||||
## 执行摘要
|
||||
|
||||
PolyWeather(仓库:`yangyuan-zhen/PolyWeather`)定位为**面向温度类结算预测市场(如 Polymarket 的温度结算合约)**的“生产级气象情报系统”,核心在于把多源天气观测/预报转化为**结算导向的概率桶(μ + bucket distribution)**,并进一步映射到市场报价完成**错价扫描**;同时提供 Web 仪表盘与 Telegram Bot 两套交互入口,并包含 Polygon 链上 USDC/USDC.e 支付、自动补单与订阅/积分体系。项目 README 明确其“Open-Core”边界:仓库公开天气聚合、基础分析、看板、Bot、标准支付流程;生产私有部分包含商业风控、阈值与运营工具等。
|
||||
从工程实现看,截至 `2026-03-20`,项目已经完成一轮明确的工程化收口:多源天气采集仍保持现有业务能力,同时已完成采集层与 Web API 大文件拆分、CI 质量门禁、配置分级(`.env.example` / `.env.secrets.example` / 中文部署文档)、EMOS/CRPS 校准链路、运行态状态与缓存向 SQLite 的渐进迁移,以及基础可观测性接口(`/healthz`、`/api/system/status`、`/metrics`)。
|
||||
从工程实现看,截至 `2026-03-21`,项目已经完成一轮明确的工程化收口:多源天气采集仍保持现有业务能力,同时已完成采集层与 Web API 大文件拆分、CI 质量门禁、配置分级(`.env.example` / `.env.secrets.example` / 中文部署文档)、EMOS/CRPS 校准链路、运行态状态与缓存向 SQLite 的渐进迁移,以及基础可观测性接口(`/healthz`、`/api/system/status`、`/metrics`)。
|
||||
这意味着报告里最初最突出的“工程地基缺失”问题,已经有一部分被关闭:`src/data_collection/weather_sources.py` 与 `web/app.py` 不再是原来的超大单文件;GitHub Actions 已覆盖 Python、前端和 Docker build;配置与密钥治理已成体系;运行态状态不再只能依赖 JSON/JSONL 文件;EMOS 也不再只是概念,而是进入了可训练、可评估、可 shadow、可门禁判断的阶段。
|
||||
但项目仍处在“从可用走向稳态”的中段,而不是终局。当前真正的高优先级问题已收敛为三类:第一,**SQLite 迁移仍处于推荐的 dual 过渡模式**,线上真正切主读路径前仍需跑一段时间验证;第二,**可观测性只完成了轻量级指标层**,还没有形成完整的外部监控、阈值告警与趋势面板;第三,**EMOS 仍未达到生产切换标准**,当前门禁结论明确为 `hold`,阻塞原因是 shadow bucket brier 明显退化。支付链路方面,链下审计与容灾已明显增强:事件重放、SQLite 审计事件、RPC 多节点容灾、合约静态检查都已补齐;当前剩余风险主要集中在**链上合约本身仍是最小实现**,尚未升级到 SafeERC20、Pausable、链上套餐绑定等更强防护版本。
|
||||
但项目仍处在“从可用走向稳态”的中段,而不是终局。当前真正的高优先级问题已收敛为三类:第一,**SQLite 迁移仍处于推荐的 dual 过渡模式**,线上真正切主读路径前仍需跑一段时间验证;第二,**可观测性只完成了轻量级指标层**,还没有形成完整的外部监控、阈值告警与趋势面板;第三,**EMOS 仍未达到生产切换标准**,当前门禁结论明确为 `hold`,阻塞原因是 shadow bucket brier 明显退化。支付链路方面,链下审计与容灾已明显增强:事件重放、SQLite 审计事件、RPC 多节点容灾、合约静态检查、`/ops` 支付异常单、按邮箱恢复脚本都已补齐;当前剩余风险主要集中在**链上合约本身仍是最小实现**,尚未升级到 SafeERC20、Pausable、链上套餐绑定等更强防护版本。
|
||||
因此,当前阶段最正确的策略已经不是继续做“大范围基础重构”,而是围绕**迁移验收、可观测性补全、EMOS 上线门禁稳定化**这三条线持续收口。短中期内更高 ROI 的方向依然不是引入新的大模型,而是把现有“采集→后处理→市场映射→支付/订阅”的链路做成**状态一致、指标可见、发布可控、回退明确**的生产平台。
|
||||
## 项目概览
|
||||
|
||||
@@ -169,7 +169,7 @@ Web/Telegram 请求 → FastAPI 调用采集器抓取/复用缓存 → 分析引
|
||||
**对标结论**:PolyWeather 与这类“全球 AI 预报模型”不在同一层级:PolyWeather 是“面向结算市场的产品化情报系统”,其价值核心是**将预测转成可交易/可结算的决策信息**。短中期内更高 ROI 的方向不是“自训大模型”,而是把现有“采集+后处理+市场映射”的链路做成**可复现、可观测、可评测、可扩展**的工程平台;在许可合规前提下,再评估引入外部模型推理作为额外信号源。
|
||||
## 优先级改进建议
|
||||
|
||||
下表按截至 `2026-03-20` 的真实状态重排优先级。已完成项不再继续列为“待做”,只保留当前仍需推进的事项。
|
||||
下表按截至 `2026-03-21` 的真实状态重排优先级。已完成项不再继续列为“待做”,只保留当前仍需推进的事项。
|
||||
| 优先级 | 改进项 | 预估工作量 | 主要收益 | 主要风险 | 可执行步骤(建议顺序) |
|
||||
| ------ | --------------------------------------------------------------------------------------------------------------------------------- | -------------------: | ------------------------------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 高 | **完成 SQLite 迁移切换与验收**:从 `dual` 过渡到 `sqlite` 主读路径 | 2–5 天 | 真正关闭 JSON/JSONL 并发一致性风险;状态/缓存统一入库 | 迁移校验不充分会导致线上行为漂移 | 1) 线上部署新代码 → 2) 执行迁移与校验脚本 → 3) `dual` 运行至少 24–48 小时 → 4) 校验 `/api/history`、bot 告警、snapshot、缓存都正常 → 5) 再切 `POLYWEATHER_STATE_STORAGE_MODE=sqlite` |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# PolyWeather 支付审计与防护说明
|
||||
|
||||
最后更新:`2026-03-20`
|
||||
最后更新:`2026-03-21`
|
||||
|
||||
## 1. 当前已落地的防护
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
- 后端只认链上 `OrderPaid` 事件。
|
||||
- 前端提交 intent 不会直接视为支付完成。
|
||||
- `confirm_loop` 会再次按链上交易与确认数校验 intent。
|
||||
- 若确认失败,当前会明确把 intent / transaction 落为失败态,而不是长期停留在 `submitted`。
|
||||
|
||||
当前已显式识别的失败原因包括:
|
||||
|
||||
- `receiver_mismatch`
|
||||
- `sender_mismatch`
|
||||
- `event_mismatch`
|
||||
- `tx_reverted`
|
||||
|
||||
### RPC 多节点容灾
|
||||
|
||||
@@ -63,6 +71,23 @@ python scripts/replay_payment_events.py --from-block 10000000 --to-block 1000100
|
||||
- event loop 最新状态
|
||||
- 最近审计事件
|
||||
|
||||
### Ops 事故单
|
||||
|
||||
现在 `/ops` 已提供单独的支付异常单列表,默认展示:
|
||||
|
||||
- `payment_intent_failed`
|
||||
|
||||
支持:
|
||||
|
||||
- 按 `reason` 过滤
|
||||
- 标记已处理
|
||||
|
||||
这让下面这类事故不再需要翻日志定位:
|
||||
|
||||
- 已付款但未开通
|
||||
- 打到旧收款地址
|
||||
- 交易事件不匹配
|
||||
|
||||
## 2. 当前合约的授权边界
|
||||
|
||||
合约源码:
|
||||
@@ -176,6 +201,38 @@ curl http://127.0.0.1:8000/api/payments/runtime
|
||||
- `event_loop_state.last_scanned_block`
|
||||
- `recent_audit_events`
|
||||
|
||||
如果你在 `/ops` 或脚本里看到:
|
||||
|
||||
- `receiver_mismatch`
|
||||
|
||||
其含义通常不是“缓存没刷新”,而是:
|
||||
|
||||
- 用户这笔交易的 `to` 地址不是当前生产收款合约
|
||||
- 常见原因是旧页面、旧 deployment、旧钱包会话,或历史收款地址仍被命中
|
||||
|
||||
此时应优先做:
|
||||
|
||||
1. 确认链上真实 `to` 地址
|
||||
2. 确认当前 `/api/payments/config` 返回的 `receiver_contract`
|
||||
3. 如确已收款,再走人工恢复或补开订阅
|
||||
|
||||
### 按邮箱恢复最近支付
|
||||
|
||||
已提供脚本:
|
||||
|
||||
- [reconcile_subscription_by_email.py](/E:/web/PolyWeather/scripts/reconcile_subscription_by_email.py)
|
||||
|
||||
命令:
|
||||
|
||||
```bash
|
||||
docker compose exec polyweather_web python scripts/reconcile_subscription_by_email.py --email user@example.com
|
||||
```
|
||||
|
||||
适用场景:
|
||||
|
||||
- 用户声称已付费但未开通
|
||||
- 需要快速确认最近一笔 intent 是否能自动恢复
|
||||
|
||||
## 7. 下一版合约建议
|
||||
|
||||
如果后续升级合约,优先级建议:
|
||||
|
||||
+45
-1
@@ -100,6 +100,50 @@ NEXT_PUBLIC_TELEGRAM_BOT_URL=https://t.me/WeatherQuant_bot
|
||||
- `POST /api/payments/intents/[intentId]/submit`
|
||||
- `POST /api/payments/intents/[intentId]/confirm`
|
||||
|
||||
Ops:
|
||||
|
||||
- `GET /ops`
|
||||
- `GET /api/ops/users`
|
||||
- `GET /api/ops/leaderboard/weekly`
|
||||
- `GET /api/ops/memberships`
|
||||
- `GET /api/ops/payments/incidents`
|
||||
- `POST /api/ops/users/grant-points`
|
||||
- `POST /api/ops/payments/incidents/[eventId]/resolve`
|
||||
|
||||
## Ops 管理后台
|
||||
|
||||
当前前端已内置轻量管理页:
|
||||
|
||||
- [https://polyweather-pro.vercel.app/ops](https://polyweather-pro.vercel.app/ops)
|
||||
|
||||
页面当前支持:
|
||||
|
||||
- 系统状态
|
||||
- SQLite / rollout / 支付运行态
|
||||
- 用户查询
|
||||
- 当前会员
|
||||
- 本周积分榜
|
||||
- 手动补分
|
||||
- 支付异常单筛选与标记已处理
|
||||
|
||||
注意:
|
||||
|
||||
- `/ops` 页面是否可写,取决于后端 `POLYWEATHER_OPS_ADMIN_EMAILS`
|
||||
- 前端登录邮箱本身不会自动获得管理员权限
|
||||
|
||||
## 支付安全补充
|
||||
|
||||
为降低“旧页面/旧配置导致打到旧收款地址”的风险,支付区现在会:
|
||||
|
||||
1. 点击支付前重新请求 `/api/payments/config`
|
||||
2. 若 `receiver_contract` 已更新,先切到最新地址
|
||||
3. 若后端返回的 `tx_payload.to` 与最新地址不一致,直接阻断支付
|
||||
|
||||
这意味着:
|
||||
|
||||
- 旧标签页风险已明显降低
|
||||
- 但支付地址变更后,仍建议在 Vercel 上 redeploy 当前 production,并清理明显过期 deployment
|
||||
|
||||
## 缓存行为
|
||||
|
||||
- `cities` / `summary` / `history`:`ETag + Cache-Control`
|
||||
@@ -113,4 +157,4 @@ NEXT_PUBLIC_TELEGRAM_BOT_URL=https://t.me/WeatherQuant_bot
|
||||
|
||||
详见根目录策略文档:`docs/OPEN_CORE_POLICY.md`
|
||||
|
||||
最后更新:`2026-03-20`
|
||||
最后更新:`2026-03-21`
|
||||
|
||||
Reference in New Issue
Block a user