Skip to content
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
ca07ccf
🐛 Fix: conflict 해결
dogmania Feb 9, 2026
a395374
♻️ Refactor: ktlint 적용
dogmania Feb 9, 2026
2719d81
♻️ Refactor: 네이밍 변경
dogmania Feb 9, 2026
4d5543b
♻️ Refactor: 네이밍 변경
dogmania Feb 9, 2026
441554e
✨ Feat: UpdateGoalParam -> UpdateGoalRequest Mapper 구현
dogmania Feb 9, 2026
faad6c2
✨ Feat: 목표 수정 요청 DTO 구현
dogmania Feb 9, 2026
6bb8b07
✨ Feat: 목표 수정 Domain Param 구현
dogmania Feb 9, 2026
bd7fe6a
🍱 Chore: string 리소스 추가
dogmania Feb 9, 2026
ea45cf5
♻️ Refactor: 네이밍 변경
dogmania Feb 9, 2026
4dcde0f
✨ Feat: 목표 수정 API 통신 로직 구현
dogmania Feb 9, 2026
f86be53
♻️ Refactor: Save Intent에 id 파라미터 추가
dogmania Feb 9, 2026
aa001af
♻️ Refactor: Save Intent에 id 파라미터 추가
dogmania Feb 9, 2026
dedee73
✨ Feat: 목표 수정 비즈니스 로직 연결
dogmania Feb 9, 2026
e9b34f7
♻️ Refactor: HorizontalDivider 위치 변경
dogmania Feb 9, 2026
662dffe
✨ Feat: 목표 상세 조회 API 통신 로직 구현
dogmania Feb 9, 2026
2d9d81b
✨ Feat: 목표 상세 조회 비즈니스 로직 연결
dogmania Feb 9, 2026
57b9d0d
🐛 Fix: conflict 해결
dogmania Feb 9, 2026
5efa27e
✨ Feat: ShowToast SideEffect 정의
dogmania Feb 9, 2026
e51acba
🍱 Chore: string 리소스 추가
dogmania Feb 9, 2026
d260d8f
✨ Feat: 목표 삭제 API 통신 로직 구현
dogmania Feb 9, 2026
1a4fed2
✨ Feat: SideEffect 핸들링 로직 구현
dogmania Feb 9, 2026
9687a03
✨ Feat: 목표 삭제 비즈니스 로직 구현
dogmania Feb 9, 2026
0882bbd
✨ Feat: DialogState 정의
dogmania Feb 9, 2026
b14d33b
✨ Feat: 삭제된 목표 상태 정의
dogmania Feb 9, 2026
c491b59
🍱 Chore: string 리소스 추가
dogmania Feb 9, 2026
b4644ae
✨ Feat: 목표 끝내기 API 통신 로직 구현
dogmania Feb 9, 2026
9fd57bb
✨ Feat: UI 제어 Intent 정의
dogmania Feb 9, 2026
7514269
♻️ Refactor: 다이얼로그 렌더링 로직을 ID 기반으로 개선
dogmania Feb 9, 2026
bf20b1e
✨ Feat: 목표 상세 리스트 조회 api 통신 로직 구현
dogmania Feb 9, 2026
c3138d8
✨ Feat: GoalSummaryListResponse DTO 구현
dogmania Feb 9, 2026
ee46d30
✨ Feat: GoalSummaryResponse 구현
dogmania Feb 9, 2026
3c5a998
✨ Feat: GoalSummaryListResponse -> List<GoalSummary> Mapper 구현
dogmania Feb 9, 2026
37b3450
✨ Feat: 목표 상세 리스트 조회 비즈니스 로직 연결
dogmania Feb 9, 2026
4bc6dc8
🍱 Chore: 리소스 추가
dogmania Feb 9, 2026
78cdd78
♻️ Refactor: 아이콘 변경
dogmania Feb 9, 2026
01facf0
♻️ Refactor: ktlint 적용
dogmania Feb 9, 2026
2fc3b76
♻️ Refactor: PUT -> PATCH로 변경
dogmania Feb 9, 2026
997b513
✨ Feat: GoalRefreshBus 이벤트 방출
dogmania Feb 9, 2026
b309e8b
♻️ Refactor: 목표 수정 로직 Intent 기반으로 변경
dogmania Feb 10, 2026
b13dea1
🍱 Chore: string 리소스 추가
dogmania Feb 10, 2026
4b5485a
✨ Feat: 목표 미입력 시 토스트 렌더링
dogmania Feb 10, 2026
1cacb7f
♻️ Refactor: 키보드 감지를 통해서 목표명 commit
dogmania Feb 10, 2026
c0b6d4c
♻️ Refactor: EmptyGoalGuide 공통 컴포넌트로 변경
dogmania Feb 10, 2026
df9db8d
🍱 Chore: string 리소스 추가
dogmania Feb 10, 2026
74dc8db
✨ Feat: 리스트가 비어있는 경우 EmptyGoalGuide 렌더링
dogmania Feb 10, 2026
df64bcb
♻️ Refactor: 컴포넌트 위치 변경
dogmania Feb 10, 2026
094acbe
🐛 Fix: conflict 해결
dogmania Feb 11, 2026
615e04d
♻️ Refactor: 서버 응답 필드 변경
dogmania Feb 11, 2026
eb70798
♻️ Refactor: 필드명 변경
dogmania Feb 11, 2026
d451302
✨ Feat: 목표 편집 화면 전용 리프레쉬 이벤트 추가
dogmania Feb 11, 2026
b572e97
♻️ Refactor: ktlint 적용
dogmania Feb 11, 2026
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
3 changes: 3 additions & 0 deletions core/design-system/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
<string name="toast_end_date_before_start_date">종료 날짜가 시작 날짜보다 이전입니다.</string>
<string name="toast_goal_fetch_failed">목표 조회에 실패했습니다.</string>
<string name="toast_create_goal_failed">목표 생성에 실패했습니다.</string>
<string name="toast_update_goal_failed">목표 수정에 실패했습니다.</string>
<string name="toast_delete_goal_failed">목표 삭제에 실패했습니다.</string>
<string name="toast_complete_goal_failed">목표 완료에 실패했습니다.</string>

