Compare commits

3 Commits

Author SHA1 Message Date
Florian THIERRY
9fcfc04117 Change category field of publication entity to its id. 2024-03-14 14:07:44 +01:00
Florian THIERRY
5d267111a9 Add illustration id to publication entity. 2024-03-14 13:58:25 +01:00
Florian THIERRY
2dc386e896 Add publisher id in picture entity. 2024-03-14 13:40:32 +01:00
19 changed files with 125 additions and 94 deletions

View File

@@ -27,6 +27,10 @@ public class CategoryUseCases {
return categoryPort.findById(categoryId); return categoryPort.findById(categoryId);
} }
public boolean existsById(UUID categoryId) {
return categoryPort.existsById(categoryId);
}
public Category createCategory(String name, List<UUID> subCategoryIds) { public Category createCategory(String name, List<UUID> subCategoryIds) {
if (isNull(name)) { if (isNull(name)) {
throw new CategoryEditionException("name can not be empty"); throw new CategoryEditionException("name can not be empty");

View File

@@ -5,21 +5,30 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import static org.codiki.domain.picture.model.builder.PictureBuilder.aPicture; import static org.codiki.domain.picture.model.builder.PictureBuilder.aPicture;
import org.codiki.application.user.UserUseCases;
import org.codiki.domain.exception.AuthenticationRequiredException;
import org.codiki.domain.picture.model.Picture; import org.codiki.domain.picture.model.Picture;
import org.codiki.domain.picture.port.PicturePort; import org.codiki.domain.picture.port.PicturePort;
import org.codiki.domain.user.model.User;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
public class PictureUseCases { public class PictureUseCases {
private final PicturePort picturePort; private final PicturePort picturePort;
private final UserUseCases userUseCases;
public PictureUseCases(PicturePort picturePort) { public PictureUseCases(PicturePort picturePort, UserUseCases userUseCases) {
this.picturePort = picturePort; this.picturePort = picturePort;
this.userUseCases = userUseCases;
} }
public Picture createPicture(File pictureFile) { public Picture createPicture(File pictureFile) {
User authenticatedUser = userUseCases.getAuthenticatedUser()
.orElseThrow(AuthenticationRequiredException::new);
Picture newPicture = aPicture() Picture newPicture = aPicture()
.withId(UUID.randomUUID()) .withId(UUID.randomUUID())
.withPublisher(authenticatedUser)
.withContentFile(pictureFile) .withContentFile(pictureFile)
.build(); .build();
@@ -35,4 +44,8 @@ public class PictureUseCases {
public Optional<Picture> findById(UUID pictureId) { public Optional<Picture> findById(UUID pictureId) {
return picturePort.findById(pictureId); return picturePort.findById(pictureId);
} }
public boolean existsById(UUID pictureId) {
return picturePort.existsById(pictureId);
}
} }

View File

@@ -19,8 +19,8 @@ public class PublicationCreationRequestValidator {
throw new PublicationEditionException("description cannot be null"); throw new PublicationEditionException("description cannot be null");
} }
if (request.pictureId() == null) { if (request.illustrationId() == null) {
throw new PublicationEditionException("pictureId cannot be null"); throw new PublicationEditionException("illustrationId cannot be null");
} }
} }
} }

View File

@@ -13,7 +13,7 @@ public class PublicationUpdateRequestValidator {
isNull(request.title()) && isNull(request.title()) &&
isNull(request.text()) && isNull(request.text()) &&
isNull(request.description()) && isNull(request.description()) &&
isNull(request.pictureId()) && isNull(request.illustrationId()) &&
isNull(request.categoryId()) isNull(request.categoryId())
) { ) {
throw new PublicationEditionException("no any field is filled"); throw new PublicationEditionException("no any field is filled");

View File

@@ -15,7 +15,6 @@ 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.exception.AuthenticationRequiredException; import org.codiki.domain.exception.AuthenticationRequiredException;
import org.codiki.domain.picture.exception.PictureNotFoundException; import org.codiki.domain.picture.exception.PictureNotFoundException;
import org.codiki.domain.picture.model.Picture;
import org.codiki.domain.publication.exception.PublicationEditionException; import org.codiki.domain.publication.exception.PublicationEditionException;
import org.codiki.domain.publication.exception.PublicationNotFoundException; import org.codiki.domain.publication.exception.PublicationNotFoundException;
import org.codiki.domain.publication.exception.PublicationUpdateForbiddenException; import org.codiki.domain.publication.exception.PublicationUpdateForbiddenException;
@@ -63,15 +62,17 @@ public class PublicationUseCases {
User authenticatedUser = userUseCases.getAuthenticatedUser() User authenticatedUser = userUseCases.getAuthenticatedUser()
.orElseThrow(AuthenticationRequiredException::new); .orElseThrow(AuthenticationRequiredException::new);
Category category = categoryUseCases.findById(request.categoryId()) if (!categoryUseCases.existsById(request.categoryId())) {
.orElseThrow(() -> new PublicationEditionException( throw new PublicationEditionException(
new CategoryNotFoundException(request.categoryId()) new CategoryNotFoundException(request.categoryId())
)); );
}
Picture picture = pictureUseCases.findById(request.pictureId()) if (!pictureUseCases.existsById(request.illustrationId())) {
.orElseThrow(() -> new PublicationEditionException( throw new PublicationEditionException(
new PictureNotFoundException(request.pictureId()) new PictureNotFoundException(request.illustrationId())
)); );
}
Publication newPublication = aPublication() Publication newPublication = aPublication()
.withId(UUID.randomUUID()) .withId(UUID.randomUUID())
@@ -79,10 +80,10 @@ public class PublicationUseCases {
.withTitle(request.title()) .withTitle(request.title())
.withText(request.text()) .withText(request.text())
.withDescription(request.description()) .withDescription(request.description())
.withPicture(picture)
.withCreationDate(ZonedDateTime.now(clock)) .withCreationDate(ZonedDateTime.now(clock))
.withIllustrationId(request.illustrationId())
.withCategoryId(request.categoryId())
.withAuthor(anAuthor().basedOn(authenticatedUser).build()) .withAuthor(anAuthor().basedOn(authenticatedUser).build())
.withCategory(category)
.build(); .build();
publicationPort.save(newPublication); publicationPort.save(newPublication);
@@ -117,21 +118,23 @@ public class PublicationUseCases {
publicationBuilder.withDescription(request.description()); publicationBuilder.withDescription(request.description());
} }
if (!isNull(request.pictureId())) { if (!isNull(request.illustrationId())) {
Picture picture = pictureUseCases.findById(request.pictureId()) if (!pictureUseCases.existsById(request.illustrationId())) {
.orElseThrow(() -> new PublicationEditionException( throw new PublicationEditionException(
new PictureNotFoundException(request.pictureId()) new PictureNotFoundException(request.illustrationId())
)); );
publicationBuilder.withPicture(picture); }
publicationBuilder.withIllustrationId(request.illustrationId());
} }
if (!isNull(request.categoryId())) { if (!isNull(request.categoryId())) {
Category newCategory = categoryUseCases.findById(request.categoryId()) if (!categoryUseCases.existsById(request.categoryId())) {
.orElseThrow(() -> new PublicationEditionException( throw new PublicationEditionException(
new CategoryNotFoundException(request.categoryId()) new CategoryNotFoundException(request.categoryId())
)); );
}
publicationBuilder.withCategory(newCategory); publicationBuilder.withCategoryId(request.categoryId());
} }
Publication updatedPublication = publicationBuilder.build(); Publication updatedPublication = publicationBuilder.build();

View File

@@ -5,5 +5,6 @@ import java.util.UUID;
public record Picture( public record Picture(
UUID id, UUID id,
UUID publisherId,
File contentFile File contentFile
) {} ) {}

View File

@@ -4,9 +4,11 @@ import java.io.File;
import java.util.UUID; import java.util.UUID;
import org.codiki.domain.picture.model.Picture; import org.codiki.domain.picture.model.Picture;
import org.codiki.domain.user.model.User;
public class PictureBuilder { public class PictureBuilder {
private UUID id; private UUID id;
private UUID publisherId;
private File contentFile; private File contentFile;
private PictureBuilder() {} private PictureBuilder() {}
@@ -26,6 +28,14 @@ public class PictureBuilder {
return this; return this;
} }
public PictureBuilder withPublisherId(UUID publisherId) {
this.publisherId = publisherId;
return this;
}
public PictureBuilder withPublisher(User publisher) {
return withPublisherId(publisher.id());
}
public PictureBuilder withContentFile(File contentFile) { public PictureBuilder withContentFile(File contentFile) {
this.contentFile = contentFile; this.contentFile = contentFile;
@@ -33,6 +43,6 @@ public class PictureBuilder {
} }
public Picture build() { public Picture build() {
return new Picture(id, contentFile); return new Picture(id, publisherId, contentFile);
} }
} }

View File

@@ -3,9 +3,6 @@ package org.codiki.domain.publication.model;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.UUID; import java.util.UUID;
import org.codiki.domain.category.model.Category;
import org.codiki.domain.picture.model.Picture;
public record Publication( public record Publication(
UUID id, UUID id,
String key, String key,
@@ -13,8 +10,8 @@ public record Publication(
String text, String text,
String description, String description,
ZonedDateTime creationDate, ZonedDateTime creationDate,
Picture picture, UUID illustrationId,
Author author, UUID categoryId,
Category category Author author
) { ) {
} }

View File

@@ -6,6 +6,6 @@ public record PublicationEditionRequest(
String title, String title,
String text, String text,
String description, String description,
UUID pictureId, UUID illustrationId,
UUID categoryId UUID categoryId
) {} ) {}

View File

@@ -20,7 +20,7 @@ public class AuthorBuilder {
return new AuthorBuilder() return new AuthorBuilder()
.withId(user.id()) .withId(user.id())
// .withName(user.name()) // .withName(user.name())
// .withImage(user.pictureId()) // .withImage(user.illustrationId())
; ;
} }

View File

@@ -3,9 +3,8 @@ package org.codiki.domain.publication.model.builder;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.UUID; import java.util.UUID;
import org.codiki.domain.picture.model.Picture;
import org.codiki.domain.publication.model.Author;
import org.codiki.domain.category.model.Category; import org.codiki.domain.category.model.Category;
import org.codiki.domain.publication.model.Author;
import org.codiki.domain.publication.model.Publication; import org.codiki.domain.publication.model.Publication;
public class PublicationBuilder { public class PublicationBuilder {
@@ -14,10 +13,10 @@ public class PublicationBuilder {
private String title; private String title;
private String text; private String text;
private String description; private String description;
private Picture picture;
private ZonedDateTime creationDate; private ZonedDateTime creationDate;
private UUID illustrationId;
private UUID categoryId;
private Author author; private Author author;
private Category category;
private PublicationBuilder() {} private PublicationBuilder() {}
@@ -25,6 +24,19 @@ public class PublicationBuilder {
return new PublicationBuilder(); return new PublicationBuilder();
} }
public PublicationBuilder basedOn(Publication publication) {
return new PublicationBuilder()
.withId(publication.id())
.withKey(publication.key())
.withTitle(publication.title())
.withText(publication.text())
.withDescription(publication.description())
.withCreationDate(publication.creationDate())
.withIllustrationId(publication.illustrationId())
.withCategoryId(publication.categoryId())
.withAuthor(publication.author());
}
public PublicationBuilder withId(UUID id) { public PublicationBuilder withId(UUID id) {
this.id = id; this.id = id;
return this; return this;
@@ -50,23 +62,23 @@ public class PublicationBuilder {
return this; return this;
} }
public PublicationBuilder withPicture(Picture picture) {
this.picture = picture;
return this;
}
public PublicationBuilder withCreationDate(ZonedDateTime creationDate) { public PublicationBuilder withCreationDate(ZonedDateTime creationDate) {
this.creationDate = creationDate; this.creationDate = creationDate;
return this; return this;
} }
public PublicationBuilder withAuthor(Author author) { public PublicationBuilder withIllustrationId(UUID illustrationId) {
this.author = author; this.illustrationId = illustrationId;
return this; return this;
} }
public PublicationBuilder withCategory(Category category) { public PublicationBuilder withCategoryId(UUID categoryId) {
this.category = category; this.categoryId = categoryId;
return this;
}
public PublicationBuilder withAuthor(Author author) {
this.author = author;
return this; return this;
} }
@@ -77,22 +89,10 @@ public class PublicationBuilder {
title, title,
text, text,
description, description,
creationDate, picture, creationDate,
author, illustrationId,
category categoryId,
author
); );
} }
public PublicationBuilder basedOn(Publication publication) {
return new PublicationBuilder()
.withId(publication.id())
.withKey(publication.key())
.withTitle(publication.title())
.withText(publication.text())
.withDescription(publication.description())
.withPicture(publication.picture())
.withCreationDate(publication.creationDate())
.withAuthor(publication.author())
.withCategory(publication.category());
}
} }

View File

@@ -13,9 +13,9 @@ public record PublicationDto(
String text, String text,
String description, String description,
ZonedDateTime creationDate, ZonedDateTime creationDate,
UUID picture, UUID illustrationId,
AuthorDto author, UUID categoryId,
CategoryDto category AuthorDto author
) { ) {
public PublicationDto(Publication publication) { public PublicationDto(Publication publication) {
this( this(
@@ -25,9 +25,9 @@ public record PublicationDto(
publication.text(), publication.text(),
publication.description(), publication.description(),
publication.creationDate(), publication.creationDate(),
publication.picture().id(), publication.illustrationId(),
new AuthorDto(publication.author()), publication.categoryId(),
new CategoryDto(publication.category()) new AuthorDto(publication.author())
); );
} }
} }

View File

@@ -8,10 +8,10 @@ public record PublicationEditionRequestDto(
String title, String title,
String text, String text,
String description, String description,
UUID pictureId, UUID illustrationId,
UUID categoryId UUID categoryId
) { ) {
public PublicationEditionRequest toDomain() { public PublicationEditionRequest toDomain() {
return new PublicationEditionRequest(title, text, description, pictureId, categoryId); return new PublicationEditionRequest(title, text, description, illustrationId, categoryId);
} }
} }

