From 73b586f40cc5471c860ba19175400af947de4974 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Wed, 8 Jul 2026 01:32:34 +0300 Subject: [PATCH 1/6] added patch archive handler --- modal_backend/routes/notes.py | 14 ++++++++++++++ modal_backend/schemas/models.py | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/modal_backend/routes/notes.py b/modal_backend/routes/notes.py index 2b04efb..faba646 100644 --- a/modal_backend/routes/notes.py +++ b/modal_backend/routes/notes.py @@ -16,6 +16,7 @@ NoteInfoPost, NoteRatingGet, NoteRatingPost, + NoteStatus, NoteTextGet, NoteTextPost, NotificationGet, @@ -185,3 +186,16 @@ async def create_note_images( session=db.session, type_id=5, **note.model_dump(), admin_id=user.get("id"), status=ModalStatus.ACTIVE ) return NoteImageGet.model_validate(new_note) + + +@note.patch("/{id}/archive", response_model=NoteStatus) +async def update_note_status(id: int, user=Depends(UnionAuth(scopes=["modal.note.patch"]))) -> NoteStatus: + """ + Архивирует модалку + + Права: `["modal.note.patch"]` + + Исключение **ObjectNotFound**, если `id` не найден + """ + note = await NoteService.archive_note(db, id) + return NoteStatus.model_validate(note) diff --git a/modal_backend/schemas/models.py b/modal_backend/schemas/models.py index f10bfaa..2127bf4 100644 --- a/modal_backend/schemas/models.py +++ b/modal_backend/schemas/models.py @@ -119,3 +119,8 @@ class GroupGet(Base): class GroupPost(Base): group_id: int name: str + + +class NoteStatus(Base): + id: int + status: ModalStatus From 21e4733290198a8a0c3298b5749e562b24b72229 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Sat, 11 Jul 2026 00:26:14 +0300 Subject: [PATCH 2/6] fixes --- modal_backend/routes/notes.py | 7 +++++-- modal_backend/utils/services.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/modal_backend/routes/notes.py b/modal_backend/routes/notes.py index faba646..2e2d2ee 100644 --- a/modal_backend/routes/notes.py +++ b/modal_backend/routes/notes.py @@ -196,6 +196,9 @@ async def update_note_status(id: int, user=Depends(UnionAuth(scopes=["modal.note Права: `["modal.note.patch"]` Исключение **ObjectNotFound**, если `id` не найден + + Исключение **AlreadyExists**, если модалка уже архивирована """ - note = await NoteService.archive_note(db, id) - return NoteStatus.model_validate(note) + Note.get(session=db.session, id=id) + updated_note = Note.update(id=id, session=db.session, status=ModalStatus.ARCHIVED) + return NoteStatus.model_validate(updated_note) diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index 82eeeec..a81834f 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -41,6 +41,22 @@ async def get_notes_by_filters( return notes +<<<<<<< HEAD +======= + @staticmethod + def validate_note_by_type(note: dict, db: Session): + type_id = note.type_id + note_type = NoteType.query(session=db.session).filter(NoteType.type_id == type_id).one_or_none() + if note_type is None: + raise ObjectNotFound(NoteType, type_id) + + @classmethod + async def create_note(cls, db: Session, note: NotificationPost, admin_id: int) -> Note: + cls.validate_note_by_type(note, db) + new_note = Note.create(session=db.session, **note, admin_id=admin_id, status=ModalStatus.ACTIVE) + return new_note + +>>>>>>> 68f174a (fixes) class NoteTypeService: """ From d13c940c45ca70dc068f60dd3ee3210576f029c3 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Tue, 14 Jul 2026 19:36:34 +0300 Subject: [PATCH 3/6] remake status update handler --- modal_backend/routes/notes.py | 10 ++++----- modal_backend/utils/services.py | 38 +++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/modal_backend/routes/notes.py b/modal_backend/routes/notes.py index 2e2d2ee..b7793bf 100644 --- a/modal_backend/routes/notes.py +++ b/modal_backend/routes/notes.py @@ -188,17 +188,17 @@ async def create_note_images( return NoteImageGet.model_validate(new_note) -@note.patch("/{id}/archive", response_model=NoteStatus) +@note.patch("/{id}/status", response_model=NoteStatus) async def update_note_status(id: int, user=Depends(UnionAuth(scopes=["modal.note.patch"]))) -> NoteStatus: """ - Архивирует модалку + Архивирует модалку, если она активна + + Возвращает модалку в активное состояние, если она в архиве Права: `["modal.note.patch"]` Исключение **ObjectNotFound**, если `id` не найден - Исключение **AlreadyExists**, если модалка уже архивирована """ - Note.get(session=db.session, id=id) - updated_note = Note.update(id=id, session=db.session, status=ModalStatus.ARCHIVED) + updated_note = await NoteService.update_status(db, id=id) return NoteStatus.model_validate(updated_note) diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index a81834f..8717068 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -1,7 +1,9 @@ +from datetime import datetime + from requests import Session -from modal_backend.exceptions import AlreadyExists, ObjectNotFound -from modal_backend.models.db import Group, Note, NoteType, Service +from modal_backend.exceptions import AlreadyExists, ForbiddenAction, ObjectNotFound +from modal_backend.models.db import Group, ModalStatus, Note, NoteType, Service from modal_backend.schemas.base import StatusResponseModel from modal_backend.schemas.models import GroupPost, NoteTypePost, ServicePost @@ -41,22 +43,26 @@ async def get_notes_by_filters( return notes -<<<<<<< HEAD -======= - @staticmethod - def validate_note_by_type(note: dict, db: Session): - type_id = note.type_id - note_type = NoteType.query(session=db.session).filter(NoteType.type_id == type_id).one_or_none() - if note_type is None: - raise ObjectNotFound(NoteType, type_id) - @classmethod - async def create_note(cls, db: Session, note: NotificationPost, admin_id: int) -> Note: - cls.validate_note_by_type(note, db) - new_note = Note.create(session=db.session, **note, admin_id=admin_id, status=ModalStatus.ACTIVE) - return new_note + async def update_status(cls, db: Session, id: int) -> Note: + note = Note.get(session=db.session, id=id) + group_ids = note.group_ids + for group_id in group_ids: + Group.get(session=db.session, id=group_id) + service_ids = note.service_ids + for service_id in service_ids: + Service.get(session=db.session, id=service_id) + end_ts = note.end_ts + time = datetime.utcnow() + if note.is_always == False and time >= end_ts: + raise ForbiddenAction(Note) + else: + if note.status == ModalStatus.ACTIVE: + updated_note = Note.update(id=id, session=db.session, status=ModalStatus.ARCHIVED) + else: + updated_note = Note.update(id=id, session=db.session, status=ModalStatus.ACTIVE) + return updated_note ->>>>>>> 68f174a (fixes) class NoteTypeService: """ From 818fbfd7e88432d82e84ed22111579fe469b59dc Mon Sep 17 00:00:00 2001 From: rifcrat Date: Thu, 23 Jul 2026 15:51:38 +0300 Subject: [PATCH 4/6] fix status update logic --- modal_backend/routes/notes.py | 9 +++++- modal_backend/utils/services.py | 51 +++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/modal_backend/routes/notes.py b/modal_backend/routes/notes.py index b7793bf..4c535eb 100644 --- a/modal_backend/routes/notes.py +++ b/modal_backend/routes/notes.py @@ -193,12 +193,19 @@ async def update_note_status(id: int, user=Depends(UnionAuth(scopes=["modal.note """ Архивирует модалку, если она активна - Возвращает модалку в активное состояние, если она в архиве + Если модалка в архиве, возвращает её в активное состояние, убирая из `group_ids` и `service_ids` ненайденные группы и сервисы Права: `["modal.note.patch"]` Исключение **ObjectNotFound**, если `id` не найден + Исключения, которые могут возникнуть при возврате в активное состояние: + + Исключение **ForbiddenAction**, если ни одна группа из списка `group_ids` не найдена + + Исключение **ForbiddenAction**, если ни один сервис из списка `service_ids` не найден + + Исключение **ForbiddenAction**, если время модалки истекло """ updated_note = await NoteService.update_status(db, id=id) return NoteStatus.model_validate(updated_note) diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index 8717068..725a7ef 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from requests import Session @@ -46,22 +46,43 @@ async def get_notes_by_filters( @classmethod async def update_status(cls, db: Session, id: int) -> Note: note = Note.get(session=db.session, id=id) - group_ids = note.group_ids - for group_id in group_ids: - Group.get(session=db.session, id=group_id) - service_ids = note.service_ids - for service_id in service_ids: - Service.get(session=db.session, id=service_id) - end_ts = note.end_ts - time = datetime.utcnow() - if note.is_always == False and time >= end_ts: - raise ForbiddenAction(Note) + if note.status == ModalStatus.ACTIVE: + updated_note = Note.update(id=id, session=db.session, status=ModalStatus.ARCHIVED) + return updated_note else: - if note.status == ModalStatus.ACTIVE: - updated_note = Note.update(id=id, session=db.session, status=ModalStatus.ARCHIVED) + group_ids = note.group_ids + new_group_ids = [] + for group_id in group_ids: + group = db.session.query(Group).filter(Group.id == group_id, Group.is_deleted == False).first() + if group is not None: + new_group_ids.append(group.id) + if new_group_ids == []: + raise ForbiddenAction(Note) + + service_ids = note.service_ids + new_service_ids = [] + for service_id in service_ids: + service = ( + db.session.query(Service).filter(Service.id == service_id, Service.is_deleted == False).first() + ) + if service is not None: + new_service_ids.append(service.id) + if new_service_ids == []: + raise ForbiddenAction(Note) + + end_ts = note.end_ts + time = datetime.now(timezone.utc).replace(tzinfo=None) + if note.is_always == False and time >= end_ts: + raise ForbiddenAction(Note) else: - updated_note = Note.update(id=id, session=db.session, status=ModalStatus.ACTIVE) - return updated_note + updated_note = Note.update( + id=id, + session=db.session, + group_ids=new_group_ids, + service_ids=new_service_ids, + status=ModalStatus.ACTIVE, + ) + return updated_note class NoteTypeService: From 7a7bbf80390479d39fc4ca86cd25e0e8b4da8c00 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Sun, 26 Jul 2026 00:44:18 +0300 Subject: [PATCH 5/6] fixes --- modal_backend/utils/services.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index 725a7ef..4e74342 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -53,7 +53,7 @@ async def update_status(cls, db: Session, id: int) -> Note: group_ids = note.group_ids new_group_ids = [] for group_id in group_ids: - group = db.session.query(Group).filter(Group.id == group_id, Group.is_deleted == False).first() + group = db.session.query(Group).filter(Group.id == group_id, Group.is_deleted == False).one_or_none() if group is not None: new_group_ids.append(group.id) if new_group_ids == []: @@ -63,7 +63,9 @@ async def update_status(cls, db: Session, id: int) -> Note: new_service_ids = [] for service_id in service_ids: service = ( - db.session.query(Service).filter(Service.id == service_id, Service.is_deleted == False).first() + db.session.query(Service) + .filter(Service.id == service_id, Service.is_deleted == False) + .one_or_none() ) if service is not None: new_service_ids.append(service.id) @@ -72,17 +74,16 @@ async def update_status(cls, db: Session, id: int) -> Note: end_ts = note.end_ts time = datetime.now(timezone.utc).replace(tzinfo=None) - if note.is_always == False and time >= end_ts: + if note.is_always == False or time >= end_ts: raise ForbiddenAction(Note) - else: - updated_note = Note.update( - id=id, - session=db.session, - group_ids=new_group_ids, - service_ids=new_service_ids, - status=ModalStatus.ACTIVE, - ) - return updated_note + updated_note = Note.update( + id=id, + session=db.session, + group_ids=new_group_ids, + service_ids=new_service_ids, + status=ModalStatus.ACTIVE, + ) + return updated_note class NoteTypeService: From 41bb17b7f04d72acad46c36af93a38c704d44339 Mon Sep 17 00:00:00 2001 From: rifcrat Date: Sun, 26 Jul 2026 11:16:18 +0300 Subject: [PATCH 6/6] little fixes --- modal_backend/utils/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modal_backend/utils/services.py b/modal_backend/utils/services.py index 4e74342..5c39c86 100644 --- a/modal_backend/utils/services.py +++ b/modal_backend/utils/services.py @@ -74,7 +74,7 @@ async def update_status(cls, db: Session, id: int) -> Note: end_ts = note.end_ts time = datetime.now(timezone.utc).replace(tzinfo=None) - if note.is_always == False or time >= end_ts: + if note.is_always == False and time >= end_ts: raise ForbiddenAction(Note) updated_note = Note.update( id=id,