Files
fete/backend/src/main/java/de/fete/application/service/EventService.java
nitrix d333ab3d39
All checks were successful
CI / backend-test (push) Successful in 1m1s
CI / frontend-test (push) Successful in 26s
CI / frontend-e2e (push) Successful in 1m25s
CI / build-and-publish (push) Has been skipped
Refactor domain models to records and move exceptions to sub-package
- Convert Event and Rsvp from mutable POJOs to Java records
- Move all 8 exception classes to application.service.exception sub-package
- Add ArchUnit rule enforcing domain models must be records

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:09:27 +01:00

85 lines
2.6 KiB
Java

package de.fete.application.service;
import de.fete.application.service.exception.EventAlreadyCancelledException;
import de.fete.application.service.exception.EventNotFoundException;
import de.fete.application.service.exception.InvalidOrganizerTokenException;
import de.fete.domain.model.CreateEventCommand;
import de.fete.domain.model.Event;
import de.fete.domain.model.EventToken;
import de.fete.domain.model.OrganizerToken;
import de.fete.domain.port.in.CreateEventUseCase;
import de.fete.domain.port.in.GetEventUseCase;
import de.fete.domain.port.in.UpdateEventUseCase;
import de.fete.domain.port.out.EventRepository;
import java.time.Clock;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.Optional;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/** Application service implementing event creation and retrieval. */
@Service
public class EventService implements CreateEventUseCase, GetEventUseCase, UpdateEventUseCase {
private static final int EXPIRY_DAYS_AFTER_EVENT = 7;
private final EventRepository eventRepository;
private final Clock clock;
/** Creates a new EventService with the given repository and clock. */
public EventService(EventRepository eventRepository, Clock clock) {
this.eventRepository = eventRepository;
this.clock = clock;
}
@Override
public Event createEvent(CreateEventCommand command) {
LocalDate expiryDate = command.dateTime().toLocalDate().plusDays(EXPIRY_DAYS_AFTER_EVENT);
var event = new Event(
null,
EventToken.generate(),
OrganizerToken.generate(),
command.title(),
command.description(),
command.dateTime(),
command.timezone(),
command.location(),
expiryDate,
OffsetDateTime.now(clock),
false,
null);
return eventRepository.save(event);
}
@Override
public Optional<Event> getByEventToken(EventToken eventToken) {
return eventRepository.findByEventToken(eventToken);
}
@Transactional
@Override
public void cancelEvent(
EventToken eventToken, OrganizerToken organizerToken,
Boolean cancelled, String reason) {
if (!Boolean.TRUE.equals(cancelled)) {
return;
}
Event event = eventRepository.findByEventToken(eventToken)
.orElseThrow(() -> new EventNotFoundException(eventToken.value()));
if (!event.organizerToken().equals(organizerToken)) {
throw new InvalidOrganizerTokenException();
}
if (event.cancelled()) {
throw new EventAlreadyCancelledException(eventToken.value());
}
eventRepository.save(event.withCancellation(true, reason));
}
}