diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..4bec4ea8
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..a55e7a17
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dictionaries/jaino.xml b/.idea/dictionaries/jaino.xml
new file mode 100644
index 00000000..8bf92705
--- /dev/null
+++ b/.idea/dictionaries/jaino.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 4aae73fa..7a8fccfd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,7 +1,7 @@
-
+
-
\ No newline at end of file
+
diff --git a/core/data/src/main/java/com/wap/wapp/core/data/repository/di/AuthRepositoryModule.kt b/core/data/src/main/java/com/wap/wapp/core/data/di/AuthRepositoryModule.kt
similarity index 92%
rename from core/data/src/main/java/com/wap/wapp/core/data/repository/di/AuthRepositoryModule.kt
rename to core/data/src/main/java/com/wap/wapp/core/data/di/AuthRepositoryModule.kt
index 799eddcb..4b8f157e 100644
--- a/core/data/src/main/java/com/wap/wapp/core/data/repository/di/AuthRepositoryModule.kt
+++ b/core/data/src/main/java/com/wap/wapp/core/data/di/AuthRepositoryModule.kt
@@ -1,4 +1,4 @@
-package com.wap.wapp.core.data.repository.di
+package com.wap.wapp.core.data.di
import com.wap.wapp.core.data.repository.auth.AuthRepository
import com.wap.wapp.core.data.repository.auth.AuthRepositoryImpl
diff --git a/core/data/src/main/java/com/wap/wapp/core/data/di/DataModule.kt b/core/data/src/main/java/com/wap/wapp/core/data/di/DataModule.kt
new file mode 100644
index 00000000..2ebbd53d
--- /dev/null
+++ b/core/data/src/main/java/com/wap/wapp/core/data/di/DataModule.kt
@@ -0,0 +1,19 @@
+package com.wap.wapp.core.data.di
+
+import com.wap.wapp.core.data.repository.user.UserRepository
+import com.wap.wapp.core.data.repository.user.UserRepositoryImpl
+import dagger.Binds
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import javax.inject.Singleton
+
+@Module
+@InstallIn(SingletonComponent::class)
+abstract class DataModule {
+ @Binds
+ @Singleton
+ abstract fun providesUserRepository(
+ userRepositoryImpl: UserRepositoryImpl,
+ ): UserRepository
+}
diff --git a/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepository.kt b/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepository.kt
index 20c718ec..1c423020 100644
--- a/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepository.kt
+++ b/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepository.kt
@@ -4,4 +4,8 @@ interface AuthRepository {
suspend fun hasPendingResult(): Boolean
suspend fun signIn(email: String): Result
+
+ suspend fun signOut(): Result
+
+ suspend fun deleteUser(): Result
}
diff --git a/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepositoryImpl.kt b/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepositoryImpl.kt
index 01146642..e7b7815f 100644
--- a/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepositoryImpl.kt
+++ b/core/data/src/main/java/com/wap/wapp/core/data/repository/auth/AuthRepositoryImpl.kt
@@ -13,4 +13,12 @@ class AuthRepositoryImpl @Inject constructor(
override suspend fun signIn(email: String): Result {
return authDataSource.signIn(email)
}
+
+ override suspend fun signOut(): Result {
+ return authDataSource.signOut()
+ }
+
+ override suspend fun deleteUser(): Result {
+ return authDataSource.deleteUser()
+ }
}
diff --git a/core/data/src/main/java/com/wap/wapp/core/data/repository/user/UserRepository.kt b/core/data/src/main/java/com/wap/wapp/core/data/repository/user/UserRepository.kt
new file mode 100644
index 00000000..f5039061
--- /dev/null
+++ b/core/data/src/main/java/com/wap/wapp/core/data/repository/user/UserRepository.kt
@@ -0,0 +1,14 @@
+package com.wap.wapp.core.data.repository.user
+
+import com.wap.wapp.core.model.user.UserProfile
+
+interface UserRepository {
+ suspend fun getUserProfile(userId: String): Result
+
+ suspend fun postUserProfile(
+ userId: String,
+ userName: String,
+ studentId: String,
+ registeredAt: String,
+ ): Result
+}
diff --git a/core/data/src/main/java/com/wap/wapp/core/data/repository/user/UserRepositoryImpl.kt b/core/data/src/main/java/com/wap/wapp/core/data/repository/user/UserRepositoryImpl.kt
new file mode 100644
index 00000000..0490832c
--- /dev/null
+++ b/core/data/src/main/java/com/wap/wapp/core/data/repository/user/UserRepositoryImpl.kt
@@ -0,0 +1,32 @@
+package com.wap.wapp.core.data.repository.user
+
+import com.wap.wapp.core.model.user.UserProfile
+import com.wap.wapp.core.network.model.user.UserProfileRequest
+import com.wap.wapp.core.network.source.user.UserDataSource
+import javax.inject.Inject
+
+class UserRepositoryImpl @Inject constructor(
+ private val userDataSource: UserDataSource,
+) : UserRepository {
+ override suspend fun getUserProfile(userId: String): Result {
+ return userDataSource.getUserProfile(userId).mapCatching { response ->
+ response.toDomain()
+ }
+ }
+
+ override suspend fun postUserProfile(
+ userId: String,
+ userName: String,
+ studentId: String,
+ registeredAt: String,
+ ): Result {
+ return userDataSource.postUserProfile(
+ UserProfileRequest(
+ userId = userId,
+ userName = userName,
+ studentId = studentId,
+ registeredAt = registeredAt,
+ ),
+ )
+ }
+}
diff --git a/core/domain/src/main/java/com/wap/wapp/core/domain/auth/SignInUseCase.kt b/core/domain/src/main/java/com/wap/wapp/core/domain/auth/SignInUseCase.kt
deleted file mode 100644
index 5677fe94..00000000
--- a/core/domain/src/main/java/com/wap/wapp/core/domain/auth/SignInUseCase.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.wap.wapp.core.domain.auth
-
-import com.wap.wapp.core.data.repository.auth.AuthRepository
-import dagger.hilt.android.scopes.ActivityScoped
-import javax.inject.Inject
-
-@ActivityScoped
-class SignInUseCase @Inject constructor(
- private val repository: AuthRepository,
-) {
- suspend operator fun invoke(email: String): Result =
- repository.signIn(email)
-}
diff --git a/core/domain/src/main/java/com/wap/wapp/core/domain/model/AuthState.kt b/core/domain/src/main/java/com/wap/wapp/core/domain/model/AuthState.kt
new file mode 100644
index 00000000..e603e17d
--- /dev/null
+++ b/core/domain/src/main/java/com/wap/wapp/core/domain/model/AuthState.kt
@@ -0,0 +1,5 @@
+package com.wap.wapp.core.domain.model
+
+enum class AuthState {
+ SIGN_IN, SIGN_UP
+}
diff --git a/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/DeleteUserUseCase.kt b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/DeleteUserUseCase.kt
new file mode 100644
index 00000000..3c08f196
--- /dev/null
+++ b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/DeleteUserUseCase.kt
@@ -0,0 +1,13 @@
+package com.wap.wapp.core.domain.usecase.auth
+
+import com.wap.wapp.core.data.repository.auth.AuthRepository
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class DeleteUserUseCase @Inject constructor(
+ private val authRepository: AuthRepository,
+) {
+ suspend operator fun invoke(): Result =
+ authRepository.deleteUser()
+}
diff --git a/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/SignInUseCase.kt b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/SignInUseCase.kt
new file mode 100644
index 00000000..04df5309
--- /dev/null
+++ b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/SignInUseCase.kt
@@ -0,0 +1,38 @@
+package com.wap.wapp.core.domain.usecase.auth
+
+import com.wap.wapp.core.data.repository.auth.AuthRepository
+import com.wap.wapp.core.data.repository.user.UserRepository
+import com.wap.wapp.core.domain.model.AuthState
+import com.wap.wapp.core.domain.model.AuthState.SIGN_IN
+import com.wap.wapp.core.domain.model.AuthState.SIGN_UP
+import dagger.hilt.android.scopes.ActivityScoped
+import javax.inject.Inject
+
+@ActivityScoped
+class SignInUseCase @Inject constructor(
+ private val authRepository: AuthRepository,
+ private val userRepository: UserRepository,
+) {
+ suspend operator fun invoke(email: String): Result {
+ return runCatching {
+ val userId = authRepository.signIn(email)
+ .getOrThrow()
+
+ userRepository.getUserProfile(userId)
+ .fold(
+ onFailure = { exception ->
+ // 사용자를 조회할 수 없는 예외인 경우
+ val userNotFoundException = IllegalStateException()
+ if (exception == userNotFoundException) {
+ SIGN_UP
+ }
+ // 이외의 예외라면,
+ throw (exception)
+ },
+ onSuccess = {
+ SIGN_IN
+ },
+ )
+ }
+ }
+}
diff --git a/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/SignOutUseCase.kt b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/SignOutUseCase.kt
new file mode 100644
index 00000000..eae7758b
--- /dev/null
+++ b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/auth/SignOutUseCase.kt
@@ -0,0 +1,13 @@
+package com.wap.wapp.core.domain.usecase.auth
+
+import com.wap.wapp.core.data.repository.auth.AuthRepository
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class SignOutUseCase @Inject constructor(
+ private val authRepository: AuthRepository,
+) {
+ suspend operator fun invoke(): Result =
+ authRepository.signOut()
+}
diff --git a/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/user/PostUserProfileUseCase.kt b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/user/PostUserProfileUseCase.kt
new file mode 100644
index 00000000..136b9ddc
--- /dev/null
+++ b/core/domain/src/main/java/com/wap/wapp/core/domain/usecase/user/PostUserProfileUseCase.kt
@@ -0,0 +1,24 @@
+package com.wap.wapp.core.domain.usecase.user
+
+import com.wap.wapp.core.data.repository.user.UserRepository
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class PostUserProfileUseCase @Inject constructor(
+ private val userRepository: UserRepository,
+) {
+ suspend operator fun invoke(
+ userId: String,
+ userName: String,
+ studentId: String,
+ registeredAt: String,
+ ): Result {
+ return userRepository.postUserProfile(
+ userId = userId,
+ userName = userName,
+ studentId = studentId,
+ registeredAt = registeredAt,
+ )
+ }
+}
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/model/auth/SignUpRequest.kt b/core/model/src/main/java/com/wap/wapp/core/model/user/UserProfile.kt
similarity index 60%
rename from core/network/src/main/java/com/wap/wapp/core/network/model/auth/SignUpRequest.kt
rename to core/model/src/main/java/com/wap/wapp/core/model/user/UserProfile.kt
index ea92c9a2..dfa5cd61 100644
--- a/core/network/src/main/java/com/wap/wapp/core/network/model/auth/SignUpRequest.kt
+++ b/core/model/src/main/java/com/wap/wapp/core/model/user/UserProfile.kt
@@ -1,6 +1,6 @@
-package com.wap.wapp.core.network.model.auth
+package com.wap.wapp.core.model.user
-data class SignUpRequest(
+data class UserProfile(
val userId: String,
val userName: String,
val studentId: String,
diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts
index e9672135..ac30dff5 100644
--- a/core/network/build.gradle.kts
+++ b/core/network/build.gradle.kts
@@ -23,6 +23,7 @@ android {
}
dependencies {
+ implementation(project(":core:model"))
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.auth)
implementation(libs.firebase.firestore)
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/constant/FirebaseConstant.kt b/core/network/src/main/java/com/wap/wapp/core/network/constant/FirebaseConstant.kt
new file mode 100644
index 00000000..e41885d6
--- /dev/null
+++ b/core/network/src/main/java/com/wap/wapp/core/network/constant/FirebaseConstant.kt
@@ -0,0 +1,6 @@
+package com.wap.wapp.core.network.constant
+
+/*
+파이어스토어 유저 컬렉션
+*/
+const val USER_COLLECTION = "users"
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/model/user/UserProfileRequest.kt b/core/network/src/main/java/com/wap/wapp/core/network/model/user/UserProfileRequest.kt
new file mode 100644
index 00000000..59968fd6
--- /dev/null
+++ b/core/network/src/main/java/com/wap/wapp/core/network/model/user/UserProfileRequest.kt
@@ -0,0 +1,15 @@
+package com.wap.wapp.core.network.model.user
+
+data class UserProfileRequest(
+ val userId: String,
+ val userName: String,
+ val studentId: String,
+ val registeredAt: String,
+) {
+ constructor() : this(
+ "",
+ "",
+ "",
+ "",
+ )
+}
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/model/user/UserProfileResponse.kt b/core/network/src/main/java/com/wap/wapp/core/network/model/user/UserProfileResponse.kt
index 9d77518b..deb0f61f 100644
--- a/core/network/src/main/java/com/wap/wapp/core/network/model/user/UserProfileResponse.kt
+++ b/core/network/src/main/java/com/wap/wapp/core/network/model/user/UserProfileResponse.kt
@@ -1,8 +1,24 @@
package com.wap.wapp.core.network.model.user
+import com.wap.wapp.core.model.user.UserProfile
+
data class UserProfileResponse(
val userId: String,
val userName: String,
val studentId: String,
val registeredAt: String,
-)
+) {
+ constructor() : this(
+ "",
+ "",
+ "",
+ "",
+ )
+
+ fun toDomain(): UserProfile = UserProfile(
+ userId = userId,
+ userName = userName,
+ studentId = studentId,
+ registeredAt = registeredAt,
+ )
+}
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSource.kt b/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSource.kt
index 8a8009bf..d728e538 100644
--- a/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSource.kt
+++ b/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSource.kt
@@ -5,9 +5,7 @@ interface AuthDataSource {
suspend fun signIn(email: String): Result
- suspend fun signUp(): Result
-
suspend fun signOut(): Result
- suspend fun resign(): Result
+ suspend fun deleteUser(): Result
}
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSourceImpl.kt b/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSourceImpl.kt
index 30c73bc4..09b5a1d6 100644
--- a/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSourceImpl.kt
+++ b/core/network/src/main/java/com/wap/wapp/core/network/source/auth/AuthDataSourceImpl.kt
@@ -33,15 +33,18 @@ class AuthDataSourceImpl @Inject constructor(
}
}
- override suspend fun signUp(): Result {
- TODO("Not yet implemented")
- }
-
override suspend fun signOut(): Result {
- TODO("Not yet implemented")
+ return runCatching {
+ firebaseAuth.signOut()
+ }
}
- override suspend fun resign(): Result {
- TODO("Not yet implemented")
+ override suspend fun deleteUser(): Result {
+ return runCatching {
+ val user = checkNotNull(firebaseAuth.currentUser)
+
+ user.delete()
+ .await()
+ }
}
}
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSource.kt b/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSource.kt
index 749533b3..4b261118 100644
--- a/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSource.kt
+++ b/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSource.kt
@@ -1,7 +1,10 @@
package com.wap.wapp.core.network.source.user
+import com.wap.wapp.core.network.model.user.UserProfileRequest
import com.wap.wapp.core.network.model.user.UserProfileResponse
interface UserDataSource {
+ suspend fun postUserProfile(userProfileRequest: UserProfileRequest): Result
+
suspend fun getUserProfile(userId: String): Result
}
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSourceImpl.kt b/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSourceImpl.kt
index c40fc34c..093318d1 100644
--- a/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSourceImpl.kt
+++ b/core/network/src/main/java/com/wap/wapp/core/network/source/user/UserDataSourceImpl.kt
@@ -1,3 +1,44 @@
package com.wap.wapp.core.network.source.user
-class UserDataSourceImpl
+import com.google.firebase.firestore.FirebaseFirestore
+import com.google.firebase.firestore.SetOptions
+import com.wap.wapp.core.network.constant.USER_COLLECTION
+import com.wap.wapp.core.network.model.user.UserProfileRequest
+import com.wap.wapp.core.network.model.user.UserProfileResponse
+import com.wap.wapp.core.network.utils.await
+import javax.inject.Inject
+
+class UserDataSourceImpl @Inject constructor(
+ private val firebaseFirestore: FirebaseFirestore,
+) : UserDataSource {
+ override suspend fun postUserProfile(
+ userProfileRequest: UserProfileRequest,
+ ): Result {
+ return runCatching {
+ val userId = userProfileRequest.userId
+ val setOption = SetOptions.merge()
+
+ firebaseFirestore.collection(USER_COLLECTION)
+ .document(userId)
+ .set(
+ userProfileRequest,
+ setOption,
+ )
+ .await()
+ }
+ }
+
+ override suspend fun getUserProfile(
+ userId: String,
+ ): Result {
+ return runCatching {
+ val result = firebaseFirestore.collection(USER_COLLECTION)
+ .document(userId)
+ .get()
+ .await()
+
+ val userProfile = result.toObject(UserProfileResponse::class.java)
+ checkNotNull(userProfile)
+ }
+ }
+}
diff --git a/core/network/src/main/java/com/wap/wapp/core/network/utils/FirebaseUtils.kt b/core/network/src/main/java/com/wap/wapp/core/network/utils/SuspendCoroutine.kt
similarity index 100%
rename from core/network/src/main/java/com/wap/wapp/core/network/utils/FirebaseUtils.kt
rename to core/network/src/main/java/com/wap/wapp/core/network/utils/SuspendCoroutine.kt