Skip to content

Commit

Permalink
Merge branch 'develop' into feature/search
Browse files Browse the repository at this point in the history
  • Loading branch information
haxwell committed Oct 4, 2024
2 parents 2787d93 + c9dc040 commit 8cfced0
Show file tree
Hide file tree
Showing 16 changed files with 599 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.savvato.tribeapp.controllers.annotations.controllers.AttributesAPIController.GetAttributesForUser;
import com.savvato.tribeapp.controllers.annotations.controllers.AttributesAPIController.GetUserPhrasesToBeReviewed;
import com.savvato.tribeapp.controllers.dto.AttributesRequest;
import com.savvato.tribeapp.controllers.dto.PhraseSequenceRequest;
import com.savvato.tribeapp.dto.AttributeDTO;
import com.savvato.tribeapp.dto.GenericResponseDTO;
import com.savvato.tribeapp.dto.ToBeReviewedDTO;
Expand Down Expand Up @@ -49,6 +50,8 @@ public class AttributesAPIController {
AttributesAPIController() {
}

//modify to send seq

@GetAttributesForUser
@GetMapping("/{userId}")
public ResponseEntity<List<AttributeDTO>> getAttributesForUser(
Expand All @@ -59,6 +62,22 @@ public ResponseEntity<List<AttributeDTO>> getAttributesForUser(
if (opt.isPresent()) return ResponseEntity.status(HttpStatus.OK).body(opt.get());
else return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}


@PostMapping("/update")
public ResponseEntity<GenericResponseDTO> uPhraseSequences(@RequestBody @Valid PhraseSequenceRequest req) {
PhraseSequenceRequest newRequest = new PhraseSequenceRequest(req.userId, req.phrases);

// Create a request object that includes userId and the list of PhraseSequenceDataRequest
boolean success = attributesService.loadSequence(newRequest);

if (success){
GenericResponseDTO rtn = GenericResponseService.createDTO(true);
return ResponseEntity.status(HttpStatus.OK).body(rtn);
} else {
return ResponseEntity.status(500).build();
}
}

@GetUserPhrasesToBeReviewed
@GetMapping("/in-review/{userId}")
Expand All @@ -78,16 +97,16 @@ public ResponseEntity<GenericResponseDTO> applyPhraseToUser(@RequestBody @Valid
req.userId, req.adverb, req.verb, req.preposition, req.noun);
if (isPhraseApplied) {
sendNotification(true, req.userId);
GenericResponseDTO rtn = GenericResponseService.createDTO("true");
GenericResponseDTO rtn = GenericResponseService.createDTO(true);
return ResponseEntity.status(HttpStatus.OK).body(rtn);
} else {
sendNotification(false, req.userId);
GenericResponseDTO rtn = GenericResponseService.createDTO("false");
GenericResponseDTO rtn = GenericResponseService.createDTO(false);
return ResponseEntity.status(HttpStatus.OK).body(rtn);
}
} else {
sendNotification(false, req.userId);
GenericResponseDTO rtn = GenericResponseService.createDTO("false");
GenericResponseDTO rtn = GenericResponseService.createDTO(false);
return ResponseEntity.status(HttpStatus.OK).body(rtn);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package com.savvato.tribeapp.controllers.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
// hold when data is coming in to the request
@Schema(description = "An attributes request")
public class AttributesRequest {
Expand All @@ -23,4 +31,7 @@ public class AttributesRequest {

@Schema(example = "UNICEF")
public String noun;

public List<PhraseSequenceDataRequest> phrases;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.savvato.tribeapp.controllers.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PhraseSequenceDataRequest {
public Long phraseId;
public Integer sequence;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.savvato.tribeapp.controllers.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PhraseSequenceRequest {
public Long userId;
public List<PhraseSequenceDataRequest> phrases;

}

6 changes: 5 additions & 1 deletion src/main/java/com/savvato/tribeapp/dto/AttributeDTO.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.savvato.tribeapp.dto;

import com.savvato.tribeapp.entities.PhraseSequence;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.*;

import java.util.List;

// hold when data is going out

Expand All @@ -11,4 +14,5 @@ public class AttributeDTO {
public PhraseDTO phrase;
@Schema(example = "1")
public Integer userCount;
public int sequence;
}
57 changes: 57 additions & 0 deletions src/main/java/com/savvato/tribeapp/entities/PhraseSequence.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.savvato.tribeapp.entities;

import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;


@Entity
@Table(name = "phrase_sequence")
public class PhraseSequence {

@EmbeddedId
private PhraseSequenceKey id;

@Column(name = "position")
private Integer position;

public PhraseSequence() {}

public PhraseSequence(Long userId, Long phraseId, Integer position) {
this.id = new PhraseSequenceKey(userId, phraseId);
this.position = position;
}

public PhraseSequenceKey getId() {
return id;
}

public void setId(PhraseSequenceKey id) {
this.id = id;
}

public Long getUserId() {
return id.getUserId();
}

public void setUserId(Long userId) {
id.setUserId(userId);
}

public Long getPhraseId() {
return id.getPhraseId();
}

public void setPhraseId(Long phraseId) {
id.setPhraseId(phraseId);
}

public Integer getPosition() {
return position;
}

public void setPosition(Integer position) {
this.position = position;
}
}
48 changes: 48 additions & 0 deletions src/main/java/com/savvato/tribeapp/entities/PhraseSequenceKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.savvato.tribeapp.entities;

import jakarta.persistence.Embeddable;
import java.io.Serializable;
import java.util.Objects;

@Embeddable
public class PhraseSequenceKey implements Serializable {
private Long userId;
private Long phraseId;

public PhraseSequenceKey() {}

public PhraseSequenceKey(Long userId, Long phraseId) {
this.userId = userId;
this.phraseId = phraseId;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
this.userId = userId;
}

public Long getPhraseId() {
return phraseId;
}

public void setPhraseId(Long phraseId) {
this.phraseId = phraseId;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PhraseSequenceKey that = (PhraseSequenceKey) o;
return Objects.equals(userId, that.userId) &&
Objects.equals(phraseId, that.phraseId);
}

@Override
public int hashCode() {
return Objects.hash(userId, phraseId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.savvato.tribeapp.repositories;

import com.savvato.tribeapp.entities.PhraseSequence;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Repository
public interface PhraseSequenceRepository extends JpaRepository<PhraseSequence, Long> {
@Query(nativeQuery = true, value = "SELECT * FROM phrase_sequence WHERE user_id = ?1 ORDER BY position")
List<PhraseSequence> findByUserIdOrderByPosition(Long userId);

@Modifying
@Transactional
@Query(nativeQuery = true, value = "INSERT INTO phrase_sequence (user_id, phrase_id, position) VALUES (:userId, :phraseId, :position) " +
"ON DUPLICATE KEY UPDATE position = VALUES(position)")
void storeOrUpdatePhrases(@Param("userId") Long userId, @Param("phraseId") Long phraseId, @Param("position") Integer position);

@Query(nativeQuery = true, value = "SELECT COALESCE(MAX(position), 0) + 1 FROM phrase_sequence WHERE user_id = ?1")
Integer findNextAvailableSequence(Long userId);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.savvato.tribeapp.services;

import com.savvato.tribeapp.controllers.dto.PhraseSequenceDataRequest;
import com.savvato.tribeapp.controllers.dto.PhraseSequenceRequest;
import com.savvato.tribeapp.dto.AttributeDTO;

import java.util.List;
Expand All @@ -8,5 +10,9 @@
public interface AttributesService {

Optional<List<AttributeDTO>> getAttributesByUserId(Long id);

void updatePhraseSequences(long userId, PhraseSequenceDataRequest phrase);

boolean loadSequence(PhraseSequenceRequest phrases);
}

Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.savvato.tribeapp.services;

import com.savvato.tribeapp.controllers.dto.PhraseSequenceDataRequest;
import com.savvato.tribeapp.controllers.dto.PhraseSequenceRequest;
import com.savvato.tribeapp.dto.AttributeDTO;
import com.savvato.tribeapp.dto.PhraseDTO;
import com.savvato.tribeapp.entities.PhraseSequence;
import com.savvato.tribeapp.repositories.PhraseSequenceRepository;
import com.savvato.tribeapp.repositories.UserPhraseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AttributesServiceImpl implements AttributesService {
Expand All @@ -20,27 +23,71 @@ public class AttributesServiceImpl implements AttributesService {
@Autowired
UserPhraseRepository userPhraseRepository;

@Autowired
private PhraseSequenceRepository phraseSequenceRepository;

@Override
public Optional<List<AttributeDTO>> getAttributesByUserId(Long userId) {

List<PhraseSequence> phraseSequences = phraseSequenceRepository.findByUserIdOrderByPosition(userId);

Map<Long, Integer> phraseIdToSequenceMap = phraseSequences.stream()
.collect(Collectors.toMap(
PhraseSequence::getPhraseId,
PhraseSequence::getPosition
));

// Get all user phrases as phraseDTOs
Optional<Map<PhraseDTO, Integer>> optUserPhraseDTOs = phraseService.getPhraseInformationByUserId(userId);

// If there are phrases, build DTO and add to attributes list
if (optUserPhraseDTOs.isPresent()) {
Map<PhraseDTO, Integer> phraseDTOUserCountMap = optUserPhraseDTOs.get();

List<AttributeDTO> attributes = phraseDTOUserCountMap
.entrySet()
.stream()
.map(
entry -> AttributeDTO.builder().phrase(entry.getKey()).userCount(entry.getValue()).build()
)
.toList();
.map(entry -> {
PhraseDTO phraseDTO = entry.getKey();
Integer userCount = entry.getValue();

// Populate the sequence in PhraseDTO
int sequence= phraseIdToSequenceMap.get(phraseDTO.id); // Find sequence
List<PhraseSequence> phrases = phraseSequenceRepository.findByUserIdOrderByPosition(userId);
return AttributeDTO.builder()
.phrase(phraseDTO)
.userCount(userCount)
.sequence(sequence) // No change to user count
.build();
})
.collect(Collectors.toList());
attributes.sort(Comparator.comparingLong(a -> (a.phrase.id)));

return Optional.of(attributes);
}

// Returns list of attributeDTOs. Can be empty.
return Optional.of(new ArrayList<>());
// If no phrases found, return an empty list
return Optional.of(Collections.emptyList());
}

//create a senario where false is returned
@Transactional
public boolean loadSequence(PhraseSequenceRequest sequence){
for (PhraseSequenceDataRequest phrase : sequence.getPhrases()) {
updatePhraseSequences(sequence.getUserId(), phrase);
}

return true;
}
@Transactional
public void updatePhraseSequences(long userId, PhraseSequenceDataRequest phrase) {

// Iterate over the list of phrases to update their positio
phraseSequenceRepository.storeOrUpdatePhrases(
userId,
phrase.phraseId,
phrase.sequence
);

}
}
Loading

0 comments on commit 8cfced0

Please sign in to comment.