- 초대 로직 변경: 이메일→휴대폰 기반 초대 전환 및 UI 업데이트
eapim-portal CI (from elink-portal-common) / build (push) Has been cancelled

- 알림 수신 동의 추가: 초대/취소 시 알림 발송 옵션 탑재
- 관리자 기능 추가: 소속 제외 및 권한 조정 기능 구현
This commit is contained in:
Rinjae
2026-06-23 20:58:27 +09:00
parent 8c45451230
commit 208b0be097
4 changed files with 20 additions and 1 deletions
@@ -6,6 +6,7 @@ import com.eactive.apim.portal.agreements.entity.AgreementsId;
import com.eactive.apim.portal.agreements.entity.AgreementsStatus; import com.eactive.apim.portal.agreements.entity.AgreementsStatus;
import com.eactive.apim.portal.agreements.repository.AgreementsRepository; import com.eactive.apim.portal.agreements.repository.AgreementsRepository;
import com.eactive.apim.portal.common.exception.NotFoundException; import com.eactive.apim.portal.common.exception.NotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -16,6 +17,7 @@ import java.util.Optional;
@Service @Service
@Transactional @Transactional
@Slf4j
public class AgreementsService { public class AgreementsService {
private static final String NOT_FOUND_MESSAGE = "해당 버전의 약관이 존재하지 않습니다."; private static final String NOT_FOUND_MESSAGE = "해당 버전의 약관이 존재하지 않습니다.";
@@ -111,6 +113,7 @@ public class AgreementsService {
public List<Agreements> findAllAgreementsSortPublishedOn(AgreementType agreementType) { public List<Agreements> findAllAgreementsSortPublishedOn(AgreementType agreementType) {
List<Agreements> agreements = agreementsRepository.findAllByAgreementsTypeOrderByPublishedOnDesc(agreementType); List<Agreements> agreements = agreementsRepository.findAllByAgreementsTypeOrderByPublishedOnDesc(agreementType);
if(agreements.isEmpty()) { if(agreements.isEmpty()) {
log.error("해당 약관 종류의 약관이 존재하지 않습니다. agreementType={}", agreementType);
throw new IllegalStateException(NOT_FOUND_BY_DATE_MESSAGE); throw new IllegalStateException(NOT_FOUND_BY_DATE_MESSAGE);
} }
return agreements; return agreements;
@@ -1,6 +1,7 @@
package com.eactive.apim.portal.invitation.entity; package com.eactive.apim.portal.invitation.entity;
import com.eactive.apim.portal.invitation.entity.UserInvitationEnums.InvitationStatus; import com.eactive.apim.portal.invitation.entity.UserInvitationEnums.InvitationStatus;
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14; import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
import lombok.Data; import lombok.Data;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
@@ -29,10 +30,15 @@ public class UserInvitation {
@Comment("기관ID") @Comment("기관ID")
private String orgId; private String orgId;
@Column(name = "INVITATION_EMAIL", length = 30, nullable = false) @Column(name = "INVITATION_EMAIL", length = 256)
@Comment("초대이메일") @Comment("초대이메일")
private String invitationEmail; private String invitationEmail;
@Column(name = "INVITATION_MOBILE", length = 256)
@Convert(converter = PersonalDataEncryptConverter.class)
@Comment("초대휴대폰")
private String invitationMobile;
@Column(name = "INVITATION_DATE", length = 14, nullable = false) @Column(name = "INVITATION_DATE", length = 14, nullable = false)
@Convert(converter = LocalDateTimeToStringConverter14.class) @Convert(converter = LocalDateTimeToStringConverter14.class)
@Comment("초대일시") @Comment("초대일시")
@@ -22,4 +22,11 @@ public interface UserInvitationRepository extends JpaRepository<UserInvitation,
Optional<UserInvitation> findFirstByInvitationEmailAndOrgIdAndStatus(String email, String orgId, InvitationStatus status); Optional<UserInvitation> findFirstByInvitationEmailAndOrgIdAndStatus(String email, String orgId, InvitationStatus status);
Optional<UserInvitation> findFirstByInvitationEmailAndOrgId(String email, String orgId); Optional<UserInvitation> findFirstByInvitationEmailAndOrgId(String email, String orgId);
// 휴대폰 번호 기반 초대 조회 (INVITATION_MOBILE 은 결정적 암호화로 저장되어 equality 조회 가능)
Optional<UserInvitation> findFirstByInvitationMobileAndStatus(String mobile, InvitationStatus status);
Optional<UserInvitation> findFirstByInvitationMobileAndOrgIdAndStatus(String mobile, String orgId, InvitationStatus status);
Optional<UserInvitation> findFirstByInvitationMobileAndOrgId(String mobile, String orgId);
} }
@@ -30,6 +30,9 @@ public interface PortalUserRepository extends BaseRepository<PortalUser, String>
boolean existsByMobileNumber(String mobileNumber); boolean existsByMobileNumber(String mobileNumber);
// 휴대폰 번호 기반 기존 회원 조회 (mobileNumber 는 유니크 제약이 없어 다건 가능)
List<PortalUser> findAllByMobileNumber(String mobileNumber);
@Query("SELECT u FROM PortalUser u WHERE u.portalOrg = :org AND u.userStatus != :status") @Query("SELECT u FROM PortalUser u WHERE u.portalOrg = :org AND u.userStatus != :status")
Page<PortalUser> findActiveUsers(@Param("org") PortalOrg org, @Param("status") PortalUserEnums.UserStatus status, Pageable pageable); Page<PortalUser> findActiveUsers(@Param("org") PortalOrg org, @Param("status") PortalUserEnums.UserStatus status, Pageable pageable);