diff --git a/src/main/java/com/chaineeproject/chainee/controller/ContractNotificationController.java b/src/main/java/com/chaineeproject/chainee/controller/ContractNotificationController.java index 3fb0ab5..befc09c 100644 --- a/src/main/java/com/chaineeproject/chainee/controller/ContractNotificationController.java +++ b/src/main/java/com/chaineeproject/chainee/controller/ContractNotificationController.java @@ -28,13 +28,24 @@ private Long meId(Jwt jwt) { /** * 구인자 → 구직자 : 계약서 전자 서명 요청 알림 - * 예: POST /api/job/applications/{applicationId}/contract-request - * body: { "transaction": "{...raw tx...}" } + * + * 예: + * POST /api/job/applications/{applicationId}/contract-request + * + * Request Body 예시: + * { + * "transaction": "{ \"chain\": \"solana\", \"network\": \"devnet\", \"tx\": \"raw-tx-base64\" }", + * "linkUrl": "/contracts/123/sign" + * } */ @PostMapping("/{applicationId}/contract-request") @Operation( summary = "계약서 전자 서명 요청 알림 (구인자 → 구직자)", - description = "공고 작성자가 지원자에게 계약서 전자 서명을 요청하는 알림을 생성합니다." + description = """ + 공고 작성자가 지원자에게 계약서 전자 서명을 요청하는 알림을 생성합니다. + - transaction: 프론트에서 생성한 트랜잭션 payload 문자열 + - linkUrl: 알림 클릭 시 이동할 계약서 페이지 엔드포인트(도메인 제외) + """ ) public ResponseEntity sendContractRequest( @AuthenticationPrincipal Jwt jwt, @@ -49,14 +60,25 @@ public ResponseEntity sendContractRequest( } /** - * 🔥 구직자 → 구인자 : 서명 완료 알림 - * 예: POST /api/job/applications/{applicationId}/contract-signed - * body: { "transaction": "{...signed tx...}" } + * 구직자 → 구인자 : 서명 완료 알림 + * + * 예: + * POST /api/job/applications/{applicationId}/contract-signed + * + * Request Body 예시: + * { + * "transaction": "{ \"chain\": \"solana\", \"network\": \"devnet\", \"tx\": \"signed-tx-base64\" }", + * "linkUrl": "/contracts/123/sign" + * } */ @PostMapping("/{applicationId}/contract-signed") @Operation( summary = "계약서 전자 서명 완료 알림 (구직자 → 구인자)", - description = "지원자가 계약서 전자 서명을 완료했음을 공고 작성자에게 알리는 알림을 생성합니다." + description = """ + 지원자가 계약서 전자 서명을 완료했음을 공고 작성자에게 알리는 알림을 생성합니다. + - transaction: 서명된 트랜잭션 payload 문자열 + - linkUrl: 알림 클릭 시 이동할 계약서 페이지 엔드포인트(도메인 제외) + """ ) public ResponseEntity sendContractSigned( @AuthenticationPrincipal Jwt jwt, diff --git a/src/main/java/com/chaineeproject/chainee/dto/ContractNotificationRequest.java b/src/main/java/com/chaineeproject/chainee/dto/ContractNotificationRequest.java index fd6f31d..304f880 100644 --- a/src/main/java/com/chaineeproject/chainee/dto/ContractNotificationRequest.java +++ b/src/main/java/com/chaineeproject/chainee/dto/ContractNotificationRequest.java @@ -3,12 +3,18 @@ import io.swagger.v3.oas.annotations.media.Schema; -@Schema(description = "계약서 전자서명 요청 알림 생성 요청") +@Schema(description = "계약서 전자서명(요청/완료) 알림 생성 요청") public record ContractNotificationRequest( @Schema( - description = "프론트에서 생성한 트랜잭션 문자열 그대로 (JSON이든 base64든 어떤 형식이든 상관 없음)", - example = "{ \"chain\": \"solana\", \"network\": \"devnet\", \"tx\": \"...\" }" + description = "프론트에서 생성한 트랜잭션 payload 문자열 (JSON이든 base64든 어떤 형식이든 상관 없음)", + example = "{ \"chain\": \"solana\", \"network\": \"devnet\", \"tx\": \"signed-tx-base64\" }" ) - String transaction + String transaction, + + @Schema( + description = "알림 클릭 시 이동할 계약서 페이지 엔드포인트(도메인 제외). 예: '/contracts/{id}/sign'", + example = "/contracts/123/sign" + ) + String linkUrl ) {} diff --git a/src/main/java/com/chaineeproject/chainee/service/EmployerApplicationService.java b/src/main/java/com/chaineeproject/chainee/service/EmployerApplicationService.java index 9af47fb..bbab294 100644 --- a/src/main/java/com/chaineeproject/chainee/service/EmployerApplicationService.java +++ b/src/main/java/com/chaineeproject/chainee/service/EmployerApplicationService.java @@ -130,9 +130,6 @@ public ResumeView getResumeForEmployer(Long employerUserId, Long applicationId) /** * 구인자 → 구직자에게 계약 전자서명 요청 알림 생성 - * - 프론트는 transaction 문자열만 넘긴다. - * - 백엔드는 transaction을 그대로 Notification에 저장하고, - * 타이틀/메시지만 사람이 읽을 수 있게 세팅. */ @Transactional public ContractNotificationResponse sendContractNotification( @@ -172,7 +169,7 @@ public ContractNotificationResponse sendContractNotification( .notificationType(NotificationType.CONTRACT_SIGNATURE_REQUEST) .title(title) .message(message) - // linkUrl은 프론트 라우팅 전략에 따라 사용/미사용 + .linkUrl(normalizeUrl(req.linkUrl())) .linkUrl(null) .build(); @@ -192,6 +189,10 @@ private static String nz(String s, String def) { return (s == null || s.isBlank()) ? def : s; } + private static String normalizeUrl(String url) { + return (url == null || url.isBlank()) ? null : url.trim(); + } + /** * 🔥 새로 추가: 구직자 → 구인자에게 "서명 완료" 알림 생성 * - applicantId: JWT uid (요청자 = 구직자) @@ -233,7 +234,7 @@ public ContractNotificationResponse sendSignedContractNotification( .notificationType(NotificationType.CONTRACT_SIGNED) .title(title) .message(message) - .linkUrl(null) + .linkUrl(normalizeUrl(req.linkUrl())) .build(); notificationRepository.save(noti);