- 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>
85 lines
2.6 KiB
Java
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));
|
|
}
|
|
}
|