Skip to content

[REFACTOR/#280] 4차 스프린트 QA를 반영합니다.#281

Merged
MoonsuKang merged 21 commits intodevelopfrom
refactor/#280-fourth-sprint-qa
Jun 21, 2025
Merged

[REFACTOR/#280] 4차 스프린트 QA를 반영합니다.#281
MoonsuKang merged 21 commits intodevelopfrom
refactor/#280-fourth-sprint-qa

Conversation

@MoonsuKang
Copy link
Contributor

@MoonsuKang MoonsuKang commented Jun 16, 2025

📌 ISSUE

closed #280

📄 Work Description

  • 리스트 화면에서 임시저장 유효성 상태 추가
  • 홈 화면에서 임시저장 유효성 상태 추가
  • 홈 화면에서 초기 데이터 로드 약간 수정
  • 임시저장 기간이 만료된 일기 전송 로직 수정

✨ PR Point

📸 ScreenShot/Video

Summary by CodeRabbit

  • New Features

    • Added new visual and interactive states for diary drafts, including handling and display of invalid or expired drafts in diary lists and buttons.
    • Enhanced button components to support customizable colors and improved disabled state visuals.
    • Introduced draft date tracking and validation to improve diary entry management.
    • Included a date field for diary entries and a flag indicating if a diary was created from a draft.
  • Bug Fixes

    • Improved logic for determining and displaying draft diary status, ensuring accurate UI feedback for invalid or expired drafts.
  • Improvements

    • Updated diary and button components to better reflect the status of drafts and replies.
    • Streamlined state management for drafts, providing more reliable and responsive UI updates.
    • Simplified calendar and diary data loading for smoother user experience.
    • Updated empty diary list message for clearer user communication.

@MoonsuKang MoonsuKang requested a review from SYAAINN June 16, 2025 08:42
@MoonsuKang MoonsuKang self-assigned this Jun 16, 2025
@MoonsuKang MoonsuKang added ♻️ REFACTOR 코드 리팩토링(전면 수정) 🌊 문수 문수 labels Jun 16, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 16, 2025

"""

Walkthrough

This update introduces new properties to several data classes, enhances UI components to handle draft and invalid draft diary states, and updates ViewModel and screen logic to track and reflect draft validity. Button components now support customized colors and disabled states based on diary reply status.

Changes

File(s) Change Summary
.../data/remote/dto/response/MonthlyCalendarResponseDto.kt Added date: String property to nested Diary data class.
.../data/remote/dto/response/WriteDiaryResponseDto.kt Added isFromDraft: Boolean property to WriteDiaryResponseDto.
.../data/remote/dto/response/DailyDiariesResponseDto.kt Added isDeleted: Boolean property to DailyDiariesResponseDto.
.../ui/component/button/ClodyButton.kt Updated ClodyButton signature to accept optional color parameters for container/content (enabled/disabled); refactored internal color logic.
.../ui/diarylist/component/DailyDiaryCard.kt Added INVALID_DRAFT handling for reply status, updating icon and button enablement/colors accordingly.
.../ui/home/component/DiaryStateButton.kt Added isInvalidDraft parameter; renders a disabled button with custom colors when true.
.../ui/home/screen/HomeScreen.kt Integrated new hasDraft and isInvalidDraft states; updated effect and dialog logic; passed new states to UI components.
.../ui/home/screen/HomeViewModel.kt Added hasDraft state flow; updated on daily diaries data fetch.
.../ui/writediary/screen/WriteDiaryViewModel.kt Added isDiaryExpired helper; updated writeDiary logic to check for expired dates before setting state.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant HomeScreen
    participant HomeViewModel
    participant DiaryStateButton
    participant WriteDiaryViewModel

    User->>HomeScreen: Open Home Screen
    HomeScreen->>HomeViewModel: Collect hasDraft, isInvalidDraft
    HomeScreen->>DiaryStateButton: Pass hasDraft, canReply, isInvalidDraft, etc.
    DiaryStateButton->>User: Render button (disabled if isInvalidDraft)
    User->>WriteDiaryViewModel: Attempt to write diary
    WriteDiaryViewModel->>WriteDiaryViewModel: Check isDiaryExpired
    alt Diary expired
        WriteDiaryViewModel->>HomeScreen: Set state to NoReply
    else Diary not expired
        WriteDiaryViewModel->>HomeScreen: Set state based on replyType
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Reflect 4th sprint QA feedback in codebase (#280)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes found.

Possibly related PRs

Suggested reviewers

  • SYAAINN

Poem

In Clody’s code, the drafts now gleam,
With buttons gray or blue, a themed new stream.
Expired dates now block the way,
While diaries track the draft each day.
With colors bright and logic neat,
This bunny’s work is quite the feat!
🐇✨
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d83e39 and cb11c8e.

📒 Files selected for processing (1)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🔭 Outside diff range comments (1)
app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt (1)

28-48: ⚠️ Potential issue

isInvalidDraft branch is unreachable – reorder the when clauses

hasDraft is true even for an invalid draft, so the first branch short-circuits the when, causing "이어쓰기" to be shown instead of the intended disabled "답장확인".

-when {
-    hasDraft -> { … }
-    isInvalidDraft -> { … }
+when {
+    isInvalidDraft -> {   // 1️⃣ highest priority
+
+    }
+    hasDraft -> {         // 2️⃣
+
+    }

Without this change, users with an expired draft will be able to tap Continue Writing, contradicting business rules.

🧹 Nitpick comments (5)
app/src/main/java/com/sopt/clody/data/remote/dto/response/WriteDiaryResponseDto.kt (1)

9-10: Annotate the new field or document expected semantics

isFromDraft is added without a @SerialName annotation or KDoc.
If the backend field name differs (e.g. is_from_draft) deserialization will silently fail.
Add an explicit annotation or short comment to avoid future regressions and improve readability.

app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt (1)

149-153: Nice: explicit variable name improves clarity

Renaming the lambda parameter to dailyResponse makes the success block self-describing.

app/src/main/java/com/sopt/clody/presentation/ui/diarylist/component/DailyDiaryCard.kt (1)

127-151: Consolidate disabled-state styling to reduce duplication

The button builds custom containerColor / contentColor yet still passes disabled*Color values.
You can delegate everything to ButtonDefaults.buttonColors by supplying only disabled*Color, avoiding manual if blocks:

-    val isDisabled = dailyDiary.isDeleted || dailyDiary.replyStatus == ReplyStatus.INVALID_DRAFT
-    val containerColor = if (dailyDiary.replyStatus == ReplyStatus.INVALID_DRAFT) {
-        ClodyTheme.colors.gray08
-    } else {
-        ClodyTheme.colors.lightBlue
-    }
-    val contentColor = if (dailyDiary.replyStatus == ReplyStatus.INVALID_DRAFT) {
-        ClodyTheme.colors.gray06
-    } else {
-        ClodyTheme.colors.blue
-    }
+    val isDisabled = dailyDiary.isDeleted || dailyDiary.replyStatus == ReplyStatus.INVALID_DRAFT
colors = ButtonDefaults.buttonColors(
    containerColor = ClodyTheme.colors.lightBlue,
    contentColor   = ClodyTheme.colors.blue,
    disabledContainerColor = ClodyTheme.colors.gray08,
    disabledContentColor   = ClodyTheme.colors.gray06,
)

Cleaner and avoids divergent colours if the theme changes.

app/src/main/java/com/sopt/clody/presentation/ui/component/button/ClodyButton.kt (1)

21-24: Leverage LocalContentColor instead of manual text-color switching

ButtonDefaults.buttonColors() already puts the contentColor / disabledContentColor in LocalContentColor.
Manually overriding the Text color duplicates that logic and makes it easy for the two sources to drift.

-Text(
-    text = text,
-    color = if (enabled) contentColor else disabledContentColor,
-    style = ClodyTheme.typography.body2SemiBold,
-)
+Text(
+    text = text,
+    style = ClodyTheme.typography.body2SemiBold,
+)

This keeps a single source of truth and lets downstream themes override content colours through ButtonDefaults.
No functional change, but eliminates an unnecessary branch.

Also applies to: 40-41

app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (1)

291-296: Misleading parameter name — replyStatus is actually a Route.ReplyLoading.ReplyLoadingFrom

onClickReplyDiary: (
    …
    replyStatus: Route.ReplyLoading.ReplyLoadingFrom
) -> Unit

replyStatus suggests a domain enum but the type is the origin enum.
Rename to from (or similar) to avoid confusion when the real ReplyStatus is also in scope.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0d4a59 and f5d5717.

📒 Files selected for processing (8)
  • app/src/main/java/com/sopt/clody/data/remote/dto/response/MonthlyCalendarResponseDto.kt (1 hunks)
  • app/src/main/java/com/sopt/clody/data/remote/dto/response/WriteDiaryResponseDto.kt (1 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/component/button/ClodyButton.kt (2 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/diarylist/component/DailyDiaryCard.kt (3 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt (2 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (7 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt (2 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/writediary/screen/WriteDiaryViewModel.kt (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt (1)
app/src/main/java/com/sopt/clody/presentation/ui/component/button/ClodyButton.kt (1)
  • ClodyButton (15-44)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (4)
app/src/main/java/com/sopt/clody/data/remote/dto/response/MonthlyCalendarResponseDto.kt (1)

17-18: Verify date–format alignment across DTOs

date: String is introduced but its expected format (ISO-8601, yyyy-MM-dd, etc.) is not stated.
Down-stream parsing (e.g. in DiaryDeleteButton, isDiaryExpired) will break if the server changes the pattern.

Document or enforce the format (e.g. with LocalDate + custom serializer).

app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt (1)

96-98: StateFlow for draft presence looks good

New _hasDraft / hasDraft flow is correctly initialised and exposed as read-only.
No issues spotted.

app/src/main/java/com/sopt/clody/presentation/ui/diarylist/component/DailyDiaryCard.kt (1)

50-56: Icon mapping covers INVALID_DRAFT state

The extra case keeps UI feedback consistent. 👍

app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (1)

126-130: Logic duplication with DiaryStateButton

hasDraft && !isValidDraftDate() opens the “continue draft” dialog, while the bottom bar still shows the disabled “답장확인” button (after the previous bug is fixed).
Double-check that these two UX paths are consistent; otherwise users may see contradictory actions.

Comment on lines +92 to 100
LaunchedEffect(Unit) {
val year = selectedDiaryDate.year
val month = selectedDiaryDate.month
val day = selectedDate.dayOfMonth

if (selectedDate.dayOfMonth != 0) {
homeViewModel.updateSelectedDate(
LocalDate.of(selectedDiaryDate.year, selectedDiaryDate.month, selectedDate.dayOfMonth),
)
} else {
homeViewModel.updateSelectedDate(LocalDate.now())
}
homeViewModel.loadCalendarData(year, month)
delay(500)
homeViewModel.loadDailyDiariesData(year, month, day)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Two LaunchedEffect(Unit) blocks fire concurrently – consider merging

Both blocks use the same key (Unit) and run on first composition, starting two coroutines that hit the network:

  1. in-app review & analytics
  2. calendar + diaries loading

The 500 ms delay is a brittle coupling between the two loads and may break on slow devices or change of dispatcher.
Combine them or chain the repository calls inside a single suspend function to guarantee ordering without magic delays.

🤖 Prompt for AI Agents
In app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt
around lines 92 to 100, two LaunchedEffect(Unit) blocks run concurrently causing
network calls to overlap and rely on a fragile 500ms delay for sequencing. To
fix this, merge these two LaunchedEffect blocks into one and chain the
repository calls sequentially within a single suspend function or coroutine,
ensuring the first completes before the second starts without using arbitrary
delays.

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6dc1a33 and 1d83e39.

📒 Files selected for processing (3)
  • app/src/main/java/com/sopt/clody/data/remote/dto/response/DailyDiariesResponseDto.kt (1 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (7 hunks)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeViewModel.kt
🧰 Additional context used
🪛 detekt (1.23.8)
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt

[warning] 106-106: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (1)
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (1)

84-91: 👍 Duplicate LaunchedEffect blocks merged – removes race & magic delay

The new single block eliminates the fragile 500 ms delay noted in the previous review and makes the sequence explicit. Nice clean-up.

Comment on lines 8 to 11
@SerialName("diaries") val diaries: List<Diary>,
@SerialName("isDeleted") val isDeleted: Boolean,
@SerialName("isDraft") val isDraft: Boolean,
) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

isDeleted should be nullable or have a default value to avoid MissingFieldException.

Adding a non-nullable field to a DTO breaks backward compatibility with older back-end payloads that don’t yet include the field. kotlinx.serialization will throw at runtime if "isDeleted" is absent.

-    @SerialName("isDeleted") val isDeleted: Boolean,
+    @SerialName("isDeleted") val isDeleted: Boolean = false,

Either supply a sensible default (false) or make it Boolean? and handle null downstream.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@SerialName("diaries") val diaries: List<Diary>,
@SerialName("isDeleted") val isDeleted: Boolean,
@SerialName("isDraft") val isDraft: Boolean,
) {
@SerialName("diaries") val diaries: List<Diary>,
- @SerialName("isDeleted") val isDeleted: Boolean,
+ @SerialName("isDeleted") val isDeleted: Boolean = false,
@SerialName("isDraft") val isDraft: Boolean,
) {
🤖 Prompt for AI Agents
In
app/src/main/java/com/sopt/clody/data/remote/dto/response/DailyDiariesResponseDto.kt
around lines 8 to 11, the non-nullable Boolean field isDeleted can cause a
MissingFieldException if the backend payload does not include it. To fix this,
either make isDeleted nullable by changing its type to Boolean? or provide a
default value such as false to ensure backward compatibility and prevent runtime
exceptions.

Comment on lines +93 to 109
LaunchedEffect(Unit) {
val year = selectedDiaryDate.year
val month = selectedDiaryDate.month
val day = selectedDate.dayOfMonth

if (selectedDate.dayOfMonth != 0) {
homeViewModel.updateSelectedDate(
LocalDate.of(selectedDiaryDate.year, selectedDiaryDate.month, selectedDate.dayOfMonth),
)
} else {
homeViewModel.updateSelectedDate(LocalDate.now())
try {
coroutineScope {
val calendarDeferred = async { homeViewModel.loadCalendarData(year, month) }
val dailyDeferred = async { homeViewModel.loadDailyDiariesData(year, month, day) }

calendarDeferred.await()
dailyDeferred.await()
}
} catch (e: Exception) {
homeViewModel.setErrorState(true, "데이터를 불러오는데 실패했습니다.")
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Catch-all Exception is swallowed; use supervisorScope + logging to preserve stack-trace.

  1. coroutineScope { async … } cancels both coroutines when one fails. If you want both results but tolerate failure in either, wrap with supervisorScope instead.
  2. The generic catch (e: Exception) silently drops the throwable after setting UI state, making debugging impossible and triggering detekt’s SwallowedException warning.
-    try {
-        coroutineScope {
-            val calendarDeferred = async { homeViewModel.loadCalendarData(year, month) }
-            val dailyDeferred = async { homeViewModel.loadDailyDiariesData(year, month, day) }
-
-            calendarDeferred.await()
-            dailyDeferred.await()
-        }
-    } catch (e: Exception) {
-        homeViewModel.setErrorState(true, "데이터를 불러오는데 실패했습니다.")
-    }
+    try {
+        supervisorScope {
+            val calendar = async { homeViewModel.loadCalendarData(year, month) }
+            val daily    = async { homeViewModel.loadDailyDiariesData(year, month, day) }
+            calendar.await()
+            daily.await()
+        }
+    } catch (e: Exception) {
+        Timber.e(e, "HomeScreen data load failed") // or Log.e(...)
+        homeViewModel.setErrorState(true, "데이터를 불러오는데 실패했습니다.")
+    }

This keeps the stack-trace, satisfies static analysis, and ensures one failed call doesn’t cancel the other unnecessarily.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
LaunchedEffect(Unit) {
val year = selectedDiaryDate.year
val month = selectedDiaryDate.month
val day = selectedDate.dayOfMonth
if (selectedDate.dayOfMonth != 0) {
homeViewModel.updateSelectedDate(
LocalDate.of(selectedDiaryDate.year, selectedDiaryDate.month, selectedDate.dayOfMonth),
)
} else {
homeViewModel.updateSelectedDate(LocalDate.now())
try {
coroutineScope {
val calendarDeferred = async { homeViewModel.loadCalendarData(year, month) }
val dailyDeferred = async { homeViewModel.loadDailyDiariesData(year, month, day) }
calendarDeferred.await()
dailyDeferred.await()
}
} catch (e: Exception) {
homeViewModel.setErrorState(true, "데이터를 불러오는데 실패했습니다.")
}
}
LaunchedEffect(Unit) {
val year = selectedDiaryDate.year
val month = selectedDiaryDate.month
val day = selectedDate.dayOfMonth
try {
supervisorScope {
val calendar = async { homeViewModel.loadCalendarData(year, month) }
val daily = async { homeViewModel.loadDailyDiariesData(year, month, day) }
calendar.await()
daily.await()
}
} catch (e: Exception) {
Timber.e(e, "HomeScreen data load failed") // or Log.e(...)
homeViewModel.setErrorState(true, "데이터를 불러오는데 실패했습니다.")
}
}
🧰 Tools
🪛 detekt (1.23.8)

[warning] 106-106: The caught exception is swallowed. The original exception could be lost.

(detekt.exceptions.SwallowedException)

🤖 Prompt for AI Agents
In app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt
around lines 93 to 109, replace the coroutineScope with supervisorScope to
prevent cancellation of both coroutines if one fails, and add proper logging
inside the catch block to preserve the stack trace. This involves changing
coroutineScope to supervisorScope and logging the caught exception before
setting the error state, ensuring failures in one async call do not cancel the
other and that exceptions are not silently swallowed.

Copy link
Contributor

@SYAAINN SYAAINN left a comment

Choose a reason for hiding this comment

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

헉 늦게 봤네요 어프했습니다!

@MoonsuKang MoonsuKang merged commit d8a1111 into develop Jun 21, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

♻️ REFACTOR 코드 리팩토링(전면 수정) 🌊 문수 문수

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] 4차 스프린트 QA를 반영합니다.

2 participants