Skip to content

Commit 54bf4ee

Browse files
authored
Merge pull request #30 from GDGoC-Peakly/main
[DEPLOY] 세션 시작, 일시정지, 재개, 종료 API
2 parents bdda2b3 + 1030584 commit 54bf4ee

11 files changed

Lines changed: 524 additions & 88 deletions

File tree

src/main/java/com/example/peakly/domain/focusSession/controller/FocusSessionController.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,15 @@ public ApiResponse<FocusSessionPauseResponse> pause(
3333
@PathVariable("sessionId") Long sessionId
3434
) {
3535
Long userId = SecurityUtil.requireUserId();
36-
// FocusSessionPauseResponse res = focusSessionService.pause(userId, sessionId);
37-
return ApiResponse.onSuccess(null);
36+
return ApiResponse.onSuccess(focusSessionService.pause(userId, sessionId));
3837
}
3938

4039
@PostMapping("/{sessionId}/resume")
4140
public ApiResponse<FocusSessionResumeResponse> resume(
4241
@PathVariable("sessionId") Long sessionId
4342
) {
4443
Long userId = SecurityUtil.requireUserId();
45-
// FocusSessionResumeResponse res = focusSessionService.resume(userId, sessionId);
46-
return ApiResponse.onSuccess(null);
44+
return ApiResponse.onSuccess(focusSessionService.resume(userId, sessionId));
4745
}
4846

4947
@PostMapping("/{sessionId}/end")
@@ -52,8 +50,7 @@ public ApiResponse<FocusSessionEndResponse> end(
5250
@Valid @RequestBody FocusSessionEndRequest req
5351
) {
5452
Long userId = SecurityUtil.requireUserId();
55-
// FocusSessionEndResponse res = focusSessionService.end(userId, sessionId, req);
56-
return ApiResponse.onSuccess(null);
53+
return ApiResponse.onSuccess(focusSessionService.end(userId, sessionId, req));
5754
}
5855

5956
}

