Ulubione na koncie - koniec kasowania zapisow przez pusta przegladarke
Deploy Polska Lokalnie / deploy (push) Successful in 12s

Dotad front po kazdej zmianie dyktowal serwerowi cala liste ulubionych.
Zalogowanie sie na innym urzadzeniu wysylalo "mam zero ulubionych"
i kasowalo zapisy, przez co wlasciciel ogloszenia tracil licznik zapisan.

Teraz: GET /api/listings/favorites zwraca ulubione konta, dodanie
i usuniecie ida pojedynczo (POST/DELETE /{id}/favorite), a wpisy z
przegladarki dopisuje jednorazowy /favorites/import. Endpoint
/favorites/sync usuniety razem z jego jedynym wywolaniem.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-23 11:26:00 +02:00
parent b9fecdea85
commit 557c76257b
3 changed files with 114 additions and 45 deletions
@@ -17,8 +17,8 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
/**
* Zapisywanie ogloszen do ulubionych. Frontend trzyma liste ulubionych lokalnie (szybkie UI),
* a tutaj rejestrujemy sam fakt zapisania - dzieki temu wlasciciel widzi, ile osob zapisalo oferte.
* Ulubione ogloszenia uzytkownika - trzymane na koncie, wiec sa te same na kazdym urzadzeniu.
* Z tych samych danych liczymy wlascicielowi, ile osob zapisalo jego oferte.
*/
@RestController
@RequestMapping("/api/listings")
@@ -49,30 +49,38 @@ public class ListingFavoriteController {
return ResponseEntity.noContent().build();
}
/**
* Ustawia ulubione uzytkownika dokladnie na przeslana liste. Front trzyma ulubione lokalnie
* i po kazdej zmianie wysyla caly zbior - dzieki temu serwer zna stan niezaleznie od tego,
* z ktorego miejsca w aplikacji uzytkownik dodal lub usunal ogloszenie.
*/
@PostMapping("/favorites/sync")
@Transactional
public ResponseEntity<Void> sync(@RequestBody SyncRequest request, Authentication authentication) {
if (request == null || request.listingIds() == null) {
return ResponseEntity.noContent().build();
}
String userEmail = authentication.getName();
List<Long> wanted = request.listingIds().stream()
.filter(java.util.Objects::nonNull)
.distinct()
.filter(listingRepository::existsById)
/** Ulubione zalogowanego uzytkownika - te same na kazdym urzadzeniu. */
@GetMapping("/favorites")
public List<ListingResponse> myFavorites(Authentication authentication) {
List<Long> listingIds = favoriteRepository.findByUserEmailIgnoreCase(authentication.getName()).stream()
.map(ListingFavorite::getListingId)
.toList();
if (listingIds.isEmpty()) {
return List.of();
}
// Ogloszenie skasowane albo odrzucone po zapisaniu po prostu znika z listy.
return listingRepository.findAllById(listingIds).stream()
.filter(listing -> listing.getStatus() == ListingStatus.APPROVED)
.map(listing -> ListingResponse.from(listing, listing.isApproximateLocation()))
.toList();
}
favoriteRepository.findByUserEmailIgnoreCase(userEmail).stream()
.filter(favorite -> !wanted.contains(favorite.getListingId()))
.forEach(favoriteRepository::delete);
wanted.forEach(listingId -> save(listingId, userEmail));
return ResponseEntity.noContent().build();
/**
* Dopisanie ulubionych zapisanych wczesniej w przegladarce. Tylko dodaje - nigdy nie kasuje,
* zeby wejscie z pustej przegladarki nie wyczyscilo listy zebranej na innym urzadzeniu.
*/
@PostMapping("/favorites/import")
@Transactional
public List<ListingResponse> importLocal(@RequestBody SyncRequest request, Authentication authentication) {
if (request != null && request.listingIds() != null) {
String userEmail = authentication.getName();
request.listingIds().stream()
.filter(java.util.Objects::nonNull)
.distinct()
.filter(listingRepository::existsById)
.forEach(listingId -> save(listingId, userEmail));
}
return myFavorites(authentication);
}
/** Liczba zapisan dla ogloszen zalogowanego uzytkownika: {listingId: liczba}. */