feat: search-engine indexing — robots.txt, sitemap.xml, llms.txt, SEO meta
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 25s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Integration Test with Services (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
Documentation / Generate API Documentation (push) Successful in 9s
Documentation / Build Sphinx Documentation (push) Successful in 16s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 13s
Documentation / Validate Documentation (push) Failing after 8s
Documentation / Documentation Summary (push) Successful in 2s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 0s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 25s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Integration Test with Services (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
Documentation / Generate API Documentation (push) Successful in 9s
Documentation / Build Sphinx Documentation (push) Successful in 16s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 13s
Documentation / Validate Documentation (push) Failing after 8s
Documentation / Documentation Summary (push) Successful in 2s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 0s
robots.txt (sitemap pointer, /metrics and /scrape/ disallowed), sitemap.xml (/ and /docs), and llms.txt (site + API summary for LLM crawlers) served at the domain root. Dashboard head gains title with keywords, meta description, canonical, Open Graph/Twitter tags, schema.org WebApplication JSON-LD, theme-color, and an inline SVG favicon (also silences the /favicon.ico 404).
This commit is contained in:
@@ -3,7 +3,18 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ping River Live Monitor</title>
|
||||
<title>Ping River Live Monitor · Chiang Mai Water Levels & Flood Forecast</title>
|
||||
<meta name="description" content="Live water levels, discharge, rainfall and ML flood forecasts for the Ping River in Chiang Mai and Northern Thailand. Hourly data from 16 RID gauges and 400+ ThaiWater/HII stations, with official inundation-stage outlooks for Chiang Mai city.">
|
||||
<link rel="canonical" href="https://water.buildfor.life/">
|
||||
<meta name="theme-color" content="#f3f7f5">
|
||||
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E%F0%9F%8C%8A%3C/text%3E%3C/svg%3E">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="Ping River Live Monitor · Chiang Mai Flood Watch">
|
||||
<meta property="og:description" content="Live water levels, rainfall and flood-risk forecasts for the Ping River basin, Northern Thailand.">
|
||||
<meta property="og:url" content="https://water.buildfor.life/">
|
||||
<meta property="og:site_name" content="Ping River Live Monitor">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebApplication","name":"Ping River Live Monitor","url":"https://water.buildfor.life/","description":"Live water levels, discharge, rainfall and flood forecasts for the Ping River, Chiang Mai, Thailand.","applicationCategory":"Weather","operatingSystem":"Web","offers":{"@type":"Offer","price":"0","priceCurrency":"THB"},"creator":{"@type":"Organization","name":"B4L","url":"https://buildfor.life"}}</script>
|
||||
<link rel="preconnect" href="https://unpkg.com">
|
||||
<link rel="preconnect" href="https://tile.openstreetmap.org">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha384-sHL9NAb7lN7rfvG5lfHpm643Xkcjzp4jFvuavGOndn6pjVqS6ny56CAt3nsEVT4H" crossorigin="anonymous">
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Ping River Live Monitor
|
||||
|
||||
> Live water levels, discharge, rainfall and machine-learning flood forecasts for
|
||||
> the Ping River basin in Northern Thailand, centered on Chiang Mai (gauge P.1,
|
||||
> Nawarat Bridge). Open-source, hourly data since 2018, operated by B4L
|
||||
> (https://buildfor.life).
|
||||
|
||||
Flood context: Chiang Mai city flooding begins when P.1 reaches 3.70 m
|
||||
(official inundation stage 1); the record peak was 5.30 m on 2024-10-05.
|
||||
|
||||
## Data
|
||||
|
||||
- Hourly water level (m) and discharge (m³/s) from 16 Royal Irrigation
|
||||
Department (RID) telemetry gauges in the Ping basin, 2018-present.
|
||||
- Hourly rainfall and water level for 400+ ThaiWater/HII stations (Ping basin),
|
||||
including historical water levels back to 2019.
|
||||
- ML flood-risk forecasts (probability of warning/danger level within 6/12/24 h)
|
||||
per station, plus Chiang Mai inundation-stage probabilities.
|
||||
|
||||
## API (no key required)
|
||||
|
||||
- https://water.buildfor.life/docs : interactive OpenAPI reference
|
||||
- /stations : station metadata (code, names, coordinates)
|
||||
- /measurements/latest?limit=N : latest readings
|
||||
- /measurements/history/{station_code}?hours=N or ?start=YYYY-MM-DD&end=YYYY-MM-DD : history
|
||||
- /forecast : flood-risk forecasts for all stations
|
||||
- /api/stats : database coverage statistics
|
||||
- /api/hii/rainfall/latest : latest rainfall per ThaiWater/HII station
|
||||
- /api/hii/waterlevel/latest : latest water level per ThaiWater/HII station (m MSL)
|
||||
|
||||
## Source
|
||||
|
||||
- https://git.b4l.co.th/B4L/Northern-Thailand-Ping-River-Monitor : code, docs,
|
||||
and the full data-source catalog (docs/DATA_SOURCES.md).
|
||||
@@ -0,0 +1,6 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: /metrics
|
||||
Disallow: /scrape/
|
||||
|
||||
Sitemap: https://water.buildfor.life/sitemap.xml
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://water.buildfor.life/</loc>
|
||||
<changefreq>hourly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://water.buildfor.life/docs</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.5</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
+22
-1
@@ -16,7 +16,7 @@ from typing import Any, Dict, List, Optional
|
||||
import requests
|
||||
from fastapi import BackgroundTasks, Depends, FastAPI, Header, HTTPException, Query
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.responses import FileResponse, HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from .config import Config
|
||||
@@ -276,6 +276,27 @@ async def root():
|
||||
return HTMLResponse(content=DASHBOARD_HTML)
|
||||
|
||||
|
||||
# Crawler/indexing files must live at the domain root (served from src/static)
|
||||
_STATIC_DIR = os.path.dirname(_DASHBOARD_HTML_PATH)
|
||||
|
||||
|
||||
@app.get("/robots.txt", include_in_schema=False)
|
||||
async def robots_txt():
|
||||
return FileResponse(os.path.join(_STATIC_DIR, "robots.txt"), media_type="text/plain")
|
||||
|
||||
|
||||
@app.get("/llms.txt", include_in_schema=False)
|
||||
async def llms_txt():
|
||||
return FileResponse(os.path.join(_STATIC_DIR, "llms.txt"), media_type="text/plain")
|
||||
|
||||
|
||||
@app.get("/sitemap.xml", include_in_schema=False)
|
||||
async def sitemap_xml():
|
||||
return FileResponse(
|
||||
os.path.join(_STATIC_DIR, "sitemap.xml"), media_type="application/xml"
|
||||
)
|
||||
|
||||
|
||||
@app.get("/health", response_model=HealthResponse)
|
||||
async def get_health():
|
||||
"""Get system health status"""
|
||||
|
||||
Reference in New Issue
Block a user