Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Viewpoint api #18

Merged
merged 23 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
dc0473c
feat: add ViewpointController and ViewpointService
kiki0518 Nov 24, 2024
fe1b5b9
chore: add Entity notation and test controller
kiki0518 Nov 24, 2024
4e7f40f
fix: ViewpointReactionEntity storage implementation
kiki0518 Nov 27, 2024
faa579d
refactor: replace direct database operation with query
kiki0518 Nov 29, 2024
9d5f625
fix: default value initialization for reactionCount
kiki0518 Nov 29, 2024
10e452e
chore: fix coding style
kiki0518 Dec 1, 2024
05eb646
test: add test for pagination
YukinaMochizuki Dec 2, 2024
ce9e486
test: add test for content contain fact
YukinaMochizuki Dec 2, 2024
35d2ba9
feat: add throwIfFactsNotExist method in service
YukinaMochizuki Dec 2, 2024
d2b62ea
chore: rename ManualIssueFactEntity table name to issue_fact_entity
YukinaMochizuki Dec 2, 2024
16a31ac
refactor: move pagination package to shared
YukinaMochizuki Dec 2, 2024
fe20561
chore: rename ViewpointUpdateRequest to ViewpointRequest
YukinaMochizuki Dec 2, 2024
081d9ec
feat: add viewpoint fact entity and repository
YukinaMochizuki Dec 2, 2024
0c57088
feat: add create and update viewpoint method in service
YukinaMochizuki Dec 2, 2024
601bada
chore: fix coding style issue
YukinaMochizuki Dec 2, 2024
541fa8f
fix: fix subject not parsing into uuid at getId in access token
YukinaMochizuki Dec 3, 2024
96d3186
fix: fix subject not parsing into uuid at getId in access token
YukinaMochizuki Dec 3, 2024
6281d7f
chore: fix typo in issue controller sortableColumn
YukinaMochizuki Dec 3, 2024
7a3641b
feat: add react to viewpoint and include fact to response
YukinaMochizuki Dec 3, 2024
fce57d4
style: fix coding style issue
YukinaMochizuki Dec 3, 2024
2341c73
style: fix coding style issues
YukinaMochizuki Dec 3, 2024
da5856b
chore: fix coding style issue
YukinaMochizuki Dec 3, 2024
6828f5c
feat: add create/get viewpoint by issue id endpoint
YukinaMochizuki Dec 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.HandlerMethodValidationException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
Expand Down Expand Up @@ -91,6 +92,14 @@ protected ResponseEntity<Object> handleHandlerMethodValidationException(HandlerM
return super.handleExceptionInternal(exception, null, headers, status, request);
}

@ExceptionHandler(IllegalArgumentException.class)
protected ResponseEntity<Object> handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) {
ErrorResponseException exception = createValidException();
exception.setDetail(ex.getMessage());

return super.handleExceptionInternal(exception, null, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}

private ErrorResponseException createValidException() {
ErrorResponseException exception = new ErrorResponseException(HttpStatus.BAD_REQUEST);
exception.setTitle("Validation error");
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import org.springframework.web.bind.annotation.*;
import tw.commonground.backend.service.fact.dto.FactRequest;
import tw.commonground.backend.service.fact.dto.FactResponse;
import tw.commonground.backend.pagination.PaginationValidator;
import tw.commonground.backend.shared.pagination.PaginationParser;
import tw.commonground.backend.service.reference.ReferenceRequest;
import tw.commonground.backend.service.reference.ReferenceResponse;
import tw.commonground.backend.pagination.PaginationRequest;
import tw.commonground.backend.pagination.WrappedPaginationResponse;
import tw.commonground.backend.shared.pagination.PaginationRequest;
import tw.commonground.backend.shared.pagination.WrappedPaginationResponse;

import java.util.*;

Expand All @@ -23,15 +23,15 @@ public class FactController {

private final Set<String> sortableColumn = Set.of("title", "createAt", "updateAt", "authorId", "authorName");

private final PaginationValidator paginationValidator = new PaginationValidator(sortableColumn, MAX_SIZE);
private final PaginationParser paginationParser = new PaginationParser(sortableColumn, MAX_SIZE);

public FactController(FactService factService) {
this.factService = factService;
}

@GetMapping("/api/facts")
public WrappedPaginationResponse<List<FactResponse>> listFacts(@Valid PaginationRequest pagination) {
Pageable pageable = paginationValidator.validatePaginationRequest(pagination);
Pageable pageable = paginationParser.parsePageable(pagination);
return factService.getFacts(pageable);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import tw.commonground.backend.service.fact.entity.FactEntity;
import tw.commonground.backend.service.fact.entity.FactRepository;
import tw.commonground.backend.service.reference.*;
import tw.commonground.backend.pagination.PaginationMapper;
import tw.commonground.backend.pagination.WrappedPaginationResponse;
import tw.commonground.backend.shared.pagination.PaginationMapper;
import tw.commonground.backend.shared.pagination.WrappedPaginationResponse;

import java.net.URL;
import java.net.URLDecoder;
Expand Down Expand Up @@ -131,6 +131,16 @@ public void deleteFactReferences(UUID id, UUID referenceId) {
factRepository.save(factEntity);
}

public void throwIfFactsNotExist(List<UUID> factIds) {
List<UUID> existingFactIds = factRepository.findExistingIdsByIds(factIds);
List<UUID> missingFacts = factIds.stream()
.filter(factId -> !existingFactIds.contains(factId))
.toList();
if (!missingFacts.isEmpty()) {
throw new EntityNotFoundException("Fact", "ids", missingFacts.toString());
}
}

private Set<ReferenceEntity> parseReferenceEntity(List<String> urls) {
urls = urlHandling(urls);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
import tw.commonground.backend.service.fact.entity.FactEntity;
import tw.commonground.backend.service.reference.ReferenceMapper;

import java.util.Collection;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

public final class FactMapper {

private FactMapper() {
Expand All @@ -21,4 +26,9 @@ public static FactResponse toResponse(FactEntity factEntity) {
.build();
}

public static Set<FactEntity> toEntities(Collection<UUID> factIds) {
return factIds.stream()
.map(factId -> FactEntity.builder().id(factId).build())
.collect(Collectors.toSet());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package tw.commonground.backend.service.fact.entity;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.UUID;

public interface FactRepository extends JpaRepository<FactEntity, UUID> {
@Query("SELECT f.id FROM FactEntity f WHERE f.id IN :ids")
List<UUID> findExistingIdsByIds(@Param("ids") List<UUID> ids);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,37 @@
import tw.commonground.backend.service.issue.dto.IssueResponse;
import tw.commonground.backend.service.issue.dto.SimpleIssueResponse;
import tw.commonground.backend.service.issue.entity.IssueEntity;
import tw.commonground.backend.pagination.PaginationMapper;
import tw.commonground.backend.pagination.PaginationRequest;
import tw.commonground.backend.pagination.PaginationValidator;
import tw.commonground.backend.pagination.WrappedPaginationResponse;
import tw.commonground.backend.shared.pagination.PaginationMapper;
import tw.commonground.backend.shared.pagination.PaginationRequest;
import tw.commonground.backend.shared.pagination.PaginationParser;
import tw.commonground.backend.shared.pagination.WrappedPaginationResponse;
import tw.commonground.backend.service.issue.entity.SimpleIssueEntity;
import tw.commonground.backend.service.issue.insight.Insight;
import tw.commonground.backend.service.issue.insight.InsightParser;
import tw.commonground.backend.shared.content.ContentContainFact;
import tw.commonground.backend.shared.content.ContentContainFactParser;

import java.util.*;

@RestController
@RequestMapping("/api")
public class IssueController {
private static final int MAX_SIZE = 200;

private final IssueService issueService;

private final FactService factService;

private final Set<String> sortableColumn = Set.of("title", "createAt", "updateAt", "authorId", "authorName");
private final Set<String> sortableColumn = Set.of("title", "createdAt", "updatedAt");

private final PaginationValidator paginationValidator = new PaginationValidator(sortableColumn, MAX_SIZE);
private final PaginationParser paginationParser = new PaginationParser(sortableColumn, MAX_SIZE);

public IssueController(IssueService issueService, FactService factService) {
this.issueService = issueService;
this.factService = factService;
}

@GetMapping("/api/issues")
@GetMapping("/issues")
public WrappedPaginationResponse<List<SimpleIssueResponse>> listIssues(@Valid PaginationRequest pagination) {
Pageable pageable = paginationValidator.validatePaginationRequest(pagination);
Pageable pageable = paginationParser.parsePageable(pagination);
Page<SimpleIssueEntity> pageIssues = issueService.getIssues(pageable);

List<SimpleIssueResponse> issueResponses = pageIssues.getContent()
Expand All @@ -54,43 +55,46 @@ public WrappedPaginationResponse<List<SimpleIssueResponse>> listIssues(@Valid Pa
return new WrappedPaginationResponse<>(issueResponses, PaginationMapper.toResponse(pageIssues));
}

@PostMapping("/api/issues")
@PostMapping("/issues")
public IssueResponse createIssue(@Valid @RequestBody IssueRequest issueRequest) {
IssueEntity issueEntity = issueService.createIssue(issueRequest);
Insight insight = InsightParser.separateInsightAndFacts(issueEntity.getInsight());
ContentContainFact contentContainFact = ContentContainFactParser
.separateContentAndFacts(issueEntity.getInsight());

List<FactEntity> factResponses = factService.getFacts(insight.getFacts());
List<FactEntity> factResponses = factService.getFacts(contentContainFact.getFacts());
return IssueMapper.toResponse(issueEntity, factResponses);
}

@GetMapping("/api/issue/{id}")
@GetMapping("/issue/{id}")
public IssueResponse getIssue(@PathVariable UUID id) {
IssueEntity issueEntity = issueService.getIssue(id);
Insight insight = InsightParser.separateInsightAndFacts(issueEntity.getInsight());
ContentContainFact contentContainFact = ContentContainFactParser
.separateContentAndFacts(issueEntity.getInsight());

List<FactEntity> factResponses = factService.getFacts(insight.getFacts());
List<FactEntity> factResponses = factService.getFacts(contentContainFact.getFacts());
return IssueMapper.toResponse(issueEntity, factResponses);
}

@PutMapping("/api/issue/{id}")
@PutMapping("/issue/{id}")
public IssueResponse updateIssue(@PathVariable UUID id, @Valid @RequestBody IssueRequest issueRequest) {
IssueEntity issueEntity = issueService.updateIssue(id, issueRequest);
Insight insight = InsightParser.separateInsightAndFacts(issueEntity.getInsight());
ContentContainFact contentContainFact = ContentContainFactParser
.separateContentAndFacts(issueEntity.getInsight());

List<FactEntity> factResponses = factService.getFacts(insight.getFacts());
List<FactEntity> factResponses = factService.getFacts(contentContainFact.getFacts());
return IssueMapper.toResponse(issueEntity, factResponses);
}

@DeleteMapping("/api/issue/{id}")
@DeleteMapping("/issue/{id}")
public void deleteIssue(@PathVariable String id) {
issueService.deleteIssue(UUID.fromString(id));
}

@GetMapping("/api/issue/{id}/facts")
@GetMapping("/issue/{id}/facts")
public WrappedPaginationResponse<List<FactResponse>> getIssueFacts(@PathVariable UUID id,
@Valid PaginationRequest pagination) {
PaginationValidator validator = new PaginationValidator(Collections.emptySet(), MAX_SIZE);
Pageable pageable = validator.validatePaginationRequest(pagination);
PaginationParser validator = new PaginationParser(Collections.emptySet(), MAX_SIZE);
Pageable pageable = validator.parsePageable(pagination);
Page<FactEntity> pageFacts = issueService.getIssueFacts(id, pageable);

List<FactResponse> factResponses = pageFacts.getContent()
Expand All @@ -101,7 +105,7 @@ public WrappedPaginationResponse<List<FactResponse>> getIssueFacts(@PathVariable
return new WrappedPaginationResponse<>(factResponses, PaginationMapper.toResponse(pageFacts));
}

@PostMapping("/api/issue/{id}/facts")
@PostMapping("/issue/{id}/facts")
public Map<String, List<FactResponse>> linkFactsToIssue(@PathVariable UUID id,
@Valid @RequestBody LinkFactsRequest request) {
List<FactEntity> factEntities = issueService.createManualFact(id, request.getFactIds());
Expand Down
Loading
Loading