Ctrl K
ComunidadGuías…

internal/app/communities/service.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package communities

import (
	"context"
	"strings"
	"unicode/utf8"

	"telesrv/internal/domain"
	"telesrv/internal/store"
)

// Service owns Community business validation. The store is the aggregate
// transaction boundary because link changes span community/link and peer rows.
type Service struct {
	communities store.CommunityStore
}

func NewService(communities store.CommunityStore) *Service {
	return &Service{communities: communities}
}

func validPeer(peer domain.Peer) bool {
	return peer.ID > 0 && (peer.Type == domain.PeerTypeChannel || peer.Type == domain.PeerTypeUser)
}

func validVisibility(v domain.CommunityPeerVisibility) bool {
	return v == domain.CommunityPeerVisible || v == domain.CommunityPeerHidden
}

func (s *Service) Create(ctx context.Context, userID int64, req domain.CreateCommunityRequest) (domain.CommunityView, error) {
	if s == nil || s.communities == nil || userID == 0 || !validPeer(req.InitialPeer) || !validVisibility(req.Visibility) {
		return domain.CommunityView{}, domain.ErrCommunityInvalid
	}
	req.CreatorUserID = userID
	req.Title = strings.TrimSpace(req.Title)
	req.About = strings.TrimSpace(req.About)
	if req.Title == "" || utf8.RuneCountInString(req.Title) > domain.MaxCommunityTitleRunes {
		return domain.CommunityView{}, domain.ErrChannelTitleInvalid
	}
	if utf8.RuneCountInString(req.About) > domain.MaxCommunityAboutRunes {
		return domain.CommunityView{}, domain.ErrAboutTooLong
	}
	return s.communities.CreateCommunity(ctx, req)
}

func (s *Service) Get(ctx context.Context, userID, communityID int64) (domain.CommunityView, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 {
		return domain.CommunityView{}, domain.ErrCommunityInvalid
	}
	return s.communities.GetCommunity(ctx, userID, communityID)
}

func (s *Service) GetMany(ctx context.Context, userID int64, ids []int64) ([]domain.CommunityView, error) {
	if s == nil || s.communities == nil || userID == 0 {
		return nil, domain.ErrCommunityInvalid
	}
	return s.communities.GetCommunities(ctx, userID, ids)
}

func (s *Service) ListJoined(ctx context.Context, userID int64) ([]domain.CommunityView, error) {
	if s == nil || s.communities == nil || userID == 0 {
		return nil, domain.ErrCommunityInvalid
	}
	return s.communities.ListJoinedCommunities(ctx, userID)
}

func (s *Service) TogglePeerLink(ctx context.Context, userID int64, req domain.CommunityTogglePeerLinkRequest) (domain.CommunityTogglePeerLinkResult, error) {
	if s == nil || s.communities == nil || userID == 0 || req.CommunityID == 0 || !validPeer(req.Peer) {
		return domain.CommunityTogglePeerLinkResult{}, domain.ErrCommunityInvalid
	}
	if !req.Deleted && !validVisibility(req.Visibility) {
		return domain.CommunityTogglePeerLinkResult{}, domain.ErrCommunityPeerInvalid
	}
	req.ActorUserID = userID
	return s.communities.ToggleCommunityPeerLink(ctx, req)
}

func (s *Service) SetCollapsed(ctx context.Context, userID, communityID int64, collapsed bool) (domain.CommunityView, bool, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 {
		return domain.CommunityView{}, false, domain.ErrCommunityInvalid
	}
	return s.communities.SetCommunityCollapsed(ctx, userID, communityID, collapsed)
}

func (s *Service) ListPeerLinkRequests(ctx context.Context, userID, communityID int64, offset string, limit int) (domain.CommunityPeerLinkRequestPage, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 {
		return domain.CommunityPeerLinkRequestPage{}, domain.ErrCommunityInvalid
	}
	if limit <= 0 || limit > domain.MaxCommunityLinkRequests {
		limit = domain.MaxCommunityLinkRequests
	}
	return s.communities.ListCommunityPeerLinkRequests(ctx, userID, communityID, offset, limit)
}

func (s *Service) DecidePeerLinkRequest(ctx context.Context, userID, communityID int64, peer domain.Peer, reject bool, date int) (domain.CommunityTogglePeerLinkResult, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 || !validPeer(peer) {
		return domain.CommunityTogglePeerLinkResult{}, domain.ErrCommunityInvalid
	}
	return s.communities.DecideCommunityPeerLinkRequest(ctx, userID, communityID, peer, reject, date)
}

