File size: 2,149 Bytes
06e876f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | """
Feedback endpoint — stores user feedback from the demo.
Simple JSON Lines file storage. No database needed.
"""
from __future__ import annotations
import json
import logging
from datetime import datetime, timezone
from pathlib import Path
from fastapi import APIRouter, Request
from pydantic import BaseModel, Field
logger = logging.getLogger(__name__)
router = APIRouter()
FEEDBACK_FILE = Path("/tmp/cds_feedback.jsonl")
class FeedbackSubmission(BaseModel):
message: str = Field(..., max_length=1000)
contact: str | None = Field(None, max_length=200)
page_url: str | None = None
user_agent: str | None = None
@router.post("/api/feedback")
async def submit_feedback(feedback: FeedbackSubmission, request: Request):
"""Save user feedback to a JSONL file."""
entry = {
"timestamp": datetime.now(timezone.utc).isoformat(),
"message": feedback.message,
"contact": feedback.contact,
"page_url": feedback.page_url,
"user_agent": feedback.user_agent,
"client_ip": request.client.host if request.client else None,
}
try:
with open(FEEDBACK_FILE, "a", encoding="utf-8") as f:
f.write(json.dumps(entry) + "\n")
logger.info(f"Feedback saved: {feedback.message[:50]}...")
except Exception as e:
logger.error(f"Failed to save feedback: {e}")
return {"status": "error", "message": "Failed to save feedback"}
return {"status": "ok", "message": "Thank you for your feedback!"}
@router.get("/api/feedback")
async def list_feedback():
"""List all feedback (for the developer). No auth — it's a demo."""
if not FEEDBACK_FILE.exists():
return {"feedback": [], "count": 0}
entries = []
try:
with open(FEEDBACK_FILE, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line:
entries.append(json.loads(line))
except Exception as e:
logger.error(f"Failed to read feedback: {e}")
return {"feedback": [], "count": 0, "error": str(e)}
return {"feedback": entries, "count": len(entries)}
|