from typing import AsyncGenerator import strawberry from channels.db import database_sync_to_async from strawberry.types import Info from core.graphql.pubsub import pubsub from core.graphql.types.scope import ScopeType, AreaType, TaskType, TaskCompletionType from core.graphql.utils import _extract_id from core.models.scope import Scope, Area, Task, TaskCompletion @strawberry.type class Subscription: # Scope subscriptions @strawberry.subscription(description="Subscribe to scope creation events") async def scope_created(self, info: Info) -> AsyncGenerator[ScopeType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("scope_created") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(Scope.objects.get)(pk=entity_id) except Scope.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to scope updates") async def scope_updated(self, info: Info) -> AsyncGenerator[ScopeType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("scope_updated") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(Scope.objects.get)(pk=entity_id) except Scope.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to scope deletion events") async def scope_deleted(self, info: Info) -> AsyncGenerator[strawberry.ID, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("scope_deleted") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) yield strawberry.ID(entity_id) # Area subscriptions @strawberry.subscription(description="Subscribe to area creation events") async def area_created(self, info: Info) -> AsyncGenerator[AreaType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("area_created") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(Area.objects.get)(pk=entity_id) except Area.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to area updates") async def area_updated(self, info: Info) -> AsyncGenerator[AreaType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("area_updated") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(Area.objects.get)(pk=entity_id) except Area.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to area deletion events") async def area_deleted(self, info: Info) -> AsyncGenerator[strawberry.ID, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("area_deleted") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) yield strawberry.ID(entity_id) # Task subscriptions @strawberry.subscription(description="Subscribe to task creation events") async def task_created(self, info: Info) -> AsyncGenerator[TaskType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("task_created") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(Task.objects.get)(pk=entity_id) except Task.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to task updates") async def task_updated(self, info: Info) -> AsyncGenerator[TaskType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("task_updated") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(Task.objects.get)(pk=entity_id) except Task.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to task deletion events") async def task_deleted(self, info: Info) -> AsyncGenerator[strawberry.ID, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("task_deleted") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) yield strawberry.ID(entity_id) # TaskCompletion subscriptions @strawberry.subscription(description="Subscribe to task completion creation events") async def task_completion_created(self, info: Info) -> AsyncGenerator[TaskCompletionType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("task_completion_created") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(TaskCompletion.objects.get)(pk=entity_id) except TaskCompletion.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to task completion updates") async def task_completion_updated(self, info: Info) -> AsyncGenerator[TaskCompletionType, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("task_completion_updated") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) try: instance = await database_sync_to_async(TaskCompletion.objects.get)(pk=entity_id) except TaskCompletion.DoesNotExist: continue yield instance @strawberry.subscription(description="Subscribe to task completion deletion events") async def task_completion_deleted(self, info: Info) -> AsyncGenerator[strawberry.ID, None]: user = info.context.user if not user or not user.is_authenticated: raise PermissionError("Authentication required") async with pubsub.subscribe("task_completion_deleted") as subscriber: async for payload in subscriber: entity_id = await _extract_id(payload) yield strawberry.ID(entity_id)