Skip to content

Commit c058788

Browse files
committed
feat: 마음 기록 업로드 기능 구현 완료
1 parent 97b0663 commit c058788

File tree

14 files changed

+316
-0
lines changed

14 files changed

+316
-0
lines changed

backend/ongi/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ repositories {
2424
}
2525

2626
dependencies {
27+
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:${springCloudAwsVersion}")
28+
implementation 'io.awspring.cloud:spring-cloud-aws-starter'
29+
implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3'
30+
2731
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2832
implementation 'org.springframework.boot:spring-boot-starter-security'
2933
implementation 'org.springframework.boot:spring-boot-starter-validation'
@@ -33,6 +37,7 @@ dependencies {
3337
compileOnly 'org.projectlombok:lombok'
3438
annotationProcessor 'org.projectlombok:lombok'
3539
runtimeOnly 'com.mysql:mysql-connector-j'
40+
3641
testImplementation 'org.springframework.boot:spring-boot-starter-test'
3742
testImplementation 'org.springframework.security:spring-security-test'
3843
testImplementation 'com.h2database:h2'

backend/ongi/gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
springCloudAwsVersion = 3.4.0
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package ongi.common;
2+
3+
import io.micrometer.common.lang.NonNull;
4+
import java.util.Optional;
5+
import ongi.security.CustomUserDetails;
6+
import ongi.user.entity.User;
7+
import org.springframework.data.domain.AuditorAware;
8+
import org.springframework.security.core.Authentication;
9+
import org.springframework.security.core.context.SecurityContextHolder;
10+
import org.springframework.stereotype.Component;
11+
12+
@Component
13+
public class AuditorAwareImpl implements AuditorAware<User> {
14+
15+
@Override
16+
@NonNull
17+
public Optional<User> getCurrentAuditor() {
18+
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
19+
if (authentication == null || !authentication.isAuthenticated()) {
20+
return Optional.empty();
21+
}
22+
23+
Object principal = authentication.getPrincipal();
24+
if (principal instanceof CustomUserDetails customUserDetails) {
25+
return Optional.of(customUserDetails.getUser());
26+
}
27+
return Optional.empty();
28+
}
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package ongi.common.entity;
2+
3+
import jakarta.persistence.Column;
4+
import jakarta.persistence.EntityListeners;
5+
import jakarta.persistence.FetchType;
6+
import jakarta.persistence.ManyToOne;
7+
import jakarta.persistence.MappedSuperclass;
8+
import java.time.LocalDateTime;
9+
import lombok.Getter;
10+
import ongi.user.entity.User;
11+
import org.springframework.data.annotation.CreatedBy;
12+
import org.springframework.data.annotation.CreatedDate;
13+
import org.springframework.data.annotation.LastModifiedBy;
14+
import org.springframework.data.annotation.LastModifiedDate;
15+
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
16+
17+
@MappedSuperclass
18+
@EntityListeners(AuditingEntityListener.class)
19+
@Getter
20+
public class BaseEntity {
21+
@CreatedDate
22+
@Column(nullable = false, updatable = false)
23+
protected LocalDateTime createdAt;
24+
25+
@LastModifiedDate
26+
@Column(nullable = false)
27+
protected LocalDateTime updatedAt;
28+
29+
@CreatedBy
30+
@ManyToOne(fetch = FetchType.LAZY)
31+
protected User createdBy;
32+
33+
@LastModifiedBy
34+
@ManyToOne(fetch = FetchType.LAZY)
35+
protected User updatedBy;
36+
}

backend/ongi/src/main/java/ongi/exception/GlobalExceptionHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ public ResponseEntity<ErrorResponse> handleValidationError(
5656
.body(new ErrorResponse(ErrorStatus.VALIDATION_ERROR.getCode(), message));
5757
}
5858

59+
@ExceptionHandler(IllegalArgumentException.class)
60+
public ResponseEntity<ErrorResponse> handleIllegalArgument() {
61+
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
62+
.body(new ErrorResponse(ErrorStatus.VALIDATION_ERROR.getCode(),
63+
ErrorStatus.VALIDATION_ERROR.getDefaultMessage()));
64+
}
65+
5966
@ExceptionHandler(HttpMessageNotReadableException.class)
6067
public ResponseEntity<ErrorResponse> handleBodyMissing() {
6168
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package ongi.maum_log.controller;
2+
3+
import jakarta.validation.Valid;
4+
import lombok.AllArgsConstructor;
5+
import ongi.maum_log.dto.MaumLogPresignedResponseDto;
6+
import ongi.maum_log.dto.MaumLogUploadRequestDto;
7+
import ongi.maum_log.service.MaumLogService;
8+
import ongi.security.CustomUserDetails;
9+
import org.springframework.http.ResponseEntity;
10+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
11+
import org.springframework.web.bind.annotation.GetMapping;
12+
import org.springframework.web.bind.annotation.PostMapping;
13+
import org.springframework.web.bind.annotation.RequestBody;
14+
import org.springframework.web.bind.annotation.RequestMapping;
15+
import org.springframework.web.bind.annotation.RestController;
16+
import software.amazon.awssdk.http.HttpStatusCode;
17+
18+
@RestController
19+
@RequestMapping("/maum-log")
20+
@AllArgsConstructor
21+
public class MaumLogController {
22+
23+
private final MaumLogService maumLogService;
24+
25+
@GetMapping("/presigned-url")
26+
public ResponseEntity<MaumLogPresignedResponseDto> getPresignedUrl(
27+
@AuthenticationPrincipal CustomUserDetails userDetails) {
28+
return ResponseEntity.ok(maumLogService.getPresignedPutUrl(userDetails));
29+
}
30+
31+
@PostMapping
32+
public ResponseEntity<Void> createMaumLog(
33+
@AuthenticationPrincipal CustomUserDetails userDetails,
34+
@Valid @RequestBody MaumLogUploadRequestDto request) {
35+
maumLogService.createMaumLog(userDetails, request);
36+
return ResponseEntity.status(HttpStatusCode.CREATED).build();
37+
}
38+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package ongi.maum_log.dto;
2+
3+
public record MaumLogPresignedResponseDto(
4+
String presignedUrl,
5+
String fileName
6+
) {
7+
public static MaumLogPresignedResponseDto from(String presignedUrl, String fileName) {
8+
return new MaumLogPresignedResponseDto(presignedUrl, fileName);
9+
}
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package ongi.maum_log.dto;
2+
3+
import java.util.List;
4+
import ongi.maum_log.enums.Emotion;
5+
6+
public record MaumLogUploadRequestDto(
7+
String fileName,
8+
String fileExtension,
9+
String location,
10+
String comment,
11+
List<Emotion> emotions
12+
) {
13+
14+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package ongi.maum_log.entity;
2+
3+
import jakarta.persistence.Column;
4+
import jakarta.persistence.Entity;
5+
import jakarta.persistence.EnumType;
6+
import jakarta.persistence.Enumerated;
7+
import jakarta.persistence.GeneratedValue;
8+
import jakarta.persistence.GenerationType;
9+
import jakarta.persistence.Id;
10+
import java.util.List;
11+
import lombok.AllArgsConstructor;
12+
import lombok.Builder;
13+
import lombok.NoArgsConstructor;
14+
import ongi.common.entity.BaseEntity;
15+
import ongi.maum_log.enums.Emotion;
16+
17+
@Entity
18+
@Builder
19+
@NoArgsConstructor
20+
@AllArgsConstructor
21+
public class MaumLog extends BaseEntity {
22+
@Id
23+
@GeneratedValue(strategy = GenerationType.IDENTITY)
24+
private Long id;
25+
26+
@Column(nullable = false, unique = true)
27+
private String fileName;
28+
29+
@Column(nullable = false)
30+
private String fileExtension;
31+
32+
private String location;
33+
34+
private String comment;
35+
36+
@Column(nullable = false)
37+
@Enumerated(EnumType.STRING)
38+
private List<Emotion> emotions;
39+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ongi.maum_log.enums;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
6+
@Getter
7+
@AllArgsConstructor
8+
public enum Emotion {
9+
JOYFUL("즐거움"),
10+
EXCITED("설렘"),
11+
RELIEVED("마음이 놓임"),
12+
SMIRK("뿌듯함"),
13+
SADNESS("서글픔"),
14+
STIFLED("답답함"),
15+
WARMHEARTED("마음이 따뜻"),
16+
EMPTY("허전함"),
17+
REFRESHING("시원섭섭함"),
18+
THRILL("들뜸"),
19+
ANNOYED("짜증남"),
20+
SORROWFUL("서운함"),
21+
WORRIED("걱정스러움"),
22+
MISSING("그리움"),
23+
DEPRESSED("울적함"),
24+
RELAXED("여유로움"),
25+
CONFUSED("마음이 복잡함"),
26+
CHEERFUL("기운이 남"),
27+
COZY("포근함");
28+
29+
private final String description;
30+
}

0 commit comments

Comments
 (0)