package kr.itn.itnhub.feed; import kr.itn.itnhub.mattermost.MattermostClient; import kr.itn.itnhub.org.Organization; import kr.itn.itnhub.org.OrganizationMapper; import kr.itn.itnhub.org.OrgNotFoundException; import org.springframework.stereotype.Service; import java.util.List; /** * 기관관리 상세 화면의 게시물/자료 탭이 쓰는 조회 전용 서비스. * Mattermost를 매번 실시간으로 읽어오는 뷰이므로 {@code @Transactional}을 걸지 않는다 - * DB 조회는 채널 id를 얻기 위한 짧은 findById 한 번뿐이고, 외부 API 호출을 트랜잭션 * 안에 묶어둘 이유가 없다. */ @Service public class ChannelFeedService { /** 게시물 탭 한 번에 보여줄 최근 게시글 수. */ private static final int RECENT_POSTS_PAGE_SIZE = 60; private final OrganizationMapper orgMapper; private final MattermostClient mattermost; public ChannelFeedService(OrganizationMapper orgMapper, MattermostClient mattermost) { this.orgMapper = orgMapper; this.mattermost = mattermost; } public List posts(Long orgId, String channel) { String channelId = resolveChannelId(orgId, channel); return mattermost.getRecentPosts(channelId, RECENT_POSTS_PAGE_SIZE); } public List files(Long orgId, String channel) { String channelId = resolveChannelId(orgId, channel); return mattermost.collectChannelFiles(channelId); } private String resolveChannelId(Long orgId, String channel) { Organization org = orgMapper.findById(orgId); if (org == null) { throw new OrgNotFoundException("기관을 찾을 수 없습니다: " + orgId); } String channelId = switch (channel) { case "mj" -> org.getChannelIdMj(); case "law" -> org.getChannelIdLaw(); default -> throw new ChannelNotReadyException("알 수 없는 채널 구분입니다: " + channel); }; if (channelId == null || channelId.isBlank()) { throw new ChannelNotReadyException("해당 채널이 아직 생성되지 않았습니다."); } return channelId; } }