105 lines
3.2 KiB
Python
105 lines
3.2 KiB
Python
import abc
|
|
from datetime import datetime
|
|
from src.services.publications import (
|
|
OrderProfile as PublicationOrderProfile,
|
|
Sequence as PublicationSequence,
|
|
Publication,
|
|
)
|
|
from src.services.users.data import UserProfile
|
|
from dataclasses import dataclass
|
|
|
|
SubscriptionId = int
|
|
|
|
|
|
@dataclass
|
|
class SubscriptionCreateParams:
|
|
user_id: int
|
|
order_id: int
|
|
|
|
|
|
@dataclass
|
|
class Subscription:
|
|
id: SubscriptionId
|
|
user: UserProfile
|
|
publication_order: PublicationOrderProfile
|
|
sequence_seen: int
|
|
start: datetime
|
|
|
|
|
|
@dataclass
|
|
class UpdateSubscription:
|
|
id: int
|
|
user_id: int
|
|
publication_order_id: int | None = None
|
|
sequence_seen: int | None = None
|
|
start: datetime | None = None
|
|
|
|
|
|
@dataclass
|
|
class AvailableSubscriptionEntry:
|
|
publication: Publication
|
|
available_since: datetime
|
|
order: PublicationOrderProfile
|
|
sequence: PublicationSequence
|
|
|
|
|
|
class SubscriptionRepo(abc.ABC):
|
|
@abc.abstractmethod
|
|
def get_subscriptions_for_user(self, user_id: int) -> list[Subscription]:
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_subscription_by_id(self, sub_id: SubscriptionId) -> Subscription | None:
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create_subscription_for_user(self, user_id: int, order_id: int) -> Subscription:
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_subscription(self, subscription_id: SubscriptionId):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update_subscription(self, subscription: UpdateSubscription) -> Subscription:
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_available_entries(self, user_id: int) -> dict[SubscriptionId, list[AvailableSubscriptionEntry]]:
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_unseen_available_subscription_entries(self, user_id: int) -> list[AvailableSubscriptionEntry]:
|
|
"""
|
|
Get all publication entries that _should_ be available to the user given the timeline but are newer than the
|
|
`sequence_seen` value from the subscription
|
|
"""
|
|
pass
|
|
|
|
|
|
class SubscriptionService:
|
|
def __init__(self, repo: SubscriptionRepo):
|
|
self._repo = repo
|
|
|
|
def get_subscriptions(self, user_id: int) -> list[Subscription]:
|
|
return self._repo.get_subscriptions_for_user(user_id)
|
|
|
|
def get_updates(self, user_id: int) -> list[AvailableSubscriptionEntry]:
|
|
return self._repo.get_unseen_available_subscription_entries(user_id)
|
|
|
|
def get_all_available_entries(self, user_id: int) -> dict[SubscriptionId, list[AvailableSubscriptionEntry]]:
|
|
return self._repo.get_available_entries(user_id)
|
|
|
|
def create_suscription(self, params: SubscriptionCreateParams) -> Subscription:
|
|
return self._repo.create_subscription_for_user(params.user_id, params.order_id)
|
|
|
|
def delete_subcription(self, user_id: int, subscription_id: SubscriptionId):
|
|
subscription = self._repo.get_subscription_by_id(subscription_id)
|
|
if subscription is None:
|
|
# TODO Domain error types
|
|
raise RuntimeError('not found')
|
|
if subscription.user.id != user_id:
|
|
# TODO: Domain error types
|
|
raise RuntimeError('Cannot delete a subscription for another user')
|
|
|
|
self._repo.delete_subscription(subscription_id)
|