Skip to content

Conversation

@rlajm1203
Copy link
Contributor

@rlajm1203 rlajm1203 commented Sep 24, 2025

📌 관련 이슈

✒️ 작업 내용

  • 출석체크 지각/불참 시에 벌점 가중치가 부여되지 않는 오류가 발생하여, 로직을 추가합니다.

스크린샷 🏞️ (선택)

💬 REVIEWER에게 요구사항 💬

Summary by CodeRabbit

  • Refactor
    • 출석 상태 변경 로직을 중앙화하여 상태 전환, 지각/결석에 대한 패널티 반영, 출석 시 순위 부여를 일관되게 처리합니다. 상태 변경 이후 점수와 순위가 보다 안정적으로 반영됩니다.
  • Chores
    • 내부 모델의 세터 관리 방식을 정리하여 코드의 일관성과 유지보수성을 향상시켰습니다.

@rlajm1203 rlajm1203 self-assigned this Sep 24, 2025
@rlajm1203 rlajm1203 added the bug Something isn't working label Sep 24, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 24, 2025

Walkthrough

AttendModel에 Lombok @Setter가 도입되어 rank와 penaltyScore의 세터가 대체되었고, AttendService는 AttendWeightCalculator 의존성을 추가하고 상태 변경 로직을 updateAttendStatus로 분리해 패널티 적용 및 랭크 부여를 캡슐화했다. 저장 호출은 유지된다.

Changes

Cohort / File(s) Summary
Model: Lombok 세터 도입
eeos/src/main/java/com/blackcompany/eeos/target/application/model/AttendModel.java
rank, penaltyScore 필드에 @Setter 추가, 기존 수동 setRank(Long) 제거, import lombok.Setter; 추가
Service: 상태 업데이트 리팩터링 및 패널티 계산 도입
eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java
AttendWeightCalculator 의존성 추가, changeStatus에서 상태/랭크/패널티 처리 로직을 updateAttendStatus(AttendModel, ProgramModel)로 분리, 결석/지각 시 패널티 적용, 출석 전환 시 랭크 할당, 기존 저장 흐름 유지

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant S as AttendService
  participant C as AttendWeightCalculator
  participant M as AttendModel
  participant P as ProgramModel
  participant R as Repository

  U->>S: changeStatus(targetId, programId, request)
  S->>S: updateAttendStatus(M, P)
  S->>M: 현재 모드 판정 및 상태 매핑
  alt 상태 == ABSENT or LATE
    S->>C: calculatePenalty(M, P)
    C-->>S: penaltyScore
    S->>M: setPenaltyScore
  else 상태 == ATTEND
    S->>S: getNextRank(P)
    S->>M: setRank
  end
  S->>R: save(M)
  R-->>S: saved(M)
  S-->>U: 응답
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • Daae-Kim
  • kssumin

Poem

깡충, 깡충 코드밭 달려온 토끼 🐇
롬복 깃결에 세터가 살랑,
지각엔 패널티, 출석엔 랭크를 쪼옥—
서비스는 분리되어 반듯히,
저장소로 폴짝, 축하해요!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed PR 제목 '[FIX] 출석체크 시 벌점 가중치 부여 로직 추가'는 변경의 핵심인 출석 체크에서 지각·불참에 대한 벌점 가중치 로직 추가를 정확히 요약합니다. 간결하고 불필요한 정보나 이모지 없이 주요 변경을 명확히 전달하며 변경사항 요지와 일치합니다. 따라서 히스토리를 스캔하는 동료가 PR 목적을 빠르게 파악할 수 있습니다.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BM/hotfix/attend-weight

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Sep 24, 2025

Test Results

101 tests  ±0   98 ✅ ±0   5s ⏱️ ±0s
 40 suites ±0    3 💤 ±0 
 40 files   ±0    0 ❌ ±0 

Results for commit ff86c9c. ± Comparison against base commit 7c6de32.

♻️ This comment has been updated with latest results.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
eeos/src/main/java/com/blackcompany/eeos/target/application/model/AttendModel.java (2)

