package logic import ( "context" "spark-server/internal/pkg/errs" ) func (s *Service) ListMembers(ctx context.Context, userID, groupID int64, limit int) (*MemberList, error) { if !s.ready() || userID <= 0 { return nil, errs.ErrUnauthorized } if _, err := s.loadActive(ctx, groupID); err != nil { return nil, err } if _, err := s.requireMember(ctx, groupID, userID); err != nil { return nil, err } rows, err := s.repo.ListMembers(ctx, groupID, limit) if err != nil { return nil, err } items := make([]*MemberView, 0, len(rows)) for _, mem := range rows { u, err := s.users.Get(ctx, mem.UserID) if err != nil { items = append(items, memberViewOf(mem, nil)) continue } items = append(items, memberViewOf(mem, u)) } return &MemberList{Items: items}, nil } func (s *Service) MemberIDs(ctx context.Context, conversationID int64) ([]int64, error) { if !s.ready() || conversationID <= 0 { return nil, errs.ErrInvalidArgument } if ids, ok := s.cachedMemberIDs(conversationID); ok { return ids, nil } g, err := s.repo.GetByConversation(ctx, conversationID) if err != nil { return nil, err } if !g.Active() { return []int64{}, nil } ids, err := s.repo.ListMemberIDs(ctx, g.ID) if err != nil { return nil, err } s.putMemberIDs(conversationID, ids) return ids, nil } func (s *Service) IDByConversation(ctx context.Context, conversationID int64) (int64, error) { if !s.ready() || conversationID <= 0 { return 0, errs.ErrInvalidArgument } g, err := s.repo.GetByConversation(ctx, conversationID) if err != nil { return 0, err } return g.ID, nil } func (s *Service) CanSend(ctx context.Context, userID, conversationID int64) error { if !s.ready() || userID <= 0 || conversationID <= 0 { return errs.ErrForbidden } g, err := s.repo.GetByConversation(ctx, conversationID) if err != nil || !g.Active() { return errs.ErrForbidden } mem, err := s.repo.GetMember(ctx, g.ID, userID) if err != nil { return errs.ErrForbidden } if !mem.CanSpeak(g.MutedAll) { return errs.ErrForbidden } return nil }