diff --git a/pom.xml b/pom.xml
index c8501a9..135fa04 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,6 +53,10 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
org.springframework.security
spring-security-test
diff --git a/src/main/java/com/example/fercoganbackend/controller/LoteControllerWebFlux.java b/src/main/java/com/example/fercoganbackend/controller/LoteControllerWebFlux.java
new file mode 100644
index 0000000..4fc4ae7
--- /dev/null
+++ b/src/main/java/com/example/fercoganbackend/controller/LoteControllerWebFlux.java
@@ -0,0 +1,90 @@
+package com.example.fercoganbackend.controller;
+
+import com.example.fercoganbackend.entity.Lote;
+import com.example.fercoganbackend.service.LoteServiceWebFlux;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
+
+import java.util.List;
+import java.util.Optional;
+
+@RestController
+@RequestMapping("/api/webflux/lotes")
+public class LoteControllerWebFlux {
+
+ @Autowired
+ private LoteServiceWebFlux loteService;
+
+ @GetMapping
+ public java.util.List getAll() {
+ return loteService.findAll();
+ }
+
+ @GetMapping("/{id}")
+ public ResponseEntity getById(@PathVariable Long id) {
+ return loteService.findById(id)
+ .map(ResponseEntity::ok)
+ .orElse(ResponseEntity.notFound().build());
+ }
+
+ @PostMapping
+ public Lote create(@RequestBody Lote remate) {
+ return loteService.save(remate);
+ }
+
+ @PutMapping("/{id}")
+ public ResponseEntity update(@PathVariable Long id, @RequestBody Lote remate) {
+ return loteService.findById(id)
+ .map(r -> {
+ remate.setId(id);
+ Lote updated = loteService.save(remate);
+ return ResponseEntity.ok(updated);
+ })
+ .orElse(ResponseEntity.notFound().build());
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity delete(@PathVariable Long id) {
+ loteService.delete(id);
+ return ResponseEntity.noContent().build();
+ }
+
+ // -------------------- NUEVO: SSE por LOTE --------------------
+ // Endpoint que devuelve el flujo de actualizaciones solo para ese lote (id).
+ @GetMapping(value = "/stream/{id}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+ public Flux streamLoteById(@PathVariable Long id) {
+ // flujo de futuras actualizaciones (todos los lotes, luego filtramos por id)
+ Flux updates = loteService.getSink().asFlux()
+ .filter(l -> l != null && l.getId() != null && l.getId().equals(id));
+
+ // enviamos primero el estado actual (si existe), luego las actualizaciones
+ Optional current = loteService.findById(id);
+ if (current.isPresent()) {
+ return Flux.concat(Flux.just(current.get()), updates);
+ } else {
+ // si no existe ahora, devolvemos solo futuras actualizaciones (por ejemplo creación posterior)
+ return updates;
+ }
+ }
+
+ @GetMapping(value = "/stream/cabanaid/{cabanaId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+ public Flux streamLote(@PathVariable Long cabanaId) {
+ // Flujo de futuras actualizaciones (todos los lotes, luego filtramos por cabanaId)
+ Flux updates = loteService.getSink().asFlux()
+ .filter(lote -> lote.getCabana().getId().equals(cabanaId));
+
+ // Enviamos primero el estado actual (todos los lotes de la cabaña), luego las actualizaciones
+ List currentLotes = loteService.findByCabanaId(cabanaId);
+
+ if (!currentLotes.isEmpty()) {
+ return Flux.concat(Flux.fromIterable(currentLotes), updates);
+ } else {
+ // Si no existen lotes ahora, devolvemos solo futuras actualizaciones
+ return updates;
+ }
+ }
+}
+
diff --git a/src/main/java/com/example/fercoganbackend/entity/Lote.java b/src/main/java/com/example/fercoganbackend/entity/Lote.java
index e585c21..30f2b8d 100644
--- a/src/main/java/com/example/fercoganbackend/entity/Lote.java
+++ b/src/main/java/com/example/fercoganbackend/entity/Lote.java
@@ -17,6 +17,7 @@ public class Lote {
private Double puja;
private String estado;
private Boolean visible = true;
+ private String video;
@ManyToOne
@JoinColumn(name = "remate_id")
@@ -26,6 +27,14 @@ public class Lote {
@JoinColumn(name = "cabana_id")
private Cabana cabana;
+ public String getVideo() {
+ return video;
+ }
+
+ public void setVideo(String video) {
+ this.video = video;
+ }
+
public Long getId() {
return id;
}
diff --git a/src/main/java/com/example/fercoganbackend/repository/LoteRepository.java b/src/main/java/com/example/fercoganbackend/repository/LoteRepository.java
index 4bfc70d..214c3e6 100644
--- a/src/main/java/com/example/fercoganbackend/repository/LoteRepository.java
+++ b/src/main/java/com/example/fercoganbackend/repository/LoteRepository.java
@@ -1,6 +1,15 @@
package com.example.fercoganbackend.repository;
import com.example.fercoganbackend.entity.Lote;
+import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
-public interface LoteRepository extends JpaRepository {}
+import java.util.List;
+
+public interface LoteRepository extends JpaRepository {
+ // Con ordenamiento
+ //List findByCabanaIdOrderByNumeroLote(Long cabanaId);
+
+ // Para paginación
+ List findByCabanaId(Long cabanaId);
+}
diff --git a/src/main/java/com/example/fercoganbackend/service/ContadorService.java b/src/main/java/com/example/fercoganbackend/service/ContadorService.java
index dab4964..4687752 100644
--- a/src/main/java/com/example/fercoganbackend/service/ContadorService.java
+++ b/src/main/java/com/example/fercoganbackend/service/ContadorService.java
@@ -22,7 +22,7 @@ public class ContadorService {
} else {
incremento = 500;
}
- return contador.getAndAdd(incremento);
+ return contador.addAndGet(incremento);
}
diff --git a/src/main/java/com/example/fercoganbackend/service/LoteServiceWebFlux.java b/src/main/java/com/example/fercoganbackend/service/LoteServiceWebFlux.java
new file mode 100644
index 0000000..cbda1b2
--- /dev/null
+++ b/src/main/java/com/example/fercoganbackend/service/LoteServiceWebFlux.java
@@ -0,0 +1,71 @@
+package com.example.fercoganbackend.service;
+
+
+import com.example.fercoganbackend.entity.Lote;
+import com.example.fercoganbackend.repository.LoteRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import reactor.core.publisher.Sinks;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class LoteServiceWebFlux {
+
+ private final LoteRepository repo;
+ private final Sinks.Many sink; // canal que emite actualizaciones por lote
+
+ public LoteServiceWebFlux(LoteRepository repo) {
+ this.repo = repo;
+ // replay().latest() guarda el último emitido (por si alguien se suscribe tarde)
+ this.sink = Sinks.many().replay().latest();
+ }
+
+ public List findAll() {
+ return repo.findAll();
+ }
+
+ public List findByCabanaId(Long id) {
+ return repo.findByCabanaId(id);
+ }
+
+ public Optional findById(Long id) {
+ return repo.findById(id);
+ }
+
+ @Transactional
+ public Lote save(Lote lote) {
+ Lote saved = repo.save(lote);
+ emitChange(saved); // notificamos a los suscriptores el lote actualizado
+ return saved;
+ }
+
+ @Transactional
+ public void delete(Long id) {
+ // Intentamos obtener el lote antes de borrar para poder notificar su eliminación
+ Optional maybe = repo.findById(id);
+ repo.deleteById(id);
+ // Emitimos un "evento de eliminación": un Lote con id y visible = false
+ Lote tombstone = maybe.orElseGet(() -> {
+ Lote t = new Lote();
+ t.setId(id);
+ return t;
+ });
+ // Si tu entidad Lote tiene campo visible, marcalo; si no, sigue emitiendo el id.
+ try {
+ tombstone.setVisible(false);
+ } catch (Exception ignored) {}
+ emitChange(tombstone);
+ }
+
+ private void emitChange(Lote lote) {
+ // emitimos el objeto lote al sink; los controladores filtran por id
+ sink.tryEmitNext(lote);
+ }
+
+ public Sinks.Many getSink() {
+ return sink;
+ }
+}
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
new file mode 100644
index 0000000..e1c1d4a
--- /dev/null
+++ b/src/main/resources/application-dev.properties
@@ -0,0 +1,3 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/testdb
+spring.datasource.username=andre
+spring.datasource.password=andre
\ No newline at end of file
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
new file mode 100644
index 0000000..be9eba9
--- /dev/null
+++ b/src/main/resources/application-prod.properties
@@ -0,0 +1,3 @@
+spring.datasource.url=jdbc:mysql://192.168.5.250:3306/TEST_fercoApp
+spring.datasource.username=ferco
+spring.datasource.password=9+k+9076[5S26#C1mn"u
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 1714341..1b1d6d5 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,7 +1,5 @@
spring.application.name=fercoganbackend
-spring.datasource.url=jdbc:mysql://192.168.5.250:3306/TEST_fercoApp
-spring.datasource.username=ferco
-spring.datasource.password=9+k+9076[5S26#C1mn"u
+spring.profiles.active=dev
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update