12-12: 도메인 모델의 Setter 공개 범위 축소 권장

Setter 노출은 도메인 불변성을 약화시킬 수 있습니다. 패키지 범위로 제한하는 것을 권장합니다.

적용 예시(diff):

 import lombok.NoArgsConstructor;
+import lombok.AccessLevel;
 import lombok.Setter;
 import lombok.ToString;

26-27: rank/penaltyScore Setter 범위 축소 및 값 검증 고려

  • Setter를 패키지 범위로 제한해 외부 임의 변경을 방지하세요.
  • 음수/비정상 값 방지(예: rank > 0, penaltyScore >= 0) 검증이 필요합니다.

적용 예시(diff):

-	@Setter private Long rank;
-	@Setter private Integer penaltyScore;
+	@Setter(AccessLevel.PACKAGE) private Long rank;
+	@Setter(AccessLevel.PACKAGE) private Integer penaltyScore;

추가로, 도메인 메서드(ex. assignRank, applyPenalty)를 통해 유효성 검사를 내재화하는 접근도 고려해 주세요.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6de32 and 7f01b91.

📒 Files selected for processing (2)
  • eeos/src/main/java/com/blackcompany/eeos/target/application/model/AttendModel.java (2 hunks)
  • eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (3)
eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java (3)

149-149: 상태 변경 로직 분리(LGTM)

변경 계산을 updateAttendStatus로 캡슐화한 것은 응집도 향상에 유익합니다.


89-89: AttendWeightCalculator 빈 등록 확인 — 생성자 주입 가능

AttendWeightCalculator에 @service@requiredargsconstructor가 선언되어 있어 생성자 주입 가능함. calculateTotalScore는 public int 반환(AttendWeightCalculator.java)이며 PenaltyPointRepository와 관련 조회 메서드가 존재함.


409-412: 벌점 타입·영속성 검증 완료 — 수정 불필요

calculateTotalScore는 int를 반환하고 AttendModel/AttendEntity의 penaltyScore는 Integer라 primitive→박싱으로 타입 불일치 없음. setPenaltyScore로 설정한 뒤 attendRepository.save(attendEntityConverter.toEntity(changedModel))가 호출되어 AttendEntity.penalty_score에 값이 저장되며, PenaltyPointRepository도 AttendEntity를 대상으로 집계 쿼리를 수행(별도 penalty_point 테이블 없음).

Comment on lines +403 to +408
ProgramAttendMode attendMode = program.getAttendMode();
AttendStatus attendStatus = AttendStatus.find(attendMode.getMode());

// 상태 바꾸기
AttendModel changedModel = model.changeStatus(attendMode.getMode());
// 벌점 반영하기
Copy link

@coderabbitai coderabbitai bot Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

ProgramAttendMode → AttendStatus 매핑/케이스 일치 여부 확인

attendMode.getMode()를 String으로 받아 AttendStatus.find로 변환합니다. 모드 문자열과 AttendStatus의 내부 문자열 표현(대소문자/별칭)이 1:1로 일치하는지 검증이 필요합니다.

점검 스크립트:


🏁 Script executed:

#!/bin/bash
# ProgramAttendMode 정의와 getMode() 반환값 확인
rg -nC3 -P 'enum\s+ProgramAttendMode\b|getMode\s*\('

# AttendStatus.find 구현과 허용 문자열(케이스/별칭) 확인
rg -nC5 -P 'enum\s+AttendStatus\b|static\s+\w+\s*find\s*\('

Length of output: 18723


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== AttendStatus.java ==="
sed -n '1,240p' eeos/src/main/java/com/blackcompany/eeos/target/application/model/AttendStatus.java || true

echo
echo "=== ProgramAttendMode.java ==="
sed -n '1,240p' eeos/src/main/java/com/blackcompany/eeos/program/application/model/ProgramAttendMode.java || true

Length of output: 1261


'END' 모드가 AttendStatus에 없음 — AttendStatus.find 호출 시 예외 발생