View File

@@ -4,6 +4,7 @@ import java.util.UUID;
import org.codiki.domain.picture.model.Picture; import org.codiki.domain.picture.model.Picture;
import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.Table; import jakarta.persistence.Table;
@@ -21,12 +22,15 @@ import lombok.Setter;
public class PictureEntity { public class PictureEntity {
@Id @Id
private UUID id; private UUID id;
@Column(nullable = false)
private UUID publisherId;
public PictureEntity(Picture picture) { public PictureEntity(Picture picture) {
id = picture.id(); id = picture.id();
publisherId = picture.publisherId();
} }
public Picture toDomain() { public Picture toDomain() {
return new Picture(id, null); return new Picture(id, publisherId, null);
} }
} }

View File

@@ -24,13 +24,13 @@ public class AuthorEntity {
private UUID id; private UUID id;
@Column(nullable = false) @Column(nullable = false)
private String name; private String name;
// private String pictureId; // private String illustrationId;
public AuthorEntity(Author author) { public AuthorEntity(Author author) {
this( this(
author.id(), author.id(),
author.name() author.name()
// author.pictureId() // author.illustrationId()
); );
} }

View File

@@ -5,7 +5,6 @@ import java.util.UUID;
import org.codiki.domain.publication.model.Publication; import org.codiki.domain.publication.model.Publication;
import org.codiki.infrastructure.category.model.CategoryEntity; import org.codiki.infrastructure.category.model.CategoryEntity;
import org.codiki.infrastructure.picture.model.PictureEntity;
import static jakarta.persistence.FetchType.LAZY; import static jakarta.persistence.FetchType.LAZY;
import jakarta.persistence.Column; import jakarta.persistence.Column;
@@ -38,15 +37,13 @@ public class PublicationEntity {
private String description; private String description;
@Column(nullable = false) @Column(nullable = false)
private ZonedDateTime creationDate; private ZonedDateTime creationDate;
@ManyToOne(fetch = LAZY) @Column(nullable = false)
@JoinColumn(name = "picture_id") private UUID illustrationId;
private PictureEntity picture; @Column(nullable = false)
private UUID categoryId;
@ManyToOne(fetch = LAZY) @ManyToOne(fetch = LAZY)
@JoinColumn(name = "author_id") @JoinColumn(name = "author_id")
private AuthorEntity author; private AuthorEntity author;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "category_id")
private CategoryEntity category;
public PublicationEntity(Publication publication) { public PublicationEntity(Publication publication) {
this( this(
@@ -56,9 +53,9 @@ public class PublicationEntity {
publication.text(), publication.text(),
publication.description(), publication.description(),
publication.creationDate(), publication.creationDate(),
new PictureEntity(publication.picture()), publication.illustrationId(),
new AuthorEntity(publication.author()), publication.categoryId(),
new CategoryEntity(publication.category()) new AuthorEntity(publication.author())
); );
} }
@@ -69,9 +66,10 @@ public class PublicationEntity {
title, title,
text, text,
description, description,
creationDate, picture.toDomain(), creationDate,
author.toDomain(), illustrationId,
category.toDomain() categoryId,
author.toDomain()
); );
} }
} }

