Skip to content

Commit

Permalink
Add rating for level of difficulty of a question
Browse files Browse the repository at this point in the history
  • Loading branch information
EnesBaserr committed Dec 7, 2024
1 parent 164bedc commit f351a33
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public static class QuestionEndpoints {
public static final String QUESTION_DELETE_UPVOTE = QUESTION_ID + "/deleteUpvote";
public static final String QUESTION_DELETE_DOWNVOTE = QUESTION_ID + "/deleteDownvote";
public static final String QUESTION_ANSWERS = BASE_PATH + "/{questionId}/answers";
public static final String QUESTION_RATE = QUESTION_ID + "/rate";
}

public static class AnswerEndpoints {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class SparqlConstants {
(SAMPLE(?officialWebSite) AS ?officialWebSiteS)\s
(SAMPLE(?stackExchangeTag) AS ?stackExchangeTagS)
WHERE {
?library wdt:P31 wd:Q188860.
?library wdt:P31 wd:Q188860.
FILTER (
EXISTS { ?library wdt:P154 ?logoImage }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

import com.group1.programminglanguagesforum.Constants.EndpointConstants;
import com.group1.programminglanguagesforum.DTOs.Requests.CreateQuestionRequestDto;
import com.group1.programminglanguagesforum.DTOs.Requests.DifficultyLevelRequestDto;
import com.group1.programminglanguagesforum.DTOs.Requests.UpdateQuestionRequestDto;
import com.group1.programminglanguagesforum.DTOs.Responses.CreateQuestionResponseDto;
import com.group1.programminglanguagesforum.DTOs.Responses.ErrorResponse;
import com.group1.programminglanguagesforum.DTOs.Responses.GenericApiResponse;
import com.group1.programminglanguagesforum.DTOs.Responses.*;
import com.group1.programminglanguagesforum.Exceptions.ExceptionResponseHandler;
import com.group1.programminglanguagesforum.DTOs.Responses.GetQuestionDetailsResponseDto;
import com.group1.programminglanguagesforum.DTOs.Responses.QuestionSummaryDto;
import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import com.group1.programminglanguagesforum.Entities.Question;
import com.group1.programminglanguagesforum.Exceptions.UnauthorizedAccessException;
import com.group1.programminglanguagesforum.Services.QuestionDifficultyRateService;
import com.group1.programminglanguagesforum.Services.QuestionService;
import com.group1.programminglanguagesforum.Util.ApiResponseBuilder;
import lombok.RequiredArgsConstructor;
Expand All @@ -32,6 +30,7 @@
@RequiredArgsConstructor
public class QuestionController extends BaseController {
private final QuestionService questionService;
private final QuestionDifficultyRateService questionDifficultyRateService;

@PostMapping(value = EndpointConstants.QuestionEndpoints.BASE_PATH)
public ResponseEntity<GenericApiResponse<CreateQuestionResponseDto>> createQuestion(
Expand Down Expand Up @@ -132,4 +131,21 @@ public ResponseEntity<GenericApiResponse<Map<String, Object>>> searchQuestions(
HttpStatus.OK);
}

@PostMapping(value = EndpointConstants.QuestionEndpoints.QUESTION_RATE)
public ResponseEntity<GenericApiResponse<QuestionRateResponseDto>> rateQuestion(
@PathVariable(value = "id") Long id,
@RequestBody DifficultyLevelRequestDto dto) {
try {
GenericApiResponse<QuestionRateResponseDto> response = ApiResponseBuilder.buildSuccessResponse(
QuestionRateResponseDto.class, "Question rated successfully", 200,
questionDifficultyRateService.rateQuestion(id, dto.getDifficulty()));
return buildResponse(response, org.springframework.http.HttpStatus.OK);
} catch (NoSuchElementException e) {
return ExceptionResponseHandler.NoSuchElementException(e);
}
catch (UnauthorizedAccessException e) {
return ExceptionResponseHandler.UnauthorizedAccessException(e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.group1.programminglanguagesforum.DTOs.Requests;

import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import lombok.*;

@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class DifficultyLevelRequestDto {
private DifficultyLevel difficulty;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.group1.programminglanguagesforum.DTOs.Requests;

import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import lombok.*;

import java.util.List;
Expand All @@ -13,4 +14,5 @@ public class UpdateQuestionRequestDto {
private String title;
private String content;
private List<Long> tags;
private DifficultyLevel difficulty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,10 @@ public class GetQuestionDetailsResponseDto {
private Long answerCount = 0L;
@Builder.Default
private boolean bookmarked = false;
@Builder.Default
private DifficultyLevel lastRatedDifficulty =null;
private Long easyCount;
private Long mediumCount;
private Long hardCount;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.group1.programminglanguagesforum.DTOs.Responses;

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

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class QuestionRateResponseDto {
private Long questionId;
private Long easyCount;
private Long mediumCount;
private Long hardCount;
private Long totalCount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.group1.programminglanguagesforum.Entities;

import jakarta.persistence.*;
import lombok.*;

import java.text.SimpleDateFormat;
import java.util.Date;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Getter
@Setter
@Table(name = "QUESTION_DIFFICULTY_RATE")
public class QuestionDifficultyRate {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "question_id", nullable = false)
private Question question;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Enumerated(EnumType.STRING)
private DifficultyLevel difficulty;
@Temporal(TemporalType.TIMESTAMP)
private Date rated_at;


@PrePersist
protected void onCreate() {
rated_at = new Date();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.group1.programminglanguagesforum.Repositories;

import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import com.group1.programminglanguagesforum.Entities.Question;
import com.group1.programminglanguagesforum.Entities.QuestionDifficultyRate;
import com.group1.programminglanguagesforum.Entities.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Optional;

@Repository
public interface QuestionDifficultyRateRepository extends JpaRepository<QuestionDifficultyRate, Long> {

Optional<QuestionDifficultyRate> findByQuestionAndUser(Question question, User user);

long countByDifficulty(DifficultyLevel difficultyLevel);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.group1.programminglanguagesforum.Services;

import com.group1.programminglanguagesforum.DTOs.Responses.QuestionRateResponseDto;
import com.group1.programminglanguagesforum.Entities.DifficultyLevel;
import com.group1.programminglanguagesforum.Entities.Question;
import com.group1.programminglanguagesforum.Entities.QuestionDifficultyRate;
import com.group1.programminglanguagesforum.Entities.User;
import com.group1.programminglanguagesforum.Exceptions.UnauthorizedAccessException;
import com.group1.programminglanguagesforum.Repositories.QuestionDifficultyRateRepository;
import com.group1.programminglanguagesforum.Repositories.QuestionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

import java.util.NoSuchElementException;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class QuestionDifficultyRateService {
private final QuestionDifficultyRateRepository questionDifficultyRateRepository;
private final UserContextService userContextService;
private final QuestionRepository questionRepository;


public QuestionRateResponseDto rateQuestion(Long id, DifficultyLevel difficultyLevel) throws UnauthorizedAccessException {
Question question = questionRepository.findById(id).orElseThrow(() -> new NoSuchElementException("Question not found"));
User user = userContextService.getCurrentUser();
Optional<QuestionDifficultyRate> questionDifficultyRateOptional = getQuestionDifficultyRate(question, user);
QuestionDifficultyRate questionDifficultyRate = questionDifficultyRateOptional.orElseGet(() -> {
QuestionDifficultyRate newQuestionDifficultyRate = new QuestionDifficultyRate();
newQuestionDifficultyRate.setQuestion(question);
newQuestionDifficultyRate.setUser(user);
return newQuestionDifficultyRate;
});
questionDifficultyRate.setDifficulty(difficultyLevel);
questionDifficultyRateRepository.save(questionDifficultyRate);
QuestionRateCounts result = getResult();
return QuestionRateResponseDto.builder()
.questionId(id)
.easyCount(result.easyCount())
.mediumCount(result.mediumCount())
.hardCount(result.hardCount())
.totalCount(result.easyCount() + result.mediumCount() + result.hardCount())
.build();



}

public Optional<QuestionDifficultyRate> getQuestionDifficultyRate(Question question, User user) {
return questionDifficultyRateRepository.findByQuestionAndUser(question, user);
}

@NonNull
public QuestionRateCounts getResult() {
long easyCount = questionDifficultyRateRepository.countByDifficulty(DifficultyLevel.EASY);
long mediumCount = questionDifficultyRateRepository.countByDifficulty(DifficultyLevel.MEDIUM);
long hardCount = questionDifficultyRateRepository.countByDifficulty(DifficultyLevel.HARD);
return new QuestionRateCounts(easyCount, mediumCount, hardCount);
}

public record QuestionRateCounts(long easyCount, long mediumCount, long hardCount) {
}
}
Loading

0 comments on commit f351a33

Please sign in to comment.