Files
PolyWeather/CLAUDE.md
T
2569718930@qq.com dca4f2d618 架构重构:拆分 core/ops/DBManager,统一 SQLite 锁,DEB 改进,新增注意力模型
- web/core.py 858→236行,拆出 schemas/middleware/auth/diagnostics
- ops_api.py 2876→4个 domain 模块 (users/payments/health/config)
- DBManager Supabase HTTP 调用提取到 SupabaseAdminClient
- 新增 LockedSQLiteConnection 统一多进程读写锁
- 新增 WeatherCacheManager 替代 12 个独立缓存字典
- METAR 缓存迁移至统一缓存管理器
- analysis_service 提取 _build_intraday_meteorology 到独立模块
- DEB 改进:偏差惩罚、分歧回退、自适应 lookback (MAE ↓12.6%)
- 新增 PyTorch 注意力模型 deb_attention.py (数据积累后启用)
- 新增 torch 到 requirements.lock
2026-06-16 02:00:22 +08:00

6.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

PolyWeather Pro — a paid institutional weather-intelligence terminal. 50 monitored cities with real-time METAR/AMOS/MADIS observations, DEB multi-model temperature blending, Mu probability calibration, and intraday bias correction. Pure meteorological decision workspace; no market/price layer. Next.js 15 + React 19 frontend (Docker / VPS, behind Cloudflare + Nginx), FastAPI backend (VPS), Telegram bot.

Business model: Paid-only, 29.9 USDC/month or 79.9 USDC/quarter, referral first month 20 USDC. New users get a one-time 3-day trial. Landing page is public; /terminal requires login + active subscription.

Environment & Preferences

  • Working directory: repo root
  • Python: python (not python3), venv at venv/
  • Frontend: cd frontend && npm run dev → localhost:3000
  • Backend: uvicorn web.app:app --reload --host 0.0.0.0 --port 8000
  • Package manager: npm (not yarn/pnpm)
  • Commit language: Chinese (简体中文) ONLY
  • NEVER start commit messages with @ — Chinese directly, no prefix

Commands

# Frontend
cd frontend
npm run dev          # dev server :3000
npm run build        # production build
npm run typecheck    # tsc --noEmit
npm run test:business  # 19 business state tests

# Backend
uvicorn web.app:app --reload --host 0.0.0.0 --port 8000
python bot_listener.py   # Telegram bot

# Python tests
python -m pytest tests/
python -m pytest tests/test_supabase_entitlement.py

# Lint
ruff check .
ruff format .

# Docker (VPS)
docker compose down && docker compose up -d --build

Architecture

Users → Cloudflare → Nginx → Docker Compose (VPS)
                                 ├── Next.js frontend → FastAPI :8000
                                 │     /terminal (paid gate)    Weather Collector
                                 │     / (landing page)         Analysis (DEB + Mu)
                                 │                               Payment Layer (USDC on Polygon)
                                 └── Redis (SSE event store)
         Telegram Bot → bot_listener.py

Frontend Structure

Path Purpose
app/page.tsx Landing page (InstitutionalLandingPage)
app/terminal/page.tsx Paid terminal (ScanTerminalDashboard)
app/account/ Account center with payment/subscription
app/auth/ Supabase login/signup
components/dashboard/scan-terminal/ Terminal sub-components
components/account/ Account + payment hooks
components/landing/ Institutional landing page
components/subscription/ UnlockProOverlay payment overlay
lib/dashboard-types.ts All TypeScript types

Terminal Component Map

  • ScanTerminalDashboard.tsx — entry, auth gate, ProductAccessRequired
  • PolyWeatherTerminal — main layout: sidebar + region tabs + 2-column grid
  • CityRegionList — city list panel (left top)
  • CityContractDetail — contract table panel (left bottom)
  • LiveTemperatureThresholdChart — multi-source overlay: obs + DEB + model curves + thresholds
  • RealtimeScrollChart — lightweight realtime scrolling temperature + threshold bars
  • TrainingDashboard — DEB + Mu accuracy charts (sidebar "训练数据" tab)
  • continent-grouping.ts — 7 trading regions (TRADING_REGIONS), city-to-region fallback (CITY_REGION_FALLBACK), timezone detection (detectLocalRegion)

