from typing import cast import strawberry from strawberry.types import Info from channels.db import database_sync_to_async from core.graphql.pubsub import pubsub from core.graphql.inputs.schedule import ScheduleInput, ScheduleUpdateInput from core.graphql.types.schedule import ScheduleType from core.models.schedule import Schedule from core.models.account import AccountAddress from core.graphql.utils import create_object, update_object, delete_object from core.services.events import ( publish_schedule_created, publish_schedule_updated, publish_schedule_deleted, publish_schedule_frequency_changed, ) @strawberry.type class Mutation: @strawberry.mutation(description="Create a new service schedule") async def create_schedule(self, input: ScheduleInput, info: Info) -> ScheduleType: instance = await create_object(input, Schedule) await pubsub.publish("schedule_created", instance.id) # Get profile from request context profile = getattr(info.context.request, 'profile', None) # Publish event with account_id in metadata account_address = await database_sync_to_async( lambda: AccountAddress.objects.select_related('account').get(id=instance.account_address_id) )() account_id = str(account_address.account_id) if account_address.account_id else None await publish_schedule_created( schedule_id=str(instance.id), triggered_by=profile, metadata={'account_id': account_id} ) return cast(ScheduleType, instance) @strawberry.mutation(description="Update an existing service schedule") async def update_schedule(self, input: ScheduleUpdateInput, info: Info) -> ScheduleType: # Get the old schedule to check for frequency changes old_schedule = await database_sync_to_async(Schedule.objects.get)(pk=input.id.node_id) # Store old frequency state old_frequency = { 'monday': old_schedule.monday_service, 'tuesday': old_schedule.tuesday_service, 'wednesday': old_schedule.wednesday_service, 'thursday': old_schedule.thursday_service, 'friday': old_schedule.friday_service, 'saturday': old_schedule.saturday_service, 'sunday': old_schedule.sunday_service, 'weekend': old_schedule.weekend_service, } instance = await update_object(input, Schedule) await pubsub.publish("schedule_updated", instance.id) # Get profile from request context profile = getattr(info.context.request, 'profile', None) # Publish schedule updated event await publish_schedule_updated( schedule_id=str(instance.id), triggered_by=profile ) # Check if frequency changed new_frequency = { 'monday': instance.monday_service, 'tuesday': instance.tuesday_service, 'wednesday': instance.wednesday_service, 'thursday': instance.thursday_service, 'friday': instance.friday_service, 'saturday': instance.saturday_service, 'sunday': instance.sunday_service, 'weekend': instance.weekend_service, } if old_frequency != new_frequency: # Publish frequency changed event await publish_schedule_frequency_changed( schedule_id=str(instance.id), old_frequency=str(old_frequency), new_frequency=str(new_frequency), triggered_by=profile ) return cast(ScheduleType, instance) @strawberry.mutation(description="Delete an existing service schedule") async def delete_schedule(self, id: strawberry.ID, info: Info) -> strawberry.ID: instance = await delete_object(id, Schedule) if not instance: raise ValueError(f"Schedule with ID {id} does not exist") await pubsub.publish("schedule_deleted", id) # Get profile from request context profile = getattr(info.context.request, 'profile', None) # Publish schedule deleted event await publish_schedule_deleted( schedule_id=str(id), triggered_by=profile ) return id