132 lines
5.7 KiB
Python
132 lines
5.7 KiB
Python
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.profile import (
|
|
CustomerProfileInput,
|
|
CustomerProfileUpdateInput,
|
|
TeamProfileInput,
|
|
TeamProfileUpdateInput,
|
|
)
|
|
from core.graphql.types.profile import CustomerProfileType, TeamProfileType
|
|
from core.models.profile import CustomerProfile, TeamProfile
|
|
from core.graphql.utils import create_object, update_object, delete_object
|
|
from core.services.events import (
|
|
publish_team_profile_created, publish_team_profile_updated, publish_team_profile_deleted,
|
|
publish_team_profile_role_changed,
|
|
publish_customer_profile_created, publish_customer_profile_updated, publish_customer_profile_deleted,
|
|
publish_customer_profile_access_granted, publish_customer_profile_access_revoked,
|
|
)
|
|
|
|
|
|
@strawberry.type
|
|
class Mutation:
|
|
@strawberry.mutation(description="Create a new customer profile")
|
|
async def create_customer_profile(
|
|
self, input: CustomerProfileInput, info: Info
|
|
) -> CustomerProfileType:
|
|
m2m_data = {"customers": input.customer_ids} if input.customer_ids else None
|
|
instance = await create_object(input, CustomerProfile, m2m_data)
|
|
await pubsub.publish(f"customer_profile_created", instance.id)
|
|
|
|
# Publish event
|
|
profile = getattr(info.context.request, 'profile', None)
|
|
await publish_customer_profile_created(str(instance.id), triggered_by=profile)
|
|
|
|
return cast(CustomerProfileType, instance)
|
|
|
|
@strawberry.mutation(description="Update an existing customer profile")
|
|
async def update_customer_profile(
|
|
self, input: CustomerProfileUpdateInput, info: Info
|
|
) -> CustomerProfileType:
|
|
# Get old profile to detect customer access changes
|
|
old_profile = await database_sync_to_async(CustomerProfile.objects.get)(pk=input.id.node_id)
|
|
old_customer_ids = set(str(cid) for cid in await database_sync_to_async(list)(
|
|
old_profile.customers.values_list('id', flat=True)
|
|
))
|
|
|
|
m2m_data = {"customers": input.customer_ids} if input.customer_ids else None
|
|
instance = await update_object(input, CustomerProfile, m2m_data)
|
|
await pubsub.publish(f"customer_profile_updated", instance.id)
|
|
|
|
# Publish event
|
|
profile = getattr(info.context.request, 'profile', None)
|
|
await publish_customer_profile_updated(str(instance.id), triggered_by=profile)
|
|
|
|
# Detect customer access changes
|
|
if input.customer_ids is not None:
|
|
new_customer_ids = set(str(cid) for cid in input.customer_ids)
|
|
|
|
# Newly granted access
|
|
for customer_id in new_customer_ids - old_customer_ids:
|
|
await publish_customer_profile_access_granted(
|
|
str(instance.id), customer_id, triggered_by=profile
|
|
)
|
|
|
|
# Revoked access
|
|
for customer_id in old_customer_ids - new_customer_ids:
|
|
await publish_customer_profile_access_revoked(
|
|
str(instance.id), customer_id, triggered_by=profile
|
|
)
|
|
|
|
return cast(CustomerProfileType, instance)
|
|
|
|
@strawberry.mutation(description="Delete an existing customer profile")
|
|
async def delete_customer_profile(self, id: strawberry.ID, info: Info) -> strawberry.ID:
|
|
instance = await delete_object(id, CustomerProfile)
|
|
if not instance:
|
|
raise ValueError(f"CustomerProfile with ID {id} does not exist")
|
|
await pubsub.publish(f"customer_profile_deleted", id)
|
|
|
|
# Publish event
|
|
profile = getattr(info.context.request, 'profile', None)
|
|
await publish_customer_profile_deleted(str(id), triggered_by=profile)
|
|
|
|
return id
|
|
|
|
@strawberry.mutation(description="Create a new team profile")
|
|
async def create_team_profile(self, input: TeamProfileInput, info: Info) -> TeamProfileType:
|
|
instance = await create_object(input, TeamProfile)
|
|
await pubsub.publish(f"team_profile_created", instance.id)
|
|
|
|
# Publish event
|
|
profile = getattr(info.context.request, 'profile', None)
|
|
await publish_team_profile_created(str(instance.id), triggered_by=profile)
|
|
|
|
return cast(TeamProfileType, instance)
|
|
|
|
@strawberry.mutation(description="Update an existing team profile")
|
|
async def update_team_profile(self, input: TeamProfileUpdateInput, info: Info) -> TeamProfileType:
|
|
# Get old profile to detect role changes
|
|
old_profile = await database_sync_to_async(TeamProfile.objects.get)(pk=input.id.node_id)
|
|
old_role = old_profile.role
|
|
|
|
instance = await update_object(input, TeamProfile)
|
|
await pubsub.publish(f"team_profile_updated", instance.id)
|
|
|
|
# Publish event
|
|
profile = getattr(info.context.request, 'profile', None)
|
|
await publish_team_profile_updated(str(instance.id), triggered_by=profile)
|
|
|
|
# Check for role change
|
|
if input.role is not None and input.role != old_role:
|
|
await publish_team_profile_role_changed(
|
|
str(instance.id), old_role, input.role, triggered_by=profile
|
|
)
|
|
|
|
return cast(TeamProfileType, instance)
|
|
|
|
@strawberry.mutation(description="Delete an existing team profile")
|
|
async def delete_team_profile(self, id: strawberry.ID, info: Info) -> strawberry.ID:
|
|
instance = await delete_object(id, TeamProfile)
|
|
if not instance:
|
|
raise ValueError(f"TeamProfile with ID {id} does not exist")
|
|
await pubsub.publish(f"team_profile_deleted", id)
|
|
|
|
# Publish event
|
|
profile = getattr(info.context.request, 'profile', None)
|
|
await publish_team_profile_deleted(str(id), triggered_by=profile)
|
|
|
|
return id
|