Account Module

  • AccountCenter.tsx (~1280 lines) — main component
  • useAccountPayment.ts — master payment hook, composes sub-hooks
  • useWalletBind.ts — EVM/WalletConnect binding
  • usePaymentFlow.ts — intent creation, payment, confirmation
  • useBilling.ts — subscription recovery, billing computation

Backend Key Files

Path Purpose
web/routers/city.py City detail/summary/realtime-stream endpoints
web/routers/scan.py Scan terminal aggregation
web/services/city_payloads.py City detail and summary payload builders
web/scan_terminal_city_row.py Builds terminal rows from analysis data
src/data_collection/city_registry.py 50-city registry with tz_offset
src/analysis/deb_algorithm.py DEB prediction + Mu calibration + accuracy
web/services/analysis_utils.py Clock helpers, bucket labeling, time parsing
web/services/observation_freshness.py Source profiles and freshness computation
web/services/scan_ai_config.py Scan terminal and AI configuration constants

Auth Gating

Middleware (middleware.ts) handles two layers:

  1. Terminal gate (handleTerminalGate): /terminal/* → redirect to /auth/login if no Supabase session
  2. Global auth (handleSupabaseAuthGate): enforced when POLYWEATHER_AUTH_REQUIRED=true

Client-side gate (ProductAccessRequired): /terminal checks auth + subscription via /api/auth/me, shows paywall if needed.

Local dev bypass: set NEXT_PUBLIC_POLYWEATHER_LOCAL_FULL_ACCESS=false to test auth locally.

Polymarket Integration

Removed. No Polymarket price fetching, no market scan, no WS cache. Terminal operates on weather data only (Live observations + DEB predictions + model probabilities). All polymarket_readonly.py, polymarket_ws_cache.py, and market-scan API routes have been deleted.

Trading Regions

7 regions: east_asia, southeast_asia, central_asia, west_asia, europe_africa, south_america, north_america. Mappings in continent-grouping.ts (CITY_REGION_FALLBACK — all 50 cities hardcoded) and scan_terminal_filters.py (market_region_from_tz_offset). Default region auto-detected from browser timezone.

Scan Terminal Performance

  • Region lazy-loading: region=east_asia filters cities server-side before scanning (see _market_region_from_tz_offset)
  • Weather-only: Terminal returns 1 row per city with Live/DEB/probability data; no market contract matching
  • DB: SQLite WAL mode + busy_timeout=5000 enabled in db_manager.py (fixes "database is locked" with parallel workers)
  • VPS env: POLYWEATHER_SCAN_TERMINAL_MAX_WORKERS=2, POLYWEATHER_SCAN_TERMINAL_BUILD_TIMEOUT_SEC=180
  • Caching: _cache is LRUDict(256) with _CACHE_LOCK; _SUMMARY_CACHE is LRUDict(128); weather caches trimmed every 200 writes

Intraday Bias Correction

analysis_service.py:_analyze() applies intraday correction after probability generation:

  • Compares current observed temp vs model hourly forecast for current hour
  • Time-of-day weight: 0.15↗0.35 pre-peak, 0.40↗0.75 during peak, 0.80 post-peak
  • Also checks if max-so-far already exceeds DEB prediction (strong upward nudge)
  • Correction capped at ±5°F / ±3°C, applied to both deb_val and mu

Code Style

  • No \uXXXX escapes — write characters directly in UTF-8
  • Use var(--color-*) CSS tokens, not hardcoded hex
  • Minimum font size: 10px (text-[10px])
  • Avoid !important except Leaflet map overrides
  • Remove dead code immediately when features are removed