Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
9b25c62
feat: 온보딩 버튼 컴포넌트 추가
stopstone Sep 4, 2025
172e602
feat: 온보딩 페이지 인디케이터 UI 구현
stopstone Sep 4, 2025
be8479c
feat: 온보딩 페이지 모델 구현
stopstone Sep 4, 2025
61d1fd4
feat: 온보딩 화면 구현
stopstone Sep 4, 2025
22c741b
feat: 온보딩 네비게이션 설정
stopstone Sep 4, 2025
717b0d4
feat: 온보딩 페이지 이미지 추가
stopstone Sep 5, 2025
ad971ef
feat: 온보딩 화면 이미지 추가
stopstone Sep 5, 2025
c4ff3c9
feat: 온보딩 UI 이미지 영역 수정
stopstone Sep 5, 2025
262ded3
feat: 온보딩 페이지 백그라운드 구성
stopstone Sep 5, 2025
45513a1
feat: 온보딩 배경 추가
stopstone Sep 5, 2025
7768d8f
refactor: 불필요한 패딩 제거
stopstone Sep 5, 2025
846bbce
feat: 온보딩 백그라운드 색상 변경
stopstone Sep 5, 2025
a053f43
refactor: OnboardingScreen UI 레이아웃 조정
stopstone Sep 5, 2025
18af35b
refactor: AnnotatedString.Builder 확장 함수 추가
stopstone Sep 5, 2025
037f6d3
feat: DataStore 분리 및 Qualifier 적용
stopstone Sep 5, 2025
ffc32db
feat: 온보딩 DataStore 추가
stopstone Sep 5, 2025
0e3ff5e
feat: 온보딩 완료 상태 저장 로직 추가
stopstone Sep 5, 2025
98a8d85
feat: 온보딩 버튼 로딩 상태 추가
stopstone Sep 5, 2025
fa5cadc
feat: 온보딩 화면 UI 상태 및 사이드 이펙트 처리
stopstone Sep 5, 2025
25f2f20
feat: 온보딩 버튼 텍스트 stirng.xml 리소스 추가
stopstone Sep 6, 2025
22ec755
feat: 온보딩 레포지토리 추가 및 ViewModel 연동
stopstone Sep 6, 2025
a99de45
refactor: 온보딩 페이지 데이터 - remember로 성능 최적화
stopstone Sep 6, 2025
2ae7148
refactor: 온보딩 Preferences 키 상수화
stopstone Sep 6, 2025
1fa484d
refactor: 불필요한 코드 제거
stopstone Sep 6, 2025
508f2d5
refactor: 온보딩 페이지 데이터 모델 변경
stopstone Sep 6, 2025
5845e24
refactor: 디자인 가이드에 맞게 텍스트 수정
stopstone Sep 6, 2025
588a6a3
feat: Color.kt 온보딩 배경 장식 색상 추가
stopstone Sep 6, 2025
7360949
refactor: 불필요한 import문 제거
stopstone Sep 6, 2025
02458a5
feat: 마이페이지 구성에 필요한 리소스 추가
stopstone Sep 10, 2025
6510ade
feat: LoginType enum 추가
stopstone Sep 10, 2025
6f5853b
feat: 마이프로필 컴포넌트 추가
stopstone Sep 10, 2025
ade3245
feat: 내 정보 화면 UI 및 ViewModel 구현
stopstone Sep 10, 2025
c76569d
refactor: LoginType model 패키지로 이동
stopstone Sep 10, 2025
b1dc0b3
feat: 내 프로필 화면 navigation 구현
stopstone Sep 10, 2025
6cc6646
feat: Glide Compose 라이브러리 추가
stopstone Sep 10, 2025
6e5b3d4
feat: 회원 정보 API 연동
stopstone Sep 10, 2025
4beb928
feat: MyProfile 에러 핸들링 추가
stopstone Sep 10, 2025
1e45366
feat: 프로필 이미지 로딩 구현
stopstone Sep 10, 2025
0cc546e
feat: 멤버 정보 API 연동
stopstone Sep 10, 2025
7fa85de
feat: 내 정보 화면 및 API 연동
stopstone Sep 10, 2025
7ce6782
feat: 마이프로필 뒤로가기 기능 구현
stopstone Sep 10, 2025
ee361dd
refactor: 마이프로필 정보에 매퍼 적용 및 UI 연결
stopstone Sep 10, 2025
edcedd1
feat: 마이프로필 로그아웃 기능 구현
stopstone Sep 10, 2025
58f927e
refactor: 로딩 화면 범위 수정
stopstone Sep 10, 2025
175c29b
refactor: MyProfileScreen 부분별 코드 분리
stopstone Sep 10, 2025
6e6b67a
feat: 회원탈퇴 화면 이동 로직 구현
stopstone Sep 10, 2025
3e6ea19
feat: 회원탈퇴 API 연동
stopstone Sep 10, 2025
3dd19fe
feat: 회원탈퇴 사유 모델 추가
stopstone Sep 11, 2025
6418d94
feat: 회원탈퇴 화면 TopAppBar 구현
stopstone Sep 11, 2025
761beb1
feat: 회원탈퇴 화면 및 기능 구현
stopstone Sep 11, 2025
b71d500
feat: NearOutlinedTextField 컴포넌트 추가
stopstone Sep 11, 2025
d515da3
refactor: NearOutlinedTextField 키보드 상호작용 개선
stopstone Sep 12, 2025
567636c
feat: 텍스트필드 에러 상태 및 관련 기능 추가
stopstone Sep 16, 2025
5e1e55a
feat: 회원탈퇴 화면 UI 및 로직 개선
stopstone Sep 16, 2025
d7f9a59
style: 회원탈퇴 화면 앱바 패딩 수정
stopstone Sep 16, 2025
18c3095
refactor: 의견 입력 에러 메시지 수정
stopstone Sep 16, 2025
abc4337
feat: 회원탈퇴 화면 뒤로가기 추가
stopstone Sep 16, 2025
5c245f4
feat: 회원탈퇴 화면에 닉네임 전달 로직 추가
stopstone Sep 16, 2025
427e766
chore: 탈퇴 화면 하단 패딩 수정
stopstone Sep 16, 2025
5505311
chore: NearServiceInfoRow 클릭 범위 수정 및 리플효과 제거
stopstone Sep 16, 2025
47c1b92
refactor: WithdrawTopAppBar → NearCancelTopAppBar로 이름 변경 및 이동
stopstone Sep 16, 2025
634872a
chore: 미사용 import 제거
stopstone Sep 16, 2025
08ad462
refactor: Modifier 파라미터 적용
stopstone Sep 16, 2025
66a6488
chore: build.gradle.kts 약관 URL 정보 추가
stopstone Sep 16, 2025
b0fe6b1
feat: 약관 및 정책 웹뷰 화면 연동
stopstone Sep 16, 2025
3917c00
refactor: 약관 및 정책 목록 표시 로직 개선
stopstone Sep 16, 2025
ad35f20
refactor: 약관 페이지 title 형식 수정
stopstone Sep 16, 2025
59d478a
feat: MY 페이지, 탈퇴하기 화면 string.xml 리소스 적용
stopstone Sep 16, 2025
fddabb7
remove: 회원 탈퇴 사유 모델 제거
stopstone Sep 16, 2025
f2ab07f
refactor: LoginType의 프로퍼티명 수정
stopstone Sep 16, 2025
fb48a73
chore: 내 정보 화면 배경색 추가
stopstone Sep 18, 2025
2fac627
feat: 온보딩 버튼 컴포넌트 추가
stopstone Sep 4, 2025
ea7a2e1
feat: 온보딩 페이지 인디케이터 UI 구현
stopstone Sep 4, 2025
0c22958
feat: 온보딩 페이지 모델 구현
stopstone Sep 4, 2025
c536bf4
feat: 온보딩 화면 구현
stopstone Sep 4, 2025
dcfd9ca
feat: 온보딩 네비게이션 설정
stopstone Sep 4, 2025
3396b74
feat: 온보딩 페이지 이미지 추가
stopstone Sep 5, 2025
48834cf
feat: 온보딩 화면 이미지 추가
stopstone Sep 5, 2025
d3c08c5
feat: 온보딩 UI 이미지 영역 수정
stopstone Sep 5, 2025
d58d85d
feat: 온보딩 페이지 백그라운드 구성
stopstone Sep 5, 2025
9d1453b
feat: 온보딩 배경 추가
stopstone Sep 5, 2025
7b59095
refactor: 불필요한 패딩 제거
stopstone Sep 5, 2025
fc190f0
feat: 온보딩 백그라운드 색상 변경
stopstone Sep 5, 2025
1577a75
refactor: OnboardingScreen UI 레이아웃 조정
stopstone Sep 5, 2025
1596dab
refactor: AnnotatedString.Builder 확장 함수 추가
stopstone Sep 5, 2025
2834cc6
feat: DataStore 분리 및 Qualifier 적용
stopstone Sep 5, 2025
b749fcb
feat: 온보딩 DataStore 추가
stopstone Sep 5, 2025
c19802b
feat: 온보딩 완료 상태 저장 로직 추가
stopstone Sep 5, 2025
e798851
feat: 온보딩 버튼 로딩 상태 추가
stopstone Sep 5, 2025
5cf9a2f
feat: 온보딩 화면 UI 상태 및 사이드 이펙트 처리
stopstone Sep 5, 2025
dc46da1
feat: 온보딩 버튼 텍스트 stirng.xml 리소스 추가
stopstone Sep 6, 2025
66ac5a1
feat: 온보딩 레포지토리 추가 및 ViewModel 연동
stopstone Sep 6, 2025
93ab1c3
refactor: 온보딩 페이지 데이터 - remember로 성능 최적화
stopstone Sep 6, 2025
b6577d0
refactor: 온보딩 Preferences 키 상수화
stopstone Sep 6, 2025
f30d851
refactor: 불필요한 코드 제거
stopstone Sep 6, 2025
4d59fef
refactor: 온보딩 페이지 데이터 모델 변경
stopstone Sep 6, 2025
d8a4c99
refactor: 디자인 가이드에 맞게 텍스트 수정
stopstone Sep 6, 2025
cd47e30
feat: Color.kt 온보딩 배경 장식 색상 추가
stopstone Sep 6, 2025
b29e18c
refactor: 불필요한 import문 제거
stopstone Sep 6, 2025
38045f7
feat: 앱 시작 시 온보딩 및 로그인 상태에 따른 화면 분기 처리
stopstone Sep 19, 2025
25b7bd9
Merge remote-tracking branch 'origin/feat/onboarding-pages' into feat…
stopstone Sep 19, 2025
a35fba3
refactor: 온보딩 관련 중복 문자열 제거
stopstone Sep 19, 2025
3d9cb34
Merge branch 'dev' into feat/my-profile
stopstone Sep 19, 2025
7be0ca9
refactor: 인증 헤더 삭제
stopstone Sep 19, 2025
3c9719e
refactor: MyProfileUiState에서 사용하지 않는 error 필드 제거
stopstone Sep 19, 2025
a89f88e
refactor: RouteWebView에서 toRoute 사용하도록 수정
stopstone Sep 19, 2025
00bb29d
feat: WebView 뒤로가기 기능 추가
stopstone Sep 19, 2025
c192e13
refactor: Glide의 contentScale 옵션 제거
stopstone Sep 19, 2025
c186b40
fix: `NearOutlinedTextField` 에러 상태 반영 오류 수정
stopstone Sep 19, 2025
2b1acb2
refactor: 회원탈퇴 화면 에러 처리 방식 변경
stopstone Sep 19, 2025
ce51d82
chore: ci 워크플로우에 개인정보처리방침 URL 추가
stopstone Sep 19, 2025
c389154
Merge pull request #29 from near-Contact-Reminder/feat/onboarding-pages
stopstone Sep 19, 2025
2b4c1d0
refactor: Glide에서 Coil로 이미지 로딩 라이브러리 변경
stopstone Sep 23, 2025
4522d0f
refactor: API 응답 타입 수정
stopstone Sep 23, 2025
fc13f52
feat: flow를 간소화 한 apiCallFlow 추가
stopstone Sep 23, 2025
5ecc798
refactor: API 호출 Flow 적용
stopstone Sep 23, 2025
b652c3e
refactor: 회원 탈퇴 API 에러 핸들링 수정
stopstone Sep 23, 2025
9e6aad2
refactor: Member 관련 데이터 모델 네이밍 및 매퍼 구조 변경
stopstone Sep 23, 2025
dc3acc4
refactor: `WithdrawRequest` 모델의 위치 변경 및 관련 로직 수정
stopstone Sep 23, 2025
96dec0a
fix: 중복된 NavGraph 정의 제거
stopstone Sep 23, 2025
158ecc5
refactor: `MyProfileInfo`를 `MyProfileInfoUIModel`로 이름 변경
stopstone Sep 23, 2025
2b53a2c
refactor: 불필요한 import 제거
stopstone Sep 23, 2025
0494397
Merge branch 'feat/my-profile' into dev
stopstone Sep 23, 2025
3522577
refactor: `NearNavHost` 시작 화면 `startDestination`으로 통합
stopstone Sep 23, 2025
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
12 changes: 11 additions & 1 deletion .github/workflows/android-pull-request-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Android Pull Request CI
on:
pull_request:
branches: [ "main", "develop", "dev" ]

