Skip to content
Closed
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
5 changes: 4 additions & 1 deletion .github/workflows/cd-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: CI/CD
on:
# push:
# branches: [ "feature/seungmin" ]

#push:
# branches: [ "feature/seungin" ]
pull_request:
branches: [ "main" ]

Expand Down Expand Up @@ -186,7 +189,7 @@ jobs:
run: |
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\": \"✅ EC2 배포 성공! (브랜치: develop)\"}" \
-d "{\"content\": \"✅ EC2 배포 성공! (브랜치: main)\"}" \
${{ secrets.DISCORD_WEBHOOK_URL }}

# ❌ 배포 실패 알림 (Discord)
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/wayble/server/ServerApplication.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.wayble.server;

import com.wayble.server.direction.external.tmap.TMapProperties;
import com.wayble.server.direction.external.kric.KricProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration;
Expand All @@ -16,7 +17,7 @@
@EnableJpaAuditing
@EnableScheduling
@EnableElasticsearchRepositories(basePackages = "com.wayble.server.explore.repository")
@EnableConfigurationProperties(TMapProperties.class)
@EnableConfigurationProperties({TMapProperties.class, KricProperties.class})
@EntityScan(basePackages = "com.wayble.server")
public class ServerApplication {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class RefreshToken {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false, unique = true) // 1인 1토큰
@Column(name = "user_id", nullable = false, unique = true)
private Long userId;

@Column(nullable = false)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
"/api/v1/users/reissue",
"/api/v1/users/logout",
"/api/v1/auth/**",
"/api/v1/directions/**",
"/swagger-ui/**",
"/v3/api-docs/**",
"/",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.wayble.server.common.config;

import com.wayble.server.direction.external.tmap.TMapProperties;
import com.wayble.server.direction.external.kric.KricProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -11,6 +12,7 @@
public class WebClientConfig {

private final TMapProperties tMapProperties;
private final KricProperties kricProperties;

@Bean
public WebClient webClient() {
Expand All @@ -24,4 +26,11 @@ public WebClient tMapWebClient() {
.baseUrl(tMapProperties.baseUrl())
.build();
}

@Bean
public WebClient kricWebClient() {
return WebClient.builder()
.baseUrl(kricProperties.baseUrl())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.wayble.server.common.dto;

import java.util.List;

public record DiscordWebhookPayload(
String content,
List<Embed> embeds
) {
public record Embed(
String title,
String description,
String timestamp,
List<Field> fields
) {
public record Field(String name, String value, boolean inline) {}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
package com.wayble.server.common.exception;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wayble.server.common.dto.DiscordWebhookPayload;
import com.wayble.server.common.response.CommonResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.http.*;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import java.time.Instant;
import java.util.List;

@Slf4j
@ControllerAdvice
@RequiredArgsConstructor
public class GlobalExceptionHandler {
Expand All @@ -19,11 +30,19 @@ public class GlobalExceptionHandler {

private final RestTemplate restTemplate = new RestTemplate();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

RestTemplate을 빈으로 주입받는 것을 권장

RestTemplate을 직접 인스턴스화하는 대신 빈으로 주입받으면 테스트 용이성과 설정 관리가 개선됩니다.

-private final RestTemplate restTemplate = new RestTemplate();
+private final RestTemplate restTemplate;

생성자나 @Autowired를 통해 주입받거나, WebClient 사용을 고려해보세요. PR 목적에서 WebClient 도입을 언급했으므로 일관성을 위해 여기서도 WebClient 사용이 적절할 수 있습니다.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/common/exception/GlobalExceptionHandler.java
at line 31, the RestTemplate is instantiated directly, which is not recommended.
Refactor the code to inject RestTemplate as a Spring bean via constructor
injection or @Autowired to improve testability and configuration management.
Alternatively, considering the PR mentions WebClient adoption, replace
RestTemplate with a WebClient bean injected similarly for consistency.


@Value("${discord.webhook-url}")
private String discordWebhookUrl;

@Autowired
private Environment env;

@ExceptionHandler(ApplicationException.class)
public ResponseEntity<CommonResponse> handleApplicationException(ApplicationException e, WebRequest request) {
CommonResponse commonResponse = CommonResponse.error(e.getErrorCase());

HttpStatus status = HttpStatus.valueOf(e.getErrorCase().getHttpStatusCode());
sendToDiscord(e, request, status);

return ResponseEntity
.status(e.getErrorCase().getHttpStatusCode())
.body(commonResponse);
Expand All @@ -36,8 +55,47 @@ public ResponseEntity<CommonResponse> handleValidException(BindingResult binding
String message = bindingResult.getAllErrors().get(0).getDefaultMessage();
CommonResponse commonResponse = CommonResponse.error(400, message);

sendToDiscord(ex, request, HttpStatus.BAD_REQUEST);
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(commonResponse);
}

private void sendToDiscord(Exception ex, WebRequest request, HttpStatus status) {
String path = ((ServletWebRequest) request).getRequest().getRequestURI();
String timestamp = Instant.now().toString();

if (!env.acceptsProfiles(Profiles.of("develop"))) {
log.info("현재 active 프로파일이 develop가 아니므로 Discord 알림을 보내지 않습니다.");
return;
}

// Embed 필드 구성
DiscordWebhookPayload.Embed embed = new DiscordWebhookPayload.Embed(
"🚨 서버 에러 발생",
"```" + ex.getMessage() + "```",
timestamp,
List.of(
new DiscordWebhookPayload.Embed.Field("URL", path, false),
new DiscordWebhookPayload.Embed.Field("Status", status.toString(), true),
new DiscordWebhookPayload.Embed.Field("Time", timestamp, true),
new DiscordWebhookPayload.Embed.Field("Exception", ex.getClass().getSimpleName(), true)
)
);
DiscordWebhookPayload payload = new DiscordWebhookPayload(null, List.of(embed));

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

try{
restTemplate.postForEntity(
discordWebhookUrl,
new HttpEntity<>(payload, headers),
String.class
);
log.info("send to Discord webhook: {} complete", payload);
} catch (Exception e){
log.error(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
Expand Down Expand Up @@ -51,8 +51,8 @@ public class TransportationController {
)
}
)
@GetMapping("/")
public CommonResponse<TransportationResponseDto> getDirections(
@PostMapping("/")
public CommonResponse<TransportationResponseDto> findDirections(
@RequestBody TransportationRequestDto request
){
TransportationResponseDto data = transportationService.findRoutes(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.wayble.server.direction.dto;

import com.wayble.server.direction.entity.DirectionType;
import io.micrometer.common.lang.Nullable;
import org.springframework.lang.Nullable;
import io.swagger.v3.oas.annotations.media.Schema;

import java.time.ZonedDateTime;
import java.util.List;

@Schema(description = "대중교통 길찾기 응답 DTO")
Expand All @@ -14,8 +13,8 @@ public record TransportationResponseDto(
) {
public record Step(
DirectionType mode, // 예: START, WALK, SUBWAY, BUS, FINISH
String routeName,// mode에 따라 null일 수 있음
NodeInfo information, // mode에 따라 null일 수 있음
@Nullable String routeName,
@Nullable NodeInfo information,
String from,
String to
) {}
Expand All @@ -33,6 +32,6 @@ public record NodeInfo(

public record LocationInfo(
Double latitude,
Double Longtitude
Double Longitude
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

@Entity
@Getter
@Builder(access = AccessLevel.PUBLIC)
@Builder(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "edge")
Expand All @@ -34,4 +34,14 @@ public class Edge {
@ManyToOne
@JoinColumn(name = "route_id")
private Route route;

public static Edge createEdge(Long id, Node startNode, Node endNode, DirectionType edgeType) {
return Edge.builder()
.id(id)
.edgeType(edgeType)
.startNode(startNode)
.endNode(endNode)
.route(null)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ public class Node {
@OneToOne(mappedBy = "node")
private Facility facility_id;

public Node(Long id, String stationName, double latitude, double longitude) {
public Node(Long id, String stationName, DirectionType nodeType, double latitude, double longitude) {
this.id = id;
this.stationName = stationName;
this.nodeType = nodeType;
this.latitude = latitude;
this.longitude = longitude;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public enum DirectionErrorCase implements ErrorCase {

HISTORY_NOT_FOUND(400, 4004, "검색 기록이 없습니다."),
DISTANCE_TOO_FAR(400, 4002, "거리가 30km 이상입니다."),
PATH_NOT_FOUND(400, 4001, "해당하는 경로를 찾을 수 없습니다.");

private final Integer httpStatusCode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.wayble.server.direction.external.kric;

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

@ConfigurationProperties(prefix = "kric.api")
public record KricProperties(
String key,
String baseUrl
) {
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wayble.server.direction.dto.toilet;
package com.wayble.server.direction.external.kric.dto;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wayble.server.direction.dto.toilet;
package com.wayble.server.direction.external.kric.dto;

import lombok.Getter;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wayble.server.direction.dto.toilet;
package com.wayble.server.direction.external.kric.dto;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.wayble.server.direction.repository;

import com.wayble.server.direction.entity.transportation.Facility;
import org.springframework.data.jpa.repository.JpaRepository;

public interface FacilityRepository extends JpaRepository<Facility, Long> {
import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

public interface FacilityRepository extends JpaRepository<Facility, Long> {
Optional<Facility> findByNodeId(Long nodeId);
}
21 changes: 0 additions & 21 deletions src/main/java/com/wayble/server/direction/service/EdgeService.java

This file was deleted.

Loading
Loading