Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
f4aa92f
chore: 데이터베이스 마이그레이션 V21~V27 복원
Sehi55 Jul 23, 2026
4d96c4c
feat: Gift Biz 상품 동기화 및 목록 조회 추가
Sehi55 Jul 23, 2026
ba7c467
feat: 메시지 요청에 선택 기프티콘 연결
Sehi55 Jul 23, 2026
eb775a1
feat: Gift Biz 템플릿 토큰 관리 추가
Sehi55 Jul 24, 2026
af187c6
security: Gift Biz 템플릿 토큰 암호화
Sehi55 Jul 24, 2026
11cba0f
feat: 메시지 수락 후 Gift Biz 선물 주문 요청
Sehi55 Jul 24, 2026
d0de5c8
feat: 기프티콘 요청 유상 팅 보류 처리
Sehi55 Jul 24, 2026
79a8a26
feat: 관리자 기프티콘 목록 검색 지원
Sehi55 Jul 24, 2026
fa4a159
feat: 관리자 기프티콘 관리 화면 추가
Sehi55 Jul 24, 2026
7e96c0b
feat: 관리자 기프티콘 수동 동기화 추가
Sehi55 Jul 24, 2026
fbbe044
feat: 팅 거래 원장 및 혼합 결제 기록 추가
Sehi55 Jul 24, 2026
0e9c075
refactor: 기프티콘 주문 토큰 중복 저장 제거
Sehi55 Jul 24, 2026
331df9a
feat: 기프티콘 발신자명에 프로필 닉네임 추가
Sehi55 Jul 24, 2026
9b5154d
fix: 기프티콘 연동 입력 검증 강화
Sehi55 Aug 6, 2026
b9fd218
refactor: 기프티콘 상태 설명 추가
Sehi55 Aug 6, 2026
3215b8d
feat: 기프티콘 원화 판매가 정책 추가
Sehi55 Aug 6, 2026
cf6b319
refactor: 기프티콘 주문 시도 트랜잭션 분리
Sehi55 Aug 6, 2026
c1982c3
fix: 0원 팅 거래 원장 생성 방지
Sehi55 Aug 6, 2026
75eb538
feat: 토스페이먼츠 결제 어댑터 추가
Sehi55 Aug 6, 2026
0ff4a84
feat: 기프티콘 결제 도메인 모델 추가
Sehi55 Aug 6, 2026
fe1a0e5
feat: 기프티콘 결제 상태 전이 추가
Sehi55 Aug 6, 2026
16d2b4a
refactor: 메시지 기프티콘을 원화 결제와 연결
Sehi55 Aug 6, 2026
87b106b
feat: 결제 완료 후 기프티콘 메시지 자동 생성
Sehi55 Aug 6, 2026
31be04e
feat: 기프티콘 결제 API 추가
Sehi55 Aug 6, 2026
4e8cb6e
feat: 메시지 거절 후 결제 환불 처리
Sehi55 Aug 6, 2026
c46725a
feat: 결제 메시지 생성 재시도 추가
Sehi55 Aug 6, 2026
b138cb9
feat: 미사용 결제 자동 환불 재시도 추가
Sehi55 Aug 6, 2026
33a21e7
feat: 결제 관리자 조작 감사 유형 추가
Sehi55 Aug 6, 2026
a16cdbb
feat: 관리자 결제 이상 사유 응답 정의
Sehi55 Aug 6, 2026
268bd3a
feat: 관리자 이상 결제 처리 서비스 추가
Sehi55 Aug 6, 2026
58e4a07
feat: 관리자 이상 결제 처리 API 추가
Sehi55 Aug 6, 2026
1c79680
test: 관리자 이상 결제 처리 검증
Sehi55 Aug 6, 2026
0f4757a
feat: 관리자 결제 처리 화면 구성
Sehi55 Aug 6, 2026
83db01a
feat: 관리자 결제 처리 화면 동작 추가
Sehi55 Aug 6, 2026
3efefbc
fix: 활성 채팅 멤버 중복 데이터 정리
Sehi55 Aug 6, 2026
3b44b78
fix: 원장 제약 추가 전 0원 거래 정리
Sehi55 Aug 6, 2026
b678708
feat: 채팅 기프티콘 주문 모델 추가
Sehi55 Aug 6, 2026
fe66c8e
feat: 채팅 기프티콘 결제 API 추가
Sehi55 Aug 6, 2026
d37db1e
feat: 기프티콘 접수 후 채팅 메시지 생성
Sehi55 Aug 6, 2026
a8f34b8
feat: 채팅 기프티콘 실패 환불 알림 추가
Sehi55 Aug 6, 2026
7fbb9bb
fix: 채팅 결제 자동 처리 대상 분리
Sehi55 Aug 6, 2026
5759090
fix: 서버 전용 채팅 타입 전송 차단
Sehi55 Aug 6, 2026
0496acd
test: 채팅 기프티콘 결제 준비 검증
Sehi55 Aug 6, 2026
781ac48
test: 채팅 기프티콘 주문 실패 검증
Sehi55 Aug 6, 2026
793fb07
test: 기프티콘 채팅 메시지 완료 검증
Sehi55 Aug 6, 2026
6af43fc
test: 기프티콘 실패 발신자 알림 검증
Sehi55 Aug 6, 2026
6d56603
test: 채팅 결제 스케줄러 제외 검증
Sehi55 Aug 6, 2026
6674213
merge: develop 브랜치 충돌 해결
Sehi55 Aug 6, 2026
b35696c
fix: 일반 메세지 요청 생성자 복원
Sehi55 Aug 6, 2026
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package mannabom_server.manabom.application.admin.dto.request;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class AdminConfigureGifticonTokenRequest {

@NotBlank(message = "templateToken은 필수입니다.")
@Size(max = 512, message = "templateToken은 512자를 초과할 수 없습니다.")
private String templateToken;

@NotBlank(message = "reason은 필수입니다.")
@Size(max = 500, message = "reason은 500자를 초과할 수 없습니다.")
private String reason;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package mannabom_server.manabom.application.admin.dto.request;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

public record AdminGifticonPaymentActionRequest(
@NotBlank(message = "reason은 필수입니다.")
@Size(max = 500, message = "reason은 500자를 초과할 수 없습니다.")
String reason
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;

@Getter
@NoArgsConstructor
public class AdminUpdatePolicyRequest {
@NotBlank(message = "key는 필수입니다.")
private String key;

private Integer value;
private BigDecimal value;

private boolean resetToDefault;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package mannabom_server.manabom.application.admin.dto.response;

import java.util.List;

public record AdminGifticonPaymentPageResponse(
List<AdminGifticonPaymentResponse> contents,
long totalCount,
int totalPages,
int page,
int size
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package mannabom_server.manabom.application.admin.dto.response;

import mannabom_server.manabom.domain.gifticon.enums.GifticonMessageCreationStatus;
import mannabom_server.manabom.domain.gifticon.enums.GifticonPaymentStatus;
import mannabom_server.manabom.domain.messageRequest.enums.MessageRequestStatus;

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

public record AdminGifticonPaymentResponse(
Long gifticonPaymentId,
String orderId,
String maskedPaymentKey,
Long userId,
Long targetProfileId,
Long gifticonProductId,
String productName,
int amount,
GifticonPaymentStatus paymentStatus,
String paymentStatusDescription,
GifticonMessageCreationStatus messageCreationStatus,
String messageCreationStatusDescription,
int messageCreationAttemptCount,
Instant lastMessageCreationAttemptAt,
String messageCreationFailureReason,
Long messageRequestId,
MessageRequestStatus messageRequestStatus,
int refundAttemptCount,
Instant lastRefundAttemptAt,
String paymentFailureReason,
Instant approvedAt,
Instant refundedAt,
Instant createdAt,
Instant updatedAt,
List<AttentionReason> attentionReasons,
String tossPaymentStatus,
Boolean tossStatusMismatch,
String tossVerificationError
) {
public record AttentionReason(
String code,
String description
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package mannabom_server.manabom.application.admin.dto.response;

import mannabom_server.manabom.domain.gifticon.entity.GifticonProduct;

import java.time.Instant;

public record AdminGifticonProductResponse(
Long gifticonProductId,
String templateTraceId,
String templateName,
String productName,
String brandName,
String productThumbnailImageUrl,
int productPrice,
int salePrice,
boolean available,
boolean templateTokenConfigured,
Instant lastSyncedAt
) {
public static AdminGifticonProductResponse from(GifticonProduct product) {
return new AdminGifticonProductResponse(
product.getGifticonProductId(),
String.valueOf(product.getTemplateTraceId()),
product.getTemplateName(),
product.getProductName(),
product.getBrandName(),
product.getProductThumbnailImageUrl(),
product.getProductPrice(),
product.getSalePrice(),
product.isAvailable(),
product.hasTemplateToken(),
product.getLastSyncedAt()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package mannabom_server.manabom.application.admin.dto.response;

import java.util.List;

public record AdminGifticonProductSliceResponse(
List<AdminGifticonProductResponse> contents,
Long nextCursor,
boolean hasNext
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package mannabom_server.manabom.application.admin.dto.response;

import java.time.Instant;

public record AdminGifticonSyncResponse(
int synchronizedCount,
Instant synchronizedAt
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package mannabom_server.manabom.application.admin.enums;

public enum GifticonPaymentAttentionReason {
REFUND_FAILED("환불 요청이 실패하여 운영자 확인이 필요합니다."),
REFUND_PROCESSING_STALE("환불 처리가 제한 시간을 넘겨 멈춰 있습니다."),
REFUND_ATTEMPTS_EXHAUSTED("자동 환불 최대 시도 횟수를 소진했습니다."),
MESSAGE_CREATION_STALE("결제 후 메시지가 장시간 생성되지 않았습니다."),
MESSAGE_CREATION_FAILED_WITHOUT_REFUND("메시지 생성이 실패했지만 환불이 시작되지 않았습니다."),
PAID_WITHOUT_MESSAGE("결제는 완료됐지만 연결된 메시지 요청이 없습니다."),
TOSS_STATUS_MISMATCH("애플리케이션 결제 상태와 토스 결제 상태가 일치하지 않습니다.");

private final String description;

GifticonPaymentAttentionReason(String description) {
this.description = description;
}

public String getDescription() {
return description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,12 @@ private PageRequest pageRequest(int page, int size) {
}

private void requireAuditReadable(AdminPrincipal admin) {
if (admin.hasAnyRole(AdminRole.SUPER_ADMIN, AdminRole.OPERATOR, AdminRole.SUPPORT)) {
if (admin.hasAnyRole(
AdminRole.SUPER_ADMIN,
AdminRole.OPERATOR,
AdminRole.SUPPORT,
AdminRole.FINANCE
)) {
return;
}
throw new SecurityException("감사 로그를 조회할 권한이 없습니다.");
Expand Down
Loading