feat: flood-verdict banner, violet rain palette, per-station bands, chip contrast, Umami
Documentation / Build Sphinx Documentation (push) Successful in 27s
Documentation / Documentation Summary (push) Successful in 3s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 1s
Documentation / Validate Documentation (push) Failing after 11s
Documentation / Generate API Documentation (push) Successful in 11s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 1m0s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (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 Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 30s
Documentation / Build Sphinx Documentation (push) Successful in 27s
Documentation / Documentation Summary (push) Successful in 3s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 1s
Documentation / Validate Documentation (push) Failing after 11s
Documentation / Generate API Documentation (push) Successful in 11s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 1m0s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (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 Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 30s
UI/UX review backlog round 2 plus analytics: - at-a-glance verdict banner (role=status, aria-live) above the tiles: ok/watch/danger from P.1 level vs the official 3.70 m stage and the 24 h forecast, with a not-an-official-warning disclaimer + ThaiWater link (also added to the forecast card) - rainfall dots switch to a violet sequential ramp so they can never be confused with flow-status colors; legend gains 'Other markers' rows (grey no-data gauges, + bank-height sensors) - history-chart flood bands now use each station's own /forecast thresholds (P.1 official fallback) instead of hardcoded 3.0/4.5 - chipStyle(): contrast-safe text on all code/risk/stage chips (dark ink on amber/ochre, darkened fills for white ink); risk/stage ramps drop the blue step for a monotonic green-ochre-amber-red escalation - plain-language tooltips on the flow and capacity tiles - Umami: client script tag plus opt-out server-side middleware posting api-request events (fire-and-forget, 3 s timeout, never blocks)
This commit is contained in:
@@ -267,6 +267,59 @@ async def background_scraping_task():
|
||||
await asyncio.sleep(60) # Wait a minute before retrying
|
||||
|
||||
|
||||
# Umami server-side API tracking (fire-and-forget; never blocks a response)
|
||||
|
||||
_UMAMI_TRACK_PREFIXES = (
|
||||
"/api/",
|
||||
"/measurements",
|
||||
"/forecast",
|
||||
"/stations",
|
||||
"/sensors",
|
||||
)
|
||||
|
||||
|
||||
def _send_umami_event(path: str, method: str, status: int, host: str, user_agent: str):
|
||||
try:
|
||||
requests.post(
|
||||
Config.UMAMI_API_URL,
|
||||
json={
|
||||
"type": "event",
|
||||
"payload": {
|
||||
"website": Config.UMAMI_WEBSITE_ID,
|
||||
"url": path,
|
||||
"hostname": host,
|
||||
"name": "api-request",
|
||||
"data": {"method": method, "status": status},
|
||||
},
|
||||
},
|
||||
headers={"User-Agent": user_agent or "api-client"},
|
||||
timeout=3,
|
||||
)
|
||||
except Exception:
|
||||
pass # analytics must never affect API behavior
|
||||
|
||||
|
||||
@app.middleware("http")
|
||||
async def umami_api_tracking(request, call_next):
|
||||
response = await call_next(request)
|
||||
if (
|
||||
Config.UMAMI_TRACK_API
|
||||
and Config.UMAMI_WEBSITE_ID
|
||||
and request.url.path.startswith(_UMAMI_TRACK_PREFIXES)
|
||||
):
|
||||
asyncio.get_event_loop().create_task(
|
||||
asyncio.to_thread(
|
||||
_send_umami_event,
|
||||
request.url.path,
|
||||
request.method,
|
||||
response.status_code,
|
||||
request.headers.get("host", "water.buildfor.life"),
|
||||
request.headers.get("user-agent", ""),
|
||||
)
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
# API Routes
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user