Skip to content

Commit

Permalink
feat: 사용자 프로필 생성 및 조회 (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
GaBaljaintheroom authored Feb 15, 2025
1 parent bd38549 commit dccca59
Show file tree
Hide file tree
Showing 59 changed files with 259 additions and 91 deletions.
1 change: 1 addition & 0 deletions .github/workflows/showpot-dev-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
spotify.client-id: ${{ secrets.SPOTIFY_CLIENT_ID }}
spotify.client-secret: ${{ secrets.SPOTIFY_CLIENT_SECRET }}
alarm.api-url: ${{ secrets.ALARM_SERVER_API_URL }}
file.root-url: ${{ secrets.FILE_ROOT_API_URL_DEV }}

- name: Build with Gradle Wrapper
run: ./gradlew clean build -Dspring.profiles.active=dev
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/showpot-prod-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
spotify.client-id: ${{ secrets.SPOTIFY_CLIENT_ID }}
spotify.client-secret: ${{ secrets.SPOTIFY_CLIENT_SECRET }}
alarm.api-url: ${{ secrets.ALARM_SERVER_API_URL_PROD }}
file.root-url: ${{ secrets.FILE_ROOT_API_URL_PROD }}

- name: Build with Gradle Wrapper
run: ./gradlew clean build -Dspring.profiles.active=prod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ private RequestMatcher getMatcherForAnyone() {
antMatcher(HttpMethod.GET, "/api/v1/shows/search/**"),
antMatcher(HttpMethod.GET, "/api/v1/artists/filter"),
antMatcher(HttpMethod.GET, "/api/v1/artists/filter-total-count"),
antMatcher(HttpMethod.GET, "/api/v1/artists/unsubscriptions")
antMatcher(HttpMethod.GET, "/api/v1/artists/unsubscriptions"),
antMatcher(HttpMethod.GET, "/api/v1/files/profile-image/{id}")
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package org.example.config;

import org.example.file.property.FileRootUrlProperty;
import org.example.property.AlarmServerProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(UserDomainConfig.class)
@EnableConfigurationProperties(AlarmServerProperty.class)
@EnableConfigurationProperties({AlarmServerProperty.class, FileRootUrlProperty.class})
@EnableCaching
@ComponentScan(basePackages = "org.example")
public class UserApiConfig {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.example.file.component;

import java.util.Optional;
import org.springframework.core.io.Resource;

public interface FileComponent {

Optional<String> getImageUrl(int id);

Resource getProfileResource(int id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.example.file.component;

import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.example.file.property.FileRootUrlProperty;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class FileLocalComponent implements FileComponent {

private final FileRootUrlProperty fileRootUrlProperty;
private static final String IMAGE_URL_TEMPLATE = "/profile-image/";
private static final String IMAGE_RESOURCE_LOCATION = "static/image/profileImage";
private static final String IMAGE_EXTENSION = ".png";

/**
* 이미지 ID를 받아서 URL을 반환하는 메서드
*
* @param id 이미지 ID (1 ~ 16)
* @return 이미지 URL
*/
@Override
public Optional<String> getImageUrl(int id) {
// ID가 범위를 벗어난 경우 빈 값을 반환
if (id < 1 || id > 16) {
return Optional.empty();
}

return Optional.of(fileRootUrlProperty.rootUrl() + IMAGE_URL_TEMPLATE + id);
}

@Override
@Cacheable(value = "profileImages", key = "#id")
public Resource getProfileResource(int id) {
Resource resource;
try {
String resourcePath = IMAGE_RESOURCE_LOCATION + id + IMAGE_EXTENSION;
resource = new UrlResource(
Objects.requireNonNull(getClass().getClassLoader().getResource(resourcePath))
.toURI());
if (!resource.exists() && !resource.isReadable()) {
throw new IllegalArgumentException();
}
} catch (Exception e) {
throw new IllegalArgumentException(e);
}

return resource;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.example.file.controller;

import lombok.RequiredArgsConstructor;
import org.example.file.component.FileLocalComponent;
import org.springframework.core.io.Resource;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/files")
public class FileController {

private final FileLocalComponent fileLocalComponent;

@GetMapping("/profile-image/{id}")
public ResponseEntity<Resource> getUserProfileImage(@PathVariable int id) {
Resource resource = fileLocalComponent.getProfileResource(id);

return ResponseEntity.ok()
.contentType(MediaType.IMAGE_PNG)
.header(
HttpHeaders.CONTENT_DISPOSITION,
ContentDisposition.inline().filename(resource.getFilename()).toString())
.body(resource);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.example.file.property;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "file")
public record FileRootUrlProperty(
String rootUrl
) {

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.example.client;
package org.example.user.client;

import java.time.LocalDateTime;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.metric.InternalApiMonitored;
import org.example.property.AlarmServerProperty;
import org.example.service.dto.response.NotificationExistServiceResponse;
import org.example.service.dto.response.NotificationPaginationResponse;
import org.example.user.service.dto.response.NotificationExistServiceResponse;
import org.example.user.service.dto.response.NotificationPaginationResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.example.controller;
package org.example.user.controller;


import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.example.controller.dto.request.AdminLoginApiRequest;
import org.example.service.AdminService;
import org.example.user.controller.dto.request.AdminLoginApiRequest;
import org.example.user.service.AdminService;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package org.example.controller;
package org.example.user.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.Max;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.example.controller.dto.param.SimpleNotificationApiParam;
import org.example.controller.dto.response.NotificationExistApiResponse;
import org.example.dto.response.PaginationApiResponse;
import org.example.dto.response.SuccessResponse;
import org.example.security.dto.AuthenticatedInfo;
import org.example.service.UserAlarmService;
import org.example.user.controller.dto.param.SimpleNotificationApiParam;
import org.example.user.controller.dto.response.NotificationExistApiResponse;
import org.example.user.service.UserAlarmService;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.example.controller;
package org.example.user.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
Expand All @@ -7,15 +7,15 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.example.controller.dto.request.LoginApiRequest;
import org.example.controller.dto.response.LoginApiResponse;
import org.example.controller.dto.response.ReissueApiResponse;
import org.example.controller.dto.response.UserProfileApiResponse;
import org.example.dto.response.SuccessResponse;
import org.example.dto.response.SuccessResponse.Empty;
import org.example.security.dto.AuthenticatedInfo;
import org.example.security.dto.TokenParam;
import org.example.service.UserService;
import org.example.user.controller.dto.request.LoginApiRequest;
import org.example.user.controller.dto.response.LoginApiResponse;
import org.example.user.controller.dto.response.ReissueApiResponse;
import org.example.user.controller.dto.response.UserProfileApiResponse;
import org.example.user.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -40,9 +40,9 @@ public SuccessResponse<LoginApiResponse> signUp(@Valid @RequestBody LoginApiRequ
TokenParam token = userService.login(request.toServiceType());

return SuccessResponse.ok(LoginApiResponse.builder()
.accessToken(token.accessToken())
.refreshToken(token.refreshToken())
.build());
.accessToken(token.accessToken())
.refreshToken(token.refreshToken())
.build());
}

@ResponseStatus(HttpStatus.OK)
Expand Down Expand Up @@ -81,21 +81,21 @@ public SuccessResponse<Empty> withdraw(
summary = "토큰 재발급",
parameters = {
@Parameter(
in = ParameterIn.HEADER,
name = "Refresh",
description = "리프레시 토큰",
in = ParameterIn.HEADER,
name = "Refresh",
description = "리프레시 토큰",
required = true)
}
}
)
public SuccessResponse<ReissueApiResponse> reissue(
@AuthenticationPrincipal AuthenticatedInfo info
) {
TokenParam reissueToken = userService.reissue(info.userId(), info.refreshToken());

return SuccessResponse.ok(ReissueApiResponse.builder()
.accessToken(reissueToken.accessToken())
.refreshToken(reissueToken.refreshToken())
.build());
.accessToken(reissueToken.accessToken())
.refreshToken(reissueToken.refreshToken())
.build());
}

@ResponseStatus(HttpStatus.OK)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.example.controller.dto.param;
package org.example.user.controller.dto.param;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.UUID;
import lombok.Builder;
import org.example.service.dto.response.NotificationServiceResponse.NotificationInfoWithImageResponse;
import org.example.user.service.dto.response.NotificationServiceResponse.NotificationInfoWithImageResponse;
import org.example.util.DateTimeUtil;

@Builder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.example.controller.dto.request;
package org.example.user.controller.dto.request;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.example.service.dto.request.AdminLoginServiceRequest;
import org.example.user.service.dto.request.AdminLoginServiceRequest;

public record AdminLoginApiRequest(

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.example.controller.dto.request;
package org.example.user.controller.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import org.example.service.dto.request.LoginServiceRequest;
import org.example.vo.SocialLoginApiType;
import org.example.user.service.dto.request.LoginServiceRequest;
import org.example.user.vo.SocialLoginApiType;

public record LoginApiRequest(

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.example.controller.dto.response;
package org.example.user.controller.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.example.controller.dto.response;
package org.example.user.controller.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.example.controller.dto.response;
package org.example.user.controller.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import org.example.service.dto.response.NotificationExistServiceResponse;
import org.example.user.service.dto.response.NotificationExistServiceResponse;

@Builder
public record NotificationExistApiResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.example.controller.dto.response;
package org.example.user.controller.dto.response;

import java.util.List;
import lombok.Builder;
import org.example.controller.dto.param.SimpleNotificationApiParam;
import org.example.user.controller.dto.param.SimpleNotificationApiParam;

@Builder
public record NotificationsApiResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.example.controller.dto.response;
package org.example.user.controller.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.example.controller.dto.response;
package org.example.user.controller.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import org.example.service.dto.response.UserProfileServiceResponse;
import org.example.vo.SocialLoginApiType;
import org.example.user.service.dto.response.UserProfileServiceResponse;
import org.example.user.vo.SocialLoginApiType;

@Builder
public record UserProfileApiResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.example.pub;
package org.example.user.pub;

import java.util.UUID;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.example.pub;
package org.example.user.pub;

public interface UserMessagePublisher {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.example.service;
package org.example.user.service;

import lombok.RequiredArgsConstructor;
import org.example.service.dto.request.AdminLoginServiceRequest;
import org.example.usecase.AdminUseCase;
import org.example.user.service.dto.request.AdminLoginServiceRequest;
import org.springframework.stereotype.Service;

@Service
Expand Down
Loading

0 comments on commit dccca59

Please sign in to comment.