from dataclasses import dataclass from typing import ClassVar from fansifter_common.auth.requests import AuthRequest from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from email_campaigns.adapters.db import Repository from email_campaigns.emails.cache import EmailPublicPreviewCache from email_campaigns.emails.exceptions import EmailNotFoundError from email_campaigns.emails.models import BaseEmail from email_campaigns.emails.types import EmailPreview @dataclass(kw_only=True) class UpdateEmailContentRequest(AuthRequest): email_id: str html: str | None = None css: str | None = None class UpdateEmailContentHandler[T: BaseEmail]: permission: ClassVar[Permission] def __init__( self, auth_service: AuthService, email_repository: Repository[T], preview_cache: EmailPublicPreviewCache, ) -> None: self.auth_service = auth_service self.email_repository = email_repository self.preview_cache = preview_cache def validate_email(self, email: T) -> None: """Additional validation of email before content update""" def validate_updated_email(self, email: T) -> None: """Additional validation of email after content update""" def handle(self, request: UpdateEmailContentRequest) -> EmailPreview: email = self.email_repository.get(request.email_id) if email is None: raise EmailNotFoundError self.auth_service.authorize_account( request.identity_id, account=email.account, permission=self.permission, ) self.validate_email(email) if request.html is not None: email.html_content = request.html if request.css is not None: email.css_content = request.css self.validate_updated_email(email) self.email_repository.save(email) # Invalidate cache after content update self.preview_cache.delete(email.id, email.email_type) return email.preview