from collections.abc import Sequence from dataclasses import dataclass from anydi import singleton from fansifter_common.identifiers.types import ProfileToken from preference_center.profile.cache import ProfileCache from preference_center.profile.dispatcher import ProfileDispatcher from preference_center.profile.models import Subscription from preference_center.profile.services import ProfileService @dataclass(kw_only=True) class UpdateSubscriptionsRequest: token: ProfileToken data: dict[str, bool] @singleton class UpdateSubscriptionsHandler: def __init__( self, dispatcher: ProfileDispatcher, cache: ProfileCache, profile_service: ProfileService, ) -> None: self.dispatcher = dispatcher self.cache = cache self.profile_service = profile_service def handle(self, request: UpdateSubscriptionsRequest) -> Sequence[Subscription]: identifier = self.profile_service.decode_profile_identifier(request.token) # Ignore empty update payloads if not request.data: return [] profile = self.profile_service.get_profile_by_identifier_cached(identifier) changed_subscriptions: list[Subscription] = [] subscriptions = self.profile_service.get_subscriptions_cached(profile.id) # Toggle subscription status flags for subscription in subscriptions: if subscription.id not in request.data: continue is_active = request.data[subscription.id] if is_active is subscription.is_active: continue subscription.is_active = is_active changed_subscriptions.append(subscription) # Skip persistence if nothing changed if not changed_subscriptions: return subscriptions profile.updated_by = identifier.impersonated_by # Invalidate cached subscriptions self.cache.set_subscriptions(profile.id, subscriptions=subscriptions) self.dispatcher.dispatch_subscriptions_updated( profile, subscriptions=changed_subscriptions, origin_id=identifier.origin_id, origin_type=identifier.origin_type, ) return subscriptions