diff --git a/backend/src/modules/notifies/repository.py b/backend/src/modules/notifies/repository.py index 987e231..4884e44 100644 --- a/backend/src/modules/notifies/repository.py +++ b/backend/src/modules/notifies/repository.py @@ -1,17 +1,21 @@ from beanie import PydanticObjectId -from src.modules.notifies.scheams import NotificationCreate from src.storages.mongo.notifies import Notification class NotificationRepository: - async def create_notification(self, notification_data: NotificationCreate) -> PydanticObjectId: - notification = Notification(**notification_data.model_dump()) - await notification.insert() - return notification.id + async def create_notification(self, notification_data: Notification) -> PydanticObjectId: + await notification_data.insert() + return notification_data.id async def get_notification(self, notification_id: PydanticObjectId) -> Notification: return await Notification.get(notification_id) + async def get_notification_by_user_id(self, user_id: PydanticObjectId) -> list[Notification]: + return await Notification.find(Notification.user_id == user_id).to_list() + + async def list_all_valid_notifications(self) -> list[Notification]: + return await Notification.find(Notification.sent is False) + notification_repository = NotificationRepository() diff --git a/backend/src/modules/notifies/routes.py b/backend/src/modules/notifies/routes.py index 7e273be..0fa70d1 100644 --- a/backend/src/modules/notifies/routes.py +++ b/backend/src/modules/notifies/routes.py @@ -1,9 +1,12 @@ from beanie import PydanticObjectId from fastapi import APIRouter, HTTPException +from src.api.dependencies import USER_AUTH from src.api.exceptions import IncorrectCredentialsException -from src.modules.notifies.repository import notification_repository -from src.modules.notifies.scheams import NotificationCreate +from src.modules.events.repository import events_repository +from src.modules.notifies.repository import Notification, notification_repository +from src.modules.notifies.scheams import NotificationCreateReq +from src.modules.sports.repository import sports_repository router = APIRouter( prefix="/notify", @@ -15,8 +18,35 @@ @router.post("/") -async def create_notification(notification_create: NotificationCreate) -> PydanticObjectId: - return await notification_repository.create_notification(notification_create) +async def create_notification(notification_create: NotificationCreateReq, auth: USER_AUTH) -> PydanticObjectId: + user_id = auth.user_id + notification_to_insert: Notification + notification_create = notification_create.model_dump() + print(notification_create["notification_type"]) + if notification_create["notification_type"]["type"] == "event": + event = await events_repository.read_one(notification_create["notification_type"]["id"]) + if event is None: + raise HTTPException(status_code=404) + notification_to_insert = Notification( + event_title=event.title, + target_date=notification_create["notification_options"]["expiration_time"], + user_id=user_id, + endpoint=notification_create["notification_options"]["endpoint"], + keys=notification_create["notification_options"]["keys"], + ) + else: + sport = await sports_repository.read_one(str(notification_create["notification_type"]["id"])) + if sport.sport is None: + raise HTTPException(status_code=404) + notification_to_insert = Notification( + sport_title=sport.sport, + target_date=notification_create["notification_options"]["expiration_time"], + user_id=user_id, + endpoint=notification_create["notification_options"]["endpoint"], + keys=notification_create["notification_options"]["keys"], + ) + + return await notification_repository.create_notification(notification_to_insert) @router.get("/{notification_id}") diff --git a/backend/src/modules/notifies/scheams.py b/backend/src/modules/notifies/scheams.py index a6f7941..96266ec 100644 --- a/backend/src/modules/notifies/scheams.py +++ b/backend/src/modules/notifies/scheams.py @@ -1,20 +1,30 @@ from datetime import datetime +from typing import Literal -from pydantic import BaseModel +from beanie import PydanticObjectId +from pydantic import BaseModel, Field -class NotificationCreate(BaseModel): - event_title: str - notification_options: dict - target_date: datetime - user_id: int - sent: bool = False +class NotificationOption(BaseModel): + class Keys(BaseModel): + p256dh: str + auth: str + endpoint: str + expiration_time: datetime + keys: Keys -class NotificationResponse(BaseModel): - id: int - event_title: str - notification_options: dict - target_date: datetime - user_id: int - sent: bool = False + +class EventNotification(BaseModel): + type: Literal["event"] + id: PydanticObjectId + + +class SportNotification(BaseModel): + type: Literal["sport"] + id: PydanticObjectId + + +class NotificationCreateReq(BaseModel): + notification_type: EventNotification | SportNotification = Field(discriminator="type") + notification_options: NotificationOption diff --git a/backend/src/storages/mongo/notifies.py b/backend/src/storages/mongo/notifies.py index 510b972..bd9adc2 100644 --- a/backend/src/storages/mongo/notifies.py +++ b/backend/src/storages/mongo/notifies.py @@ -1,14 +1,18 @@ import datetime +from beanie import PydanticObjectId + from src.pydantic_base import BaseSchema from src.storages.mongo.__base__ import CustomDocument class NotifySchema(BaseSchema): - event_title: str - notification_options: dict + event_title: str | None = None + sport_title: str | None = None + endpoint: str + keys: dict target_date: datetime.datetime - user_id: int + user_id: PydanticObjectId sent: bool = False