feat: migrate pricing from legacy tables to anvil_pricing
- Replace pricing/instance_types/providers/regions with anvil_* tables - Add real-time USD→KRW exchange rate conversion (open.er-api.com) - Korean users (lang=ko) see KRW prices, others see USD - Remove provider_filter parameter (now single provider: Anvil) - Add ExchangeRateCache interface with 1-hour KV caching - Update CLAUDE.md with new table structure and exchange rate docs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
40
CLAUDE.md
40
CLAUDE.md
@@ -51,14 +51,19 @@ src/
|
||||
|
||||
### D1 Database Tables (cloud-instances-db)
|
||||
|
||||
- `providers` - Cloud providers (50+)
|
||||
- `instance_types` - Server specifications
|
||||
- `pricing` - Regional pricing
|
||||
- `regions` - Geographic regions
|
||||
**Primary tables (Anvil pricing)**:
|
||||
- `anvil_instances` - Anvil server specifications (vcpus, memory_gb, disk_gb, etc.)
|
||||
- `anvil_regions` - Anvil data center regions (name, display_name, country_code)
|
||||
- `anvil_pricing` - Anvil pricing data (monthly_price in USD)
|
||||
|
||||
**Support tables**:
|
||||
- `tech_specs` - Resource requirements per technology (vcpu_per_users, min_memory_mb)
|
||||
- `vps_benchmarks` - Geekbench 6 benchmark data (269 records)
|
||||
- `benchmark_results` / `benchmark_types` / `processors` - Phoronix benchmark data
|
||||
|
||||
**Legacy tables (no longer used)**:
|
||||
- `providers`, `instance_types`, `pricing`, `regions` - Old Linode/Vultr data
|
||||
|
||||
## Key Implementation Details
|
||||
|
||||
### DB Workload Multiplier (`recommend.ts`)
|
||||
@@ -90,20 +95,26 @@ Estimates monthly bandwidth based on use_case patterns:
|
||||
|
||||
Heavy bandwidth (>1TB/month) prefers Linode for included bandwidth.
|
||||
|
||||
### Flexible Region Matching (`utils.ts`)
|
||||
### Flexible Region Matching
|
||||
|
||||
Both `/api/recommend` and `/api/servers` use shared `buildFlexibleRegionConditions()`:
|
||||
Both `/api/recommend` and `/api/servers` use `buildFlexibleRegionConditionsAnvil()` for anvil_regions:
|
||||
```sql
|
||||
LOWER(r.region_code) = ? OR
|
||||
LOWER(r.region_code) LIKE ? OR
|
||||
LOWER(r.region_name) LIKE ? OR
|
||||
LOWER(r.country_code) = ?
|
||||
LOWER(ar.name) = ? OR
|
||||
LOWER(ar.name) LIKE ? OR
|
||||
LOWER(ar.display_name) LIKE ? OR
|
||||
LOWER(ar.country_code) = ?
|
||||
```
|
||||
|
||||
Valid inputs: `"korea"`, `"KR"`, `"seoul"`, `"tokyo"`, `"japan"`, `"ap-northeast-2"`, `"icn"`
|
||||
|
||||
Country names are auto-expanded via `COUNTRY_NAME_TO_REGIONS` mapping.
|
||||
|
||||
### Exchange Rate Handling (`utils.ts`)
|
||||
|
||||
- Korean users (lang=ko) see prices in KRW
|
||||
- Exchange rate fetched from open.er-api.com with 1-hour KV cache
|
||||
- Fallback rate: 1450 KRW/USD if API unavailable
|
||||
|
||||
### AI Prompt Strategy (`recommend.ts`)
|
||||
|
||||
- Uses OpenAI GPT-4o-mini via Cloudflare AI Gateway (bypasses regional restrictions)
|
||||
@@ -174,6 +185,13 @@ curl -s "https://server-recommend.kappa-d8e.workers.dev/api/servers?region=korea
|
||||
|
||||
## Recent Changes
|
||||
|
||||
### Anvil Pricing Migration (Latest)
|
||||
- **New tables**: Migrated from `pricing` to `anvil_pricing` tables
|
||||
- **Provider**: Now uses "Anvil" as single provider (previously Linode/Vultr)
|
||||
- **Exchange rate**: Real-time USD→KRW conversion via open.er-api.com
|
||||
- **Removed**: `provider_filter` parameter no longer supported
|
||||
- **Currency handling**: Korean users see KRW, others see USD
|
||||
|
||||
### Architecture
|
||||
- **Modular architecture**: Split from single 2370-line file into organized modules
|
||||
- **Centralized config**: All magic numbers moved to `LIMITS` in config.ts
|
||||
@@ -197,6 +215,4 @@ curl -s "https://server-recommend.kappa-d8e.workers.dev/api/servers?region=korea
|
||||
|
||||
### Code Quality
|
||||
- **Dead code removed**: Unused `queryVPSBenchmarks` function deleted
|
||||
- **DRY**: `DEFAULT_REGION_FILTER_SQL` and `buildFlexibleRegionConditions()` shared between handlers
|
||||
- **Name-based filtering**: Provider queries use names, not hardcoded IDs
|
||||
- **Flexible region matching**: Both endpoints support country/city/code inputs (korea, seoul, icn)
|
||||
|
||||
Reference in New Issue
Block a user