<!-- 다이얼로그 -->
<string name="dialog_end_goal_title">%s\n목표를 이루셨나요?</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.twix.network.model.request.goal.mapper

import com.twix.domain.model.goal.CreateGoalParam
import com.twix.domain.model.goal.UpdateGoalParam
import com.twix.network.model.request.goal.model.CreateGoalRequest
import com.twix.network.model.request.goal.model.UpdateGoalRequest

fun CreateGoalParam.toRequest(): CreateGoalRequest =
CreateGoalRequest(
Expand All @@ -12,3 +14,12 @@ fun CreateGoalParam.toRequest(): CreateGoalRequest =
startDate = startDate.toString(),
endDate = endDate?.toString(),
)

fun UpdateGoalParam.toRequest(): UpdateGoalRequest =
UpdateGoalRequest(
name = name,
icon = icon.toApi(),
repeatCycle = repeatCycle.toApi(),
repeatCount = repeatCount,
endDate = endDate?.toString(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.twix.network.model.request.goal.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class UpdateGoalRequest(
@SerialName("name") val name: String,
@SerialName("icon") val icon: String,
@SerialName("repeatCycle") val repeatCycle: String,
@SerialName("repeatCount") val repeatCount: Int,
@SerialName("endDate") val endDate: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package com.twix.network.model.response.goal.mapper
import com.twix.domain.model.enums.GoalIconType
import com.twix.domain.model.enums.GoalReactionType
import com.twix.domain.model.enums.RepeatCycle
import com.twix.domain.model.goal.CreatedGoal
import com.twix.domain.model.goal.Goal
import com.twix.domain.model.goal.GoalDetail
import com.twix.domain.model.goal.GoalList
import com.twix.domain.model.goal.GoalSummary
import com.twix.domain.model.goal.GoalVerification
import com.twix.network.model.response.goal.model.CreateGoalResponse
import com.twix.network.model.response.goal.model.GoalDetailResponse
import com.twix.network.model.response.goal.model.GoalListResponse
import com.twix.network.model.response.goal.model.GoalResponse
import com.twix.network.model.response.goal.model.GoalSummaryListResponse
import com.twix.network.model.response.goal.model.VerificationResponse
import java.time.LocalDate

Expand Down Expand Up @@ -41,8 +43,8 @@ fun VerificationResponse.toDomainOrNull(): GoalVerification? =
uploadedAt = uploadedAt,
)

fun CreateGoalResponse.toDomain(): CreatedGoal =
CreatedGoal(
fun GoalDetailResponse.toDomain(): GoalDetail =
GoalDetail(
goalId = goalId,
name = name,
icon = GoalIconType.fromApi(icon),
Expand All @@ -52,3 +54,15 @@ fun CreateGoalResponse.toDomain(): CreatedGoal =
endDate = endDate?.let(LocalDate::parse),
createdAt = createdAt,
)

fun GoalSummaryListResponse.toDomain(): List<GoalSummary> =
this.goals.map {
GoalSummary(
goalId = it.goalId,
name = it.name,
icon = GoalIconType.fromApi(it.icon),
repeatCycle = RepeatCycle.fromApi(it.repeatCycle),
startDate = LocalDate.parse(it.startDate),
it.endDate?.let(LocalDate::parse)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class CreateGoalResponse(
data class GoalDetailResponse(
@SerialName("goalId") val goalId: Long,
@SerialName("name") val name: String,
@SerialName("icon") val icon: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.twix.network.model.response.goal.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class GoalSummaryListResponse(
@SerialName("goals") val goals: List<GoalSummaryResponse>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.twix.network.model.response.goal.model

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class GoalSummaryResponse(
@SerialName("goalId") val goalId: Long,
@SerialName("name") val name: String,
@SerialName("icon") val icon: String,
@SerialName("repeatCycle") val repeatCycle: String,
@SerialName("startDate") val startDate: String,
@SerialName("endDate") val endDate: String?,
)
35 changes: 33 additions & 2 deletions core/network/src/main/java/com/twix/network/service/GoalService.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.twix.network.service

import com.twix.network.model.request.goal.model.CreateGoalRequest
import com.twix.network.model.response.goal.model.CreateGoalResponse
import com.twix.network.model.request.goal.model.UpdateGoalRequest
import com.twix.network.model.response.goal.model.GoalDetailResponse
import com.twix.network.model.response.goal.model.GoalListResponse
import com.twix.network.model.response.goal.model.GoalSummaryListResponse
import de.jensklingenberg.ktorfit.http.Body
import de.jensklingenberg.ktorfit.http.DELETE
import de.jensklingenberg.ktorfit.http.GET
import de.jensklingenberg.ktorfit.http.POST
import de.jensklingenberg.ktorfit.http.PUT
import de.jensklingenberg.ktorfit.http.Path
import de.jensklingenberg.ktorfit.http.Query

interface GoalService {
Expand All @@ -17,5 +22,31 @@ interface GoalService {
@POST("api/v1/goals")
suspend fun createGoal(
@Body body: CreateGoalRequest,
): CreateGoalResponse
): GoalDetailResponse

@PUT("api/v1/goals/{goalId}")
suspend fun updateGoal(
@Body body: UpdateGoalRequest,
@Path("goalId") goalId: Long,
): GoalDetailResponse

@GET("api/v1/goals/{goalId}")
suspend fun fetchGoalDetail(
@Path("goalId") goalId: Long,
): GoalDetailResponse

@DELETE("api/v1/goals/{goalId}")
suspend fun deleteGoal(
@Path("goalId") goalId: Long,
)

@PUT("api/v1/goals/{goalId}/complete")
suspend fun completeGoal(
@Path("goalId") goalId: Long,
)

@GET("api/v1/goals/detail")
suspend fun fetchGoalSummaryList(
@Query("date") date: String,
): GoalSummaryListResponse
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.twix.data.repository

import com.twix.domain.model.goal.CreateGoalParam
import com.twix.domain.model.goal.CreatedGoal
import com.twix.domain.model.goal.GoalDetail
import com.twix.domain.model.goal.GoalList
import com.twix.domain.model.goal.GoalSummary
import com.twix.domain.model.goal.UpdateGoalParam
import com.twix.domain.repository.GoalRepository
import com.twix.network.execute.safeApiCall
import com.twix.network.model.request.goal.mapper.toRequest
Expand All @@ -15,8 +17,27 @@ class DefaultGoalRepository(
) : GoalRepository {
override suspend fun fetchGoalList(date: String): AppResult<GoalList> = safeApiCall { service.fetchGoals(date).toDomain() }

override suspend fun createGoal(param: CreateGoalParam): AppResult<CreatedGoal> =
override suspend fun createGoal(param: CreateGoalParam): AppResult<GoalDetail> =
safeApiCall {
service.createGoal(param.toRequest()).toDomain()
}

override suspend fun updateGoal(param: UpdateGoalParam): AppResult<GoalDetail> =
safeApiCall {
service.updateGoal(body = param.toRequest(), goalId = param.goalId).toDomain()
}

override suspend fun fetchGoalDetail(goalId: Long): AppResult<GoalDetail> =
safeApiCall {
service.fetchGoalDetail(goalId).toDomain()
}

override suspend fun deleteGoal(goalId: Long): AppResult<Unit> = safeApiCall { service.deleteGoal(goalId) }

override suspend fun completeGoal(goalId: Long): AppResult<Unit> = safeApiCall { service.completeGoal(goalId) }

override suspend fun fetchGoalSummaryList(date: String): AppResult<List<GoalSummary>> =
safeApiCall {
service.fetchGoalSummaryList(date).toDomain()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.twix.domain.model.enums.GoalIconType
import com.twix.domain.model.enums.RepeatCycle
import java.time.LocalDate

data class CreatedGoal(
data class GoalDetail(
val goalId: Long,
val name: String,
val icon: GoalIconType,
Expand Down
14 changes: 14 additions & 0 deletions domain/src/main/java/com/twix/domain/model/goal/UpdateGoalParam.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.twix.domain.model.goal

import com.twix.domain.model.enums.GoalIconType
import com.twix.domain.model.enums.RepeatCycle
import java.time.LocalDate

data class UpdateGoalParam(
val goalId: Long,
val name: String,
val icon: GoalIconType,
val repeatCycle: RepeatCycle,
val repeatCount: Int,
val endDate: LocalDate?,
)
16 changes: 14 additions & 2 deletions domain/src/main/java/com/twix/domain/repository/GoalRepository.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
package com.twix.domain.repository

import com.twix.domain.model.goal.CreateGoalParam
import com.twix.domain.model.goal.CreatedGoal
import com.twix.domain.model.goal.GoalDetail
import com.twix.domain.model.goal.GoalList
import com.twix.domain.model.goal.GoalSummary
import com.twix.domain.model.goal.UpdateGoalParam
import com.twix.result.AppResult

interface GoalRepository {
suspend fun fetchGoalList(date: String): AppResult<GoalList>

suspend fun createGoal(param: CreateGoalParam): AppResult<CreatedGoal>
suspend fun createGoal(param: CreateGoalParam): AppResult<GoalDetail>

suspend fun updateGoal(param: UpdateGoalParam): AppResult<GoalDetail>

suspend fun fetchGoalDetail(goalId: Long): AppResult<GoalDetail>

suspend fun deleteGoal(goalId: Long): AppResult<Unit>

suspend fun completeGoal(goalId: Long): AppResult<Unit>

suspend fun fetchGoalSummaryList(date: String): AppResult<List<GoalSummary>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ sealed interface GoalEditorIntent : Intent {
val enabled: Boolean,
) : GoalEditorIntent

data object Save : GoalEditorIntent
data class Save(
val id: Long,
) : GoalEditorIntent

data class InitGoal(
val id: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fun GoalEditorRoute(
onCommitStartDate = { viewModel.dispatch(GoalEditorIntent.SetStartDate(it)) },
onCommitRepeatCount = { viewModel.dispatch(GoalEditorIntent.SetRepeatCount(it)) },
onToggleEndDateEnabled = { viewModel.dispatch(GoalEditorIntent.SetEndDateEnabled(it)) },
onComplete = { viewModel.dispatch(GoalEditorIntent.Save) },
onComplete = { viewModel.dispatch(GoalEditorIntent.Save(goalId)) },
)
}

Expand Down
Loading
Loading