""" Support Request API Handles user support requests with page screenshots. """ import base64 import logging from datetime import datetime from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from database import get_db from auth import get_current_user, require_cap from models.user import User, Kitchen from models.settings import KitchenSettings from services.email_service import EmailService from sqlalchemy import select router = APIRouter() logger = logging.getLogger(__name__) class SupportRequest(BaseModel): """Support request payload""" description: str screenshot: str # Base64 encoded PNG page_url: str browser_info: str | None = None class SupportResponse(BaseModel): """Support request response""" success: bool message: str def generate_support_email_html( user_name: str, user_email: str, kitchen_name: str, description: str, page_url: str, browser_info: str | None, timestamp: datetime ) -> str: """Generate HTML email body for support request""" return f"""

Support Request

From: {user_name} ({user_email})

Kitchen: {kitchen_name}

Page URL: {page_url}

Timestamp: {timestamp.strftime('%Y-%m-%d %H:%M:%S UTC')}

{f'

Browser: {browser_info}

' if browser_info else ''}

Issue Description

{description.replace(chr(10), '
')}

A screenshot of the page is attached to this email.

""" @router.post("/support/request", response_model=SupportResponse) async def submit_support_request( request: SupportRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """ Submit a support request with page screenshot. The screenshot is sent as an email attachment to the configured support email. """ # Get kitchen settings result = await db.execute( select(KitchenSettings).where(KitchenSettings.kitchen_id == current_user.kitchen_id) ) settings = result.scalar_one_or_none() if not settings: raise HTTPException(status_code=404, detail="Kitchen settings not found") # Check if support email is configured if not settings.support_email: raise HTTPException( status_code=400, detail="Support email not configured. Please contact your administrator." ) # Check if SMTP is configured if not settings.smtp_host or not settings.smtp_from_email: raise HTTPException( status_code=400, detail="Email settings not configured. Please contact your administrator." ) # Fetch kitchen name explicitly to avoid lazy loading issues kitchen_result = await db.execute( select(Kitchen).where(Kitchen.id == current_user.kitchen_id) ) kitchen = kitchen_result.scalar_one_or_none() kitchen_name = kitchen.name if kitchen else "Unknown Kitchen" try: # Decode screenshot from base64 # Remove data URL prefix if present screenshot_data = request.screenshot if screenshot_data.startswith('data:'): screenshot_data = screenshot_data.split(',', 1)[1] screenshot_bytes = base64.b64decode(screenshot_data) # Generate email timestamp = datetime.utcnow() html_body = generate_support_email_html( user_name=current_user.name, user_email=current_user.email, kitchen_name=kitchen_name, description=request.description, page_url=request.page_url, browser_info=request.browser_info, timestamp=timestamp ) # Create email subject subject = f"Support Request from {current_user.name} - {kitchen_name}" # Send email with screenshot attachment email_service = EmailService(settings) filename = f"screenshot_{timestamp.strftime('%Y%m%d_%H%M%S')}.png" success = email_service.send_email( to_email=settings.support_email, subject=subject, html_body=html_body, attachments=[(filename, screenshot_bytes)] ) if success: logger.info(f"Support request sent from {current_user.name} to {settings.support_email}") return SupportResponse( success=True, message="Support request sent successfully. We'll get back to you soon." ) else: logger.error(f"Failed to send support request email") raise HTTPException( status_code=500, detail="Failed to send support request. Please try again later." ) except base64.binascii.Error: raise HTTPException(status_code=400, detail="Invalid screenshot data") except Exception as e: logger.error(f"Support request error: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/support/enabled") async def check_support_enabled( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """ Check if support requests are enabled (support email configured). Returns whether the support button should be shown. """ result = await db.execute( select(KitchenSettings).where(KitchenSettings.kitchen_id == current_user.kitchen_id) ) settings = result.scalar_one_or_none() enabled = bool( settings and settings.support_email and settings.smtp_host and settings.smtp_from_email ) return {"enabled": enabled}