ProgramAttendMode.getMode()가 "attend"|"late"|"end"을 반환하는데 "end"는 AttendStatus(허용값: "attend","absent","late","nonResponse","nonRelated")에 없어 AttendStatus.find(attendMode.getMode()) 호출이 NotFoundAttendStatusException을 던집니다.

위치: eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java (updateAttendStatus 호출부, 약 401–411행); 관련 파일: ProgramAttendMode.java, AttendStatus.java.

해결안(중 택1):

  • AttendStatus.find 호출 전에 ProgramAttendMode.END를 분기 처리(무시/기본값 변환 등)하거나
  • 명시적 매핑 함수를 만들어 "end"를 적절한 AttendStatus로 변환하거나 AttendStatus에 대응값 추가
🤖 Prompt for AI Agents
In
eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java
around lines 403–408, ProgramAttendMode.getMode() can return "end" which is not
present in AttendStatus and causes AttendStatus.find(...) to throw
NotFoundAttendStatusException; fix by adding a branch before calling
AttendStatus.find to handle ProgramAttendMode.END (either skip the find and
treat as a no-op or map it to a sensible default AttendStatus), or implement an
explicit mapping function that converts ProgramAttendMode values (including END)
to corresponding AttendStatus values (or update AttendStatus to include a
matching value) and use that mapping instead of calling AttendStatus.find
directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음 저 함수를 호출하기 전에, AttendStatus 가 END인 경우는 이미 validate 함수를 호출해서 미리 검증하고 있어

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@rlajm1203 맞습니다! 코드를 다시 확인해보니 changeStatus 메서드에서 validateAttend(program, model)를 먼저 호출하고, 이 함수가 programModel.getAttendMode().equals(ProgramAttendMode.END)인 경우 NotStartAttendException을 던져서 updateAttendStatus가 호출되기 전에 이미 차단하고 있네요.

따라서 updateAttendStatus 함수는 실제로 ProgramAttendMode.END 케이스를 만나지 않게 되어 있어서 제가 지적한 문제는 발생하지 않을 것 같습니다. 검증 로직이 잘 되어 있군요! 😊

  (\   /)
 ( ._.)
o_(")(")

thinking rabbit


🏁 Script executed:

#!/bin/bash
# Check the validateAttend function implementation and how it handles END mode
rg -nC5 -P 'validateAttend\s*\(' eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java

# Check the changeStatus method flow to see the validation order
rg -nC10 -P 'changeStatus\s*\(' eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java

Length of output: 2530


@rlajm1203 완전히 맞습니다! 스크립트 결과를 보니 확실히 검증되었네요.

changeStatus 메서드에서:

  1. Line 147: validateAttend(program, model) 먼저 호출
  2. Line 149: updateAttendStatus(model, program) 나중에 호출

그리고 validateAttend 함수 (Line 432)에서:

if (programModel.getAttendMode().equals(ProgramAttendMode.END))
    throw new NotStartAttendException();

이렇게 END 모드일 때 예외를 던져서 updateAttendStatus가 호출되기 전에 이미 차단하고 있군요. 제가 놓친 부분이었습니다. 검증 로직이 잘 설계되어 있어서 문제없이 동작할 것 같습니다!

감사합니다. 🙂

  (\   /)
 ( ^.^)
o_(")(")

happy rabbit


✏ Learnings added
Learnt from: rlajm1203
PR: JNU-econovation/EEOS-BE#291
File: eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java:403-408
Timestamp: 2025-09-24T15:04:52.518Z
Learning: In AttendService.changeStatus(), the validateAttend() method is called before updateAttendStatus() and throws NotStartAttendException when ProgramAttendMode is END, preventing updateAttendStatus from encountering the END case that would cause AttendStatus.find() to fail.

Learnt from: rlajm1203
PR: JNU-econovation/EEOS-BE#291
File: eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java:403-408
Timestamp: 2025-09-24T15:04:52.518Z
Learning: In AttendService.changeStatus(), the validateAttend() method is called before updateAttendStatus() and throws NotStartAttendException when ProgramAttendMode is END (line 432-433), preventing updateAttendStatus from encountering the END case that would cause AttendStatus.find() to fail.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@rlajm1203 rlajm1203 merged commit 45fa388 into develop Sep 24, 2025
2 of 3 checks passed
@rlajm1203 rlajm1203 deleted the BM/hotfix/attend-weight branch September 24, 2025 15:10
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f01b91 and ff86c9c.

