diff --git a/application/src/main/java/com/pablotj/restemailbridge/application/dto/EmailDTO.java b/application/src/main/java/com/pablotj/restemailbridge/application/dto/EmailDTO.java
new file mode 100644
index 0000000..02e4026
--- /dev/null
+++ b/application/src/main/java/com/pablotj/restemailbridge/application/dto/EmailDTO.java
@@ -0,0 +1,8 @@
+package com.pablotj.restemailbridge.application.dto;
+
+public record EmailDTO(
+ String from,
+ String subject,
+ String body
+) {
+}
diff --git a/application/src/main/java/com/pablotj/restemailbridge/application/port/EmailConfigurationPort.java b/application/src/main/java/com/pablotj/restemailbridge/application/port/EmailConfigurationPort.java
new file mode 100644
index 0000000..b3dff6a
--- /dev/null
+++ b/application/src/main/java/com/pablotj/restemailbridge/application/port/EmailConfigurationPort.java
@@ -0,0 +1,5 @@
+package com.pablotj.restemailbridge.application.port;
+
+public interface EmailConfigurationPort {
+ String getDefaultRecipient();
+}
diff --git a/application/src/main/java/com/pablotj/restemailbridge/application/usecase/SendEmailUseCase.java b/application/src/main/java/com/pablotj/restemailbridge/application/usecase/SendEmailUseCase.java
new file mode 100644
index 0000000..c98c574
--- /dev/null
+++ b/application/src/main/java/com/pablotj/restemailbridge/application/usecase/SendEmailUseCase.java
@@ -0,0 +1,32 @@
+package com.pablotj.restemailbridge.application.usecase;
+
+import com.pablotj.restemailbridge.application.dto.EmailDTO;
+import com.pablotj.restemailbridge.application.port.EmailConfigurationPort;
+import com.pablotj.restemailbridge.domain.model.Email;
+import com.pablotj.restemailbridge.domain.repository.EmailRepository;
+import com.pablotj.restemailbridge.domain.service.EmailService;
+
+public class SendEmailUseCase {
+ private final EmailConfigurationPort emailConfigurationPort;
+ private final EmailService emailService;
+ private final EmailRepository emailRepository;
+
+ public SendEmailUseCase(EmailConfigurationPort emailConfigurationPort, EmailService emailService, EmailRepository emailRepository) {
+ this.emailConfigurationPort = emailConfigurationPort;
+ this.emailService = emailService;
+ this.emailRepository = emailRepository;
+ }
+
+ public void handle(EmailDTO emailDTO) {
+ String to = emailConfigurationPort.getDefaultRecipient();
+ Email email = emailService.sendEmail(
+ Email.builder()
+ .from(emailDTO.from())
+ .to(to)
+ .subject(emailDTO.subject())
+ .body(emailDTO.body())
+ .build()
+ );
+ emailRepository.save(email);
+ }
+}
diff --git a/bootstrap/src/main/java/com/pablotj/restemailbridge/bootstrap/RestEmailBridgeApplication.java b/bootstrap/src/main/java/com/pablotj/restemailbridge/bootstrap/RestEmailBridgeApplication.java
index cadc539..e3953b8 100644
--- a/bootstrap/src/main/java/com/pablotj/restemailbridge/bootstrap/RestEmailBridgeApplication.java
+++ b/bootstrap/src/main/java/com/pablotj/restemailbridge/bootstrap/RestEmailBridgeApplication.java
@@ -6,8 +6,8 @@ import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication(scanBasePackages = "com.pablotj.restemailbridge")
-@EnableJpaRepositories(basePackages = {"com.pablotj.restemailbridge.infrastructure"})
-@EntityScan(basePackages = {"com.pablotj.restemailbridge.infrastructure"})
+@EnableJpaRepositories(basePackages = {"com.pablotj.restemailbridge"})
+@EntityScan(basePackages = {"com.pablotj.restemailbridge"})
public class RestEmailBridgeApplication {
public static void main(String[] args) {
diff --git a/domain/src/main/java/com/pablotj/restemailbridge/domain/model/Email.java b/domain/src/main/java/com/pablotj/restemailbridge/domain/model/Email.java
new file mode 100644
index 0000000..ea590bd
--- /dev/null
+++ b/domain/src/main/java/com/pablotj/restemailbridge/domain/model/Email.java
@@ -0,0 +1,15 @@
+package com.pablotj.restemailbridge.domain.model;
+
+import lombok.Builder;
+import lombok.Getter;
+
+@Getter
+@Builder
+public class Email {
+
+ private String from;
+ private String to;
+ private String subject;
+ private String body;
+
+}
diff --git a/domain/src/main/java/com/pablotj/restemailbridge/domain/repository/EmailRepository.java b/domain/src/main/java/com/pablotj/restemailbridge/domain/repository/EmailRepository.java
new file mode 100644
index 0000000..4639bd3
--- /dev/null
+++ b/domain/src/main/java/com/pablotj/restemailbridge/domain/repository/EmailRepository.java
@@ -0,0 +1,8 @@
+package com.pablotj.restemailbridge.domain.repository;
+
+import com.pablotj.restemailbridge.domain.model.Email;
+
+public interface EmailRepository {
+
+ Email save(Email email);
+}
diff --git a/domain/src/main/java/com/pablotj/restemailbridge/domain/service/EmailService.java b/domain/src/main/java/com/pablotj/restemailbridge/domain/service/EmailService.java
new file mode 100644
index 0000000..c527615
--- /dev/null
+++ b/domain/src/main/java/com/pablotj/restemailbridge/domain/service/EmailService.java
@@ -0,0 +1,8 @@
+package com.pablotj.restemailbridge.domain.service;
+
+import com.pablotj.restemailbridge.domain.model.Email;
+
+public interface EmailService {
+
+ Email sendEmail(Email email);
+}
diff --git a/infrastructure/pom.xml b/infrastructure/pom.xml
index d397999..11e20aa 100644
--- a/infrastructure/pom.xml
+++ b/infrastructure/pom.xml
@@ -33,6 +33,12 @@
spring-boot-starter-validation
+
+ org.reflections
+ reflections
+ 0.10.2
+
+
org.mapstruct
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/EmailConfigurationAdapter.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/EmailConfigurationAdapter.java
new file mode 100644
index 0000000..cff4675
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/EmailConfigurationAdapter.java
@@ -0,0 +1,12 @@
+package com.pablotj.restemailbridge.infrastructure.config;
+
+import com.pablotj.restemailbridge.application.port.EmailConfigurationPort;
+import org.springframework.stereotype.Component;
+
+@Component
+public class EmailConfigurationAdapter implements EmailConfigurationPort {
+ @Override
+ public String getDefaultRecipient() {
+ return "1234@1234.com";
+ }
+}
\ No newline at end of file
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/spring/UseCaseConfig.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/spring/UseCaseConfig.java
new file mode 100644
index 0000000..7e4168a
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/config/spring/UseCaseConfig.java
@@ -0,0 +1,17 @@
+package com.pablotj.restemailbridge.infrastructure.config.spring;
+
+import com.pablotj.restemailbridge.application.port.EmailConfigurationPort;
+import com.pablotj.restemailbridge.application.usecase.SendEmailUseCase;
+import com.pablotj.restemailbridge.domain.repository.EmailRepository;
+import com.pablotj.restemailbridge.domain.service.EmailService;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class UseCaseConfig {
+
+ @Bean
+ public SendEmailUseCase sendEmailUseCase(EmailConfigurationPort emailConfigurationPort, EmailService emailService, EmailRepository emailRepository) {
+ return new SendEmailUseCase(emailConfigurationPort, emailService, emailRepository);
+ }
+}
\ No newline at end of file
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/mail/GmailOAuth2MailService.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/mail/GmailOAuth2MailService.java
new file mode 100644
index 0000000..5cb8221
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/mail/GmailOAuth2MailService.java
@@ -0,0 +1,15 @@
+package com.pablotj.restemailbridge.infrastructure.mail;
+
+import com.pablotj.restemailbridge.domain.model.Email;
+import com.pablotj.restemailbridge.domain.service.EmailService;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GmailOAuth2MailService implements EmailService {
+
+ @Override
+ public Email sendEmail(Email email) {
+ System.out.println("Sending email " + email.getSubject() + " to " + email.getTo());
+ return email;
+ }
+}
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/MailJpa.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/MailJpa.java
new file mode 100644
index 0000000..9684e8d
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/MailJpa.java
@@ -0,0 +1,33 @@
+package com.pablotj.restemailbridge.infrastructure.persistence;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Table;
+import lombok.Getter;
+import lombok.Setter;
+
+@Entity
+@Table(name = "MAIL")
+@Getter
+@Setter
+public class MailJpa {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(nullable = false)
+ private String sender;
+
+ @Column(nullable = false)
+ private String recipient;
+
+ @Column(nullable = false)
+ private String subjet;
+
+ @Column(nullable = false)
+ private String body;
+}
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/MailRepositoryAdapter.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/MailRepositoryAdapter.java
new file mode 100644
index 0000000..8acf59c
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/MailRepositoryAdapter.java
@@ -0,0 +1,28 @@
+package com.pablotj.restemailbridge.infrastructure.persistence;
+
+import com.pablotj.restemailbridge.domain.model.Email;
+import com.pablotj.restemailbridge.domain.repository.EmailRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class MailRepositoryAdapter implements EmailRepository {
+
+ private final SpringDataMailRepository springDataMailRepository;
+
+ public MailRepositoryAdapter(SpringDataMailRepository springDataMailRepository) {
+ this.springDataMailRepository = springDataMailRepository;
+ }
+
+ @Override
+ public Email save(Email email) {
+ MailJpa mailJpa = new MailJpa();
+ mailJpa.setSender(email.getFrom());
+ mailJpa.setRecipient(email.getTo());
+ mailJpa.setSubjet(email.getSubject());
+ mailJpa.setBody(email.getBody());
+
+ springDataMailRepository.save(mailJpa);
+
+ return email;
+ }
+}
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/SpringDataMailRepository.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/SpringDataMailRepository.java
new file mode 100644
index 0000000..d880e88
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/persistence/SpringDataMailRepository.java
@@ -0,0 +1,7 @@
+package com.pablotj.restemailbridge.infrastructure.persistence;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface SpringDataMailRepository extends JpaRepository {
+}
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/rest/MailController.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/rest/MailController.java
new file mode 100644
index 0000000..5d7340a
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/rest/MailController.java
@@ -0,0 +1,29 @@
+package com.pablotj.restemailbridge.infrastructure.rest;
+
+import com.pablotj.restemailbridge.application.dto.EmailDTO;
+import com.pablotj.restemailbridge.application.usecase.SendEmailUseCase;
+import com.pablotj.restemailbridge.infrastructure.rest.dto.SendMailRequest;
+import jakarta.validation.Valid;
+import org.springframework.http.ResponseEntity;
+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("/v1/mail")
+public class MailController {
+
+ private final SendEmailUseCase sendEmailUseCase;
+
+ public MailController(SendEmailUseCase sendEmailUseCase) {
+ this.sendEmailUseCase = sendEmailUseCase;
+ }
+
+
+ @PostMapping
+ public ResponseEntity send(@Valid @RequestBody SendMailRequest request) {
+ sendEmailUseCase.handle(new EmailDTO(request.from(), request.subject(), request.body()));
+ return ResponseEntity.ok().build();
+ }
+}
\ No newline at end of file
diff --git a/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/rest/dto/SendMailRequest.java b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/rest/dto/SendMailRequest.java
new file mode 100644
index 0000000..ba07d94
--- /dev/null
+++ b/infrastructure/src/main/java/com/pablotj/restemailbridge/infrastructure/rest/dto/SendMailRequest.java
@@ -0,0 +1,8 @@
+package com.pablotj.restemailbridge.infrastructure.rest.dto;
+
+public record SendMailRequest(
+ String from,
+ String subject,
+ String body
+) {
+}