diff --git a/pom.xml b/pom.xml
index 1f3ca8a..bea7224 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,10 @@
h2
test
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
io.jsonwebtoken
jjwt-api
diff --git a/src/main/java/com/guilherme/finance_api/config/RabbitMQConfig.java b/src/main/java/com/guilherme/finance_api/config/RabbitMQConfig.java
new file mode 100644
index 0000000..fb931eb
--- /dev/null
+++ b/src/main/java/com/guilherme/finance_api/config/RabbitMQConfig.java
@@ -0,0 +1,23 @@
+package com.guilherme.finance_api.config;
+
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RabbitMQConfig {
+
+ @Bean
+ public Jackson2JsonMessageConverter messageConverter() {
+ return new Jackson2JsonMessageConverter();
+ }
+
+ @Bean
+ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
+ RabbitTemplate template = new RabbitTemplate(connectionFactory);
+ template.setMessageConverter(messageConverter());
+ return template;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/guilherme/finance_api/event/TransactionEvent.java b/src/main/java/com/guilherme/finance_api/event/TransactionEvent.java
new file mode 100644
index 0000000..cbad7d3
--- /dev/null
+++ b/src/main/java/com/guilherme/finance_api/event/TransactionEvent.java
@@ -0,0 +1,21 @@
+package com.guilherme.finance_api.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TransactionEvent {
+ private Long id;
+ private String description;
+ private BigDecimal amount;
+ private LocalDate date;
+ private String type;
+ private String userEmail;
+ private String categoryName;
+}
\ No newline at end of file
diff --git a/src/main/java/com/guilherme/finance_api/event/TransactionPublisher.java b/src/main/java/com/guilherme/finance_api/event/TransactionPublisher.java
new file mode 100644
index 0000000..b131a1c
--- /dev/null
+++ b/src/main/java/com/guilherme/finance_api/event/TransactionPublisher.java
@@ -0,0 +1,30 @@
+package com.guilherme.finance_api.event;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class TransactionPublisher {
+
+ private final RabbitTemplate rabbitTemplate;
+
+ @Value("${rabbitmq.exchange}")
+ private String exchange;
+
+ @Value("${rabbitmq.routing-key}")
+ private String routingKey;
+
+ public void publish(TransactionEvent event) {
+ log.info("📤 Publicando evento na fila: transação '{}' do usuário {}",
+ event.getDescription(), event.getUserEmail());
+
+ rabbitTemplate.convertAndSend(exchange, routingKey, event);
+
+ log.info("✅ Evento publicado com sucesso.");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/guilherme/finance_api/service/TransactionService.java b/src/main/java/com/guilherme/finance_api/service/TransactionService.java
index a8f353b..144fdf5 100644
--- a/src/main/java/com/guilherme/finance_api/service/TransactionService.java
+++ b/src/main/java/com/guilherme/finance_api/service/TransactionService.java
@@ -6,6 +6,8 @@
import com.guilherme.finance_api.entity.Category;
import com.guilherme.finance_api.entity.Transaction;
import com.guilherme.finance_api.entity.User;
+import com.guilherme.finance_api.event.TransactionEvent;
+import com.guilherme.finance_api.event.TransactionPublisher;
import com.guilherme.finance_api.exception.ResourceNotFoundException;
import com.guilherme.finance_api.repository.CategoryRepository;
import com.guilherme.finance_api.repository.TransactionRepository;
@@ -28,6 +30,7 @@ public class TransactionService {
private final TransactionRepository transactionRepository;
private final UserRepository userRepository;
private final CategoryRepository categoryRepository;
+ private final TransactionPublisher transactionPublisher;
public Page findAll(TransactionFilter filter, Pageable pageable) {
String email = SecurityContextHolder.getContext().getAuthentication().getName();
@@ -97,6 +100,17 @@ public TransactionResponse save(TransactionRequest request) {
transaction.setCategory(category);
Transaction savedTransaction = transactionRepository.save(transaction);
+
+ TransactionEvent event = new TransactionEvent(
+ savedTransaction.getId(),
+ savedTransaction.getDescription(),
+ savedTransaction.getAmount(),
+ savedTransaction.getDate(),
+ savedTransaction.getType().name(),
+ savedTransaction.getUser().getEmail(),
+ savedTransaction.getCategory() != null ? savedTransaction.getCategory().getName() : null
+ );
+ transactionPublisher.publish(event);
return toResponse(savedTransaction);
}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index b24ffdc..0a45536 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -6,4 +6,10 @@ spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
jwt.secret=${JWT_SECRET:5b6f8d2a1e4c7f9b3d0e2a5c8f1b4d7e9a2c5f8b1d4e7a0c3f6b9d2e5a8c1f4}
-jwt.expiration=${JWT_EXPIRATION:86400000}
\ No newline at end of file
+jwt.expiration=${JWT_EXPIRATION:86400000}
+spring.rabbitmq.host=${RABBITMQ_HOST:localhost}
+spring.rabbitmq.port=${RABBITMQ_PORT:5672}
+spring.rabbitmq.username=${RABBITMQ_USER:guest}
+spring.rabbitmq.password=${RABBITMQ_PASSWORD:guest}
+rabbitmq.exchange=transactions.exchange
+rabbitmq.routing-key=transactions.created