📒 Files selected for processing (1)
  • eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-24T15:04:52.518Z
Learnt from: rlajm1203
PR: JNU-econovation/EEOS-BE#291
File: eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java:403-408
Timestamp: 2025-09-24T15:04:52.518Z
Learning: In AttendService.changeStatus(), the validateAttend() method is called before updateAttendStatus() and throws NotStartAttendException when ProgramAttendMode is END (line 432-433), preventing updateAttendStatus from encountering the END case that would cause AttendStatus.find() to fail.

Applied to files:

  • eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java
📚 Learning: 2025-09-24T15:04:52.518Z
Learnt from: rlajm1203
PR: JNU-econovation/EEOS-BE#291
File: eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java:403-408
Timestamp: 2025-09-24T15:04:52.518Z
Learning: In AttendService.changeStatus(), the validateAttend() method is called before updateAttendStatus() and throws NotStartAttendException when ProgramAttendMode is END, preventing updateAttendStatus from encountering the END case that would cause AttendStatus.find() to fail.

Applied to files:

  • eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (4)
eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java (4)

147-154: 상태 변경 로직 분리로 응집도/가독성 개선

changeStatus에서 updateAttendStatus로 위임한 방향성 좋습니다. 퍼시스턴스 흐름도 유지됩니다.


403-405: END 모드 매핑 이슈는 validate에서 선제 차단됨 — OK

ProgramAttendMode.END → AttendStatus 미존재 문제는 changeStatus()에서 validateAttend()가 먼저 예외를 던져 실제로는 도달하지 않습니다. 이 부분은 이전 논의와 일치합니다.


413-416: 랭크 부여 조건의 enum 비교로 안정화 — 좋습니다

문자열 비교 대신 enum 비교 사용으로 회귀 위험 감소했습니다.


89-90: AttendWeightCalculator 빈 등록/스캔 확인 — 조치 불필요

AttendWeightCalculator(eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendWeightCalculator.java)는 @service로 빈 등록되어 있고, AttendPenaltyResponseConverter(eeos/src/main/java/com/blackcompany/eeos/target/application/dto/converter/AttendPenaltyResponseConverter.java)는 @component로 등록되어 있습니다. @requiredargsconstructor 기반 생성자 주입으로 문제가 없으며, 검색 결과 명시적 순환 참조는 발견되지 않습니다.

Comment on lines +409 to +412
if (attendStatus == AttendStatus.ABSENT || attendStatus == AttendStatus.LATE)
changedModel.setPenaltyScore(
attendWeightCalculator.calculateTotalScore(List.of(attendStatus)));

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

ABSENT 벌점 분기 도달 불가 가능성 + 벌점 덮어쓰기 의도 확인

  • 현재 흐름(updateAttendStatus)은 ProgramAttendMode 기반이라 LATE는 적용되지만 ABSENT는 호출 경로상 도달하지 않습니다(END는 validate에서 차단). “불참(ABSENT)” 벌점은 어디서 반영되는지 확인 필요합니다(예: 배치/일괄 마감 로직). 요구사항이 “지각/불참 모두 가중치 부여”라면, 불참 경로의 반영 위치가 이 메서드가 아니라면 그 근거를 남겨 주세요.
  • setPenaltyScore는 ‘대입’입니다. 기존 값 누적이 의도라면 += 또는 계산기에서 누계 반환이 필요합니다. 단건 대입이 의도면 현 구현으로 충분합니다.

명시적 분기로 의도를 드러내는 것을 권장합니다.

적용 예시(diff):

