Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions api/app-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ dependencies {
implementation(project(":core:common"))
implementation(project(":core:domain:event"))
implementation(project(":core:domain:internal"))
implementation(project(":core:domain:file"))
implementation(project(":core:domain:welfare"))
implementation(project(":gateway:auth"))
implementation(project(":gateway:logging"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package kr.ac.kookmin.stream.api.app.event.archive;

import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
import kr.ac.kookmin.stream.api.common.dto.ApiResponse;
import kr.ac.kookmin.stream.api.app.event.archive.request.ArchiveListParams;
import kr.ac.kookmin.stream.api.app.event.archive.response.ArchiveDetailResponse;
import kr.ac.kookmin.stream.api.app.event.archive.response.ArchiveListResponse;
import kr.ac.kookmin.stream.event.domain.archive.domain.ArchiveDetail;
import kr.ac.kookmin.stream.event.domain.archive.domain.ArchiveSummary;
import kr.ac.kookmin.stream.event.domain.archive.service.ArchiveService;
import kr.ac.kookmin.stream.file.domain.File;
import kr.ac.kookmin.stream.file.service.FileService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
Expand All @@ -19,22 +25,30 @@
public class AppArchiveController implements AppArchiveApi {

private final ArchiveService archiveService;
private final FileService fileService;

/**
* 목록과 연도는 서로 독립적인 조회다. 연도 버튼은 필터와 무관하게 전체가 보여야 하므로 각각 조회해 응답에서 합친다.
*/
@Override
@GetMapping
public ApiResponse<ArchiveListResponse> getArchives(@Valid @ModelAttribute ArchiveListParams params) {
return ApiResponse.success(ArchiveListResponse.of(
archiveService.getArchives(params.year()),
archiveService.getYears()
));
List<ArchiveSummary> archives = archiveService.getArchives(params.year());
List<Long> thumbnailIds = archives.stream()
.map(ArchiveSummary::thumbnailFileId)
.filter(id -> id != null)
.toList();
Map<Long, File> filesById = fileService.findAllByIdIn(thumbnailIds);

return ApiResponse.success(ArchiveListResponse.of(archives, archiveService.getYears(), filesById));
}

@Override
@GetMapping("/{archiveId}")
public ApiResponse<ArchiveDetailResponse> getArchive(@PathVariable Long archiveId) {
return ApiResponse.success(ArchiveDetailResponse.from(archiveService.getArchive(archiveId)));
ArchiveDetail detail = archiveService.getArchive(archiveId);
Map<Long, File> imagesById = fileService.findAllByIdIn(detail.imageIds());

return ApiResponse.success(ArchiveDetailResponse.from(detail, imagesById));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import kr.ac.kookmin.stream.api.common.StorageUrlBuilder;
import kr.ac.kookmin.stream.event.domain.archive.domain.ArchiveDetail;
import kr.ac.kookmin.stream.event.domain.archive.domain.ArchiveRelatedLink;
import kr.ac.kookmin.stream.file.domain.File;

public record ArchiveDetailResponse(
Long archiveId,
Expand All @@ -17,7 +20,10 @@ public record ArchiveDetailResponse(
List<RelatedLink> relatedLinks
) {

public static ArchiveDetailResponse from(ArchiveDetail detail) {
/**
* 존재하지 않는(삭제된) fileId는 imagesById에 키가 없다 — 그런 항목은 목록에서 조용히 제외한다.
*/
public static ArchiveDetailResponse from(ArchiveDetail detail, Map<Long, File> imagesById) {
return new ArchiveDetailResponse(
detail.archiveId(),
detail.title(),
Expand All @@ -26,18 +32,18 @@ public static ArchiveDetailResponse from(ArchiveDetail detail) {
detail.location(),
detail.departmentName(),
detail.content(),
detail.imageIds().stream().map(Image::from).toList(),
detail.imageIds().stream()
.filter(imagesById::containsKey)
.map(fileId -> Image.of(fileId, imagesById.get(fileId)))
.toList(),
detail.relatedLinks().stream().map(RelatedLink::from).toList()
);
}

public record Image(Long fileId, String fileUrl) {

/**
* 파일 키 → 공개 URL 조립이 아직 없어 URL은 비어 있다. 조립이 생기면 이 팩토리만 채우면 된다.
*/
public static Image from(Long fileId) {
return new Image(fileId, null);
public static Image of(Long fileId, File file) {
return new Image(fileId, StorageUrlBuilder.build(file.getFileKey()));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package kr.ac.kookmin.stream.api.app.event.archive.response;

import java.time.LocalDate;
import java.util.Map;
import kr.ac.kookmin.stream.api.common.StorageUrlBuilder;
import kr.ac.kookmin.stream.event.domain.archive.domain.ArchiveSummary;
import kr.ac.kookmin.stream.file.domain.File;

public record ArchiveListItemResponse(
Long archiveId,
Expand All @@ -11,22 +14,13 @@ public record ArchiveListItemResponse(
String thumbnailUrl
) {

public static ArchiveListItemResponse from(ArchiveSummary summary) {
public static ArchiveListItemResponse from(ArchiveSummary summary, Map<Long, File> filesById) {
return new ArchiveListItemResponse(
summary.archiveId(),
summary.title(),
summary.startDate(),
summary.endDate(),
thumbnailUrlOf(summary.thumbnailFileId())
StorageUrlBuilder.build(summary.thumbnailFileId(), filesById)
);
}

/**
* 대표 이미지 파일 id를 공개 URL로 바꾼다.
* <p>
* 파일 키 → 공개 URL 조립이 아직 없어 현재는 항상 비어 있다. 조립이 생기면 이 메서드만 채우면 된다.
*/
private static String thumbnailUrlOf(Long thumbnailFileId) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package kr.ac.kookmin.stream.api.app.event.archive.response;

import java.util.List;
import java.util.Map;
import kr.ac.kookmin.stream.event.domain.archive.domain.ArchiveSummary;
import kr.ac.kookmin.stream.file.domain.File;

public record ArchiveListResponse(List<ArchiveListItemResponse> archives, List<Integer> years) {

public static ArchiveListResponse of(List<ArchiveSummary> archives, List<Integer> years) {
public static ArchiveListResponse of(List<ArchiveSummary> archives, List<Integer> years, Map<Long, File> filesById) {
return new ArchiveListResponse(
archives.stream().map(ArchiveListItemResponse::from).toList(),
archives.stream().map(summary -> ArchiveListItemResponse.from(summary, filesById)).toList(),
years
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package kr.ac.kookmin.stream.api.app.event.event;

import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import kr.ac.kookmin.stream.api.common.dto.ApiResponse;
import kr.ac.kookmin.stream.api.common.dto.CursorSliceResponse;
import kr.ac.kookmin.stream.api.app.AppApiUser;
Expand All @@ -15,9 +18,12 @@
import kr.ac.kookmin.stream.api.app.event.event.response.EventListItemResponse;
import kr.ac.kookmin.stream.common.CursorSliceResult;
import kr.ac.kookmin.stream.event.domain.event.domain.EventApplicationSummary;
import kr.ac.kookmin.stream.event.domain.event.domain.EventDetail;
import kr.ac.kookmin.stream.event.domain.event.domain.EventSummary;
import kr.ac.kookmin.stream.event.domain.event.service.EventApplicationService;
import kr.ac.kookmin.stream.event.domain.event.service.EventService;
import kr.ac.kookmin.stream.file.domain.File;
import kr.ac.kookmin.stream.file.service.FileService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
Expand All @@ -43,6 +49,7 @@ public class AppEventController implements AppEventApi {

private final EventService eventService;
private final EventApplicationService eventApplicationService;
private final FileService fileService;

@Override
@GetMapping
Expand All @@ -51,7 +58,10 @@ public ApiResponse<CursorSliceResponse<EventListItemResponse>> getEvents(
) {
CursorSliceResult<EventSummary> result = eventService.getPublishedEvents(
params.toRecruitStatus(), params.toCursor(), params.sizeOrDefault());
return ApiResponse.success(CursorSliceResponse.from(result, EventListItemResponse::from));
Map<Long, File> filesById = fileService.findAllByIdIn(thumbnailIdsOf(result.content(), EventSummary::thumbnailFileId));

return ApiResponse.success(
CursorSliceResponse.from(result, summary -> EventListItemResponse.from(summary, filesById)));
}

@Override
Expand All @@ -62,8 +72,11 @@ public ApiResponse<CursorSliceResponse<EventApplicationListItemResponse>> getMyA
) {
CursorSliceResult<EventApplicationSummary> result = eventApplicationService.getMyApplications(
apiUser.userId(), params.toCursor(), params.sizeOrDefault());
Map<Long, File> filesById = fileService.findAllByIdIn(
thumbnailIdsOf(result.content(), EventApplicationSummary::thumbnailFileId));

return ApiResponse.success(
CursorSliceResponse.from(result, EventApplicationListItemResponse::from));
CursorSliceResponse.from(result, summary -> EventApplicationListItemResponse.from(summary, filesById)));
}

@Override
Expand All @@ -89,7 +102,10 @@ public ApiResponse<Void> cancelApplication(
@Override
@GetMapping("/{eventId}")
public ApiResponse<EventDetailResponse> getEvent(@PathVariable Long eventId) {
return ApiResponse.success(EventDetailResponse.from(eventService.getPublishedEvent(eventId)));
EventDetail detail = eventService.getPublishedEvent(eventId);
Map<Long, File> imagesById = fileService.findAllByIdIn(detail.imageIds());

return ApiResponse.success(EventDetailResponse.from(detail, imagesById));
}

@Override
Expand All @@ -109,4 +125,8 @@ public ApiResponse<EventApplyResponse> apply(
EventApplyResponse.from(eventApplicationService.apply(eventId, apiUser.userId(), request.toCommand()))
);
}

private static <T> List<Long> thumbnailIdsOf(List<T> items, Function<T, Long> thumbnailFileId) {
return items.stream().map(thumbnailFileId).filter(id -> id != null).toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package kr.ac.kookmin.stream.api.app.event.event.response;

import java.time.LocalDateTime;
import java.util.Map;
import kr.ac.kookmin.stream.api.common.StorageUrlBuilder;
import kr.ac.kookmin.stream.event.domain.event.domain.EventApplicationStatus;
import kr.ac.kookmin.stream.event.domain.event.domain.EventApplicationSummary;
import kr.ac.kookmin.stream.file.domain.File;

public record EventApplicationListItemResponse(
Long applicationId,
Expand All @@ -14,24 +17,15 @@ public record EventApplicationListItemResponse(
LocalDateTime canceledAt
) {

public static EventApplicationListItemResponse from(EventApplicationSummary summary) {
public static EventApplicationListItemResponse from(EventApplicationSummary summary, Map<Long, File> filesById) {
return new EventApplicationListItemResponse(
summary.applicationId(),
summary.eventId(),
summary.title(),
thumbnailUrlOf(summary.thumbnailFileId()),
StorageUrlBuilder.build(summary.thumbnailFileId(), filesById),
summary.applicationStatus(),
summary.appliedAt(),
summary.canceledAt()
);
}

/**
* 대표 이미지 파일 id를 공개 URL로 바꾼다.
* <p>
* 파일 키 → 공개 URL 조립(#17)이 아직 없어 현재는 항상 비어 있다. #17이 머지되면 이 메서드만 채우면 된다.
*/
private static String thumbnailUrlOf(Long thumbnailFileId) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import kr.ac.kookmin.stream.api.common.StorageUrlBuilder;
import kr.ac.kookmin.stream.event.domain.event.domain.EventDetail;
import kr.ac.kookmin.stream.event.domain.event.domain.RecruitStatus;
import kr.ac.kookmin.stream.file.domain.File;

public record EventDetailResponse(
Long eventId,
Expand All @@ -20,7 +23,10 @@ public record EventDetailResponse(
List<Image> images
) {

public static EventDetailResponse from(EventDetail detail) {
/**
* 존재하지 않는(삭제된) fileId는 imagesById에 키가 없다 — 그런 항목은 목록에서 조용히 제외한다.
*/
public static EventDetailResponse from(EventDetail detail, Map<Long, File> imagesById) {
return new EventDetailResponse(
detail.eventId(),
detail.title(),
Expand All @@ -33,17 +39,17 @@ public static EventDetailResponse from(EventDetail detail) {
detail.applyEndAt(),
detail.recruitStatus(),
detail.daysUntilDeadline(),
detail.imageIds().stream().map(Image::from).toList()
detail.imageIds().stream()
.filter(imagesById::containsKey)
.map(fileId -> Image.of(fileId, imagesById.get(fileId)))
.toList()
);
}

public record Image(Long fileId, String fileUrl) {

/**
* 파일 키 → 공개 URL 조립(#17)이 아직 없어 URL은 비어 있다. #17이 머지되면 이 팩토리만 채우면 된다.
*/
public static Image from(Long fileId) {
return new Image(fileId, null);
public static Image of(Long fileId, File file) {
return new Image(fileId, StorageUrlBuilder.build(file.getFileKey()));
}
}
}
Loading