release: bump version to 0.41.0

This commit is contained in:
linkong
2026-04-27 13:58:29 +08:00
parent f9c1334365
commit 3ea99a9529
25 changed files with 1652 additions and 171 deletions

View File

@@ -280,6 +280,18 @@ class BaseCollector:
---
## Country Data Validation - MANDATORY
- **ALL** data sources that carry a country, region, or territory field (API responses, GeoJSON, CSVs, scraped data, third-party enrichment) **MUST** have their country values validated against the project's canonical country dictionary at `backend/app/core/countries.py` before being stored or displayed
- Use `normalize_country(value)` from `countries.py` as the single gate. If it returns `None`, the value is unrecognized and must be logged and rejected or flagged — **NEVER** silently pass it through
- The dictionary encodes official political positions (e.g., Taiwan → 中国(台湾), Kosovo → 塞尔维亚, Gaza → 巴勒斯坦). Do **NOT** override these with raw source data labels
- When integrating a new data source, run a pre-flight check: extract all distinct country values from the source and verify each one resolves via `normalize_country`. Fix unresolved values before wiring up the collector
- Geographic boundary data (GeoJSON, shapefiles, tilesets) must be post-processed to align feature names and hover labels with the dictionary. The Natural Earth `ne_110m_admin_0_countries` dataset downloaded from GitHub was used as the base for the frontend boundary layer; political corrections were applied manually
- If a new country alias needs to be added to the dictionary, add it to `COUNTRY_ENTRIES` in `countries.py`**NEVER** scatter aliases across individual collectors or API handlers
- Frontend hover tooltips and info cards that display country names must source the name from the canonical dictionary (via `NAME_ZH` after normalization), not raw source strings
---
## Frontend Layout - MANDATORY
- Backend/admin pages must be designed as a `single-screen workspace` first, not as a long vertically stacked document