API 文档
所有公开接口使用 /api/v1 前缀,供 Web、未来 App 和受限第三方调用复用。
App/API 响应契约
"contract": {
"api_version": "v1",
"contract_version": "2026-07-26.1",
"minimum_supported_app_version": "0.1.0",
"stability": "mvp_contract",
"production_ready": false
},
"meta": {
"request_id": "uuid",
"generated_at": "2026-07-26T00:00:00.000Z",
"cache_profile": "short",
"cache_ttl_seconds": 60,
"data_version": "2026-07-23",
"path": "/api/v1/safety-score"
}业务字段仍保留在响应顶层;App 可统一读取 contract/meta 处理版本、缓存、错误和排障。破坏性变更必须进入新的 API 版本。
坐标安全评分
GET /api/v1/safety-score?lat=53.3498&lon=-6.2603
地址安全评分
GET /api/v1/safety-score/address?query=Temple%20Bar
地址解析先查本地 seed 和本地缓存;配置 Nominatim 后可使用 OpenStreetMap 地址搜索,并返回 provider、缓存和置信度状态。
"geocoding_provider": "local_seed", "geocoding_status": "matched_local_seed", "geocoding_cache_hit": false, "geocoding_confidence": 0.95, "coordinate_source": "seed"
候选犯罪率字段
"candidate_crime_signal": {
"status": "available",
"crime_rate_per_1000_residents": 60.43,
"source_table_id": "CJQ06",
"source_period_label": "2025Q1-2025Q4",
"production_ready": false,
"official_records": [
{
"offence_label": "Theft and related offences (08)",
"source_incident_count": 7775
}
]
}该字段供 Web 和未来 App 预览真实数据管线状态;它本身不代表已经参与评分,是否校准由评分准入字段决定。
官方汇总风险警报
"official_alert": {
"status": "active",
"severity": "high",
"source_table_id": "CJQ06",
"source_period_label": "2025Q1-2025Q4",
"source_geography": "D.M.R. South Central Garda Division",
"trigger_reasons": [
{
"code": "candidate_rate_high",
"value": 86.69,
"threshold": 50
}
],
"metrics": {
"division_raw_incident_count": 17813,
"source_overlap_percent": 9.9132,
"apportioned_incident_count": 1765.84,
"candidate_rate_per_1000_residents": 86.69
},
"records": [
{
"rank": 1,
"offence_label": "Theft and related offences (08)",
"source_incident_count": 7775,
"source_share_percent": 43.65,
"apportioned_incident_count": 770.75
}
],
"caveats": [
"CJQ06 是官方 CSO/PxStat Garda Division 聚合统计,不是街道、楼宇或实时事件数据。"
]
}该字段用于地图上的风险警报点和未来 App 展示;记录来自官方 Garda Division 聚合数据,不代表具体道路或实时事件。
评分准入字段
"scoring_readiness_status": "eligible_candidate_calibration",
"eligible_for_v1_review": true,
"v1_readiness_status": "v1_review_ready",
"score_version": "baseline_v0_candidate_v1_review",
"score_production_status": "v1_review_candidate_not_production",
"candidate_score_calibration_applied": true,
"candidate_score_calibration": {
"previous_score": 74,
"calibrated_score": 69,
"candidate_weight": 0.15,
"v1_readiness_status": "v1_review_ready",
"production_ready": false
}该字段说明候选犯罪率是否已进入小权重校准,以及该区域是否达到 v1 人工复核门槛。校准有最大分数影响限制,并且仍标记为非生产评分。
分数解释字段
"score_explanation": {
"current_score": 69,
"baseline_score": 74,
"total_delta_from_baseline": -5,
"used_user_feedback": false,
"used_candidate_crime_rate": true,
"candidate_crime_rate_delta": -5,
"eligible_for_v1_review": true,
"v1_readiness_status": "v1_review_ready",
"production_ready": false,
"summary_label": "当前 69 分,baseline 为 74 分;..."
}Web 使用简洁摘要展示;App 和第三方可读取完整 JSON,解释分数来源、阻塞原因和生产状态。
地图图层
GET /api/v1/map-layer?bbox=-6.40,53.25,-6.10,53.45&zoom=12
反馈提交
POST /api/v1/feedback
{
"area_id": "dublin-2",
"rating": 72,
"comment": "Felt fine around the main streets in the evening.",
"tags": []
}错误格式
{
"error": {
"code": "INVALID_BBOX",
"message": "bbox must use minLon,minLat,maxLon,maxLat",
"details": {}
},
"contract": {
"api_version": "v1",
"contract_version": "2026-07-26.1"
},
"meta": {
"request_id": "uuid",
"cache_profile": "none",
"cache_ttl_seconds": 0
}
}完整开发文档见 docs/api.md。