This commit is contained in:
ondal
2025-02-12 21:24:01 +09:00
commit 7a4f60c842
222 changed files with 3018 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'jakarta.persistence:jakarta.persistence-api'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.google.code.gson:gson'
}
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
Manifest-Version: 1.0
@@ -0,0 +1,110 @@
package com.unicorn.lifesub.common.aop;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Map;
@Aspect //Disable하려면 리마크 함
@Component
@Slf4j
@SuppressWarnings("unused")
public class LoggingAspect {
private final Gson gson = new Gson();
@Pointcut("execution(* com.unicorn..*.*(..))")
private void loggingPointcut() {}
@Before("loggingPointcut()")
public void logMethodStart(JoinPoint joinPoint) {
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
String argString = getArgumentString(args);
log.info("[START] {}.{} - Args: [{}]", className, methodName, argString);
}
@AfterReturning(pointcut = "loggingPointcut()", returning = "result")
public void logMethodEnd(JoinPoint joinPoint, Object result) {
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
String resultString = getResultString(result);
log.info("[END] {}.{} - Result: {}", className, methodName, resultString);
}
@AfterThrowing(pointcut = "loggingPointcut()", throwing = "exception")
public void logMethodException(JoinPoint joinPoint, Exception exception) {
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
log.error("[EXCEPTION] {}.{} - Exception: {}", className, methodName, exception.getMessage());
}
private String getArgumentString(Object[] args) {
StringBuilder argString = new StringBuilder();
for (Object arg : args) {
if (arg != null) {
if (arg instanceof String || arg instanceof Number || arg instanceof Boolean) {
argString.append(arg).append(", ");
} else if (arg instanceof Collection) {
argString.append(((Collection<?>) arg).size()).append(" elements, ");
} else if (arg instanceof Map) {
argString.append(((Map<?, ?>) arg).size()).append(" entries, ");
} else {
argString.append(arg);
/*
try {
String jsonString = gson.toJson(arg);
argString.append(jsonString).append(", ");
} catch (Exception e) {
log.warn("JSON serialization failed for argument: {}", arg);
argString.append("JSON serialization failed, ");
}
*/
}
} else {
argString.append("null, ");
}
}
if (!argString.isEmpty()) {
argString.setLength(argString.length() - 2);
}
return argString.toString();
}
private String getResultString(Object result) {
if (result != null) {
if (result instanceof String || result instanceof Number || result instanceof Boolean) {
return result.toString();
} else if (result instanceof Collection) {
return ((Collection<?>) result).size() + " elements";
} else if (result instanceof Map) {
return ((Map<?, ?>) result).size() + " entries";
} else {
return result.toString();
/*
try {
return gson.toJson(result);
} catch (Exception e) {
log.warn("JSON serialization failed for result: {}", result);
return "JSON serialization failed";
}
*/
}
} else {
return "null";
}
}
}
@@ -0,0 +1,29 @@
package com.unicorn.lifesub.common.dto;
import com.unicorn.lifesub.common.exception.ErrorCode;
import lombok.Getter;
import java.time.LocalDateTime;
@Getter
public class ApiResponse<T> {
private final int status;
private final String message;
private final T data;
private final LocalDateTime timestamp;
private ApiResponse(int status, String message, T data) {
this.status = status;
this.message = message;
this.data = data;
this.timestamp = LocalDateTime.now();
}
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(200, "Success", data);
}
public static <T> ApiResponse<T> error(ErrorCode errorCode) {
return new ApiResponse<>(errorCode.getStatus(), errorCode.getMessage(), null);
}
}
@@ -0,0 +1,14 @@
package com.unicorn.lifesub.common.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
@Builder
@Getter
@AllArgsConstructor
public class JwtTokenDTO {
private String accessToken;
private String refreshToken;
}
@@ -0,0 +1,10 @@
package com.unicorn.lifesub.common.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class JwtTokenRefreshDTO {
private String refreshToken;
}
@@ -0,0 +1,10 @@
package com.unicorn.lifesub.common.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class JwtTokenVerifyDTO {
private String token;
}
@@ -0,0 +1,21 @@
package com.unicorn.lifesub.common.entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseTimeEntity {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@@ -0,0 +1,13 @@
package com.unicorn.lifesub.common.exception;
import lombok.Getter;
@Getter
public class BusinessException extends RuntimeException {
private final ErrorCode errorCode;
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
}
@@ -0,0 +1,33 @@
package com.unicorn.lifesub.common.exception;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum ErrorCode {
// Common
INVALID_INPUT_VALUE(400, "Invalid input value"),
INTERNAL_SERVER_ERROR(500, "Internal server error"),
// Member
MEMBER_NOT_FOUND(404, "Member not found"),
INVALID_CREDENTIALS(401, "Invalid credentials"),
TOKEN_EXPIRED(401, "Token expired"),
SIGNATURE_VERIFICATION_EXCEPTION(20, "서명 검증 실패"),
ALGORITHM_MISMATCH_EXCEPTION(30, "알고리즘 불일치"),
INVALID_CLAIM_EXCEPTION(40, "유효하지 않은 클레임"),
// Subscription
SUBSCRIPTION_NOT_FOUND(404, "Subscription not found"),
ALREADY_SUBSCRIBED(400, "Already subscribed to this service"),
// Recommend
NO_SPENDING_DATA(404, "No spending data found"),
// UnDefined
UNDIFINED_ERROR(0, "정의되지 않은 에러");
private final int status;
private final String message;
}
@@ -0,0 +1,13 @@
package com.unicorn.lifesub.common.exception;
import lombok.Getter;
@Getter
public class InfraException extends RuntimeException {
private final ErrorCode errorCode;
public InfraException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
}