2026-06-09 00:41:27 +00:00
|
|
|
from pathlib import Path
|
2026-08-01 17:50:45 +00:00
|
|
|
from typing import Any, Optional
|
2026-06-09 00:41:27 +00:00
|
|
|
|
2026-08-01 17:50:45 +00:00
|
|
|
from fastapi import APIRouter, Body, Query, Request
|
2026-06-09 00:41:27 +00:00
|
|
|
from fastapi.responses import JSONResponse
|
|
|
|
|
from fastapi.templating import Jinja2Templates
|
2026-08-01 17:50:45 +00:00
|
|
|
from pydantic import BaseModel, Field
|
2026-06-09 00:41:27 +00:00
|
|
|
|
2026-08-01 17:50:45 +00:00
|
|
|
from app.services.analytics_data import add_finding, collect_analytics, list_hermes_findings
|
2026-06-09 00:41:27 +00:00
|
|
|
|
|
|
|
|
router = APIRouter(prefix="/analytics", tags=["analytics"])
|
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
|
|
|
|
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
|
|
|
|
|
|
|
|
|
|
|
2026-08-01 17:50:45 +00:00
|
|
|
class FindingIn(BaseModel):
|
|
|
|
|
kind: str = Field(default="insight", description="win|opportunity|attention|insight")
|
|
|
|
|
title: str
|
|
|
|
|
body: str = ""
|
|
|
|
|
score: float | None = None
|
|
|
|
|
source: str = "hermes"
|
|
|
|
|
href: str | None = None
|
|
|
|
|
meta: dict[str, Any] | None = None
|
|
|
|
|
|
|
|
|
|
|
2026-06-09 00:41:27 +00:00
|
|
|
@router.get("")
|
|
|
|
|
async def analytics_page(request: Request):
|
|
|
|
|
initial = collect_analytics({})
|
|
|
|
|
return templates.TemplateResponse(
|
|
|
|
|
"analytics.html",
|
|
|
|
|
{"request": request, "page_title": "Analytics", "initial_data": initial},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/api/data")
|
|
|
|
|
async def analytics_api(
|
|
|
|
|
chain: Optional[str] = None,
|
|
|
|
|
province: Optional[str] = None,
|
|
|
|
|
stage: Optional[str] = None,
|
|
|
|
|
agent: Optional[str] = None,
|
|
|
|
|
days: int = Query(90, ge=7, le=365),
|
|
|
|
|
):
|
|
|
|
|
filters = {"chain": chain, "province": province, "stage": stage, "agent": agent, "days": days}
|
|
|
|
|
return JSONResponse(collect_analytics(filters))
|
2026-08-01 17:50:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/api/findings")
|
|
|
|
|
async def analytics_findings(limit: int = Query(20, ge=1, le=100)):
|
|
|
|
|
return {"items": list_hermes_findings(limit)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/api/findings")
|
|
|
|
|
async def analytics_findings_create(payload: FindingIn = Body(...)):
|
|
|
|
|
"""Hermes (of admin) kan bevindingen pushen naar het intelligence dashboard."""
|
|
|
|
|
row = add_finding(
|
|
|
|
|
kind=payload.kind,
|
|
|
|
|
title=payload.title,
|
|
|
|
|
body=payload.body,
|
|
|
|
|
score=payload.score,
|
|
|
|
|
source=payload.source,
|
|
|
|
|
href=payload.href,
|
|
|
|
|
meta=payload.meta,
|
|
|
|
|
)
|
|
|
|
|
return {"ok": True, "finding": row}
|