"""admin/routers/settings.py — Author settings and account management. Routes: POST /{slug}/password GET /{slug}/widget-config PUT /{slug}/widget-config GET /{slug}/profile PUT /{slug}/profile GET /{slug}/personality PUT /{slug}/personality GET /{slug}/notifications PUT /{slug}/notifications GET /{slug}/embed-token GET /{slug}/token-usage """ from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from app.dependencies import get_db, get_current_author_scoped from app.schemas.admin import ( NotificationUpdate, PasswordChangeRequest, PersonalityUpdate, ProfileUpdate, WidgetConfigUpdate, ) from app.services.settings_service import SettingsService router = APIRouter() @router.post("/{author_slug}/password") async def change_password( author_slug: str, body: PasswordChangeRequest, current_user=Depends(get_current_author_scoped), db: AsyncSession = Depends(get_db), ): """Self-service password change. R-010: Validates via Pydantic schema.""" return await SettingsService(db).change_password(current_user, body) @router.get("/{author_slug}/widget-config") async def get_widget_config( author_slug: str, current_user=Depends(get_current_author_scoped), ): """Return current widget configuration.""" return SettingsService.get_widget_config(current_user) @router.put("/{author_slug}/widget-config") async def update_widget_config( author_slug: str, body: WidgetConfigUpdate, current_user=Depends(get_current_author_scoped), db: AsyncSession = Depends(get_db), ): """Update widget configuration. R-029: Validated via Pydantic schema.""" return await SettingsService(db).update_widget_config(current_user, body) @router.get("/{author_slug}/profile") async def get_profile( author_slug: str, current_user=Depends(get_current_author_scoped), ): """Return current author profile.""" return SettingsService.get_profile(current_user) @router.put("/{author_slug}/profile") async def update_profile( author_slug: str, body: ProfileUpdate, current_user=Depends(get_current_author_scoped), db: AsyncSession = Depends(get_db), ): """Update author profile. R-029: Validated via Pydantic schema.""" return await SettingsService(db).update_profile(current_user, body) @router.get("/{author_slug}/personality") async def get_personality( author_slug: str, current_user=Depends(get_current_author_scoped), ): """Return bot personality settings.""" return SettingsService.get_personality(current_user) @router.put("/{author_slug}/personality") async def update_personality( author_slug: str, body: PersonalityUpdate, current_user=Depends(get_current_author_scoped), db: AsyncSession = Depends(get_db), ): """Update bot personality settings. R-029: Validated via Pydantic schema.""" return await SettingsService(db).update_personality(current_user, body) @router.get("/{author_slug}/notifications") async def get_notifications( author_slug: str, current_user=Depends(get_current_author_scoped), ): """Return notification preferences.""" return SettingsService.get_notifications(current_user) @router.put("/{author_slug}/notifications") async def update_notifications( author_slug: str, body: NotificationUpdate, current_user=Depends(get_current_author_scoped), db: AsyncSession = Depends(get_db), ): """Update notification preferences. R-029: Validated via Pydantic schema.""" return await SettingsService(db).update_notifications(current_user, body) @router.get("/{author_slug}/embed-token") async def get_embed_token( author_slug: str, current_user=Depends(get_current_author_scoped), db: AsyncSession = Depends(get_db), ): """Return the active subscription token for embedding the widget.""" return await SettingsService(db).get_embed_token(current_user) @router.get("/{author_slug}/token-usage") async def get_token_usage( author_slug: str, current_user=Depends(get_current_author_scoped), db: AsyncSession = Depends(get_db), ): """Return token budget and consumption for the active subscription.""" return await SettingsService(db).get_token_usage(current_user.id)