diff --git a/codiki-domain/src/main/java/org/codiki/domain/publication/model/Author.java b/codiki-domain/src/main/java/org/codiki/domain/publication/model/Author.java
index b4d7c2a..57fbd5f 100644
--- a/codiki-domain/src/main/java/org/codiki/domain/publication/model/Author.java
+++ b/codiki-domain/src/main/java/org/codiki/domain/publication/model/Author.java
@@ -2,8 +2,6 @@ package org.codiki.domain.publication.model;
import java.util.UUID;
-import org.codiki.domain.user.model.User;
-
public record Author(
UUID id,
String name,
diff --git a/codiki-exposition/pom.xml b/codiki-exposition/pom.xml
index dd17eec..95b3ca0 100644
--- a/codiki-exposition/pom.xml
+++ b/codiki-exposition/pom.xml
@@ -25,6 +25,10 @@
org.springframework.boot
spring-boot-starter-web
+
+ org.projectlombok
+ lombok
+
diff --git a/codiki-exposition/src/main/java/org/codiki/exposition/category/model/CategoryDto.java b/codiki-exposition/src/main/java/org/codiki/exposition/category/model/CategoryDto.java
new file mode 100644
index 0000000..d103929
--- /dev/null
+++ b/codiki-exposition/src/main/java/org/codiki/exposition/category/model/CategoryDto.java
@@ -0,0 +1,23 @@
+package org.codiki.exposition.category.model;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.codiki.domain.category.model.Category;
+
+public record CategoryDto(
+ UUID id,
+ String name,
+ List subCategories
+) {
+ public CategoryDto(Category category) {
+ this(
+ category.id(),
+ category.name(),
+ category.subCategories()
+ .stream()
+ .map(CategoryDto::new)
+ .toList()
+ );
+ }
+}
diff --git a/codiki-exposition/src/main/java/org/codiki/exposition/publication/PublicationController.java b/codiki-exposition/src/main/java/org/codiki/exposition/publication/PublicationController.java
new file mode 100644
index 0000000..5c8072e
--- /dev/null
+++ b/codiki-exposition/src/main/java/org/codiki/exposition/publication/PublicationController.java
@@ -0,0 +1,27 @@
+package org.codiki.exposition.publication;
+
+import org.codiki.application.publication.PublicationUseCases;
+import org.codiki.domain.publication.model.Publication;
+import org.codiki.domain.publication.model.PublicationCreationRequest;
+import org.codiki.exposition.publication.model.PublicationCreationRequestDto;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/publications")
+public class PublicationController {
+ private final PublicationUseCases publicationUseCases;
+
+ public PublicationController(PublicationUseCases publicationUseCases) {
+ this.publicationUseCases = publicationUseCases;
+ }
+
+ @PostMapping
+ public PublicationDto createPublication(@RequestBody PublicationCreationRequestDto requestDto) {
+ PublicationCreationRequest request = requestDto.toDomain();
+ Publication newPublication = publicationUseCases.createPublication(request);
+ return new PublicationDto(newPublication);
+ }
+}
diff --git a/codiki-exposition/src/main/java/org/codiki/exposition/publication/PublicationDto.java b/codiki-exposition/src/main/java/org/codiki/exposition/publication/PublicationDto.java
new file mode 100644
index 0000000..c3c5642
--- /dev/null
+++ b/codiki-exposition/src/main/java/org/codiki/exposition/publication/PublicationDto.java
@@ -0,0 +1,36 @@
+package org.codiki.exposition.publication;
+
+import java.time.ZonedDateTime;
+import java.util.UUID;
+
+import org.codiki.domain.category.model.Category;
+import org.codiki.domain.publication.model.Author;
+import org.codiki.domain.publication.model.Publication;
+import org.codiki.exposition.category.model.CategoryDto;
+import org.codiki.exposition.publication.model.AuthorDto;
+
+public record PublicationDto(
+ UUID id,
+ String key,
+ String title,
+ String text,
+ String description,
+ String image,
+ ZonedDateTime creationDate,
+ AuthorDto author,
+ CategoryDto category
+) {
+ public PublicationDto(Publication publication) {
+ this(
+ publication.id(),
+ publication.key(),
+ publication.title(),
+ publication.text(),
+ publication.description(),
+ publication.image(),
+ publication.creationDate(),
+ new AuthorDto(publication.author()),
+ new CategoryDto(publication.category())
+ );
+ }
+}
diff --git a/codiki-exposition/src/main/java/org/codiki/exposition/publication/model/AuthorDto.java b/codiki-exposition/src/main/java/org/codiki/exposition/publication/model/AuthorDto.java
new file mode 100644
index 0000000..9f83c7a
--- /dev/null
+++ b/codiki-exposition/src/main/java/org/codiki/exposition/publication/model/AuthorDto.java
@@ -0,0 +1,19 @@
+package org.codiki.exposition.publication.model;
+
+import java.util.UUID;
+
+import org.codiki.domain.publication.model.Author;
+
+public record AuthorDto(
+ UUID id,
+ String name,
+ String image
+) {
+ public AuthorDto(Author author) {
+ this(
+ author.id(),
+ author.name(),
+ author.image()
+ );
+ }
+}
diff --git a/codiki-exposition/src/main/java/org/codiki/exposition/publication/model/PublicationCreationRequestDto.java b/codiki-exposition/src/main/java/org/codiki/exposition/publication/model/PublicationCreationRequestDto.java
new file mode 100644
index 0000000..9a88994
--- /dev/null
+++ b/codiki-exposition/src/main/java/org/codiki/exposition/publication/model/PublicationCreationRequestDto.java
@@ -0,0 +1,17 @@
+package org.codiki.exposition.publication.model;
+
+import java.util.UUID;
+
+import org.codiki.domain.publication.model.PublicationCreationRequest;
+
+public record PublicationCreationRequestDto(
+ String title,
+ String text,
+ String description,
+ String image,
+ UUID categoryId
+) {
+ public PublicationCreationRequest toDomain() {
+ return new PublicationCreationRequest(title, text, description, image, categoryId);
+ }
+}
diff --git a/codiki-infrastructure/src/main/java/org/codiki/infrastructure/category/model/CategoryEntity.java b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/category/model/CategoryEntity.java
new file mode 100644
index 0000000..6da54a6
--- /dev/null
+++ b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/category/model/CategoryEntity.java
@@ -0,0 +1,27 @@
+package org.codiki.infrastructure.category.model;
+
+import java.util.UUID;
+
+import org.codiki.domain.category.model.Category;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "category")
+public record CategoryEntity(
+ @Id
+ UUID id,
+ @Column(nullable = false)
+ String name
+// List subCategories
+) {
+ public CategoryEntity(Category category) {
+ this(
+ category.id(),
+ category.name()
+ );
+ }
+}
diff --git a/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/PublicationJpaAdapter.java b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/PublicationJpaAdapter.java
new file mode 100644
index 0000000..c40f597
--- /dev/null
+++ b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/PublicationJpaAdapter.java
@@ -0,0 +1,22 @@
+package org.codiki.infrastructure.publication;
+
+import org.codiki.domain.publication.model.Publication;
+import org.codiki.domain.publication.port.PublicationPort;
+import org.codiki.infrastructure.publication.model.PublicationEntity;
+import org.codiki.infrastructure.publication.repository.PublicationRepository;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PublicationJpaAdapter implements PublicationPort {
+ private final PublicationRepository repository;
+
+ public PublicationJpaAdapter(PublicationRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public void save(final Publication publication) {
+ PublicationEntity newPublicationEntity = new PublicationEntity(publication);
+ repository.save(newPublicationEntity);
+ }
+}
diff --git a/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/model/AuthorEntity.java b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/model/AuthorEntity.java
new file mode 100644
index 0000000..a8bd2cb
--- /dev/null
+++ b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/model/AuthorEntity.java
@@ -0,0 +1,28 @@
+package org.codiki.infrastructure.publication.model;
+
+import java.util.UUID;
+
+import org.codiki.domain.publication.model.Author;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "`user`")
+public record AuthorEntity(
+ @Id
+ UUID id,
+ @Column(nullable = false)
+ String name,
+ String image
+) {
+ public AuthorEntity(Author author) {
+ this(
+ author.id(),
+ author.name(),
+ author.image()
+ );
+ }
+}
diff --git a/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/model/PublicationEntity.java b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/model/PublicationEntity.java
new file mode 100644
index 0000000..250350d
--- /dev/null
+++ b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/model/PublicationEntity.java
@@ -0,0 +1,54 @@
+package org.codiki.infrastructure.publication.model;
+
+import java.time.ZonedDateTime;
+import java.util.UUID;
+
+import org.codiki.domain.publication.model.Publication;
+import org.codiki.infrastructure.category.model.CategoryEntity;
+
+import static jakarta.persistence.FetchType.LAZY;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "publication")
+public record PublicationEntity(
+ @Id
+ UUID id,
+ @Column(nullable = false)
+ String key,
+ @Column(nullable = false)
+ String title,
+ @Column(nullable = false)
+ String text,
+ @Column(nullable = false)
+ String description,
+ @Column(nullable = false)
+ String image,
+ @Column(nullable = false)
+ ZonedDateTime creationDate,
+ @ManyToOne(fetch = LAZY)
+ @JoinColumn(name = "author_id")
+ AuthorEntity author,
+ @ManyToOne(fetch = LAZY)
+ @JoinColumn(name = "category_id")
+ CategoryEntity categoryId
+) {
+ public PublicationEntity(Publication publication) {
+ this(
+ publication.id(),
+ publication.key(),
+ publication.title(),
+ publication.text(),
+ publication.description(),
+ publication.image(),
+ publication.creationDate(),
+ new AuthorEntity(publication.author()),
+ new CategoryEntity(publication.category())
+ );
+ }
+}
diff --git a/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/repository/PublicationRepository.java b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/repository/PublicationRepository.java
new file mode 100644
index 0000000..8b513f0
--- /dev/null
+++ b/codiki-infrastructure/src/main/java/org/codiki/infrastructure/publication/repository/PublicationRepository.java
@@ -0,0 +1,9 @@
+package org.codiki.infrastructure.publication.repository;
+
+import java.util.UUID;
+
+import org.codiki.infrastructure.publication.model.PublicationEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface PublicationRepository extends JpaRepository {
+}
diff --git a/codiki-infrastructure/src/main/resources/sql/001-initial-script-tables-creation.sql b/codiki-infrastructure/src/main/resources/sql/001-initial-script-tables-creation.sql
index fbe60ba..afbfc5b 100644
--- a/codiki-infrastructure/src/main/resources/sql/001-initial-script-tables-creation.sql
+++ b/codiki-infrastructure/src/main/resources/sql/001-initial-script-tables-creation.sql
@@ -1,5 +1,6 @@
CREATE TABLE IF NOT EXISTS "user" (
id UUID NOT NULL,
+ name VARCHAR NOT NULL,
password VARCHAR NOT NULL,
CONSTRAINT user_pk PRIMARY KEY (id)
);
@@ -19,4 +20,27 @@ CREATE TABLE IF NOT EXISTS refresh_token (
CONSTRAINT refresh_token_pk PRIMARY KEY (user_id),
CONSTRAINT refresh_token_fk_user_id FOREIGN KEY (user_id) REFERENCES "user" (id)
);
-CREATE INDEX refresh_token_fk_user_id_idx ON user_role (user_id);
\ No newline at end of file
+CREATE INDEX refresh_token_fk_user_id_idx ON user_role (user_id);
+
+CREATE TABLE IF NOT EXISTS category (
+ id UUID NOT NULL,
+ name VARCHAR NOT NULL,
+ CONSTRAINT category_pk PRIMARY KEY (id)
+);
+
+CREATE TABLE IF NOT EXISTS publication (
+ id UUID NOT NULL,
+ key VARCHAR(10) NOT NULL,
+ title VARCHAR NOT NULL,
+ text VARCHAR NOT NULL,
+ description VARCHAR NOT NULL,
+ image VARCHAR NOT NULL,
+ creationDate TIMESTAMP NOT NULL,
+ author_id UUID NOT NULL,
+ category_id UUID NOT NULL,
+ CONSTRAINT publication_pk PRIMARY KEY (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)
+);
+CREATE INDEX publication_author_id_idx ON publication (author_id);
+CREATE INDEX publication_category_id_idx ON publication (category_id);