func (s *Service) DecideAllPeerLinkRequests(ctx context.Context, userID, communityID int64, reject bool, date int) ([]domain.CommunityTogglePeerLinkResult, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 {
		return nil, domain.ErrCommunityInvalid
	}
	return s.communities.DecideAllCommunityPeerLinkRequests(ctx, userID, communityID, reject, date)
}

func (s *Service) ToggleParticipantBanned(ctx context.Context, userID, communityID, participantUserID int64, unban bool, date int) (domain.CommunityParticipantBanResult, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 || participantUserID == 0 {
		return domain.CommunityParticipantBanResult{}, domain.ErrCommunityInvalid
	}
	return s.communities.ToggleCommunityParticipantBanned(ctx, userID, communityID, participantUserID, unban, date)
}

func (s *Service) ParticipantJoinedChats(ctx context.Context, userID, communityID, participantUserID int64) (domain.CommunityParticipantJoinedChats, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 || participantUserID == 0 {
		return domain.CommunityParticipantJoinedChats{}, domain.ErrCommunityInvalid
	}
	return s.communities.GetCommunityParticipantJoinedChats(ctx, userID, communityID, participantUserID)
}

func (s *Service) Participants(ctx context.Context, userID, communityID int64, filter domain.ChannelParticipantsFilter, offset, limit int) (domain.CommunityParticipantList, error) {
	if s == nil || s.communities == nil || userID == 0 || communityID == 0 {
		return domain.CommunityParticipantList{}, domain.ErrCommunityInvalid
	}
	if offset < 0 {
		offset = 0
	}
	if offset > domain.MaxChannelParticipantsOffset {
		offset = domain.MaxChannelParticipantsOffset
	}
	if limit <= 0 || limit > domain.MaxCommunityParticipants {
		limit = domain.MaxCommunityParticipants
	}
	return s.communities.ListCommunityParticipants(ctx, userID, communityID, filter, offset, limit)
}

func (s *Service) EditTitle(ctx context.Context, userID, communityID int64, title string) (domain.CommunityView, bool, error) {
	title = strings.TrimSpace(title)
	if title == "" || utf8.RuneCountInString(title) > domain.MaxCommunityTitleRunes {
		return domain.CommunityView{}, false, domain.ErrChannelTitleInvalid
	}
	return s.communities.EditCommunityTitle(ctx, userID, communityID, title)
}

func (s *Service) EditAbout(ctx context.Context, userID, communityID int64, about string) (domain.CommunityView, bool, error) {
	about = strings.TrimSpace(about)
	if utf8.RuneCountInString(about) > domain.MaxCommunityAboutRunes {
		return domain.CommunityView{}, false, domain.ErrAboutTooLong
	}
	return s.communities.EditCommunityAbout(ctx, userID, communityID, about)
}

func (s *Service) EditAdmin(ctx context.Context, userID int64, req domain.CommunityEditAdminRequest) (domain.CommunityView, bool, error) {
	if req.CommunityID == 0 || req.UserID == 0 || userID == 0 {
		return domain.CommunityView{}, false, domain.ErrCommunityInvalid
	}
	req.ActorUserID = userID
	return s.communities.EditCommunityAdmin(ctx, req)
}

func (s *Service) EditDefaultBannedRights(ctx context.Context, userID, communityID int64, rights domain.ChannelBannedRights) (domain.CommunityView, bool, error) {
	return s.communities.EditCommunityDefaultBannedRights(ctx, userID, communityID, rights)
}

func (s *Service) SetPhoto(ctx context.Context, userID, communityID int64, photo *domain.Photo, date int) (domain.CommunityView, bool, error) {
	return s.communities.SetCommunityPhoto(ctx, userID, communityID, photo, date)
}

func (s *Service) Delete(ctx context.Context, userID, communityID int64, date int) (domain.CommunityView, []domain.Peer, error) {
	return s.communities.DeleteCommunity(ctx, userID, communityID, date)
}

func (s *Service) SetPinned(ctx context.Context, userID, communityID int64, pinned bool) (bool, error) {
	return s.communities.SetCommunityPinned(ctx, userID, communityID, pinned)
}

func (s *Service) ReorderPinned(ctx context.Context, userID int64, order []domain.Peer, force bool) (bool, error) {
	return s.communities.ReorderCommunityPinned(ctx, userID, order, force)
}

func (s *Service) SearchScope(ctx context.Context, userID, communityID int64) (domain.CommunitySearchScope, error) {
	return s.communities.CommunitySearchScope(ctx, userID, communityID)
}