Skip to content

Commit

Permalink
Merge pull request #87 from YAPP-Github/dev
Browse files Browse the repository at this point in the history
release
  • Loading branch information
CChuYong authored Dec 13, 2024
2 parents 6026245 + b1d2932 commit 03dbfce
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,14 @@ public Mono<AlbumResponse> createAlbum(
String memberId,
AlbumCreateRequest request
){
if (request.name().equals("SUMONE")) {
if (request.type().equals("SUMONE")) {
throw new RuntimeException(); // should not be happened
}
if(request.sumoneInviteCode() != null) {
return albumService
.addSumoneAlbum(request.name(), request.type(), memberId, request.sumoneInviteCode())
.map(AlbumResponse::fromEntity);
}
return albumService
.addAlbum(request.name(), request.type(), memberId)
.map(AlbumResponse::fromEntity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import kr.mafoo.photo.domain.enums.AlbumType;
import kr.mafoo.photo.domain.enums.BrandType;
import kr.mafoo.photo.exception.*;
import kr.mafoo.photo.repository.AlbumRepository;
import kr.mafoo.photo.repository.SumoneEventMappingRepository;
import kr.mafoo.photo.service.AlbumCommand;
import kr.mafoo.photo.service.AlbumQuery;
Expand Down Expand Up @@ -46,6 +47,7 @@ public class SumoneController {
private final RecapService recapService;
private final RecapLambdaService recapLambdaService;
private final SumoneEventMappingRepository sumoneEventMappingRepository;
private final AlbumRepository albumRepository;

@Operation(summary = "통계 api")
@GetMapping("/summary")
Expand All @@ -58,21 +60,10 @@ public Mono<SumoneSummaryResponse> getSummary() {
@Transactional
@Operation(summary = "앨범 생성 api")
@PostMapping("/albums")
public Mono<SumoneAlbumResponse> createAlbum(
@RequestBody SumoneAlbumCreateRequest request
) {
if(request.userId() == null || request.userId().isEmpty()) {
return Mono.error(new DomainException(ErrorCode.REQUEST_INPUT_NOT_VALID));
}

return sumoneEventMappingRepository
.findById(request.userId())
.switchIfEmpty(sumoneEventMappingRepository.save(SumoneEventMappingEntity.newEventMember(
request.userId(),
RandomCodeGenerator.generateAlphanumericString(8)
)))
.then(albumCommand.addAlbum(sumoneAlbumCommonName, "SUMONE", sumoneAlbumCommonMemberId, "SUMONE_" + request.userId())
.map(SumoneAlbumResponse::fromEntity));
public Mono<SumoneAlbumResponse> createAlbum() {
return albumCommand
.addAlbum(sumoneAlbumCommonName, "SUMONE", sumoneAlbumCommonMemberId, null)
.map(SumoneAlbumResponse::fromEntity);
}

@Operation(summary = "앨범에 이미지 url 추가")
Expand Down Expand Up @@ -139,15 +130,26 @@ Mono<RecapUrlDto> createRecapVideo(
@RequestBody
SumoneRecapCreateRequest request
) {
if(request.fileUrls().size() < 1 || request.fileUrls().size() > 10) {
if(request.fileUrls().isEmpty() || request.fileUrls().size() > 10) {
return Mono.error(new RecapPhotoCountNotValidException());
}
if(request.userId() == null || request.userId().isEmpty()) {
return Mono.error(new DomainException(ErrorCode.REQUEST_INPUT_NOT_VALID));
}
return albumQuery.findById(albumId).flatMap(album -> {
if(album.getType() != AlbumType.SUMONE) {
return Mono.error(new AlbumNotFoundException());
}
//TODO: add timeout
return recapLambdaService.generateVideo(request.fileUrls());

return sumoneEventMappingRepository
.findById(request.userId())
.switchIfEmpty(sumoneEventMappingRepository.save(SumoneEventMappingEntity.newEventMember(
request.userId(),
RandomCodeGenerator.generateAlphanumericString(8)
)))
.then(albumRepository.save(album.setExternalId("SUMONE_" + request.userId())))
.then(recapLambdaService.generateVideo(request.fileUrls()));
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public record AlbumCreateRequest(

@MatchEnum(enumClass = AlbumType.class)
@Schema(description = "앨범 타입")
String type
String type,

@Schema(description = "초대 코드")
String sumoneInviteCode
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public record SumoneRecapCreateRequest(
schema = @Schema(description = "파일 URL 목록"),
arraySchema = @Schema(example = "[\"file_url_1\", \"file_url_2\", \"file_url_3\"]")
)
List<String> fileUrls
List<String> fileUrls,

@Schema(description = "썸원 유저ID")
String userId
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ public AlbumEntity decreasePhotoCount(int count) {
return this;
}

public AlbumEntity setExternalId(String externalId) {
this.externalId = externalId;
return this;
}

public static AlbumEntity newAlbum(String albumId, String albumName, AlbumType albumType, String ownerMemberId, String externalId) {
AlbumEntity album = new AlbumEntity();
album.albumId = albumId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ public interface AlbumRepository extends R2dbcRepository<AlbumEntity, String> {
Flux<AlbumEntity> findAllByOwnerMemberIdOrderByAlbumIdDesc(String ownerMemberId, Pageable pageable);

Mono<Long> countAlbumEntityByType(AlbumType albumType);

Flux<AlbumEntity> findAllByExternalId(String externalId);
}
108 changes: 74 additions & 34 deletions photo-service/src/main/java/kr/mafoo/photo/service/AlbumService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@

import java.util.Comparator;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

import kr.mafoo.photo.domain.AlbumEntity;
import kr.mafoo.photo.domain.enums.AlbumType;
import kr.mafoo.photo.domain.enums.BrandType;
import kr.mafoo.photo.exception.AlbumNotFoundException;
import kr.mafoo.photo.exception.AlbumOwnerChangeDeniedException;
import kr.mafoo.photo.exception.SharedMemberNotFoundException;
import kr.mafoo.photo.repository.AlbumRepository;
import kr.mafoo.photo.repository.PhotoRepository;
import kr.mafoo.photo.repository.SumoneEventMappingRepository;
import kr.mafoo.photo.service.dto.AlbumDto;
import kr.mafoo.photo.service.dto.SharedAlbumDto;
import kr.mafoo.photo.service.dto.SharedMemberDto;
Expand All @@ -26,84 +32,118 @@ public class AlbumService {

private final AlbumQuery albumQuery;
private final AlbumCommand albumCommand;
private final AlbumRepository albumRepository;

private final PhotoCommand photoCommand;
private final PhotoRepository photoRepository;


private final AlbumPermissionVerifier albumPermissionVerifier;

private final SharedMemberQuery sharedMemberQuery;
private final MemberService memberService;
private final SharedMemberCommand sharedMemberCommand;

private final SumoneEventMappingRepository sumoneEventMappingRepository;

@Transactional(readOnly = true)
public Flux<AlbumDto> findAlbumListByMemberId(String memberId, String token) {
return Flux.merge(
findOwnedAlbumListByMemberId(memberId),
findSharedAlbumListByMemberId(memberId, token)
findOwnedAlbumListByMemberId(memberId),
findSharedAlbumListByMemberId(memberId, token)
).sort(Comparator.comparing(AlbumDto::createdAt).reversed());
}

private Flux<AlbumDto> findOwnedAlbumListByMemberId(String memberId) {
return albumQuery.findByMemberId(memberId)
.onErrorResume(AlbumNotFoundException.class, ex -> Mono.empty())
.map(AlbumDto::fromOwnedAlbum);
.onErrorResume(AlbumNotFoundException.class, ex -> Mono.empty())
.map(AlbumDto::fromOwnedAlbum);
}

private Flux<AlbumDto> findSharedAlbumListByMemberId(String memberId, String token) {
return sharedMemberQuery.findAllByMemberIdWhereStatusNotRejected(memberId)
.onErrorResume(SharedMemberNotFoundException.class, ex -> Mono.empty())
.concatMap(sharedMember -> albumQuery.findById(sharedMember.getAlbumId())
.flatMap(album -> memberService.getMemberInfoById(album.getOwnerMemberId(), token)
.flatMap(member -> Mono.just(AlbumDto.fromSharedAlbum(album, sharedMember, member)))
)
);
.onErrorResume(SharedMemberNotFoundException.class, ex -> Mono.empty())
.concatMap(sharedMember -> albumQuery.findById(sharedMember.getAlbumId())
.flatMap(album -> memberService.getMemberInfoById(album.getOwnerMemberId(), token)
.flatMap(member -> Mono.just(AlbumDto.fromSharedAlbum(album, sharedMember, member)))
)
);
}

@Transactional(readOnly = true)
public Mono<SharedAlbumDto> findAlbumDetailById(String albumId, String requestMemberId, String token) {
return albumPermissionVerifier.verifyOwnershipOrAccessPermission(albumId, requestMemberId, VIEW_ACCESS)
.flatMap(album -> sharedMemberQuery.findAllByAlbumIdWhereStatusNotRejected(albumId)
.onErrorResume(SharedMemberNotFoundException.class, ex -> Mono.empty())

.flatMap(sharedMember -> memberService.getMemberInfoById(sharedMember.getMemberId(), token)
.map(memberInfo -> SharedMemberDto.fromSharedMember(sharedMember, memberInfo)))
.sort(Comparator.comparing(SharedMemberDto::shareStatus))
.collectList()
.flatMap(sharedMembers -> memberService.getMemberInfoById(album.getOwnerMemberId(), token)
.map(ownerMember -> SharedAlbumDto.fromSharedAlbum(album, ownerMember, sharedMembers))
)

.switchIfEmpty(Mono.just(SharedAlbumDto.fromOwnedAlbum(album)))
);
.flatMap(album -> sharedMemberQuery.findAllByAlbumIdWhereStatusNotRejected(albumId)
.onErrorResume(SharedMemberNotFoundException.class, ex -> Mono.empty())

.flatMap(sharedMember -> memberService.getMemberInfoById(sharedMember.getMemberId(), token)
.map(memberInfo -> SharedMemberDto.fromSharedMember(sharedMember, memberInfo)))
.sort(Comparator.comparing(SharedMemberDto::shareStatus))
.collectList()
.flatMap(sharedMembers -> memberService.getMemberInfoById(album.getOwnerMemberId(), token)
.map(ownerMember -> SharedAlbumDto.fromSharedAlbum(album, ownerMember, sharedMembers))
)

.switchIfEmpty(Mono.just(SharedAlbumDto.fromOwnedAlbum(album)))
);
}

@Transactional
public Mono<AlbumEntity> addAlbum(String albumName, String albumType, String requestMemberId) {
return albumCommand.addAlbum(albumName, albumType, requestMemberId, null);
}

@Transactional
public Mono<AlbumEntity> addSumoneAlbum(String albumName, String albumType, String requestMemberId, String inviteCode) {
AtomicInteger displayIndex = new AtomicInteger(0);
return albumCommand
.addAlbum(albumName, albumType, requestMemberId, null)
.flatMap(album -> sumoneEventMappingRepository
.findByInviteCode(inviteCode)
.switchIfEmpty(Mono.error(new AlbumNotFoundException()))
.flatMap(sumoneEventMappingEntity ->
sumoneEventMappingRepository.delete(sumoneEventMappingEntity).then(Mono.just(sumoneEventMappingEntity)))
.map(entity -> "SUMONE_" + entity.getId())
.flatMapMany(albumRepository::findAllByExternalId)
.flatMap(sumoneAlbum ->
photoRepository.findAllByAlbumIdOrderByCreatedAtAsc(sumoneAlbum.getAlbumId()).flatMap(photo ->
photoCommand.addPhoto(
photo.getPhotoUrl(),
BrandType.EXTERNAL,
album.getAlbumId(),
displayIndex.getAndIncrement(),
requestMemberId
)
)
)
.then(albumQuery.findById(album.getAlbumId()))
.flatMap(newAlbum -> albumCommand.increaseAlbumPhotoCount(newAlbum, displayIndex.get())));
}

@Transactional
public Mono<AlbumEntity> modifyAlbumNameAndType(String albumId, String newAlbumName, String newAlbumType, String requestMemberId) {
return albumPermissionVerifier.verifyOwnershipOrAccessPermission(albumId, requestMemberId, FULL_ACCESS)
.flatMap(album -> albumCommand.modifyAlbumNameAndType(album, newAlbumName, newAlbumType));
.flatMap(album -> albumCommand.modifyAlbumNameAndType(album, newAlbumName, newAlbumType));
}

@Transactional
public Mono<AlbumEntity> modifyAlbumOwnership(String albumId, String newOwnerMemberId, String requestMemberId) {
return albumPermissionVerifier.verifyOwnership(albumId, requestMemberId)
.flatMap(album -> sharedMemberQuery.findByAlbumIdAndMemberIdWhereStatusAccepted(albumId, newOwnerMemberId)
.onErrorResume(SharedMemberNotFoundException.class, ex ->
Mono.error(new AlbumOwnerChangeDeniedException())
)
.flatMap(sharedMemberCommand::removeSharedMember)
.then(albumCommand.modifyAlbumOwnership(album, newOwnerMemberId))
.then(sharedMemberCommand.addSharedMember(albumId, String.valueOf(FULL_ACCESS), Optional.of(ACCEPTED), requestMemberId))
.thenReturn(album)
);
.flatMap(album -> sharedMemberQuery.findByAlbumIdAndMemberIdWhereStatusAccepted(albumId, newOwnerMemberId)
.onErrorResume(SharedMemberNotFoundException.class, ex ->
Mono.error(new AlbumOwnerChangeDeniedException())
)
.flatMap(sharedMemberCommand::removeSharedMember)
.then(albumCommand.modifyAlbumOwnership(album, newOwnerMemberId))
.then(sharedMemberCommand.addSharedMember(albumId, String.valueOf(FULL_ACCESS), Optional.of(ACCEPTED), requestMemberId))
.thenReturn(album)
);
}

@Transactional
public Mono<Void> removeAlbum(String albumId, String requestMemberId) {
return albumPermissionVerifier.verifyOwnership(albumId, requestMemberId)
.flatMap(albumCommand::removeAlbum);
.flatMap(albumCommand::removeAlbum);
}

public Mono<Long> countAlbumByAlbumType(AlbumType albumType) {
Expand Down
12 changes: 9 additions & 3 deletions user-service/src/main/java/kr/mafoo/user/api/MeApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import kr.mafoo.user.annotation.RequestMemberId;
import kr.mafoo.user.controller.dto.request.ChangeNameRequest;
import kr.mafoo.user.controller.dto.response.MemberResponse;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

@Tag(name = "로그인 사용자 정보 API", description = "현재 토큰 주인의 정보를 다루는 API")
Expand All @@ -26,4 +25,11 @@ Mono<MemberResponse> getMemberWhoRequested(
Mono<Void> deleteMemberWhoRequested(
@RequestMemberId @Parameter(hidden = true) String memberId
);

@Operation(summary = "이름 변경", description = "현재 토큰 주인의 이름을 변경합니다.")
@PostMapping("/name")
Mono<MemberResponse> changeName(
@RequestMemberId @Parameter(hidden = true) String memberId,
@RequestBody ChangeNameRequest name
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kr.mafoo.user.controller;

import kr.mafoo.user.api.MeApi;
import kr.mafoo.user.controller.dto.request.ChangeNameRequest;
import kr.mafoo.user.controller.dto.response.MemberResponse;
import kr.mafoo.user.service.MemberService;
import lombok.RequiredArgsConstructor;
Expand All @@ -24,4 +25,11 @@ public Mono<Void> deleteMemberWhoRequested(String memberId) {
return memberService
.quitMemberByMemberId(memberId);
}

@Override
public Mono<MemberResponse> changeName(String memberId, ChangeNameRequest name) {
return memberService
.changeName(memberId, name.name())
.map(MemberResponse::fromEntity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package kr.mafoo.user.controller.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "이름 변경 요청")
public record ChangeNameRequest(
@Schema(description = "새 이름", example = "염수연")
String name
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,16 @@ public Mono<MemberEntity> createNewMember(String username, String profileImageUr
.then(Mono.just(savedMember))
);
}

@Transactional
public Mono<MemberEntity> changeName(String memberId, String name) {
return memberRepository
.findById(memberId)
.switchIfEmpty(Mono.error(new MemberNotFoundException()))
.map(member -> {
member.setName(name);
return member;
})
.flatMap(memberRepository::save);
}
}

0 comments on commit 03dbfce

Please sign in to comment.