-    // 벌점 반영하기
-    if (attendStatus == AttendStatus.ABSENT || attendStatus == AttendStatus.LATE)
-        changedModel.setPenaltyScore(
-                attendWeightCalculator.calculateTotalScore(List.of(attendStatus)));
+    // 벌점 반영하기
+    switch (attendStatus) {
+        case LATE:
+            // 단건 가중치라면 List.of(AttendStatus.LATE) 그대로 사용
+            changedModel.setPenaltyScore(
+                    attendWeightCalculator.calculateTotalScore(List.of(AttendStatus.LATE)));
+            break;
+        case ATTEND:
+            // 참석 시 벌점 초기화가 요구사항이면 유지, 아니라면 제거
+            changedModel.setPenaltyScore(0L);
+            break;
+        default:
+            // ABSENT는 별도 마감/배치 로직에서 처리된다면 여기서는 no-op
+            break;
+    }

추가 확인 스크립트(ABSENT 벌점 반영 경로 탐색):


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ABSENT 벌점 관련 코드 경로 탐색 =="
rg -nC3 -P 'ABSENT|setPenaltyScore|calculateTotalScore|AttendWeightCalculator' --type=java

Length of output: 12094


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Show AttendService.java (first 800 lines with numbers) =="
nl -ba eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java | sed -n '1,800p'

Length of output: 101


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate files =="
attend_service_file=$(rg -n --hidden -S "^public class AttendService\b" --type java | head -n1 | cut -d: -f1 || true)
attend_model_file=$(rg -n --hidden -S "^public class AttendModel\b" --type java | head -n1 | cut -d: -f1 || true)
attend_calc_file=$(rg -n --hidden -S "^public class AttendWeightCalculator\b" --type java | head -n1 | cut -d: -f1 || true)
program_quit_file=$(rg -n --hidden -S "^public class ProgramQuitService\b" --type java | head -n1 | cut -d: -f1 || true)
attend_repo_file=$(rg -n --hidden -S "interface .*AttendRepository|interface AttendRepository" --type java | head -n1 | cut -d: -f1 || true)
attend_count_calc_file=$(rg -n --hidden -S "^public class AttendCountCalculate\b" --type java | head -n1 | cut -d: -f1 || true)

echo "AttendService: $attend_service_file"
echo "AttendModel: $attend_model_file"
echo "AttendWeightCalculator: $attend_calc_file"
echo "ProgramQuitService: $program_quit_file"
echo "AttendRepository: $attend_repo_file"
echo "AttendCountCalculate: $attend_count_calc_file"

echo
echo "== Show AttendService (around lines 350-440) =="
if [ -n "$attend_service_file" ] && [ -f "$attend_service_file" ]; then
  sed -n '340,440p' "$attend_service_file"
else
  echo "AttendService file not found"
fi

echo
echo "== Show AttendModel (full) =="
if [ -n "$attend_model_file" ] && [ -f "$attend_model_file" ]; then
  sed -n '1,240p' "$attend_model_file"
else
  echo "AttendModel file not found"
fi

echo
echo "== Show AttendWeightCalculator (full) =="
if [ -n "$attend_calc_file" ] && [ -f "$attend_calc_file" ]; then
  sed -n '1,240p' "$attend_calc_file"
else
  echo "AttendWeightCalculator file not found"
fi

echo
echo "== Show ProgramQuitService (around lines 1-160) =="
if [ -n "$program_quit_file" ] && [ -f "$program_quit_file" ]; then
  sed -n '1,240p' "$program_quit_file"
else
  echo "ProgramQuitService file not found"
fi

echo
echo "== Show AttendRepository (any match) =="
if [ -n "$attend_repo_file" ] && [ -f "$attend_repo_file" ]; then
  sed -n '1,240p' "$attend_repo_file"
else
  rg -n --hidden -S "updateAttendStatusByProgramId|updateAttendStatus" --type java || true
fi

echo
echo "== Show AttendCountCalculate (full) =="
if [ -n "$attend_count_calc_file" ] && [ -f "$attend_count_calc_file" ]; then
  sed -n '1,240p' "$attend_count_calc_file"
else
  echo "AttendCountCalculate file not found"
fi

Length of output: 13525


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ProgramAttendMode 정의 위치 검색 =="
rg -n --hidden -S "enum ProgramAttendMode|public enum ProgramAttendMode" --type java || true