jobs:
build:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -49,6 +49,16 @@ jobs:
run: |
echo "KAKAO_NATIVE_APP_KEY=\"$KAKAO_NATIVE_APP_KEY\"" >> local.properties

- name: Access Near PRIVACY URLS
env:
SERVICE_AGREED_TERMS_URL: ${{ secrets.SERVICE_AGREED_TERMS_URL }}
PERSONAL_INFO_TERMS_URL: ${{ secrets.PERSONAL_INFO_TERMS_URL }}
PRIVACY_POLICY_TERMS_URL: ${{ secrets.PRIVACY_POLICY_TERMS_URL }}
run: |
echo "SERVICE_AGREED_TERMS_URL=\"$SERVICE_AGREED_TERMS_URL\"" >> local.properties
echo "PERSONAL_INFO_TERMS_URL=\"$PERSONAL_INFO_TERMS_URL\"" >> local.properties
echo "PRIVACY_POLICY_TERMS_URL=\"$PRIVACY_POLICY_TERMS_URL\"" >> local.properties

- name: Grant execute permission for gradlew
run: chmod +x gradlew

Expand Down
11 changes: 8 additions & 3 deletions Near/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ android {
buildConfigField("String", "NEAR_URL", getProperty("NEAR_PROD_URL"))
buildConfigField("String", "TEMP_TOKEN", getProperty("TEMP_TOKEN")) // TODO 추후 삭제 필요
buildConfigField("String", "KAKAO_NATIVE_APP_KEY", getProperty("KAKAO_NATIVE_APP_KEY"))
buildConfigField("String", "SERVICE_AGREED_TERMS_URL", getProperty("SERVICE_AGREED_TERMS_URL"))
buildConfigField("String", "PERSONAL_INFO_TERMS_URL", getProperty("PERSONAL_INFO_TERMS_URL"))
buildConfigField("String", "PRIVACY_POLICY_TERMS_URL", getProperty("PRIVACY_POLICY_TERMS_URL"))
Comment on lines +37 to +39

Choose a reason for hiding this comment

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

medium

releasedebug 빌드 유형 모두에서 동일한 buildConfigField가 반복적으로 선언되고 있습니다. 코드를 더 간결하게 유지하고 중복을 줄이기 위해 이 필드들을 defaultConfig 블록으로 옮기는 것을 고려해 보세요. NEAR_URL과 같이 빌드 유형에 따라 다른 값을 가져야 하는 경우에만 각 buildType에 남겨두는 것이 좋습니다.

manifestPlaceholders["kakaoAppKey"] = getProperty("KAKAO_NATIVE_APP_KEY").replace("\"", "")
}
debug {
buildConfigField("String", "NEAR_URL", getProperty("NEAR_DEV_URL"))
buildConfigField("String", "TEMP_TOKEN", getProperty("TEMP_TOKEN")) // TODO 추후 삭제 필요
buildConfigField("String", "KAKAO_NATIVE_APP_KEY", getProperty("KAKAO_NATIVE_APP_KEY"))
buildConfigField("String", "SERVICE_AGREED_TERMS_URL", getProperty("SERVICE_AGREED_TERMS_URL"))
buildConfigField("String", "PERSONAL_INFO_TERMS_URL", getProperty("PERSONAL_INFO_TERMS_URL"))
buildConfigField("String", "PRIVACY_POLICY_TERMS_URL", getProperty("PRIVACY_POLICY_TERMS_URL"))
manifestPlaceholders["kakaoAppKey"] = getProperty("KAKAO_NATIVE_APP_KEY").replace("\"", "")
}
}
Expand Down Expand Up @@ -81,9 +87,8 @@ dependencies {
implementation(libs.retrofit)
implementation(libs.retrofit.kotlin.serialization.converter)
implementation(libs.logging.interceptor)
// Glide
implementation(libs.glide)
kapt(libs.glide.compiler)
// Coil
implementation(libs.coil.compose)
// Room
implementation(libs.room.runtime)
implementation(libs.room.ktx)
Expand Down
24 changes: 21 additions & 3 deletions Near/app/src/main/java/com/alarmy/near/data/di/DataStoreModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,35 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Qualifier
import javax.inject.Singleton

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthDataStore

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OnboardingDataStore

// DataStore 확장 프로퍼티
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "auth_preferences")
private val Context.authDataStore: DataStore<Preferences> by preferencesDataStore(name = "auth_preferences")
private val Context.onboardingDataStore: DataStore<Preferences> by preferencesDataStore(name = "onboarding_preferences")

