유저 차단 - 앱 스토어의 요구사항
앱 심사 제출 후 날아온 거절 메시지
앱 스토어의 심사 과정은 상당히 까다롭기로 유명하다. 애플 측에서 제시하는 가이드라인 에 출시하고자 하는 앱의 기능을 맞춰야 하기 때문이다.
특히나 네이티브 기능 대신 웹뷰로 웹사이트를 보여주는 웹뷰앱에 대해서는 더 엄격하게 심사를 한다고 한다.
내가 제출한 앱 또한 한번에 통과될 리가 없었고, 여러 거절 메시지가 왔다. 그 중에 하나인 ‘Guildline 1.2 - Safety - User-Generated Content’에 대해 알아보도록 하겠다.
요구사항: 차단과 신고 기능을 만들라

위 이미지를 요약하면 다음과 같다.
- abusive한 유저를 차단하는 메카니즘을 구현하라
- 신고가 들어오면 24시간 내 해당 컨텐츠를 제거하고 해당 컨텐츠를 만든 유저에 대해 조치를 취하라
신고 및 신고를 관리하는 관리자 기능은 이미 완성되어 있었기 때문에, 유저를 차단할 수 있는 기능을 추가하기로 했다.
차단 기능

차단 기능 자체를 구현하는 것은 어렵지 않았다. 우선 차단 기록을 담아 둘 block 테이블을 설계했고, 운영 중인 DB에 추가하였다.
차단하는 유저와 차단당한 유저의 id를 컬럼에 추가하였다. 차단 관계는 일방적이기 때문에 이런 형태로 설계하였다.
A가 B를 차단하더라도, B가 A를 차단한 것은 아니다.
또한 차단하는 유저의 id와 차단당한 유저의 id를 묶어 유니크 제약조건을 걸어둠으로써 중복 차단을 방지하고, 컨텐츠 열람 시 차단 여부를 판별할 때 테이블에서 더 빠르게 찾을 수 있도록 인덱싱 효과도 가져갈 수 있다.
CREATE TABLE block (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
blocker_id BIGINT NOT NULL,
blocked_id BIGINT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_block_blocker FOREIGN KEY (blocker_id) REFERENCES member(id) ON DELETE CASCADE,
CONSTRAINT fk_block_blocked FOREIGN KEY (blocked_id) REFERENCES member(id) ON DELETE CASCADE,
CONSTRAINT uq_block UNIQUE (blocker_id, blocked_id) -- 중복 차단 방지
);
비즈니스 로직 작성 또한 어렵지 않았다. 유저를 차단하는 기능, 유저 차단을 해제하는 기능, 내가 차단한 유저들을 열람하는 기능만 만들면 끝이였다.
카카오톡이나 당근마켓의 로직을 많이 참고하여 만들었다.
차단한 유저의 컨텐츠를 보이지 않게 하기
모임조회 시
모임을 조회할 때는 내가 차단한 유저가 모임장인 모임을 보이지 않게 where로 적절히 필터링해주면 된다.AND NOT EXISTS ( -- 차단 로직 SELECT 1 FROM block b WHERE b.blocker_id = #{memberId} AND b.blocked_id = m.host_id )채팅조회 시
채팅은 상당히 까다롭다. 일단 채팅 목록을 불러올 때는 DB에서 가져오므로 백엔드에서 적절히 필터링해서 주면 되지만, STOMP를 이용해 실시간 채팅이 전송되는 경우 같은 채널을 구독하고 있는 채팅방 사람들에게 모두 같은 채팅이 전송된다. 그러나 차단은 특정 유저가 특정 유저를 단방향으로 하는 로직이기 때문에, STOMP를 통한 실시간 채팅을 전송 시 처리가 매우 까다롭다.
따라서, 생각을 바꿔서 ‘채팅 수신 시 처리’를 하기로 했다.
채팅방에 입장 시, 채팅방의 정보를 가져오는 api에 다음과 같은 필드를 하나 추가했다.
private List<Long> blockMemberIdList
그러면 해당 유저가 차단한 유저들의 리스트를 받았으므로, 이 리스트에 있는 유저들의 채팅 메시지를 프론트엔드 단에서 적절히 마스킹하여 보여주면 된다.
물론 백엔드에서 최대한 완성된 데이터를 제공해 주는 것이 이상적인 설계인 것을 알고 있으나, 이번 상황에서만큼은 타협하여 설계하기로 했다.
댓글남기기