echo
echo "== Show ProgramAttendMode file =="
rg -n --hidden -S "enum ProgramAttendMode|public enum ProgramAttendMode" --type java | head -n1 | cut -d: -f1 | xargs -r sed -n '1,240p'

echo
echo "== Show AttendEntity =="
rg -n --hidden -S "class AttendEntity" --type java | head -n1 | cut -d: -f1 | xargs -r sed -n '1,240p'

echo
echo "== Search for calculateTotalScore / setPenaltyScore usages =="
rg -n --hidden -S "calculateTotalScore|setPenaltyScore" --type java || true

echo
echo "== Search for code handling ABSENT penalty elsewhere =="
rg -n --hidden -S "ABSENT.*penal|penal.*ABSENT|penaltyScore|penalty point|penaltyPoint|updateAttendStatusByProgramId" --type java || true

echo
echo "== Search for places that create/update AttendEntity penaltyScore field =="
rg -n --hidden -S "penaltyScore" --type java || true

echo
echo "== Show AttendRepository.updateAttendStatusByProgramId implementation (persistence layer) =="
rg -n --hidden -S "updateAttendStatusByProgramId" --type java -n || true
rg -n --hidden -S "updateAttendStatusByProgramId" --type sql || true

Length of output: 11722


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Show persistence AttendRepository =="
sed -n '1,240p' eeos/src/main/java/com/blackcompany/eeos/target/persistence/AttendRepository.java

Length of output: 4577


ABSENT 분기 불필요 — 배치로 상태 전환 시 벌점이 반영되지 않음(수정 필요)

  • 검증 결과: updateAttendStatus(...)는 ProgramAttendMode(ATTEND/LATE/END)를 기반으로 호출되며 validateAttend()에서 END는 차단됨 → 이 경로에서 AttendStatus.ABSENT에 도달하지 않음. (eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java — updateAttendStatus)
  • 현재 배치(ProgramQuitService.doQuit)에서 attendRepository.updateAttendStatusByProgramId(..., NONRESPONSE, ABSENT)로 상태만 변경하고 penaltyScore는 업데이트하지 않음(eeos/src/main/java/com/blackcompany/eeos/program/application/service/ProgramQuitService.java, eeos/src/main/java/com/blackcompany/eeos/target/persistence/AttendRepository.java, eeos/src/main/java/com/blackcompany/eeos/target/persistence/AttendEntity.java — penaltyScore 필드). setPenaltyScore 사용처는 updateAttendStatus 하나뿐임.
  • setPenaltyScore는 대입(assign)임. 벌점 누적이 의도라면 현재 구현(대입)은 잘못이고, 단건 대입이 의도라면 유지하면 됨.

권장 조치:

  • AttendService의 ABSENT 분기는 제거하거나 명시적 주석/분기로 의도 표시.
  • 배치에서 NONRESPONSE→ABSENT 전환 시 벌점도 함께 반영하도록 수정(예: 배치에서 attendWeightCalculator.calculateTotalScore(List.of(AttendStatus.ABSENT))로 penaltyScore 일괄 업데이트 또는 엔티티 로드 후 setPenaltyScore 적용).
  • 벌점 대입 vs 누적 요구사항을 명확히 하고 그에 따라 setPenaltyScore 동작을 조정.
🤖 Prompt for AI Agents
In
eeos/src/main/java/com/blackcompany/eeos/target/application/service/AttendService.java
around lines 409-412, remove the unreachable AttendStatus.ABSENT branch (or
replace it with an explicit comment clarifying it is unreachable in
updateAttendStatus) to avoid dead code; then ensure batch-driven status
transitions (ProgramQuitService.doQuit) also update penaltyScore: modify
ProgramQuitService to compute penaltyScore for ABSENT (e.g., use
attendWeightCalculator.calculateTotalScore(List.of(AttendStatus.ABSENT))) and
persist it via AttendRepository update or by loading entities and calling
setPenaltyScore, and finally decide whether penaltyScore should be assigned or
accumulated and adjust setPenaltyScore implementation and all callers
accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants