Compare commits
4 Commits
47876cc775
...
ed766d4c8c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed766d4c8c | ||
|
|
a3295636b4 | ||
|
|
94180e8efc | ||
|
|
b0e682e82e |
@@ -0,0 +1,7 @@
|
|||||||
|
package org.codiki.application.category;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CategoryCreationValidator {
|
||||||
|
}
|
||||||
@@ -1,9 +1,17 @@
|
|||||||
package org.codiki.application.category;
|
package org.codiki.application.category;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.codiki.domain.category.model.builder.CategoryBuilder.aCategory;
|
||||||
|
import org.codiki.domain.category.exception.CategoryDeletionException;
|
||||||
|
import org.codiki.domain.category.exception.CategoryEditionException;
|
||||||
|
import org.codiki.domain.category.exception.CategoryNotFoundException;
|
||||||
import org.codiki.domain.category.model.Category;
|
import org.codiki.domain.category.model.Category;
|
||||||
|
import org.codiki.domain.category.model.builder.CategoryBuilder;
|
||||||
import org.codiki.domain.category.port.CategoryPort;
|
import org.codiki.domain.category.port.CategoryPort;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -18,4 +26,78 @@ public class CategoryUseCases {
|
|||||||
public Optional<Category> findById(UUID categoryId) {
|
public Optional<Category> findById(UUID categoryId) {
|
||||||
return categoryPort.findById(categoryId);
|
return categoryPort.findById(categoryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Category createCategory(String name, List<UUID> subCategoryIds) {
|
||||||
|
if (isNull(name)) {
|
||||||
|
throw new CategoryEditionException("name can not be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Category> subCategories = emptyList();
|
||||||
|
if (!isNull(subCategoryIds)) {
|
||||||
|
try {
|
||||||
|
subCategories = categoryPort.findAllByIds(subCategoryIds);
|
||||||
|
} catch (CategoryNotFoundException exception) {
|
||||||
|
throw new CategoryEditionException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Category newCategory = aCategory()
|
||||||
|
.withId(UUID.randomUUID())
|
||||||
|
.withName(name)
|
||||||
|
.withSubCategories(subCategories)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
categoryPort.save(newCategory);
|
||||||
|
|
||||||
|
return newCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category updateCategory(UUID categoryId, String name, List<UUID> subCategoryIds) {
|
||||||
|
if (isNull(name) && isNull(subCategoryIds)) {
|
||||||
|
throw new CategoryEditionException("no any field is filled");
|
||||||
|
}
|
||||||
|
|
||||||
|
Category categoryToUpdate = categoryPort.findById(categoryId)
|
||||||
|
.orElseThrow(() -> new CategoryNotFoundException(categoryId));
|
||||||
|
|
||||||
|
CategoryBuilder categoryBuilder = aCategory()
|
||||||
|
.basedOn(categoryToUpdate);
|
||||||
|
|
||||||
|
if (!isNull(name)) {
|
||||||
|
categoryBuilder.withName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNull(subCategoryIds)) {
|
||||||
|
List<Category> subCategories = emptyList();
|
||||||
|
|
||||||
|
if (!subCategoryIds.isEmpty()) {
|
||||||
|
try {
|
||||||
|
subCategories = categoryPort.findAllByIds(subCategoryIds);
|
||||||
|
} catch (CategoryNotFoundException exception) {
|
||||||
|
throw new CategoryEditionException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
categoryBuilder.withSubCategories(subCategories);
|
||||||
|
}
|
||||||
|
|
||||||
|
Category updatedCategory = categoryBuilder.build();
|
||||||
|
categoryPort.save(updatedCategory);
|
||||||
|
return updatedCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteCategory(UUID categoryId) {
|
||||||
|
if (!categoryPort.existsById(categoryId)) {
|
||||||
|
throw new CategoryNotFoundException(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (categoryPort.existsAnyAssociatedPublication(categoryId)) {
|
||||||
|
throw new CategoryDeletionException(categoryId, "some publications are associated to the category");
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryPort.deleteById(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Category> getAll() {
|
||||||
|
return categoryPort.findAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.codiki.domain.category.exception;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.codiki.domain.exception.FunctionnalException;
|
||||||
|
|
||||||
|
public class CategoryDeletionException extends FunctionnalException {
|
||||||
|
public CategoryDeletionException(UUID categoryId, String cause) {
|
||||||
|
super(String.format("Impossible to delete category with id %s. Cause: %s.", categoryId, cause));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.codiki.domain.category.exception;
|
||||||
|
|
||||||
|
import org.codiki.domain.exception.FunctionnalException;
|
||||||
|
|
||||||
|
public class CategoryEditionException extends FunctionnalException {
|
||||||
|
public CategoryEditionException(String reason) {
|
||||||
|
super(String.format("Impossible to edit a category because : %s.", reason));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryEditionException(FunctionnalException cause) {
|
||||||
|
super("Impossible to edit a category due to a root cause.", cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package org.codiki.domain.category.model.builder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.codiki.domain.category.model.Category;
|
||||||
|
|
||||||
|
public class CategoryBuilder {
|
||||||
|
private UUID id;
|
||||||
|
private String name;
|
||||||
|
private List<Category> subCategories;
|
||||||
|
|
||||||
|
public static CategoryBuilder aCategory() {
|
||||||
|
return new CategoryBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private CategoryBuilder() {}
|
||||||
|
|
||||||
|
public CategoryBuilder basedOn(Category category) {
|
||||||
|
this.id = category.id();
|
||||||
|
this.name = category.name();
|
||||||
|
this.subCategories = category.subCategories();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryBuilder withId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryBuilder withName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryBuilder withSubCategories(List<Category> subCategories) {
|
||||||
|
this.subCategories = subCategories;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryBuilder withSubCategory(Category subCategory) {
|
||||||
|
if (subCategories == null) {
|
||||||
|
subCategories = new ArrayList<>();
|
||||||
|
}
|
||||||
|
subCategories.add(subCategory);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category build() {
|
||||||
|
return new Category(id, name, subCategories);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,23 @@
|
|||||||
package org.codiki.domain.category.port;
|
package org.codiki.domain.category.port;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.domain.category.model.Category;
|
import org.codiki.domain.category.model.Category;
|
||||||
|
|
||||||
public interface CategoryPort {
|
public interface CategoryPort {
|
||||||
Optional<Category> findById(final UUID uuid);
|
Optional<Category> findById(UUID uuid);
|
||||||
|
|
||||||
|
void save(Category category);
|
||||||
|
|
||||||
|
List<Category> findAllByIds(List<UUID> subCategoryIds);
|
||||||
|
|
||||||
|
boolean existsAnyAssociatedPublication(UUID categoryId);
|
||||||
|
|
||||||
|
void deleteById(UUID categoryId);
|
||||||
|
|
||||||
|
boolean existsById(UUID categoryId);
|
||||||
|
|
||||||
|
List<Category> findAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package org.codiki.exposition.category;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.springframework.http.HttpStatus.CREATED;
|
||||||
|
import static org.springframework.http.HttpStatus.NO_CONTENT;
|
||||||
|
import org.codiki.application.category.CategoryUseCases;
|
||||||
|
import org.codiki.domain.category.model.Category;
|
||||||
|
import org.codiki.exposition.category.model.CategoryDto;
|
||||||
|
import org.codiki.exposition.category.model.CategoryEditionRequest;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/categories")
|
||||||
|
public class CategoryController {
|
||||||
|
private final CategoryUseCases categoryUseCases;
|
||||||
|
|
||||||
|
public CategoryController(CategoryUseCases categoryUseCases) {
|
||||||
|
this.categoryUseCases = categoryUseCases;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@ResponseStatus(CREATED)
|
||||||
|
public CategoryDto createCategory(@RequestBody CategoryEditionRequest request) {
|
||||||
|
Category createdCategory = categoryUseCases.createCategory(request.name(), request.subCategoryIds());
|
||||||
|
return new CategoryDto(createdCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{categoryId}")
|
||||||
|
public CategoryDto updateCategory(
|
||||||
|
@PathVariable("categoryId") UUID categoryId,
|
||||||
|
@RequestBody CategoryEditionRequest request
|
||||||
|
) {
|
||||||
|
Category createdCategory = categoryUseCases.updateCategory(
|
||||||
|
categoryId,
|
||||||
|
request.name(),
|
||||||
|
request.subCategoryIds()
|
||||||
|
);
|
||||||
|
return new CategoryDto(createdCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{categoryId}")
|
||||||
|
@ResponseStatus(NO_CONTENT)
|
||||||
|
public void deleteCategory(@PathVariable("categoryId") UUID categoryId) {
|
||||||
|
categoryUseCases.deleteCategory(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public List<CategoryDto> getAllCategories() {
|
||||||
|
return categoryUseCases.getAll()
|
||||||
|
.stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.codiki.exposition.category.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public record CategoryEditionRequest(
|
||||||
|
String name,
|
||||||
|
List<UUID> subCategoryIds
|
||||||
|
) {}
|
||||||
@@ -4,6 +4,8 @@ import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
|||||||
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||||
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
|
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
|
||||||
|
import org.codiki.domain.category.exception.CategoryDeletionException;
|
||||||
|
import org.codiki.domain.category.exception.CategoryEditionException;
|
||||||
import org.codiki.domain.category.exception.CategoryNotFoundException;
|
import org.codiki.domain.category.exception.CategoryNotFoundException;
|
||||||
import org.codiki.domain.exception.LoginFailureException;
|
import org.codiki.domain.exception.LoginFailureException;
|
||||||
import org.codiki.domain.exception.RefreshTokenDoesNotExistException;
|
import org.codiki.domain.exception.RefreshTokenDoesNotExistException;
|
||||||
@@ -66,4 +68,16 @@ public class GlobalControllerExceptionHandler {
|
|||||||
public void handlePublicationUpdateForbiddenException() {
|
public void handlePublicationUpdateForbiddenException() {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResponseStatus(BAD_REQUEST)
|
||||||
|
@ExceptionHandler(CategoryEditionException.class)
|
||||||
|
public void handleCategoryEditionException() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseStatus(BAD_REQUEST)
|
||||||
|
@ExceptionHandler(CategoryDeletionException.class)
|
||||||
|
public void handleCategoryDeletionException() {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package org.codiki.exposition.configuration.security;
|
package org.codiki.exposition.configuration.security;
|
||||||
|
|
||||||
|
import static org.springframework.http.HttpMethod.DELETE;
|
||||||
import static org.springframework.http.HttpMethod.GET;
|
import static org.springframework.http.HttpMethod.GET;
|
||||||
import static org.springframework.http.HttpMethod.OPTIONS;
|
import static org.springframework.http.HttpMethod.OPTIONS;
|
||||||
import static org.springframework.http.HttpMethod.POST;
|
import static org.springframework.http.HttpMethod.POST;
|
||||||
|
import static org.springframework.http.HttpMethod.PUT;
|
||||||
import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
|
import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -41,6 +43,7 @@ public class SecurityConfiguration {
|
|||||||
.requestMatchers(
|
.requestMatchers(
|
||||||
GET,
|
GET,
|
||||||
"/api/health/check",
|
"/api/health/check",
|
||||||
|
"/api/categories",
|
||||||
"/error"
|
"/error"
|
||||||
).permitAll()
|
).permitAll()
|
||||||
.requestMatchers(
|
.requestMatchers(
|
||||||
@@ -48,6 +51,18 @@ public class SecurityConfiguration {
|
|||||||
"/api/users/login",
|
"/api/users/login",
|
||||||
"/api/users/refresh-token"
|
"/api/users/refresh-token"
|
||||||
).permitAll()
|
).permitAll()
|
||||||
|
.requestMatchers(
|
||||||
|
POST,
|
||||||
|
"/api/categories"
|
||||||
|
).hasRole("ADMIN")
|
||||||
|
.requestMatchers(
|
||||||
|
PUT,
|
||||||
|
"/api/categories/{categoryId}"
|
||||||
|
).hasRole("ADMIN")
|
||||||
|
.requestMatchers(
|
||||||
|
DELETE,
|
||||||
|
"/api/categories/{categoryId}"
|
||||||
|
).hasRole("ADMIN")
|
||||||
.requestMatchers(OPTIONS).permitAll()
|
.requestMatchers(OPTIONS).permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package org.codiki.infrastructure.category;
|
package org.codiki.infrastructure.category;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.codiki.domain.category.exception.CategoryNotFoundException;
|
||||||
import org.codiki.domain.category.model.Category;
|
import org.codiki.domain.category.model.Category;
|
||||||
import org.codiki.domain.category.port.CategoryPort;
|
import org.codiki.domain.category.port.CategoryPort;
|
||||||
import org.codiki.infrastructure.category.model.CategoryEntity;
|
import org.codiki.infrastructure.category.model.CategoryEntity;
|
||||||
@@ -22,4 +24,49 @@ public class CategoryJpaAdapter implements CategoryPort {
|
|||||||
return categoryRepository.findById(categoryId)
|
return categoryRepository.findById(categoryId)
|
||||||
.map(CategoryEntity::toDomain);
|
.map(CategoryEntity::toDomain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(Category category) {
|
||||||
|
CategoryEntity categoryEntity = new CategoryEntity(category);
|
||||||
|
categoryRepository.save(categoryEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Category> findAllByIds(List<UUID> categoryIds) {
|
||||||
|
final List<Category> categories = categoryRepository.findAllById(categoryIds)
|
||||||
|
.stream()
|
||||||
|
.map(CategoryEntity::toDomain)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Optional<UUID> notFoundCategoryId = categoryIds.stream()
|
||||||
|
.filter(categoryId -> categories.stream().map(Category::id).noneMatch(categoryId::equals))
|
||||||
|
.findFirst();
|
||||||
|
if (notFoundCategoryId.isPresent()) {
|
||||||
|
throw new CategoryNotFoundException(notFoundCategoryId.get());
|
||||||
|
}
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean existsAnyAssociatedPublication(UUID categoryId) {
|
||||||
|
return categoryRepository.existsAnyAssociatedPublication(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteById(UUID categoryId) {
|
||||||
|
categoryRepository.deleteById(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean existsById(UUID categoryId) {
|
||||||
|
return categoryRepository.existsById(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Category> findAll() {
|
||||||
|
return categoryRepository.findAll()
|
||||||
|
.stream()
|
||||||
|
.map(CategoryEntity::toDomain)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,24 @@
|
|||||||
package org.codiki.infrastructure.category.model;
|
package org.codiki.infrastructure.category.model;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.stream.Collectors.toSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.codiki.domain.category.model.Category;
|
import org.codiki.domain.category.model.Category;
|
||||||
|
|
||||||
|
import static jakarta.persistence.CascadeType.ALL;
|
||||||
|
import static jakarta.persistence.FetchType.LAZY;
|
||||||
|
import jakarta.persistence.CascadeType;
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.OneToMany;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -25,12 +36,18 @@ public class CategoryEntity {
|
|||||||
private UUID id;
|
private UUID id;
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String name;
|
private String name;
|
||||||
// List<Category> subCategories
|
@OneToMany
|
||||||
|
@JoinColumn(name = "parent_category_id")
|
||||||
|
private Set<CategoryEntity> subCategories;
|
||||||
|
|
||||||
public CategoryEntity(Category category) {
|
public CategoryEntity(Category category) {
|
||||||
this(
|
this(
|
||||||
category.id(),
|
category.id(),
|
||||||
category.name()
|
category.name(),
|
||||||
|
category.subCategories()
|
||||||
|
.stream()
|
||||||
|
.map(CategoryEntity::new)
|
||||||
|
.collect(toSet())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +55,9 @@ public class CategoryEntity {
|
|||||||
return new Category(
|
return new Category(
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
emptyList()
|
subCategories.stream()
|
||||||
|
.map(CategoryEntity::toDomain)
|
||||||
|
.toList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import org.codiki.infrastructure.category.model.CategoryEntity;
|
import org.codiki.infrastructure.category.model.CategoryEntity;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
public interface CategoryRepository extends JpaRepository<CategoryEntity, UUID> {
|
public interface CategoryRepository extends JpaRepository<CategoryEntity, UUID> {
|
||||||
|
@Query(value = """
|
||||||
|
SELECT (
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM publication p
|
||||||
|
WHERE p.category_id = :categoryId
|
||||||
|
) > 0
|
||||||
|
""", nativeQuery = true)
|
||||||
|
boolean existsAnyAssociatedPublication(@Param("categoryId") UUID categoryId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,11 @@ CREATE INDEX refresh_token_fk_user_id_idx ON user_role (user_id);
|
|||||||
CREATE TABLE IF NOT EXISTS category (
|
CREATE TABLE IF NOT EXISTS category (
|
||||||
id UUID NOT NULL,
|
id UUID NOT NULL,
|
||||||
name VARCHAR NOT NULL,
|
name VARCHAR NOT NULL,
|
||||||
CONSTRAINT category_pk PRIMARY KEY (id)
|
parent_category_id UUID,
|
||||||
|
CONSTRAINT category_pk PRIMARY KEY (id),
|
||||||
|
CONSTRAINT category_parent_category_id_fk FOREIGN KEY (parent_category_id) REFERENCES category (id)
|
||||||
);
|
);
|
||||||
|
CREATE INDEX category_parent_category_id_idx ON category (parent_category_id);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS publication (
|
CREATE TABLE IF NOT EXISTS publication (
|
||||||
id UUID NOT NULL,
|
id UUID NOT NULL,
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
meta {
|
|
||||||
name: Login
|
|
||||||
type: http
|
|
||||||
seq: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
post {
|
|
||||||
url: {{url}}/api/users/login
|
|
||||||
body: json
|
|
||||||
auth: none
|
|
||||||
}
|
|
||||||
|
|
||||||
body:json {
|
|
||||||
{
|
|
||||||
"id": "5ad462b8-8f9e-4a26-bb86-c74fef5d11b6",
|
|
||||||
"password": "password"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
vars {
|
vars {
|
||||||
url: http://localhost:8080
|
url: http://localhost:8080
|
||||||
publicationId: fce1de27-11c6-4deb-a248-b63288c00037
|
publicationId: fce1de27-11c6-4deb-a248-b63288c00037
|
||||||
bearerToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1YWQ0NjJiOC04ZjllLTRhMjYtYmI4Ni1jNzRmZWY1ZDExYjYiLCJleHAiOjE3MTAyNDk1MjJ9.gKS4h4sWXlFn4DImsXk6NDa2wEz8ZpG0qoX-IaGPHHaMJObds4qVqK91WPgrVQ6Ci0_W6wCoDImLrrPEDgtJag
|
bearerToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxNWExM2RjNy0wMjlkLTRlYWItYTYzZC1jMWU5NmY5MDI0MWQiLCJleHAiOjE3MTAyNjU4MTZ9.t8tZce0gAXZ_DC2QEsdvJn6m-Ykjou1v4zDUIPWhzfWYR-JTeiFsfa68jkFwK2WT1aMvZppnVuc991g-yAjrPg
|
||||||
|
categoryId: 172fa901-3f4b-4540-92f3-1c15820e8ec9
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user