View File

@@ -12,9 +12,7 @@ public interface PublicationRepository extends JpaRepository<PublicationEntity,
@Query(""" @Query("""
SELECT p SELECT p
FROM PublicationEntity p FROM PublicationEntity p
JOIN FETCH p.picture pi
JOIN FETCH p.author a JOIN FETCH p.author a
JOIN FETCH p.category c
WHERE p.id = :publicationId WHERE p.id = :publicationId
""") """)
Optional<PublicationEntity> findById(@Param("publicationId") UUID publicationId); Optional<PublicationEntity> findById(@Param("publicationId") UUID publicationId);

View File

@@ -33,8 +33,11 @@ CREATE INDEX category_parent_category_id_idx ON category (parent_category_id);
CREATE TABLE IF NOT EXISTS picture ( CREATE TABLE IF NOT EXISTS picture (
id UUID NOT NULL, id UUID NOT NULL,
CONSTRAINT picture_pk PRIMARY KEY (id) publisher_id UUID NOT NULL,
CONSTRAINT picture_pk PRIMARY KEY (id),
CONSTRAINT picture_publisher_id_fk FOREIGN KEY (publisher_id) REFERENCES "user" (id)
); );
CREATE INDEX picture_publisher_id_idx ON picture (publisher_id);
CREATE TABLE IF NOT EXISTS publication ( CREATE TABLE IF NOT EXISTS publication (
id UUID NOT NULL, id UUID NOT NULL,
@@ -43,15 +46,15 @@ CREATE TABLE IF NOT EXISTS publication (
text VARCHAR NOT NULL, text VARCHAR NOT NULL,
description VARCHAR NOT NULL, description VARCHAR NOT NULL,
creation_date TIMESTAMP NOT NULL, creation_date TIMESTAMP NOT NULL,
picture_id UUID NOT NULL, illustration_id UUID NOT NULL,
author_id UUID NOT NULL, author_id UUID NOT NULL,
category_id UUID NOT NULL, category_id UUID NOT NULL,
CONSTRAINT publication_pk PRIMARY KEY (id), CONSTRAINT publication_pk PRIMARY KEY (id),
CONSTRAINT publication_picture_id_fk FOREIGN KEY (picture_id) REFERENCES picture (id), CONSTRAINT publication_picture_id_fk FOREIGN KEY (illustration_id) REFERENCES picture (id),
CONSTRAINT publication_author_id_fk FOREIGN KEY (author_id) REFERENCES "user" (id), CONSTRAINT publication_author_id_fk FOREIGN KEY (author_id) REFERENCES "user" (id),
CONSTRAINT publication_category_id_fk FOREIGN KEY (category_id) REFERENCES category (id) CONSTRAINT publication_category_id_fk FOREIGN KEY (category_id) REFERENCES category (id)
); );
CREATE INDEX publication_picture_id_idx ON publication (picture_id); CREATE INDEX publication_picture_id_idx ON publication (illustration_id);
CREATE INDEX publication_author_id_idx ON publication (author_id); CREATE INDEX publication_author_id_idx ON publication (author_id);
CREATE INDEX publication_category_id_idx ON publication (category_id); CREATE INDEX publication_category_id_idx ON publication (category_id);

View File

@@ -1,7 +1,7 @@
vars { vars {
url: http://localhost:8080 url: http://localhost:8080
publicationId: e23831a6-9cc0-4f3d-9efa-7a1cae191cb1 publicationId: e23831a6-9cc0-4f3d-9efa-7a1cae191cb1
bearerToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1YWQ0NjJiOC04ZjllLTRhMjYtYmI4Ni1jNzRmZWY1ZDExYjYiLCJleHAiOjE3MTA0MDc5Mjd9.QdanZXjfLztIVJU-pRS3gZxnC4GIycyhmlCkhYSPchiXpeNzruw_GY3fH1_qshC_AjOCSqGmCq3X1S_zVFdodQ bearerToken: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1YWQ0NjJiOC04ZjllLTRhMjYtYmI4Ni1jNzRmZWY1ZDExYjYiLCJleHAiOjE3MTA0MjI2NTl9.yHT26uwON5Kk5CWgNvzq2a9OrdJACG4Rk034GPKoZlaxXwK0k8meSHVlrX4ZqTyR3zoL3fm_ujootZRISqOPZw
categoryId: 172fa901-3f4b-4540-92f3-1c15820e8ec9 categoryId: 172fa901-3f4b-4540-92f3-1c15820e8ec9
pictureId: 65b660b7-66bb-4e4a-a62c-fd0ca101f972 pictureId: 65b660b7-66bb-4e4a-a62c-fd0ca101f972
} }