Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.fowoco.server.casework.application;

/**
* Case 표시 상태를 계산할 때 사용하는 조회 사실입니다.
*
* @param completed Case 업무가 모두 완료됐는지 여부
* @param linkIssued 근로자용 요청 링크를 발급했는지 여부
* @param reviewRequired 도착한 답변이나 서류에 HR 검토가 남아 있는지 여부
* @param unreadResponse 도착했지만 아직 읽지 않은 근로자 응답이 있는지 여부
*/
public record CaseDisplayFacts(
boolean completed,
boolean linkIssued,
boolean reviewRequired,
boolean unreadResponse
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.fowoco.server.casework.application;

import com.fowoco.server.casework.domain.CaseDisplayStatus;
import java.util.Objects;

/**
* 업무함 API에 반환할 Case 표시 상태와 새 응답 표시입니다.
*/
public record CaseDisplayState(
CaseDisplayStatus status,
boolean hasUnreadResponse
) {
public CaseDisplayState {
Objects.requireNonNull(status, "status must not be null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.fowoco.server.casework.application;

import com.fowoco.server.casework.domain.CaseDisplayStatus;
import java.util.Objects;

/**
* 여러 모듈의 상태를 변경하지 않고 업무함 표시 상태만 계산합니다.
*/
public final class CaseDisplayStatusResolver {

public CaseDisplayState resolve(CaseDisplayFacts facts) {
Objects.requireNonNull(facts, "facts must not be null");

if (facts.completed()) {
return new CaseDisplayState(CaseDisplayStatus.COMPLETED, false);
}
if (facts.reviewRequired() || facts.unreadResponse()) {
return new CaseDisplayState(
CaseDisplayStatus.REVIEW_REQUIRED,
facts.unreadResponse()
);
}
if (facts.linkIssued()) {
return new CaseDisplayState(CaseDisplayStatus.REQUEST_SENT, false);
}
return new CaseDisplayState(CaseDisplayStatus.DOCUMENT_PENDING, false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.fowoco.server.casework.domain;

/**
* 업무함에서 사용자에게 보여 주는 Case 요약 상태입니다.
*
* <p>Task의 업무 처리 상태와 Worker Link의 전달 상태를 바꾸지 않고,
* 조회 시점의 사실을 조합해 화면에 표시할 값만 나타냅니다.</p>
*/
public enum CaseDisplayStatus {
DOCUMENT_PENDING,
REQUEST_SENT,
REVIEW_REQUIRED,
COMPLETED
}
4 changes: 4 additions & 0 deletions src/main/java/com/fowoco/server/casework/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Case grouping, workflow snapshots, and work-inbox projections.
*/
package com.fowoco.server.casework;
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.fowoco.server.casework.application;

import static com.fowoco.server.casework.domain.CaseDisplayStatus.COMPLETED;
import static com.fowoco.server.casework.domain.CaseDisplayStatus.DOCUMENT_PENDING;
import static com.fowoco.server.casework.domain.CaseDisplayStatus.REQUEST_SENT;
import static com.fowoco.server.casework.domain.CaseDisplayStatus.REVIEW_REQUIRED;
import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;

class CaseDisplayStatusResolverTest {

private final CaseDisplayStatusResolver resolver = new CaseDisplayStatusResolver();

@Test
void showsDocumentPendingBeforeWorkerLinkIsIssued() {
CaseDisplayState result = resolver.resolve(facts(false, false, false, false));

assertThat(result.status()).isEqualTo(DOCUMENT_PENDING);
assertThat(result.hasUnreadResponse()).isFalse();
}

@Test
void showsRequestSentAfterWorkerLinkIsIssuedWithoutResponse() {
CaseDisplayState result = resolver.resolve(facts(false, true, false, false));

assertThat(result.status()).isEqualTo(REQUEST_SENT);
assertThat(result.hasUnreadResponse()).isFalse();
}

@Test
void keepsReviewRequiredAfterResponseIsReadUntilHrDecision() {
CaseDisplayState result = resolver.resolve(facts(false, true, true, false));

assertThat(result.status()).isEqualTo(REVIEW_REQUIRED);
assertThat(result.hasUnreadResponse()).isFalse();
}

@Test
void showsReviewRequiredAndUnreadBadgeForNewWorkerResponse() {
CaseDisplayState result = resolver.resolve(facts(false, true, false, true));

assertThat(result.status()).isEqualTo(REVIEW_REQUIRED);
assertThat(result.hasUnreadResponse()).isTrue();
}

@Test
void completedTakesPriorityAndClearsUnreadBadge() {
CaseDisplayState result = resolver.resolve(facts(true, true, true, true));

assertThat(result.status()).isEqualTo(COMPLETED);
assertThat(result.hasUnreadResponse()).isFalse();
}

private CaseDisplayFacts facts(
boolean completed,
boolean linkIssued,
boolean reviewRequired,
boolean unreadResponse
) {
return new CaseDisplayFacts(
completed,
linkIssued,
reviewRequired,
unreadResponse
);
}
}
Loading