src/main/java/com/example/peakly/domain/focusSession/entity/FocusSession.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public class FocusSession extends BaseEntity {
7272
@Column(name = "is_counted_in_stats", nullable = false)
7373
private boolean countedInStats;
7474

75+
@Column(name = "is_recorded", nullable = false)
76+
private boolean recorded;
77+
78+
@Version
79+
private Long version;
80+
7581
@OneToMany(mappedBy = "focusSession", cascade = CascadeType.ALL, orphanRemoval = true)
7682
private final List<SessionPause> pauses = new ArrayList<>();
7783

@@ -102,10 +108,16 @@ public static FocusSession start(
102108

103109
s.sessionStatus = SessionStatus.RUNNING;
104110
s.totalFocusSec = 0;
105-
s.countedInStats = true;
111+
s.countedInStats = false;
112+
113+
s.recorded = false;
106114
return s;
107115
}
108116

117+
public void markRecorded(boolean recorded) {
118+
this.recorded = recorded;
119+
}
120+
109121
private static void validateStart(
110122
User user,
111123
FocusSessionStartCommand cmd,
@@ -139,31 +151,30 @@ public void pause(LocalDateTime pausedAt) {
139151
this.pauses.add(SessionPause.create(this, pausedAt));
140152
}
141153

142-
public void resume(LocalDateTime resumedAt, int pauseSec) {
143-
if (resumedAt == null) throw new IllegalArgumentException("resumedAt은 필수입니다.");
144-
if (pauseSec < 0) throw new IllegalArgumentException("pauseSec는 0 이상이어야 합니다.");
154+
public void addFocusSec(int deltaSec) {
155+
if (deltaSec < 0) throw new IllegalArgumentException("deltaSec는 0 이상이어야 합니다.");
156+
this.totalFocusSec += deltaSec;
157+
}
158+
159+
public void markRunning() {
145160
if (this.sessionStatus != SessionStatus.PAUSED) {
146-
throw new IllegalStateException("PAUSED 상태에서만 재개가 가능합니다.");
161+
throw new IllegalStateException("PAUSED 상태에서만 RUNNING으로 바꿀 수 있습니다.");
147162
}
148-
if (pauses.isEmpty()) throw new IllegalStateException("pause 기록이 없습니다.");
149-
150-
SessionPause last = pauses.get(pauses.size() - 1);
151-
last.resume(resumedAt, pauseSec);
152-
153163
this.sessionStatus = SessionStatus.RUNNING;
154164
}
155165

156-
public void end(LocalDateTime endedAt, int totalFocusSec) {
166+
public void end(LocalDateTime endedAt, int countedThresholdSec) {
157167
if (endedAt == null) throw new IllegalArgumentException("endedAt은 필수입니다.");
158-
if (totalFocusSec < 0) throw new IllegalArgumentException("totalFocusSec는 0 이상이어야 합니다.");
168+
if (countedThresholdSec < 0) throw new IllegalArgumentException("countedThresholdSec는 0 이상이어야 합니다.");
159169

160170
if (this.sessionStatus == SessionStatus.ENDED || this.sessionStatus == SessionStatus.CANCELED) {
161-
throw new IllegalStateException("이미 종료/취소된 세션입니다.");
171+
throw new IllegalStateException("이미 종료 또는 취소된 세션입니다.");
162172
}
163173

164174
this.endedAt = endedAt;
165-
this.totalFocusSec = totalFocusSec;
166175
this.sessionStatus = SessionStatus.ENDED;
176+
177+
this.countedInStats = this.totalFocusSec >= countedThresholdSec;
167178
}
168179

169180
public void cancel(LocalDateTime canceledAt) {

src/main/java/com/example/peakly/domain/focusSession/repository/FocusSessionRepository.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
import org.springframework.data.jpa.repository.JpaRepository;
66
import org.springframework.stereotype.Repository;
77

8+
import java.util.Optional;
9+
810
@Repository
911
public interface FocusSessionRepository extends JpaRepository<FocusSession, Long> {
12+
13+
Optional<FocusSession> findByIdAndUser_Id(Long sessionId, Long userId);
14+
1015
boolean existsByUser_IdAndSessionStatusIn(Long userId, Iterable<SessionStatus> statuses);
1116
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.example.peakly.domain.focusSession.repository;
2+
3+
import com.example.peakly.domain.focusSession.entity.SessionPause;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
import org.springframework.stereotype.Repository;
7+
8+
import java.util.List;
9+
import java.util.Optional;
10+
11+
@Repository
12+
public interface SessionPauseRepository extends JpaRepository<SessionPause, Long> {
13+
14+
boolean existsByFocusSession_IdAndResumedAtIsNull(Long sessionId);
15+
16+
@Query("SELECT sp FROM SessionPause sp" +
17+
" WHERE sp.focusSession.id = :sessionId" +
18+
" AND sp.resumedAt IS NOT NULL" +
19+
" ORDER BY sp.resumedAt DESC" +
20+
" LIMIT 1")
21+
Optional<SessionPause> findLatestResumedPause(Long sessionId);
22+
23+
List<SessionPause> findAllByFocusSession_IdAndResumedAtIsNull(Long sessionId);
24+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
package com.example.peakly.domain.focusSession.service;
22

3+
import com.example.peakly.domain.focusSession.dto.request.FocusSessionEndRequest;
34
import com.example.peakly.domain.focusSession.dto.request.FocusSessionStartRequest;
5+
import com.example.peakly.domain.focusSession.dto.response.FocusSessionEndResponse;
6+
import com.example.peakly.domain.focusSession.dto.response.FocusSessionPauseResponse;
7+
import com.example.peakly.domain.focusSession.dto.response.FocusSessionResumeResponse;
48
import com.example.peakly.domain.focusSession.dto.response.FocusSessionStartResponse;
59

610
public interface FocusSessionService {
11+
712
FocusSessionStartResponse start(Long userId, FocusSessionStartRequest req);
13+
14+
FocusSessionPauseResponse pause(Long userId, Long sessionId);
15+
16+
FocusSessionResumeResponse resume(Long userId, Long sessionId);
17+
18+
FocusSessionEndResponse end(Long userId, Long sessionId, FocusSessionEndRequest req);
819
}

0 commit comments

Comments
 (0)