Skip to content

Commit 56987f2

Browse files
authored
Merge pull request #16 from Neighbors-dev/develop
[FEAT] 편지 생성 API 구현
2 parents 8242ba2 + 2ebb35f commit 56987f2

31 files changed

Lines changed: 466 additions & 47 deletions

src/main/java/com/neighbors/tohero/SantaApplication.java renamed to src/main/java/com/neighbors/tohero/ToHeroApplication.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
@SpringBootApplication
99
@EnableJpaAuditing
1010
@EntityScan(basePackages = "com.neighbors.tohero.infrastructure.entity")
11-
public class SantaApplication {
11+
public class ToHeroApplication {
1212

1313
public static void main(String[] args) {
14-
SpringApplication.run(SantaApplication.class, args);
14+
SpringApplication.run(ToHeroApplication.class, args);
1515
}
1616

1717
}

src/main/java/com/neighbors/tohero/application/baseResponse/BaseResponseMessage.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ public enum BaseResponseMessage {
3939
//address
4040
주소_검색_쿼리의_길이는_1부터_50까지만_가능합니다("주소 검색 쿼리의 길이는 1부터 50까지만 가능합니다"),
4141
일치하는_관할서_정보가_없습니다("일치하는 관할서 정보가 없습니다"),
42-
주소_검색이_성공적으로_응답되었습니다("주소 검색이 성공적으로 응답되었습니다");
42+
주소_검색이_성공적으로_응답되었습니다("주소 검색이 성공적으로 응답되었습니다"),
4343

44+
//letter
45+
편지가_성공적으로_생성_되었습니다("편지가 성공적으로 생성 되었습니다"),
46+
편지_생성이_실패_했습니다("편지 생성이 실패했습니다");
4447

4548
private final String message;
4649

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
11
package com.neighbors.tohero.application.letter.dto;
22

3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import com.neighbors.tohero.common.enums.TargetJob;
5+
import jakarta.validation.constraints.NotBlank;
6+
import jakarta.validation.constraints.NotNull;
7+
import org.hibernate.validator.constraints.Length;
8+
39
public record CreateLetterRequest (
10+
@NotBlank
11+
@Length(min =1, max = 1000)
12+
String content,
13+
14+
@JsonInclude(JsonInclude.Include.NON_NULL)
15+
TargetJob targetJob,
16+
17+
@JsonInclude(JsonInclude.Include.NON_NULL)
18+
Long addressId,
19+
20+
@JsonInclude(JsonInclude.Include.NON_NULL)
21+
@Length(min = 1, max = 100)
22+
String heroName,
23+
24+
@JsonInclude(JsonInclude.Include.NON_NULL)
25+
Boolean readingAlarm,
426

27+
@NotNull
28+
boolean isPublic
529
){
630
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.neighbors.tohero.application.letter.dto;
2+
3+
public record CreateLetterResponse(
4+
long createdLetterId
5+
) {
6+
}
Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,86 @@
11
package com.neighbors.tohero.application.letter.service;
22

33
import com.neighbors.tohero.application.baseResponse.BaseResponse;
4+
import com.neighbors.tohero.application.baseResponse.BaseResponseMessage;
5+
import com.neighbors.tohero.application.baseResponse.BaseResponseStatus;
46
import com.neighbors.tohero.application.letter.dto.CreateLetterRequest;
7+
import com.neighbors.tohero.application.letter.dto.CreateLetterResponse;
8+
import com.neighbors.tohero.common.enums.Role;
9+
import com.neighbors.tohero.common.exception.address.AddressException;
10+
import com.neighbors.tohero.common.exception.letter.LetterException;
11+
import com.neighbors.tohero.common.jwt.JwtUserDetails;
12+
import com.neighbors.tohero.domain.domain.address.service.GetAddress;
13+
import com.neighbors.tohero.domain.domain.letter.service.CreateLetter;
514
import lombok.RequiredArgsConstructor;
615
import org.springframework.stereotype.Service;
716

17+
import java.util.ArrayList;
18+
import java.util.List;
19+
820
@Service
921
@RequiredArgsConstructor
1022
public class LetterService {
1123

12-
public BaseResponse createLetter(CreateLetterRequest createLetterRequest) {
13-
return null;
24+
private final CreateLetter createLetter;
25+
private final GetAddress getAddress;
26+
27+
public BaseResponse<CreateLetterResponse> createLetter(final JwtUserDetails jwtUserDetail, final CreateLetterRequest createLetterRequest) {
28+
29+
throwExceptionIfAddressIsNotExist(createLetterRequest.addressId());
30+
31+
if(jwtUserDetail.getRole() == Role.GUEST){
32+
return createGuestLetter(jwtUserDetail.getNickname(), createLetterRequest);
33+
}
34+
long createdLetterId = createLetter.createLetter(
35+
jwtUserDetail.getUserId(),
36+
jwtUserDetail.getNickname(),
37+
createLetterRequest
38+
);
39+
40+
throwIfLetterNotCreate(createdLetterId);
41+
42+
return new BaseResponse<>(
43+
BaseResponseStatus.OK,
44+
BaseResponseMessage.편지가_성공적으로_생성_되었습니다.getMessage(),
45+
new CreateLetterResponse(createdLetterId)
46+
);
47+
}
48+
49+
private BaseResponse<CreateLetterResponse> createGuestLetter(final String nickname, final CreateLetterRequest createLetterRequest) {
50+
long createdLetterId = createLetter.createGuestLetter(
51+
nickname,
52+
createLetterRequest.content(),
53+
createLetterRequest.targetJob(),
54+
createLetterRequest.addressId(),
55+
createLetterRequest.heroName(),
56+
createLetterRequest.isPublic()
57+
);
58+
59+
throwIfLetterNotCreate(createdLetterId);
60+
61+
return new BaseResponse<>(
62+
BaseResponseStatus.OK,
63+
BaseResponseMessage.편지가_성공적으로_생성_되었습니다.getMessage(),
64+
new CreateLetterResponse(createdLetterId)
65+
);
66+
}
67+
68+
private void throwExceptionIfAddressIsNotExist(final Long addressId){
69+
if(addressId == null) {return ;}
70+
if(!getAddress.existAddressById(addressId)){
71+
throw new AddressException(
72+
BaseResponseStatus.NO_RESULT,
73+
BaseResponseMessage.일치하는_관할서_정보가_없습니다.getMessage()
74+
);
75+
}
76+
}
77+
78+
private void throwIfLetterNotCreate(final long createdLetterId){
79+
if(createdLetterId == 0){
80+
throw new LetterException(
81+
BaseResponseStatus.BAD_REQUEST,
82+
BaseResponseMessage.편지_생성이_실패_했습니다.getMessage()
83+
);
84+
}
1485
}
1586
}

src/main/java/com/neighbors/tohero/application/mainPage/dto/OpenedLetter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ public record OpenedLetter(
88
String content
99
){
1010
public static OpenedLetter from(Letter letter){
11-
return new OpenedLetter(letter.getTargetName(), letter.getFromUserName(), letter.getLetterContent());
11+
return new OpenedLetter(letter.getTargetName(), letter.getWriter(), letter.getLetterContent());
1212
}
1313
}

src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
2020
import org.springframework.web.filter.CorsFilter;
2121

22+
import java.util.ArrayList;
2223
import java.util.List;
2324

2425
@Configuration
@@ -55,9 +56,6 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
5556
.formLogin(AbstractHttpConfigurer::disable) //form login 비활성화
5657
.httpBasic(AbstractHttpConfigurer::disable)//http 기본 인증 비활성화
5758
.cors(Customizer.withDefaults())
58-
.authorizeHttpRequests(auth -> auth
59-
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
60-
.anyRequest().authenticated())
6159
.sessionManagement(session -> {
6260
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
6361
})
@@ -75,7 +73,11 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
7573
public CorsFilter corsFilter() {
7674
CorsConfiguration config = new CorsConfiguration();
7775
config.setAllowCredentials(true); // 쿠키 포함 허용
78-
config.setAllowedOrigins(List.of("http://localhost:5173", "https://glittery-madeleine-215e2f.netlify.app")); // 허용할 도메인
76+
// 여러 도메인 허용
77+
List<String> allowedOrigins = new ArrayList<>();
78+
allowedOrigins.add("https://glittery-madeleine-215e2f.netlify.app");
79+
allowedOrigins.add("https://tohero.co.kr");
80+
config.setAllowedOrigins(allowedOrigins); // 여러 도메인 추가
7981
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 허용할 HTTP 메서드
8082
config.setAllowedHeaders(List.of("*")); // 모든 헤더 허용
8183
config.setExposedHeaders(List.of("Authorization")); // 노출할 헤더

src/main/java/com/neighbors/tohero/common/config/SwaggerConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public OpenAPI openAPI() {
2929
.addSecurityItem(securityRequirement)
3030
.components(components)
3131
.servers(Arrays.asList(new Server().url("https://tohero.co.kr"),
32-
new Server().url("http://localhost:8080"),new Server().url("https://tohero.co.kr")));
32+
new Server().url("http://localhost:8080")));
3333
}
3434
private Info apiInfo() {
3535
return new Info()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.neighbors.tohero.common.exception.letter;
2+
3+
import com.neighbors.tohero.application.baseResponse.BaseResponseStatus;
4+
5+
public class LetterException extends RuntimeException {
6+
7+
private final BaseResponseStatus status;
8+
private final String message;
9+
10+
public LetterException(BaseResponseStatus status, String message) {
11+
super(message);
12+
this.status = status;
13+
this.message = message;
14+
}
15+
}

src/main/java/com/neighbors/tohero/common/jwt/JwtProvider.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public AuthTokens createToken(JwtUserDetails jwtUserDetails) {
3535

3636
claims.put("role", jwtUserDetails.getRole());
3737
if(jwtUserDetails.getRole() == Role.USER) {
38-
claims.put("id", jwtUserDetails.getUserId());
38+
claims.put("userId", jwtUserDetails.getUserId());
3939
claims.put("email", jwtUserDetails.getEmail());
4040
}
4141

@@ -105,7 +105,7 @@ public void loggingToken(String token) {
105105

106106
public Long getId(String token) {
107107
Claims claims = getBody(token);
108-
return Long.parseLong(claims.get("id").toString());
108+
return Long.parseLong(claims.get("userId").toString());
109109
}
110110

111111
private Claims getBody(String token) {
@@ -131,4 +131,14 @@ public JwtUserDetails getJwtUserDetails(String token) {
131131
.build();
132132

133133
}
134+
135+
public JwtUserDetails getGuestJwtUserDetails(String token) {
136+
Claims claims = getBody(token);
137+
138+
return JwtUserDetails.builder()
139+
.nickname(String.valueOf(claims.getSubject()))
140+
.role(Role.valueOf(claims.get("role").toString()))
141+
.build();
142+
143+
}
134144
}

0 commit comments

Comments
 (0)