Merge branch 'refs/heads/24-fix-achievement-date' into sattelgeschichten
This commit is contained in:
commit
bda2ab13cf
5 changed files with 65 additions and 1 deletions
|
|
@ -35,6 +35,11 @@ public interface PersonalRecordRepository extends JpaRepository<PersonalRecord,
|
|||
PersonalRecord.RecordType recordType
|
||||
);
|
||||
|
||||
/**
|
||||
* Delete all personal records for a user.
|
||||
*/
|
||||
void deleteByUserId(UUID userId);
|
||||
|
||||
/**
|
||||
* Get count of personal records set by a user.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ public class ActivityDeleteRecalculationService {
|
|||
|
||||
private final AchievementService achievementService;
|
||||
private final ActivitySummaryService activitySummaryService;
|
||||
private final PersonalRecordService personalRecordService;
|
||||
private final ConcurrentMap<UUID, PendingUserRecalculation> pendingRecalculations = new ConcurrentHashMap<>();
|
||||
|
||||
@Async
|
||||
|
|
@ -42,6 +43,7 @@ public class ActivityDeleteRecalculationService {
|
|||
do {
|
||||
Set<LocalDate> datesToRecalculate = pending.drainDates();
|
||||
achievementService.rebuildAchievementsForUser(event.userId());
|
||||
personalRecordService.rebuildPersonalRecordsForUser(event.userId());
|
||||
for (LocalDate date : datesToRecalculate) {
|
||||
activitySummaryService.updateWeeklySummary(event.userId(), date);
|
||||
activitySummaryService.updateMonthlySummary(event.userId(), date);
|
||||
|
|
@ -49,7 +51,7 @@ public class ActivityDeleteRecalculationService {
|
|||
}
|
||||
} while (pending.keepProcessing());
|
||||
|
||||
log.info("Recalculated achievements and summaries after deleting activities for user {}", event.userId());
|
||||
log.info("Recalculated achievements, personal records, and summaries after deleting activities for user {}", event.userId());
|
||||
}
|
||||
|
||||
private static final class PendingUserRecalculation {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.PersonalRecord;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.PersonalRecordRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -23,6 +24,7 @@ import java.util.UUID;
|
|||
@Slf4j
|
||||
public class PersonalRecordService {
|
||||
|
||||
private final ActivityRepository activityRepository;
|
||||
private final PersonalRecordRepository personalRecordRepository;
|
||||
|
||||
/**
|
||||
|
|
@ -320,4 +322,19 @@ public class PersonalRecordService {
|
|||
public long getPersonalRecordCount(UUID userId) {
|
||||
return personalRecordRepository.countByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild all personal records for a user from remaining activities.
|
||||
*/
|
||||
@Transactional
|
||||
public void rebuildPersonalRecordsForUser(UUID userId) {
|
||||
personalRecordRepository.deleteByUserId(userId);
|
||||
|
||||
List<Activity> activities = activityRepository.findByUserIdOrderByStartedAtAsc(userId);
|
||||
for (Activity activity : activities) {
|
||||
checkAndUpdatePersonalRecords(activity);
|
||||
}
|
||||
|
||||
log.info("Rebuilt personal records for user {} from {} activities", userId, activities.size());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ class ActivityDeleteRecalculationServiceTest {
|
|||
@Mock
|
||||
private ActivitySummaryService activitySummaryService;
|
||||
|
||||
@Mock
|
||||
private PersonalRecordService personalRecordService;
|
||||
|
||||
@InjectMocks
|
||||
private ActivityDeleteRecalculationService activityDeleteRecalculationService;
|
||||
|
||||
|
|
@ -36,6 +39,7 @@ class ActivityDeleteRecalculationServiceTest {
|
|||
activityDeleteRecalculationService.handleActivityDeleted(new ActivityDeletedEvent(userId, activityDate));
|
||||
|
||||
verify(achievementService).rebuildAchievementsForUser(userId);
|
||||
verify(personalRecordService).rebuildPersonalRecordsForUser(userId);
|
||||
verify(activitySummaryService).updateWeeklySummary(userId, activityDate);
|
||||
verify(activitySummaryService).updateMonthlySummary(userId, activityDate);
|
||||
verify(activitySummaryService).updateYearlySummary(userId, activityDate);
|
||||
|
|
@ -59,6 +63,7 @@ class ActivityDeleteRecalculationServiceTest {
|
|||
activityDeleteRecalculationService.handleActivityDeleted(new ActivityDeletedEvent(userId, firstDate));
|
||||
|
||||
verify(achievementService, times(2)).rebuildAchievementsForUser(userId);
|
||||
verify(personalRecordService, times(2)).rebuildPersonalRecordsForUser(userId);
|
||||
verify(activitySummaryService).updateWeeklySummary(userId, firstDate);
|
||||
verify(activitySummaryService).updateMonthlySummary(userId, firstDate);
|
||||
verify(activitySummaryService).updateYearlySummary(userId, firstDate);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||
import net.javahippie.fitpub.model.entity.Activity;
|
||||
import net.javahippie.fitpub.model.entity.ActivityMetrics;
|
||||
import net.javahippie.fitpub.model.entity.PersonalRecord;
|
||||
import net.javahippie.fitpub.repository.ActivityRepository;
|
||||
import net.javahippie.fitpub.repository.PersonalRecordRepository;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
|
@ -33,6 +34,9 @@ class PersonalRecordServiceTest {
|
|||
@Mock
|
||||
private PersonalRecordRepository personalRecordRepository;
|
||||
|
||||
@Mock
|
||||
private ActivityRepository activityRepository;
|
||||
|
||||
@InjectMocks
|
||||
private PersonalRecordService personalRecordService;
|
||||
|
||||
|
|
@ -415,6 +419,37 @@ class PersonalRecordServiceTest {
|
|||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should rebuild personal records from remaining activities")
|
||||
void testRebuildPersonalRecordsForUser() {
|
||||
Activity firstActivity = createActivity(
|
||||
10000L,
|
||||
3600L,
|
||||
BigDecimal.valueOf(100)
|
||||
);
|
||||
firstActivity.setStartedAt(testTime.minusDays(2));
|
||||
|
||||
Activity secondActivity = createActivity(
|
||||
15000L,
|
||||
4500L,
|
||||
BigDecimal.valueOf(200)
|
||||
);
|
||||
secondActivity.setStartedAt(testTime.minusDays(1));
|
||||
|
||||
when(activityRepository.findByUserIdOrderByStartedAtAsc(userId))
|
||||
.thenReturn(List.of(firstActivity, secondActivity));
|
||||
when(personalRecordRepository.findByUserIdAndActivityTypeAndRecordType(any(), any(), any()))
|
||||
.thenReturn(Optional.empty());
|
||||
when(personalRecordRepository.save(any(PersonalRecord.class)))
|
||||
.thenAnswer(invocation -> invocation.getArgument(0));
|
||||
|
||||
personalRecordService.rebuildPersonalRecordsForUser(userId);
|
||||
|
||||
verify(personalRecordRepository).deleteByUserId(userId);
|
||||
verify(activityRepository).findByUserIdOrderByStartedAtAsc(userId);
|
||||
verify(personalRecordRepository, atLeastOnce()).save(any(PersonalRecord.class));
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
|
||||
private Activity createActivity(long distanceMeters, long durationSeconds, BigDecimal elevationGain) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue