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

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 

5 

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 

26 

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 

54 

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() 

67 

68 if existing: 

69 return existing 

70 

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 

81 

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.") 

88 

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 ) 

96 

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 ) 

107 

108 return msg