package com.mydreamjob.talentinvitation; import jakarta.persistence.LockModeType; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.*; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.time.LocalDateTime; import java.util.Optional; @Repository public interface TalentInvitationRepository extends JpaRepository { Optional findByCompanyIdAndIdempotencyKey(Long companyId, String idempotencyKey); Optional findByIdAndCompanyId(Long id, Long companyId); Optional findByIdAndStudentUserId(Long id, Long studentUserId); Optional findByCompanyIdAndJobIdAndStudentUserIdAndStatus( Long companyId, Long jobId, Long studentUserId, String status); Page findByCompanyIdOrderByCreatedAtDescIdDesc(Long companyId, Pageable pageable); Page findByStudentUserIdOrderByCreatedAtDescIdDesc(Long studentUserId, Pageable pageable); @Query("select count(t) from TalentInvitation t where t.companyId=:companyId and t.createdAt>=:from and t.createdAt<:to") long countCreatedBetween(@Param("companyId") Long companyId, @Param("from") LocalDateTime from, @Param("to") LocalDateTime to); @Query("select count(t) from TalentInvitation t where t.companyId=:companyId and t.jobId=:jobId " + "and t.createdAt>=:from and t.createdAt<:to") long countJobCreatedBetween(@Param("companyId") Long companyId, @Param("jobId") Long jobId, @Param("from") LocalDateTime from, @Param("to") LocalDateTime to); @Query("select case when count(t)>0 then true else false end from TalentInvitation t " + "where t.companyId=:companyId and t.studentUserId=:studentUserId and t.expiresAt>:since") boolean existsInCooldown(@Param("companyId") Long companyId, @Param("studentUserId") Long studentUserId, @Param("since") LocalDateTime since); @Modifying(clearAutomatically = true, flushAutomatically = true) @Query("update TalentInvitation t set t.status=:status, t.activeKey=null, t.decidedAt=:decidedAt, " + "t.version=t.version+1 where t.id=:id and t.studentUserId=:studentUserId " + "and t.status='PENDING' and t.version=:version and t.expiresAt>:now") int decide(@Param("id") Long id, @Param("studentUserId") Long studentUserId, @Param("status") String status, @Param("version") Long version, @Param("decidedAt") LocalDateTime decidedAt, @Param("now") LocalDateTime now); @Modifying(clearAutomatically = true, flushAutomatically = true) @Query("update TalentInvitation t set t.conversationId=:conversationId " + "where t.id=:id and t.studentUserId=:studentUserId and t.status='ACCEPTED' " + "and t.version=:version and t.conversationId is null") int attachConversation(@Param("id") Long id, @Param("studentUserId") Long studentUserId, @Param("conversationId") Long conversationId, @Param("version") Long version); @Modifying(clearAutomatically = true, flushAutomatically = true) @Query("update TalentInvitation t set t.status='EXPIRED', t.activeKey=null, t.decidedAt=:now, " + "t.version=t.version+1 where t.id=:id and t.status='PENDING' and t.expiresAt<=:now") int expire(@Param("id") Long id, @Param("now") LocalDateTime now); }