main
py 137 lines 4.77 KB
Raw
1 from datetime import datetime
2
3 from fastapi import APIRouter
4 from fastapi import Depends
5 from fastapi import HTTPException
6 from fastapi import status
7 from loguru import logger
8 from sqlalchemy import select
9 from sqlalchemy.ext.asyncio import AsyncSession
10
11 from app.auth.utils import AuthHandler
12 from app.customer_portal.schema.settings import PortalSettingsData
13 from app.customer_portal.schema.settings import PortalSettingsResponse
14 from app.customer_portal.schema.settings import UpdatePortalSettingsRequest
15 from app.customer_portal.schema.settings import UpdatePortalSettingsResponse
16 from app.db.db_session import get_db
17 from app.db.universal_models import CustomerPortalSettings
18
19 customer_portal_settings_router = APIRouter()
20
21
22 @customer_portal_settings_router.post(
23 "/settings",
24 response_model=UpdatePortalSettingsResponse,
25 description="Update customer portal settings (logo and title). Set fields to null to restore defaults.",
26 dependencies=[Depends(AuthHandler().require_any_scope("admin"))],
27 )
28 async def update_portal_settings(
29 request: UpdatePortalSettingsRequest,
30 session: AsyncSession = Depends(get_db),
31 auth_handler: AuthHandler = Depends(AuthHandler().get_current_user),
32 ) -> UpdatePortalSettingsResponse:
33 """
34 Update customer portal settings including logo and title.
35 Set any field to null to restore its default value.
36 Requires authentication.
37 """
38 try:
39 # Check if settings exist
40 result = await session.execute(select(CustomerPortalSettings))
41 settings = result.scalars().first()
42
43 if not settings:
44 # Create default settings if none exist
45 settings = CustomerPortalSettings.create_default()
46 session.add(settings)
47
48 # Get default values
49 defaults = CustomerPortalSettings.get_default_values()
50
51 # Handle title: if explicitly set to null, restore default
52 if request.title is None:
53 settings.title = defaults["title"]
54 else:
55 settings.title = request.title
56
57 # Handle logo_base64: if explicitly set to null, restore default
58 if request.logo_base64 is None:
59 settings.logo_base64 = defaults["logo_base64"]
60 else:
61 settings.logo_base64 = request.logo_base64
62
63 # Handle logo_mime_type: if explicitly set to null, restore default
64 if request.logo_mime_type is None:
65 settings.logo_mime_type = defaults["logo_mime_type"]
66 else:
67 settings.logo_mime_type = request.logo_mime_type
68
69 # Update metadata
70 settings.updated_by = auth_handler.user_id if hasattr(auth_handler, "user_id") else None
71 settings.updated_at = datetime.now()
72
73 await session.commit()
74 await session.refresh(settings)
75
76 logger.info(
77 f"Portal settings updated successfully by user {auth_handler.user_id if hasattr(auth_handler, 'user_id') else 'unknown'}",
78 )
79
80 return UpdatePortalSettingsResponse(
81 success=True,
82 message="Portal settings updated successfully",
83 )
84
85 except Exception as e:
86 logger.error(f"Failed to update portal settings: {e}")
87 await session.rollback()
88 raise HTTPException(
89 status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
90 detail=f"Failed to update portal settings: {str(e)}",
91 )
92
93
94 @customer_portal_settings_router.get(
95 "/settings",
96 response_model=PortalSettingsResponse,
97 description="Get customer portal settings (public endpoint)",
98 )
99 async def get_portal_settings(
100 session: AsyncSession = Depends(get_db),
101 ) -> PortalSettingsResponse:
102 """
103 Get customer portal settings including logo and title.
104 This is a public endpoint (no authentication required).
105 """
106 try:
107 # Get settings
108 result = await session.execute(select(CustomerPortalSettings))
109 settings = result.scalars().first()
110
111 if not settings:
112 # Create and return default settings
113 settings = CustomerPortalSettings.create_default()
114 session.add(settings)
115 await session.commit()
116 await session.refresh(settings)
117
118 settings_data = PortalSettingsData(
119 id=settings.id,
120 title=settings.title,
121 logo_base64=settings.logo_base64,
122 logo_mime_type=settings.logo_mime_type,
123 updated_at=settings.updated_at.isoformat(),
124 )
125
126 return PortalSettingsResponse(
127 success=True,
128 message="Portal settings retrieved successfully",
129 settings=settings_data,
130 )
131
132 except Exception as e:
133 logger.error(f"Failed to get portal settings: {e}")
134 raise HTTPException(
135 status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
136 detail=f"Failed to get portal settings: {str(e)}",
137 )