Platform bundle: marketing publish, IT ops, packaging, agents mesh.
Volledige Foodlinkk Command Center uitbreiding met social automatisering, reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Query, Request
|
||||
from fastapi.responses import JSONResponse, PlainTextResponse, Response
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
from app.db import fetch_all
|
||||
from app.services.reports_export import EXPORT_DATASETS, export_all_json, fetch_dataset, list_datasets, to_csv
|
||||
|
||||
router = APIRouter(prefix="/reports", tags=["reports"])
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
||||
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
|
||||
|
||||
|
||||
def _iso_rows(rows: list) -> list:
|
||||
for row in rows:
|
||||
for key, val in list(row.items()):
|
||||
if hasattr(val, "isoformat"):
|
||||
row[key] = val.isoformat()
|
||||
return rows
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def reports_page(request: Request):
|
||||
briefings, events = [], []
|
||||
try:
|
||||
briefings = _iso_rows(fetch_all(
|
||||
"SELECT id, content, generated_by, created_at FROM daily_briefings ORDER BY created_at DESC LIMIT 20"
|
||||
))
|
||||
except Exception:
|
||||
briefings = []
|
||||
try:
|
||||
events = _iso_rows(fetch_all(
|
||||
"""SELECT id, agent_name, event_type, title, status, created_at FROM agent_events
|
||||
WHERE event_type IN ('briefing','report','herman_chat') ORDER BY created_at DESC LIMIT 50"""
|
||||
))
|
||||
except Exception:
|
||||
events = []
|
||||
datasets = list_datasets()
|
||||
return templates.TemplateResponse(
|
||||
"reports.html",
|
||||
{
|
||||
"request": request,
|
||||
"page_title": "Reports & Export",
|
||||
"briefings": briefings,
|
||||
"report_events": events,
|
||||
"datasets": datasets,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/api/datasets")
|
||||
async def reports_datasets():
|
||||
return JSONResponse({"items": list_datasets()})
|
||||
|
||||
|
||||
@router.get("/api/export/{name}")
|
||||
async def reports_export_one(name: str, format: str = Query("csv", pattern="^(csv|json)$"), limit: int = Query(10000, ge=1, le=50000)):
|
||||
if name not in EXPORT_DATASETS:
|
||||
raise HTTPException(404, "Dataset not found")
|
||||
try:
|
||||
rows = fetch_dataset(name, limit)
|
||||
except Exception as exc:
|
||||
raise HTTPException(500, str(exc)) from exc
|
||||
if format == "json":
|
||||
return JSONResponse({"dataset": name, "count": len(rows), "items": rows})
|
||||
csv_text = to_csv(rows)
|
||||
return PlainTextResponse(
|
||||
csv_text,
|
||||
media_type="text/csv",
|
||||
headers={"Content-Disposition": f'attachment; filename="foodlinkk_{name}.csv"'},
|
||||
)
|
||||
|
||||
|
||||
@router.get("/api/export-all")
|
||||
async def reports_export_all(format: str = Query("json", pattern="^(json)$"), limit: int = Query(3000, ge=100, le=10000)):
|
||||
bundle = export_all_json(limit)
|
||||
return JSONResponse(bundle, headers={"Content-Disposition": 'attachment; filename="foodlinkk_full_export.json"'})
|
||||
Reference in New Issue
Block a user