@Module
@InstallIn(SingletonComponent::class)
object DataStoreModule {
@Provides
@Singleton
fun provideDataStore(
@AuthDataStore
fun provideAuthDataStore(
@ApplicationContext context: Context,
): DataStore<Preferences> = context.authDataStore

@Provides
@Singleton
@OnboardingDataStore
fun provideOnboardingDataStore(
@ApplicationContext context: Context,
): DataStore<Preferences> = context.dataStore
): DataStore<Preferences> = context.onboardingDataStore
}
12 changes: 12 additions & 0 deletions Near/app/src/main/java/com/alarmy/near/data/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import com.alarmy.near.data.repository.DefaultFriendRepository
import com.alarmy.near.data.repository.ExampleRepository
import com.alarmy.near.data.repository.ExampleRepositoryImpl
import com.alarmy.near.data.repository.FriendRepository
import com.alarmy.near.data.repository.OnBoardingRepository
import com.alarmy.near.data.repository.OnBoardingRepositoryImpl
import com.alarmy.near.data.repository.MemberRepository
import com.alarmy.near.data.repository.MemberRepositoryImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -26,4 +30,12 @@ interface RepositoryModule {
@Binds
@Singleton
abstract fun bindAuthRepository(authRepositoryImpl: AuthRepositoryImpl): AuthRepository

@Binds
@Singleton
abstract fun bindOnBoardingRepository(onBoardingRepositoryImpl: OnBoardingRepositoryImpl): OnBoardingRepository

@Binds
@Singleton
abstract fun bindMemberRepository(memberRepositoryImpl: MemberRepositoryImpl): MemberRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.alarmy.near.data.entity

import kotlinx.serialization.Serializable

/**
* 회원 정보 Data Layer 엔티티
* API 응답 데이터를 나타내는 모델
*/
@Serializable
data class MemberInfoEntity(
val memberId: String,
val username: String,
val nickname: String,
val imageUrl: String?,
val notificationAgreedAt: String?,
val providerType: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.alarmy.near.data.entity

import kotlinx.serialization.Serializable

/**
* 회원 탈퇴 요청 Data Layer 엔티티
* Network Layer의 WithdrawRequest와 동일한 구조
*/
@Serializable
data class WithdrawRequestEntity(
val reasonType: String,
val customReason: String? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.alarmy.near.data.local.datastore

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import com.alarmy.near.data.di.OnboardingDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton

/**
* 온보딩 완료 상태를 관리하는 DataStore
* 최초 접속 여부를 확인하여 온보딩 화면 표시 여부를 결정
*/
@Singleton
class OnboardingPreferences @Inject constructor(
@OnboardingDataStore private val dataStore: DataStore<Preferences>,
) {
companion object {
private val ONBOARDING_COMPLETED_KEY = booleanPreferencesKey("onboarding_completed")
}

/**
* 온보딩 완료 여부를 확인하는 Flow
* true: 온보딩 완료됨, false: 온보딩 미완료
*/
val isOnboardingCompleted: Flow<Boolean> = dataStore.data.map { preferences ->
preferences[ONBOARDING_COMPLETED_KEY] ?: false
}

/**
* 온보딩 완료 상태를 저장
*/
suspend fun setOnboardingCompleted(completed: Boolean) {
dataStore.edit { preferences ->
preferences[ONBOARDING_COMPLETED_KEY] = completed
}
}

/**
* 온보딩 완료 상태를 true로 설정
*/
suspend fun markOnboardingAsCompleted() {
setOnboardingCompleted(true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import com.alarmy.near.data.di.AuthDataStore
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map

import javax.inject.Inject
import javax.inject.Singleton

Expand All @@ -16,11 +16,9 @@ import javax.inject.Singleton
* 액세스 토큰과 리프레시 토큰의 저장, 조회, 삭제를 담당
*/
@Singleton
class TokenPreferences
@Inject
constructor(
private val dataStore: DataStore<Preferences>,
) {
class TokenPreferences @Inject constructor(
@AuthDataStore private val dataStore: DataStore<Preferences>,
) {
private val accessTokenKey = stringPreferencesKey("access_token")
private val refreshTokenKey = stringPreferencesKey("refresh_token")
private val expiresAtKey = longPreferencesKey("expires_at")
Expand Down
70 changes: 70 additions & 0 deletions Near/app/src/main/java/com/alarmy/near/data/mapper/MemberMapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.alarmy.near.data.mapper

import com.alarmy.near.data.entity.MemberInfoEntity
import com.alarmy.near.data.entity.WithdrawRequestEntity
import com.alarmy.near.model.member.MemberInfo
import com.alarmy.near.network.request.WithdrawRequest
import com.alarmy.near.presentation.feature.myprofile.model.LoginType
import com.alarmy.near.presentation.feature.myprofile.model.MyProfileInfoUIModel
import com.alarmy.near.presentation.feature.myprofile.model.WithdrawReason

/**
* Data Layer Entity를 Model Layer로 변환
*/
fun MemberInfoEntity.toModel(): MemberInfo =
MemberInfo(
memberId = memberId,
username = username,
nickname = nickname,
imageUrl = imageUrl,
notificationAgreedAt = notificationAgreedAt,
providerType = providerType,
)

/**
* Model Layer를 Data Layer Entity로 변환
*/
fun MemberInfo.toEntity(): MemberInfoEntity =
MemberInfoEntity(
memberId = memberId,
username = username,
nickname = nickname,
imageUrl = imageUrl,
notificationAgreedAt = notificationAgreedAt,
providerType = providerType,
)

/**
* WithdrawReason을 Network Layer로 변환
*/
fun WithdrawReason.toRequest(customReason: String? = null): WithdrawRequest =
WithdrawRequest(
reasonType = this.name,
customReason = customReason,
)

fun WithdrawRequest.toEntity(): WithdrawRequestEntity =
WithdrawRequestEntity(
reasonType = reasonType,
customReason = customReason,
)

/**
* Model 계층 모델을 UI 계층 모델로 변환
*/
fun MemberInfo.toMyProfileInfoUIModel(): MyProfileInfoUIModel =
MyProfileInfoUIModel(
nickname = nickname,
imageUrl = imageUrl,
notificationAgreedAt = notificationAgreedAt,
providerType = mapProviderType(providerType),
)

/**
* ProviderType 문자열을 LoginType enum으로 변환
*/
private fun mapProviderType(providerType: String): LoginType =
when (providerType.uppercase()) {
"KAKAO" -> LoginType.KAKAO
else -> LoginType.ETC
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.alarmy.near.data.repository

import com.alarmy.near.model.member.MemberInfo
import com.alarmy.near.presentation.feature.myprofile.model.WithdrawReason
import kotlinx.coroutines.flow.Flow

interface MemberRepository {
// 현재 로그인한 회원의 정보를 조회
fun getMyInfo(): Flow<MemberInfo>

// 회원 탈퇴
fun withdraw(reason: WithdrawReason, customReason: String? = null): Flow<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.alarmy.near.data.repository

import com.alarmy.near.data.mapper.toEntity
import com.alarmy.near.data.mapper.toModel
import com.alarmy.near.data.mapper.toRequest
import com.alarmy.near.model.member.MemberInfo
import com.alarmy.near.network.service.MemberApiService
import com.alarmy.near.presentation.feature.myprofile.model.WithdrawReason
import com.alarmy.near.utils.extensions.apiCallFlow
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
import javax.inject.Singleton

/**
* 회원 정보 Repository 구현체
*/
@Singleton
class MemberRepositoryImpl
@Inject
constructor(
private val memberApiService: MemberApiService,
) : MemberRepository {
// 현재 로그인한 회원의 정보를 조회
override fun getMyInfo(): Flow<MemberInfo> =
apiCallFlow {
memberApiService.getMyInfo().toModel()
}

// 회원 탈퇴
override fun withdraw(
reason: WithdrawReason,
customReason: String?,
): Flow<Unit> =
apiCallFlow {
val request = reason.toRequest(customReason)
memberApiService.withdraw(request.toEntity())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.alarmy.near.data.repository

import kotlinx.coroutines.flow.Flow

/**
* 온보딩 관련 데이터를 관리하는 Repository 인터페이스
* 온보딩 완료 상태의 저장, 조회, 확인 기능을 제공
*/
interface OnBoardingRepository {

/**
* 온보딩 완료 여부를 확인하는 Flow
* true: 온보딩 완료됨, false: 온보딩 미완료
*/
fun observeOnboardingStatus(): Flow<Boolean>

/**
* 온보딩 완료 상태를 저장
* completed: 온보딩 완료 여부
*/
suspend fun setOnboardingCompleted(completed: Boolean)

/**
* 온보딩을 완료로 표시
*/
suspend fun markOnboardingAsCompleted()

/**
* 온보딩 완료 상태를 확인
*/
suspend fun isOnboardingCompleted(): Boolean

/**
* 온보딩 상태를 초기화 (테스트용 또는 재온보딩용)
*/
suspend fun resetOnboardingStatus()
}
Loading