Coverage for modules\chat\services.py: 36%
45 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-05 09:25 +0800
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-05 09:25 +0800
1from django.db import transaction
2from core.exceptions import NotFoundException, BadRequestException
3from .models import Channel, ChannelMember, Message, MessageAttachment, MessageReaction, ReadReceipt
4from modules.authentication.models import User
6class ChatService:
7 @staticmethod
8 def get_or_create_general_channel(tenant_id, user):
9 """Ensure default #general channel exists."""
10 channel = Channel.objects.filter(tenant_id=tenant_id, name='general', type='PUBLIC').first()
11 if not channel:
12 channel = Channel.objects.create(
13 tenant_id=tenant_id,
14 name='general',
15 topic='Company-wide announcements and general discussion',
16 type='PUBLIC',
17 created_by=user
18 )
19 ChannelMember.objects.create(
20 tenant_id=tenant_id,
21 channel=channel,
22 user=user,
23 role='ADMIN'
24 )
25 return channel
27 @staticmethod
28 @transaction.atomic
29 def create_channel(tenant_id, creator, data):
30 channel = Channel.objects.create(
31 tenant_id=tenant_id,
32 name=data.name.lower().replace(' ', '-'),
33 topic=data.topic,
34 type=data.type or 'PUBLIC',
35 created_by=creator
36 )
37 ChannelMember.objects.create(
38 tenant_id=tenant_id,
39 channel=channel,
40 user=creator,
41 role='ADMIN'
42 )
43 if data.member_ids:
44 for uid in data.member_ids:
45 u = User.objects.filter(id=uid).first()
46 if u and u != creator:
47 ChannelMember.objects.create(
48 tenant_id=tenant_id,
49 channel=channel,
50 user=u,
51 role='MEMBER'
52 )
53 return channel
55 @staticmethod
56 @transaction.atomic
57 def create_direct_message_channel(tenant_id, user1, user2):
58 """Find or create a 1-on-1 DM channel."""
59 # Find existing channel with only these 2 members
60 existing = Channel.objects.filter(
61 tenant_id=tenant_id,
62 type='DIRECT',
63 members__user=user1
64 ).filter(
65 members__user=user2
66 ).first()
68 if existing:
69 return existing
71 name = f"dm-{user1.id}-{user2.id}"
72 channel = Channel.objects.create(
73 tenant_id=tenant_id,
74 name=name,
75 type='DIRECT',
76 created_by=user1
77 )
78 ChannelMember.objects.create(tenant_id=tenant_id, channel=channel, user=user1, role='MEMBER')
79 ChannelMember.objects.create(tenant_id=tenant_id, channel=channel, user=user2, role='MEMBER')
80 return channel
82 @staticmethod
83 @transaction.atomic
84 def send_message(tenant_id, user, channel_id, data):
85 channel = Channel.objects.filter(id=channel_id, tenant_id=tenant_id).first()
86 if not channel:
87 raise NotFoundException("Channel not found.")
89 msg = Message.objects.create(
90 tenant_id=tenant_id,
91 channel=channel,
92 sender=user,
93 content=data.content,
94 parent_id=data.parent_id
95 )
97 if data.attachments:
98 for att in data.attachments:
99 MessageAttachment.objects.create(
100 tenant_id=tenant_id,
101 message=msg,
102 file_name=att.file_name,
103 file_size=att.file_size,
104 file_type=att.file_type,
105 file_url=att.file_url
106 )
108 return msg