Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OING-340] feature: 가족 초대 딥링크 발급 로직 변경 및 가족 초대 뷰 기반 API 실제 로직 추가 #262

Merged
merged 11 commits into from
Jun 18, 2024
Merged
5 changes: 5 additions & 0 deletions common/src/main/java/com/oing/service/FamilyBridge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.oing.service;

public interface FamilyBridge {
String findFamilyNameByFamilyId(String familyId);
}
6 changes: 6 additions & 0 deletions common/src/main/java/com/oing/service/MemberBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,10 @@ public interface MemberBridge {
boolean isDeletedMember(String memberId);

List<String> getFamilyMembersIdsByFamilyId(String familyId);

String getMemberNameByMemberId(String memberId);

List<String> getFamilyMemberProfileImgUrlsByFamilyId(String familyId);

int getFamilyMemberCountByFamilyId(String familyId);
}
2 changes: 2 additions & 0 deletions common/src/main/java/com/oing/service/PostBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
*/
public interface PostBridge {
boolean isUploadedToday(String familyId, String memberId);

int countSurvivalPostsByFamilyId(String familyId);
}
6 changes: 5 additions & 1 deletion family/src/main/java/com/oing/domain/Family.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ public class Family extends BaseEntity {
@Column(name = "family_id", columnDefinition = "CHAR(26)", nullable = false)
private String id;

@Column(name = "family_name", columnDefinition = "CHAR(10)")
private String familyName;

@Column(name = "score", nullable = false)
private Integer score = 0;


public Family(String id) {
public Family(String id, String familyName) {
this.id = id;
this.familyName = familyName;
}

public static final int NEW_POST_SCORE = 20;
Expand Down
8 changes: 7 additions & 1 deletion family/src/main/java/com/oing/domain/FamilyInviteLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ public class FamilyInviteLink extends BaseEntity implements SerializableDeepLink
@Column(name = "family_id", columnDefinition = "CHAR(26)", nullable = false)
private String familyId;

@Column(name = "member_id", columnDefinition = "CHAR(26)", nullable = false)
private String memberId;

@Override
public Map<String, String> serialize() {
return Map.of("familyId", familyId);
return Map.of(
"familyId", familyId,
"memberId", memberId
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
* Time: 7:17 PM
*/
public interface FamilyInviteLinkRepository extends JpaRepository<FamilyInviteLink, String> {
public FamilyInviteLink findByFamilyId(String familyId);
public FamilyInviteLink findByFamilyIdAndMemberId(String familyId, String memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public FamilyInviteLink storeDeepLinkDetails(FamilyInviteLink details) {

@Override
public FamilyInviteLink findPriorDeepLinkDetails(FamilyInviteLink details) {
return familyInviteLinkRepository.findByFamilyId(details.getFamilyId());
return familyInviteLinkRepository.findByFamilyIdAndMemberId(details.getFamilyId(), details.getMemberId());
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion family/src/main/java/com/oing/service/FamilyService.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class FamilyService {

@Transactional
public Family createFamily() {
Family family = new Family(identityGenerator.generateIdentity());
Family family = new Family(identityGenerator.generateIdentity(), null);
return familyRepository.save(family);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,21 @@ public DeepLinkResponse getLinkDetails(String linkId) {
@Transactional
@Override
public DeepLinkResponse createFamilyDeepLink(
String familyId, String loginFamilyId
String familyId, String loginFamilyId, String loginMemberId
) {
String linkId = deepLinkService.generateNewDeepLinkId();

// 내 가족 외의 딥링크를 생성하려는 경우
if (!Objects.equals(loginFamilyId, familyId)) throw new AuthorizationFailedException();

FamilyInviteLink newInviteLink = new FamilyInviteLink(linkId, familyId);
FamilyInviteLink newInviteLink = new FamilyInviteLink(linkId, familyId, loginMemberId);
FamilyInviteLink familyInviteLink = familyDeepLinkService.findPriorDeepLinkDetails(newInviteLink);
if (familyInviteLink != null) {
return getLinkDetails(familyInviteLink.getLinkId());
}
newInviteLink = familyDeepLinkService.storeDeepLinkDetails(newInviteLink);

DeepLink deepLink = deepLinkService.createDeepLink(linkId, DeepLinkType.FAMILY_REGISTRATION);
DeepLink deepLink = deepLinkService.createDeepLink(linkId, DeepLinkType.FAMILY_REGISTRATION, loginMemberId, loginFamilyId);
return new DeepLinkResponse(
deepLink.getLinkId(),
generateLink(deepLink.getLinkId()),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.oing.controller;

import com.oing.dto.response.DeepLinkResponse;
import com.oing.dto.response.FamilyInviteDeepLinkResponse;
import com.oing.dto.response.MemberResponse;
import com.oing.restapi.DeepLinkApi;
import com.oing.restapi.FamilyInviteViewApi;
import com.oing.restapi.MeApi;
import com.oing.service.FamilyBridge;
import com.oing.service.MemberBridge;
import com.oing.service.PostBridge;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;

Expand All @@ -14,32 +18,44 @@
public class FamilyInviteViewController implements FamilyInviteViewApi {

private final DeepLinkApi deepLinkApi;
private final MeApi meApi;
private final MemberBridge memberBridge;
private final FamilyBridge familyBridge;
private final PostBridge postBridge;
private final MemberController memberController;

@Override
public FamilyInviteDeepLinkResponse getFamilyInviteLinkDetails(String linkId, String loginMemberId) {

// TODO : 기능 구현할 때, 응답 모킹용 코드 삭제하고 아래 주석 풀기
boolean isRequesterJoinedFamily = false;
// MemberResponse me = meApi.getMe(loginMemberId);
Copy link
Member Author

@Ji-soo708 Ji-soo708 Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meApi의 getMe 메서드를 그대로 사용하면 로그인하지 않은 사용자가 해당 API를 호출할 때, Member를 찾을 수 없다는 예외가 터져 해당 API용 getMemberNullable를 따로 추가해서 처리했습니다.

// if (me.familyId() != null) {
// isRequesterJoinedFamily = true;
// }
//
if (loginMemberId != null) {
isRequesterJoinedFamily = true;
boolean isRequesterJoinedFamily = true;
MemberResponse me = memberController.getMemberNullable(loginMemberId);
if (me.familyId() == null) {
isRequesterJoinedFamily = false;
}

DeepLinkResponse deepLinkResponse = deepLinkApi.getLinkDetails(linkId);
String familyId = deepLinkResponse.getDetails().get("familyId");
String familyName = familyBridge.findFamilyNameByFamilyId(familyId);
List<String> familyMemberProfileImgUrls = memberBridge.getFamilyMemberProfileImgUrlsByFamilyId(familyId);
int familyMemberCount = memberBridge.getFamilyMemberCountByFamilyId(familyId);
int extraFamilyMemberCount;
if (familyMemberCount<3) {
extraFamilyMemberCount = 0;
} else {
extraFamilyMemberCount = familyMemberCount - 2;
}
int survivalPostCount = postBridge.countSurvivalPostsByFamilyId(familyId);

String inviterId = deepLinkResponse.getDetails().get("memberId");
String inviterName = memberBridge.getMemberNameByMemberId(inviterId);

return new FamilyInviteDeepLinkResponse (
"01HGW2N7EHJVJ4CJ999RRS2E97",
"사랑하는 우리가족",
List.of("https://upload.wikimedia.org/wikipedia/en/thumb/6/63/Feels_good_man.jpg/200px-Feels_good_man.jpg", "https://upload.wikimedia.org/wikipedia/en/thumb/6/63/Feels_good_man.jpg/200px-Feels_good_man.jpg"),
3,
5,
"김철수",
3,
familyId,
familyName,
familyMemberProfileImgUrls,
extraFamilyMemberCount,
familyMemberCount,
inviterName,
survivalPostCount,
isRequesterJoinedFamily
);
}
Expand Down
6 changes: 6 additions & 0 deletions gateway/src/main/java/com/oing/domain/DeepLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ public class DeepLink extends BaseEntity {
@Enumerated(EnumType.STRING)
@Column(name = "type", columnDefinition = "VARCHAR(64)", nullable = false)
private DeepLinkType type;

@Column(name = "member_id", columnDefinition = "CHAR(26)", nullable = false)
private String memberId;

@Column(name = "family_id", columnDefinition = "CHAR(26)", nullable = false)
private String familyId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ public int countTodaySurvivalPostsByFamilyId(String familyId) {
return count.intValue();
}

@Override
public int countSurvivalPostsByFamilyId(String familyId) {
Long count = queryFactory
.select(post.id.count())
.from(post)
.where(post.familyId.eq(familyId),
post.type.eq(SURVIVAL))
.fetchFirst();
return count.intValue();
}

private BooleanExpression eqDate(LocalDate date) {
DateTimeTemplate<LocalDate> createdAtDate = Expressions.dateTimeTemplate(LocalDate.class,
"DATE({0})", post.createdAt);
Expand Down
7 changes: 6 additions & 1 deletion gateway/src/main/java/com/oing/restapi/DeepLinkApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.oing.dto.response.DeepLinkResponse;
import com.oing.util.security.LoginFamilyId;
import com.oing.util.security.LoginMemberId;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -36,6 +37,10 @@ DeepLinkResponse createFamilyDeepLink(

@Parameter(hidden = true)
@LoginFamilyId
String loginFamilyId
String loginFamilyId,

@Parameter(hidden = true)
@LoginMemberId
String loginMemberId
);
}
5 changes: 2 additions & 3 deletions gateway/src/main/java/com/oing/service/DeepLinkService.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ public String generateNewDeepLinkId() {
}

@Transactional
public DeepLink createDeepLink(String linkId, DeepLinkType type) {
DeepLink newDeepLink = new DeepLink(linkId, type);
public DeepLink createDeepLink(String linkId, DeepLinkType type, String memberId, String familyId) {
DeepLink newDeepLink = new DeepLink(linkId, type, memberId, familyId);
return deepLinkRepository.save(newDeepLink);
}


@Transactional
public DeepLink getDeepLink(String linkId) {
return deepLinkRepository
Expand Down
19 changes: 19 additions & 0 deletions gateway/src/main/java/com/oing/service/FamilyBridgeImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.oing.service;

import com.oing.domain.Family;
import com.oing.repository.FamilyRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
public class FamilyBridgeImpl implements FamilyBridge {
private final FamilyRepository familyRepository;

@Override
public String findFamilyNameByFamilyId(String familyId) {
return familyRepository.findById(familyId)
.map(Family::getFamilyName)
.orElse(null);
}
}
19 changes: 19 additions & 0 deletions gateway/src/main/java/com/oing/service/MemberBridgeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,23 @@ public List<String> getFamilyMembersIdsByFamilyId(String familyId) {
.map(Member::getId)
.toList();
}

@Override
public String getMemberNameByMemberId(String memberId) {
return memberRepository.findById(memberId)
.map(Member::getName)
.orElseThrow(MemberNotFoundException::new);
}

@Override
public List<String> getFamilyMemberProfileImgUrlsByFamilyId(String familyId) {
return memberRepository.findAllByFamilyIdAndDeletedAtIsNull(familyId).stream()
.map(Member::getProfileImgUrl)
.toList();
}

@Override
public int getFamilyMemberCountByFamilyId(String familyId) {
return memberRepository.countByFamilyIdAndDeletedAtIsNull(familyId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE `deep_link` ADD COLUMN (`member_id` CHAR(26) NOT NULL COMMENT 'ULID');
ALTER TABLE `deep_link` ADD COLUMN (`family_id` CHAR(26) NOT NULL COMMENT 'ULID');
ALTER TABLE `family_invite_link` ADD COLUMN (`member_id` CHAR(26) NOT NULL COMMENT 'ULID');
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE `family` ADD COLUMN (`family_name` CHAR(10));
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class FamilyScoreEventListenerTest {

@BeforeEach
void setUp() {
familyRepository.save(new Family(testMember1.getFamilyId()));
familyRepository.save(new Family(testMember1.getFamilyId(), null));
memberRepository.save(testMember1);
memberRepository.save(testMember2);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class PostRepositoryCustomTest {
@BeforeEach
void setup() {
// Family & Members
familyRepository.save(new Family("testFamily"));
familyRepository.save(new Family("testFamily", null));
memberRepository.save(testMember1);
memberRepository.save(testMember2);
memberRepository.save(testMember3);
Expand Down
16 changes: 12 additions & 4 deletions member/src/main/java/com/oing/controller/MemberController.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.oing.exception.AuthorizationFailedException;
import com.oing.exception.PickFailedAlreadyUploadedException;
import com.oing.restapi.MemberApi;
import com.oing.service.MemberService;
import com.oing.service.*;
import com.oing.util.FCMNotificationUtil;
import com.oing.util.PreSignedUrlGenerator;
Expand All @@ -22,18 +21,17 @@
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;

import static com.oing.exception.ErrorCode.UNAUTHORIZED_MEMBER_USED;
import java.util.List;

import static com.oing.exception.ErrorCode.UNAUTHORIZED_MEMBER_USED;

@Controller
@RequiredArgsConstructor
public class MemberController implements MemberApi {

private final MemberPickService memberPickService;
private final MemberService memberService;
private final MemberDeviceService memberDeviceService;
private final MemberQuitReasonService memberQuitReasonService;

private final PreSignedUrlGenerator preSignedUrlGenerator;
private final PostBridge postBridge;
private final FCMNotificationService fcmNotificationService;
Expand All @@ -59,6 +57,16 @@ public MemberResponse getMember(String memberId, String loginFamilyId) {
return MemberResponse.of(member);
}

// 가족 링크 초대 정보 조회 API에서 사용되는 메서드
@Override
public MemberResponse getMemberNullable(String memberId) {
Member member = memberService.getMemberByMemberIdOrNull(memberId);
if (member == null) {
return new MemberResponse(null, null, null, null, null, null);
}
return MemberResponse.of(member);
}

@Override
public PreSignedUrlResponse requestPresignedUrl(PreSignedUrlRequest request) {
String imageName = request.imageName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ public interface MemberRepository extends JpaRepository<Member, String> {
List<Member> findAllByDeletedAtIsNull();

boolean existsByIdAndDeletedAtNotNull(String memberId);

int countByFamilyIdAndDeletedAtIsNull(String familyId);
}
2 changes: 2 additions & 0 deletions member/src/main/java/com/oing/restapi/MemberApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ MemberResponse getMember(
String loginFamilyId
);

MemberResponse getMemberNullable(String memberId);

@Operation(summary = "회원 프로필 사진 S3 Presigned Url 요청", description = "S3 Presigned Url을 요청합니다.")
@PostMapping("/image-upload-request")
PreSignedUrlResponse requestPresignedUrl(
Expand Down
6 changes: 6 additions & 0 deletions member/src/main/java/com/oing/service/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ public Member getMemberByMemberId(String memberId) {
.orElseThrow(MemberNotFoundException::new);
}

public Member getMemberByMemberIdOrNull(String memberId) {
return memberRepository
.findById(memberId)
.orElse(null);
}

public String getFamilyIdByMemberId(String memberId) {
Member member = getMemberByMemberId(memberId);
if (member.getFamilyId() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ QueryResults<Post> searchPosts(int page, int size, LocalDate date, String member
int countFamilyMembersByFamilyIdAtYesterday(String familyId);

int countTodaySurvivalPostsByFamilyId(String familyId);

int countSurvivalPostsByFamilyId(String familyId);
}
Loading
Loading