diff --git a/CHANGELOG.md b/CHANGELOG.md index 0446cd2d..d13ec5ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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` diff --git a/README.md b/README.md index 2e8ea389..e7f80b76 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,16 @@ Official dashboard: [polyweather-pro.vercel.app](https://polyweather-pro.vercel. ![PolyWeather Ankara analysis](docs/images/demo_ankara.png) -## 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` diff --git a/README_ZH.md b/README_ZH.md index 4dfdd8f5..4686dbe1 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -14,13 +14,14 @@ ![PolyWeather Ankara 分析页](docs/images/demo_ankara.png) -## 当前产品状态(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` diff --git a/docs/API_ZH.md b/docs/API_ZH.md index 3b0d8bab..844dc7b8 100644 --- a/docs/API_ZH.md +++ b/docs/API_ZH.md @@ -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=` +- 默认不返回已标记处理的记录 +- 重点用于排查“已付款未开通”“打到旧收款地址”等事故 +## 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 契约。生产商业策略参数不在公开文档披露。 diff --git a/docs/CONFIGURATION_ZH.md b/docs/CONFIGURATION_ZH.md index 6cc2beaf..65fdd43d 100644 --- a/docs/CONFIGURATION_ZH.md +++ b/docs/CONFIGURATION_ZH.md @@ -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 迁移配置支持 diff --git a/docs/FRONTEND_DEPLOYMENT_ZH.md b/docs/FRONTEND_DEPLOYMENT_ZH.md index 0b3fcfca..79b08c41 100644 --- a/docs/FRONTEND_DEPLOYMENT_ZH.md +++ b/docs/FRONTEND_DEPLOYMENT_ZH.md @@ -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= 适合前后端都启用了会员/订阅保护的生产环境。 -## 六、不要放进 Vercel 的变量 +## 七、不要放进 Vercel 的变量 这些属于后端私密配置,不应该放到前端项目: @@ -138,7 +158,7 @@ POLYWEATHER_BACKEND_ENTITLEMENT_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 ``` -这是钱包连接的必需项。 \ No newline at end of file +这是钱包连接的必需项。 diff --git a/docs/OPS_ADMIN_ZH.md b/docs/OPS_ADMIN_ZH.md new file mode 100644 index 00000000..92986d35 --- /dev/null +++ b/docs/OPS_ADMIN_ZH.md @@ -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 +``` + +如果仍然失败,再人工补订阅。 + +### 6.2 已人工处理 + +在 `/ops` 里直接点: + +- `标记已处理` + +这不会删除审计事件,只会给原事件写: + +- `resolved_at` +- `resolved_by` + +## 7. 备注 + +`/ops` 是运营后台最小版,不是完整 Admin 平台。当前目标是: + +- 让会员、积分、支付事故、系统状态可查 +- 让常见人工操作不必再直接写 SQL diff --git a/docs/deep-research-report.md b/docs/deep-research-report.md index d1716564..d66004b5 100644 --- a/docs/deep-research-report.md +++ b/docs/deep-research-report.md @@ -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` | diff --git a/docs/payments/PAYMENT_AUDIT_ZH.md b/docs/payments/PAYMENT_AUDIT_ZH.md index c7f86988..025a0bfa 100644 --- a/docs/payments/PAYMENT_AUDIT_ZH.md +++ b/docs/payments/PAYMENT_AUDIT_ZH.md @@ -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. 下一版合约建议 如果后续升级合约,优先级建议: diff --git a/frontend/README.md b/frontend/README.md index 29820d4d..be7c7afd 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -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` \ No newline at end of file +最后更新:`2026-03-21`